[I can’t squeeze any more acronyms into this title]

It’s probably very easy to setup an STM32F4 as a virtual com port (VCP) with the CubeMX software, but I’m getting old and new tricks are getting increasingly hard to learn, so I did it with the standard peripherals library (SPL). Here’s how:

Download the STM32 SPL USB OTG host and device library.

Unzip to somewhere. It should give you a directory like this:


Download the USB CDC VCP Loopback firmware and place the zip-file in the above directory and unzip.

Set the HSE-frequency in:


Modify this file:


Specifically line 98. Change the declaration of *pIf_DataTx from
uint16_t (*pIf_DataTx) (void);
uint16_t (*pIf_DataTx) (uint8_t* Buf, uint32_t Len);

You will of course need the gcc-arm-none-eabi compiler, and put it in your path, so add a line similar to this to .bashrc:

export PATH=/home/user/gcc-arm-none-eabi-4_9-2015q1/bin:$PATH

(of course change “/home/user” and the version number).

After that it should simply be a matter of entering the directory of the firmware and typing make.

Let me know if it’s not working for you..

ps. I realize there’s a more straighth-forward example in the project-directory of USB library, but I just couldn’t get it working.


Inverting and scaling

Fiddling a little (I don’t have a fiddle) with the resistors for the opamp, I finally ended up with this:


It’s the thorlabs logo again, covering the TCD1304. The opamp (AD8027) has scaled end shifted the output to match the ADC’s range. Zero light corresponds to 145mV and full saturation is around 3.23V.

I don’t think I can get closer to 0-3.3V than this without buying fancier resistors. The values are:

R₁ = 510
R₂ = 1k
R₃ = 620
R₄ = 510

for this:


Not exactly what LTspice suggested, but who cares.

Oh yeah and with everything soldered up, it looks like this:


Pin headers for the GPIOs and u.fl. connector for the analogi input.

Did I mention USB is working.. someday soon I’ll have the firmware ported to the STM32F405 🙂

An ideal world

I’m still trying to figure out the purrrfect combination of resistors for the opamp-section of the new STM32 board.

The circuit is the same as my previous experiments with signal conditioning:


Gain is still:

G = - R₂ / R₁

and the level shift is still:

S = R₄/(R₃+R₄)·(1+R₂/R₁)·Vref

The output voltage still becomes:

Vout = G·Vin + S = -R₂/R₁·Vin + R₄/(R₃+R₄)·(1+R₂/R₁)·Vref

Having learnt to use LTspice a little since last, I thought it best to simulate the circuit before putting the iron to the solder. And it works just as it’s supposed to ..until the typical drive circuit from the CCD is connected. Which, in case you spent your life with something meaningful and hence forgot, is here:

tcd1304 typical drive circuit

Then it looks like this:


The green trace is the output from the CCD. The blue trace is the input for the opamp. The red trace is the output from the opamp. The blue trace is clipped. Having read some excellent posts on HaD I didn’t understand about transistor biasing, I thought this could be remedied by adjusting the resistor values around the 2SA1015, and sure enough:

By replacing the 150R resistor to gnd and the 2k2 resistor to +4V with 50R and 150R respectively, everything is back to what it’s supposed. (If any clever ee-geniouses knows if this is not a good idea, please let me know asap). The circuit now looks like this, well in LTspice it looks like this:


And the simulation like this:


No clipping this time 🙂 But of course as my good friend Kensha’s dog Feynmann would say, it’s nothing without an experiment. And so I soldered up the opamp with the resistors (and changed the two on my TCD1304-board).

And of course it didn’t work.. Well it sort of did. The input doesn’t clip (and I tried with the CCD in an unaltered circuit, and the clipping is real with the old resistors). It’s just that I didn’t measure the output from the CCD’s drive circuit with adequate precision before, and so the gain and the level shift needs adjusting.

Which is why I’m writing all this, so I won’t forget about my latest findings. So back to the algebra:

The CCD’s drive circuit delivers output from just above 1.45 V to just under 3.10 V when connected to the opamp (this will sure change with R₁ and R₂).

So anyway, the gain should be (the ADC range is actually 0-3.3V, but playing it safe I’m aiming for a signal range of 3.2V):

3.2V = G(3.10V - 1.45V)     
G = 3.2V/(3.10V - 1.45V) = 1.94

So I will try R₂ = 750R and R₁ = 390, once I get some more time on my hands.

With an input of 3.10V I’d like an output of 0V (slightly above, to keep the ADC happy), so the next equation becomes (the gain is actually negative, because the opamp is in inverting mode, so observe the signs):

Vout = G·Vin + S
S = Vout - G·Vin = 0.05V + 1.94·3.10 V = 6.064V

To find nice resistor values for R₃ and R₄, we need to look at S’ dependence on those:

S = R₄/(R₃+R₄)·(1+R₂/R₁)·Vref
6.064V = R₄/(R₃+R₄)(1+1.94)·Vref
6.064V/(2.94·Vref) = R₄/(R₃+R₄)
6.064V/(2.94·Vref)·(R₃+R₄) = R₄
6.064V/(2.94·Vref)·R₃ = R₄(1 - 6.064V/[2.94·Vref])
R₃ = R₄·(1 - 6.064V/[2.94·Vref])/(6.064V/[2.94·Vref])

Vref is 4.65V, so this all then becomes:

R₃ = 1.254·R₄

So I will try with R₃ = 620R and R₄ = 510R  ..but not tonight. I deserve TV now.

Replacing the STM32F4 nucleo

If you are a recurring visitor of this blog you probably know that the detector in the Raman spectrometer is the TCD1304DG linear CCD, driven by an STM32F401RE nucleo board. If not, you do now. And it looks like this:


The firmwares for the STM32F401 are stable, and I’ve not encountered any problems or bugs in neither the SPI- nor the UART-version.

Each firmware has its merits.

The UART-version is usable with any computer with a USB-port, but because of the limitations of the ST-link’s implementation of a virtual com port it’s rather slow and cannot achieve frame-rates much higher than 1 Hz. This is not a problem for Raman spectroscopy which will probably require long integration times anyway.

The SPI-version is fast, but requires a raspberry pie or something else with an SPI-controller. The frame-rate can be as high as 125 Hz (or higher still, with a slight modification of the DMA-setup). This is high enough that it can be used for glowstick kinetics.

But regardless of the firmware, the nucleo board is not tailored for reading the CCD. The CCD output needs conditioning to match the input range of the ADC, and a (very) cheap development board like the nucleo doesn’t include that.

I’ve tried to do the signal conditioning on the TCD1304 circuit board:


While very cramped it works. However it didn’t do anything positive (or negative) for the noise that always seems to be present, even with very low noise voltage regulators like this (here there’s no opamp for signal conditioning):


the noise is still there:


ok maybe it doesn’t look super-noisy, but in this graph (which is one of the cleanest) the baseline is constantly fluctuating ±4 mV. 8 mV doesn’t sound like a lot, but it’s actually a magnitude higher than the resolution of the ADC (and it’s evident from the data, that it’s not the register imbalance of the CCD in play).

So after a few different PCBs (with and without opamp) the conclusion is that the noise is inherent to the nucleo board. Whether it’s the board’s layout or the choice of voltage regulators I don’t know, though Bertrand in Switzerland suggested that it could be the connection and choice of wire between the nucleo and the CCD (he’s most probably right).

Anyway, it’s great to have an excuse to try something new, and here is the substitute for the nucleo board¹:


It’s an STM32F405RG on a 4-layer PCB, with discrete power planes for the digital and analog parts of the board. All regulators have a noise level of 20 µV (that’s 40x beneath the ADC’s LSB). The analog section features a ±4.65 V power supply for the four AD8027 high speed, low distortion, rail-to-rail opamps (not fitted).

The circuit around opamps U0 and U1 looks like this:


(correct for the supply voltages) and the simulation like this:


(sorry for the mess of the circuit). The blue trace represents the signal from the TCD1304 in the LDO-version of the PCB. The green trace is the conditioned signal, inverted and scaled to fit the range of the ADC.

The plan is to use STMicro’s USB-driver to attach the board as a virtual com port. So far the DfuSe bootloader appears to be working, but I’m back to scratch for getting my compiler to produce working binaries.

Being an absolute dummy with makefiles this may take a while..

Update: I hugely overestimated the troubles I would have with this last part. I can’t even remember what I changed in my f401 makefile (though I do know I did change something).

The board is working. At least my blinky works, and initial speed test with a timer yielded a timer clock with the expected 72 MHz. Which means that the clock configuration is correct:


[1] The board is inspired by the STM32F4Stamp and I’ve tried to follow all recommendations in the datasheets and application notes for every component. Still I’m sure there’s room for improvement.

Other sites of interest

Here’s a list of pages I find interesting (occasionally steal inspiration from):

    A belgian chemist and optical engineer who does many different things from counting bubbles to building thin film refractometers.
    A subsection of the astrosurf site with a lot of information for building spectrometers. (There’s lots more on the astrosurf site itself.)
    T.J. Nelsons site contains information about lens and spectrograph design.

The list is so I don’t forget about these resources (because I’m sure I already forgot some). Feel free to send me more links.


(my) Latest spectrograph advances

With my girlfriend out of the flat for a few days, it was time to finally do something about the spectrograph. If you’ve been looking at my hackaday projects you may know I’m trying to make a Gil-Simon spectrograph.¹

Much like nuclear fusion reactor technology, my Raman spectrometer has been close to completion since the beginning, and right now I’m closer than ever, and I have the pictures to prove it:


All mirror mounts approximately in their final positions.

As evident from the photo, I’ve become quite adept at anodizing aluminium.

The geometry of the spectrograph is more apparent here:


Here a few of the mirrors are in place:


In the vertical mount: Two 90° off-axis parabolic mirrors (OAP).
In the top center kinematic mount: A 25,4mm elliptical plane mirror.

The mirrors work: The reflection of Little My is caught by mirror on the aluminium angle on the right and focused by the two OAPs:


Unfortunately my 3D printer is out of commision for the time being, so for the time being, I cannot print a mount for the grating..

[1] M. A. Gil and J. M. Simon, “New plane grating monochromator with off-axis parabolical mirrors,” Appl. Opt. 22, 152-158 (1983)