The picture above shows an arduino interpreting the drive signals of an LCD clock and feeding them to the serial port. A truly silly way to tell the time but an interesting exercise.
It’s a follow-on to this http://arduino.cc/forum/index.php/topic,51464.0.html project where I was driving the same LCD directly from the arduino and someone on hack-a-day posed the question of whether you could READ the LCD signals.
These clocks were remaindered at Staples after Christmas. They have motors and wheels to run around and, more importantly for this project, they have LCDs with relatively huge, easy to solder, connectors.
LCDs like this are multiplexed with four common connectors called backplanes that go sort-of horizontally across the display and eight segment connectors that address separate vertical slices. To activate a particular segment/backplane you put a square wave across the two with at least a couple of volts potential. To keep the other segments from lighting up you keep them no more than 1.5 volts from the backplanes. The segments can’t stand ANY DC voltage so you have to weave a complex pattern to light up the ones you want at any given time. My driver circuit used only three voltages in a simple pattern but commercial drivers use more levels, probabl to get more separation between signal levels. See http://ww1.microchip.com/downloads/en/AppNotes/00658a.pdf and the picture below.
When I was developing my LCD driver proof of concept I had to map the segment and backplane connectors of the LCD. Each of the three full digits occupies two of the segment drivers across the four backplanes as shown below for the second digit. The first digit is a special case using only one segment connector.
The picture below shows the four backplanes waveforms and one pair of segment waveforms lighting up the segments for the digit “2”. The time for each part of the cycle is about 4 ms. If you look for example at state 0, BP1 is at 0 volts, S2 is at 1 volt, and S3 is at 3 volts. With a 1 volt difference S2 will not be activated but with a 3 volt difference, S3 will be active. So the topmost segment which is where S3 and BP1 intersect will be active. Similarly if you look at the other states you can trace which segments are active. Generally the second four states are a mirror image of the first four.
In principle then, you can tell if a segment is lit by continuously reading the backplane and segment waveforms and watching for voltage differences. There are two things wrong with that, both have to do with the arduino’s analog inputs.
The first problem is that the arduino’s analog pins present about a 10K impedance and that is low enough to interfere with the LCD driver. Once I hooked up more than one or two segments I got the whole LCD fading on me – oops. A simple op-amp buffer circuit worked a treat to beef up the signal and keep from loading down the clock’s LCD drivers. The second problem is that to read all seven digit signals and the four backplanes would take 11 analog inputs and the arduino has only six. I worked with the four backplanes and a single digit while I struggled with this and gradually came to a solution. Because the backplane signals always repeat in a cycle of eight transitions, I only had to read one of them to synchronize with the cycle then I would know the other three automatically. Also, I realized that I could use the op-amps as more than buffers: I made a second op-amp circuit that multiplied the input voltage by 10 so anything except a zero would look high to the arduino. This worked perfectly to help me synchronize with one backplane and to interpret the signal on the first segment connector.
The picture below shows the whole setup. The ribbon connector on the right carries the backplane and segment signals from the clock. It also connects the grounds and carries power back to the clock. The diode at the extreme right drops the 5v of the arduino a bit for the clock which runs normally on 4 Aas.
The first op-amp amplifies the signals of the first backplane and the first segment pins and connect to digital pins 2 and three respectively. The other three are the buffers for the six segment pins driving the 3 other digits and connect to the analog pins.
The code below uses the backplane on digital pin 2 to synchronize itself with the clock. It establishes a state variable and increases the variable every four ms. In each state it samples each of the segments and compares it with the known backplane voltages for that state. If a segment shows a difference of two volts from a backplane it records the segment and backplane in the seglit array. It doesn’t care which state or how many times the segment is lit – just that it is. After the eight cycles are done, it assembles the segments for each digit and looks up in a table to see what digit is represented by that pattern. It sends the digits out on the serial port where it’s displayed by the pc.
The version below just runs once. I’ve had it rigged to run continuously and watch for changes in the digits to send back but it tends to get flakey results doing that and I’m not sure why.
Conclusion. So, this is doable but not all that practical. You have to know the details of the waveform your circuit uses and be prepared to solder into it. I can see some special case where knowing the state of a particular segment you would need only two connection points but it might be easier to either watch that spot with an optical sensor or trap an output like an alarm.