The output of the CCD – without any circuitry – is app. 0.6V-2.5V. When placed in the drive circuit from in datasheet the output voltages are app. 1.2V-3V.

Neither of them is good match for the range of the ADC in the STM32F401RE – and then there’s the annoying thing with the inverse relationship between exposure and output-voltage.

One solution to this problem is to use an opamp in inverting mode before the ADC, to invert and scale the output from the CCD to match the 0-3.3V input range of the STM32F4’s ADC. I’ve used the AD8027, which is a high speed rail-to-rail opamp, in a circuit like this:

The ±4.65V supply voltages are generated from the USB’s 5V. A charge pump inverts the supply voltage to -5V, and the positive and negative rails are regulated down to the ±4.65V by two low-noise low drop-out regulators.

The gain is:

`G = - R₂ / R₁`

we have an input range of 1.9V, but want 3.2V (actually 3.3V but I don’t want to saturate the ADC-input), so G should be -1.68.

The level shift is:

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

The output voltage then becomes:

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

The following values gave an output close to the limits of the ADC’s range, when using the TCD1304 in the typical drive circuit (supply voltage 4V):

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

However, the input and feedback resistors affect the drive circuit, so the 150R resistor to gnd and the 2k2 resistor to +4V must be replaced with 50R and 150R respectively.

The solution above is implemented in two different circuit boards:

The custom MCU-board is considerably more complex than the shield and I’ve yet to confirm if there are any benefits (except for a direct USB-connection) over the simpler shield for the nucleo.

The custom board looks like this:

Details can be found at the HaD project-page.