Sunday 5 October 2014

Fun with a Linear CCD

Some time back, Billy gutted a USB scanner, so he could grab the fun parts like mirrors, steppers etc. He sent me the board with the sensor on it, in the vague hope I might be able to do something with it. Sadly, I didn't take a picture of the original board then. Initially, I looked over the board, and could identify the memory, the scanner USB chip, and the fact there was a linear CCD onboard. After figuring out there wasn't anything much I could do quickly, it sat on the side for a while. Eventually, I figured that I should do something with it, and if I was going to do anything with it, I'd need to figure out how to interface with the CCD. If nothing else, I figured this would be a good learning exercise.

As the top of my linear CCD is the light sensitive part, there were no part markings on the top. This meant that if I wanted to know the part number, I'd have to unsolder it from the board before I could find much more out about it. The device is a 22pin DIP package on a fairly tight board, so unsoldering it was a bit of fun, especially as I didn't want to damage the part. Ultimately, I ended up taking a cutting tool to the PCB so I could remove the majority of the PCB around the CCD, and then unsolder the CCD without the clutter of the rest of the board. I was left with the following part:


Before I had removed it, I'd tried to take some guesses at what part it might be, based on the bits of pinout I could determine. I spent far too much time trying to find datasheets for 22 pin linear CCDs! I'd ended up suspecting a Toshiba part, but nothing conclusive. Once I'd removed the part, it was pretty clear that it was a Sony part, an ILX555K. This is a colour 10680 pixel by three line CCD linear sensor. Basically, it means there's three rows (red, green and blue) of 10680 pixels that you can read from! That's a fair number of pixels more than I was expecting, so this might be more challenging than I was hoping for. Looking at the block diagram that was on the datasheet, I'm slightly more mystified as to how the device is driven (or how it works), but it's worth a shot playing with it anyhow.


If you're anything like me, you're probably looking at that, wondering what and how it works! This was further not helped by the pin description of the device, which read like this:

Pin No.
Symbol
Description
Pin No.
Symbol
Description
1
NC
NC
12
NC
NC
2
φ1
Clock pulse input
13
NC
NC
3
φRS
Clock pulse input
14
φROG-G
Clock pulse input
4
GND
GND
15
φ1
Clock pulse input
5
VOUT-G
Signal out (green)
16
NC
NC
6
VDD
12V power
17
VOUT-R
Signal out (red)
7
Φ2
Clock pulse input
18
VOUT-B
Signal out (blue)
8
φROG-R
Clock pulse input
19
GND
GND
9
φROG-B
Clock pulse input
20
GND
GND
10
NC
NC
21
Φ2
Clock pulse input
11
NC
NC
22
NC
NC

I can tell there's a lot of clock pulses going on here, but I'm not really sure what they do. There's a few clock timing charts later on, which really help the clueless though. The power supply indications are that I need to provide 12V for the CCD, although fortunately the datasheet indicates that the inputs are CMOS 5v compatible. Sadly, as I'm going to be using a Fubarino SD, this rather means I'm going to have to do level translation from 3.3V up to 5V. I have a 74HCT244 device somewhere, and that's just about perfect for this application. At this point, I'm not going to try to read the output of the device, as I'm not sure exactly what it looks like. I do know that the datasheet indicates that there's an offset level of 4.7v, which seems to suggest that a dark pixel is at 4.7v above ground. It also suggests that a dark pixel has the highest voltage - this fits with my limited understanding that the CCD leaks charge when hit with light. The datasheet also indicates that the saturation voltage is 1.8V, so we know the output is between 4.7v and 1.8v, a range of 2.9v total. Sadly, the Fubarino SD DAC runs between 0v and 3.3v, so I'm going to have to do some level shifting and some minor amplification before I can read the data.

The great news is that Sony provide an example application circuit, which is helpful (somewhat). They indicate the following:

This gives me a good basis to start with. Rather than use the 74AC04, I can just drop my 74HCT244 in, and I can use the rest of the circuit as a template to begin with. This is something that I can build up on a breadboard as a proof of concept, before I try anything more. Without further ado, I end with something like this:


(Yes, there's a 7805 regulator to take the 12V down to 5V for the 74HCT244. The Fubarino SD has it's own LDO regulator to drop down to 3.3v). When putting the circuit together, I chose to use pins that were on the same port, so that I could toggle several simultaneously.  Now that the hardware is "ready", there's some software to write too. Fortunately, Sony provide a timing diagram to help understand how to drive it:


One thing that is of interest here is that although the chip has three φROG lines, the timing diagram only indicates one. From further research, the φROG lines simply transfer charge from the sensor itself to a readout gate, where they won't be affected by further exposure to light. It also seems to reset all the sensor pixels back to a dark level ready for the next set of readings. This means the device doesn't have a shutter per se, instead the integration time being the time between one φROG and another. There's also only one set of φ1 and φ2 lines, which helps to show that we can drive both φ1 lines as a single line, and both φ2 lines as a single line. At a basic level, the φ1 and φ2 lines step the charges through the readout register, so they're presented one at a time at the output. The φRS line resets the charge on output amplifier, so that it's ready to accept the output of a new charge from the readout register.

Knowing that, with the timing diagram, the code basically becomes something like the following:

// known state
PORTD = P1 + RS;
delayMicroseconds(1);

PORTD = P1 + RS + ROG;    // transfer charge to readout register
delayMicroseconds(5);
PORTD = P1 + RS + _TRIG;  // Ready to read new line
delayMicroseconds(2);
PORTD = P1 + RS;
// start readout
for (cntr = 0; cntr<10757; cntr++) {
       PORTD = P2;                // φP2 Shift pixel into output
       pixVal = analogRead(A0);   // Read pixel data output
       PORTD = P1;                // Shift pixels along
       PORTD = P1 + RS;           // Zap charge on transfer gate
       asm("nop\n\t""nop\n\t""nop\n\t""nop\n\t");  // meet φRS high level period.
       PORTD = P1;                // Get ready to repeat
       asm("nop");

}

Running this code without the CCD attached gave me some waveform that looked approximately correctly. The next step is to take a deep breath and try it with the CCD attached. Sadly, I didn't get what I expected out. After much searching, it turned out to be a connection that was made incorrectly on the breadboard! Fortunately I have a current limiting power supply set fairly low, otherwise there would have been a nasty amount of 12V being injected into my output buffer!

Fixing this problem and trying again looked more successful. I'd placed an object on top of the CCD, so that the middle was in shadow. I then illuminated it so that I'd be able to see the "shadow" in the output. Hooking a scope up to the output got me the following:


The green trace is the output from the output transistor, and the blue trace is my trigger signal to sync the oscilloscope up. So far so good! I get a recognisable waveform out. The next step is to deal with the offset so the output can be digitised.



9 comments:

  1. Thanks for taking the time to figure this and write it up.

    I just pulled an identical part from a junked scanner left by the side of the road near my house, and Google image search led me here. The datasheet link is especially useful.

    Mine is still on its original board from the scanner. There are some SN74ACT244 buffers that I guess were used to clean up the clock signals after their long, noisy path through the scanners guts from the logic board and a few transistors that I suspect might provide amplification to the CCD voltage outputs for its similarly noisy path back.

    If I get it working, then I'll let you know.

    ReplyDelete
    Replies
    1. It'll be interesting to hear how you get on! I'd recommend you take a look at the datasheets for image signal processors - there's a fair few ideas that will make life much easier in there. Things like correlated double sampling (CDS) and switched capacitors can make life easier in the long run. For example, the Circuit Operation section in the AD9826 datasheet ( http://www.analog.com/media/en/technical-documentation/data-sheets/AD9826.pdf ) has some good detail.

      Delete
  2. I need some help in a similar project. Can you help Graham, please?

    ReplyDelete
    Replies
    1. Hi Petr. You'll need to give more details about what you're trying to do and what problems you've having.

      Delete
  3. I was almost giving up to understand an Sony ILX-533, but when I found your site, my hope was renewed; since ILX-555 has almost same circuit than ILX-533.
    Thanks for sharing!

    ReplyDelete
  4. What is _TRIG in PORTD = P1 + RS + _TRIG

    ReplyDelete
    Replies
    1. From memory (as it was a while ago), I think I used it to trigger my scope that a new line readout was about to happen.

      Delete
  5. Awesome! So I don't need _TRIG right? (Sorry, I'm an arguing newbie).

    ReplyDelete
    Replies
    1. no, you don't definitively need it. It's just useful if you're trying to debug what was going on (or wrong!)

      Delete