Wednesday 3 December 2014

Trying to read from a linear CCD

I found some more time to play with the linear CCD that Billy had sent me. If you remember last time, I'd managed to get a working clock signal and I could "see" the output on an oscilloscope. In some ways, that was the easy bit! Actually getting the output into a digital form is harder than it looks.

A linear CCD has some interesting characteristics, due to how it operates. If I want to get the output into a digital form, I needed to understand how to deal with a few things:
  • The output voltage is the inverse of the amount of light falling.
  • The output voltage has an offset.
  • The output voltage "spikes" above the maximum signal during clocking.
  • The device can suffer saturation, where too much light enters for the integration time (shutter).

Inversion

The linear CCD works by charging the CCD elements with a known amount of charge. Exposing those elements to light causes the charge to leak away, proportional to the amount of light that falls on the elements. The higher the sensitivity of the CCD, the less light to cause the charge to leak away.

When it comes to the read out gate, the packet of charge is converted into a voltage. A CCD element that wasn't exposed to the light will have a high charge, whereas one that is exposed will have less charge. This means that darkness is the highest voltage, and lots of light is the lowest voltage. Obviously to make sense of the image, I need to invert it, so that black is the lowest digital value. This is probably easiest done in software.

Offset voltage

The offset voltage is the most troublesome part. The output voltage is for black is about 4.7v, and the output voltage for saturated pixels is between 1.5 and 1.8v. I measured 1.8v when I tested the saturated output.  I could simply feed the output into an ADC, but the Fubarino SD's ADC is strictly 3.3v maximum. The ADC pins are not 5v tolerant, so I'd kill the Fubarino if I tried. I could use an external ADC, but that's more work than I wanted to do at the time. I had a couple of ideas I wanted to try; the most obvious (to me) was to use an op-amp to level shift.

Voltage spikes

The output voltage spikes above the black level when the readout gate is reset (φRS), so even a 5V ADC wouldn't be suitable here. I need to find a way to ensure that these spikes don't affect the ADC.

Saturation

One interesting observation with the linear CCD was that when the output is saturated, it affects other pixels. A high enough level of saturation even affects the dummy black pixels at the start and end of the line! This means I need to be careful to avoid saturation if I want any sensible output from the device. On the other hand, the dummy pixels being at the wrong level gives me a big warning that the device has saturated, and the results are meaningless. I can reduce the integration time and try again.

Op-amp solution

My first attempt was to use an op-amp solution, where an op-amp is used to correct the voltage offset, together with some gain to fill the ADC range. I thought I'd be clever and use a programmable offset, as the PIC32 on the Fubarino SD has an adjustable comparator reference (Thanks to Tahmid for identifying this). I can use that as a basic DAC to generate the reference voltage for the opamp. A quick bit of calculation, and I end up with a circuit like the following:

This should allow the PIC32 to provide a voltage offset to the op-amp, which will use that to null the output from the CCD. The op-amp has minor gain to better fill the ADC range on the PIC32. Making the output voltage fill the range of the ADC helps to get the most out of its 10 bit resolution, making it worthwhile trying. I happened to have some LM358 op-amps lying around, so I decided to put one of them to use. At this point in time, I'm only using a single output from the linear CCD, but being a colour device it has three outputs (red, green and blue).

My first attempt? I didn't get a lot of sense out of the ADC - all the voltages looked rather similar. I ended up putting a scope on the output from the op-amp, and quickly discovered it just didn't have the bandwidth to handle the signal! On the other hand, the offset worked, but not well due to noise from the PIC32 ending up on the comparator reference. I ended up putting a large delay of about a microsecond just before each ADC conversion. This allowed the op-amp to keep up, but made reading quite slow.

Obviously this isn't going to work well, so time for a different idea.

Switched capacitor idea

I can use a capacitor and some analog switches to perform the level shifting. Basically, I charge the capacitor up to 3.3V when a black reference voltage is output (one of the 60 black pixels at the start of a line), The capacitor then acts as the level shifter (assuming it doesn't discharge too quickly!). The analog switches deal with switching the 3.3V onto the capacitor, as well as switching the capacitor out of the signal path at the right time. The following picture is a rough idea - obviously this needs to be worked out in a bit more detail!


There's a few more subtles in getting a good output from a linear CCD, such as correlated double sampling to help to remove some noise from the output. This appears to be done by subtracting the reference voltage from the signal voltage, but I'm not sure I'm ready to try to figure out differential sampling yet.


No comments:

Post a Comment