Go Down

Topic: Driving a Salvaged LCD Directly from Arduino (Read 12030 times) previous topic - next topic

bill2009


Probably lots of us have poked at an LCD from a clock or wherever and wondered what it would take to drive it.  I've even taken a multimeter to one to see what the voltages looked like.  I never got far doing this but I did break some lcds.

After a lot, a lot, of reading and googling around I discovered the two issues:
Most LCDs that you see around are multiplexed.  For something like a clock with 7 segment digits, there's a set of 4 backplane connectors that connect to the same parts of each digit and a set of segment connectors that connect to one particular digit; and LCDs require an AC voltage to drive them - the segment will be visible if it gets a voltage of more than 2V relative to a backplane but that voltage can be positive or negative and it HAS to even out to zero over a few tens of ms.

The result, when you look at waveforms is something like this with the backplanes and segments dancing around multiple voltage levels.


The best general reference on LCDs I found was http://ww1.microchip.com/downloads/en/AppNotes/00658a.pdf.  That shows how they're connected and driven.  I later found an atmel application note http://www.atmel.com/dyn/resources/prod_documents/doc8103.pdf that shows you how to drive a multiplexed LCD with the avr's digital I/O pins.

I had all this stuff percolating when I came across these little runaway alarm clocks for $2.50 in our local Staples.  I took one apart finding great little motors, wheels with tires, a battery holder, and an LCD setup that looked like it would be easy to get test probes on and inject signals into.




By the way, I used to think those elastomeric connectors between an LCD and circuit board were from the devil but they're actually great for hacking.  I did what I've done before and used little bits of post-it notes to insulate the connectors from the circuit one at a time and identify the eight segment and four backplane pins.  With a scope I was able to see the typical stair-step voltages on the backplanes and segments.  I drew myself many many little signal diagrams and built a spreadsheet and finally a segment/backplane diagram.


The segments turned out to be particularly easy to understand.  The leftmost digit could only be 1 or blank and each of the other digits needed two segment pins: sort of for the left side of the digit and the right side.  For my proof of concept I'm only actively driving one digit so I only need two segment pins.

Armed with this and the info from the application note I built a proof of concept driver.  To get three voltage levels for the backplanes, I tied each of the pins to ground through a 33K resistor.  If I set the arduino's pin as output it could easily pull that to VCC or 0 and, if I set the pin to input with the pull-up resistor enabled I got a nice balance at ½ VCC.  I used a 3V supply to run the AVR chip because the highest voltage I'd seen driving the LCD was around 3V.


The software feels clumsy to me but it proves the concept.  The main loop just sets the single digit to be displayed and repeatedly calls the display driver.  The display driver keeps track of millis() and every 4ms it advances a state counter.  Each state from 0-7 defines a half cycle for one of the backplanes: backplane 1 in states 0 and 1, backplane 2 in states 2&3, backplane 3 in states 4 and 5, and backplane 4 in states 6 and 7.
I have a particular application in mind for this and I'll use a timer interrupt to better separate the functions.
Code: [Select]
#include <Streaming.h>
#define cout Serial
#define endl '\n'
const int BP1=7, BP2=9, BP3=8, BP4=10; //backplanes
int S1=11, S2=6, S3=12; //segment outputs.  S1 is always blanked, S2&3 are driven

void setup()
{
  Serial.begin(19200);
  cout <<"Hello from the clock LCD test mule \n";
  pinMode(S1,OUTPUT); pinMode(S2,OUTPUT);pinMode(S3,OUTPUT); //segments are live
}

void loop(){
  int displaydigit= (millis()/1000)%11; //test pattern cycles from 0 to 10
  drivelcd(displaydigit);
}


void drivelcd(int digit){ //drive the LCD to display a digit
  //each of the LCD backplanes is cycled low then high for 4ms while the others are held at a middle-voltage
  //the segments are lit by setting them opposite to the active backplane
  //each bit in the digit segment table below defines the state of a segment for a particular backplane for that digit
  //the segment 2 bits are first then the segment 3 bits
  //e.g. for a 0(the 1st element) segment 2 is on for backplanes 2 and 4 (0101) and segment 3 is on for all of them(1111)
  const unsigned char dst[]={0b01011111,0b00000110,0b00111101,0b00101111,0b01100110,0b01101011,0b01111011,0b00001110,0b01111111,0b01101110,0b01111110}; //digits 0-A
  static int stateprev=8; //tells us when we change states
  int statenow=(millis()/4)&0x07; //cycles from 0-7 changing every 4 ms
  if (statenow!=stateprev){ //if the state has changed
    //reset backplane pins to input and activate the pull-up resistors
    pinMode(BP1,INPUT); pinMode(BP2,INPUT);  pinMode(BP3,INPUT);pinMode(BP4,INPUT);
    digitalWrite(BP1,HIGH);digitalWrite(BP2,HIGH);digitalWrite(BP3,HIGH);digitalWrite(BP4,HIGH);
    switch (statenow) {
      case 0:
        pinMode(BP1,OUTPUT); digitalWrite(BP1,LOW); //activate backplane 1 for 1st half of its cycle
        digitalWrite(S1,LOW); //ensure segment 1 stays blank
        digitalWrite(S2,(dst[digit]&0x80)>>7); //activate segment 2 if needed
        digitalWrite(S3,(dst[digit]&0x08)>>3); //activate segment 3 if needed
        break;
      case 1:
        pinMode(BP1,OUTPUT); digitalWrite(BP1,HIGH); //set BP1 2nd half of its cycle
        digitalWrite(S1,HIGH); //ensure segment 1 stays blank
        digitalWrite(S2,!digitalRead(S2)); //toggle segment 2
        digitalWrite(S3,!digitalRead(S3)); //toggle segment 3
        break;
      case 2:
        pinMode(BP2,OUTPUT); digitalWrite(BP2,LOW); //set BP2 1st half of its cycle
        digitalWrite(S1,LOW); //ensure segment 1 stays blank
        digitalWrite(S2,(dst[digit]&0x40)>>6); //activate segment 2 if needed
        digitalWrite(S3,(dst[digit]&0x04)>>2); //activate segment 3 if needed
        break;
      case 3:
        pinMode(BP2,OUTPUT); digitalWrite(BP2,HIGH); //set BP2 2nd half of its cycle
        digitalWrite(S1,HIGH); //ensure segment 1 stays blank
        digitalWrite(S2,!digitalRead(S2)); //toggle segment 2
        digitalWrite(S3,!digitalRead(S3)); //toggle segment 3
        break;
      case 4:
        pinMode(BP3,OUTPUT); digitalWrite(BP3,LOW); //set BP3 1st half of its cycle
        digitalWrite(S1,LOW); //ensure segment 1 stays blank
        digitalWrite(S2,(dst[digit]&0x20)>>5); //activate segment 2 if needed
        digitalWrite(S3,(dst[digit]&0x02)>>1); //activate segment 3 if needed
        break;
      case 5:
        pinMode(BP3,OUTPUT); digitalWrite(BP3,HIGH); //set BP3 2nd half of its cycle
        digitalWrite(S1,HIGH); //ensure segment 1 stays blank
        digitalWrite(S2,!digitalRead(S2)); //toggle segment 2
        digitalWrite(S3,!digitalRead(S3)); //toggle segment 3
        break;
      case 6:
        pinMode(BP4,OUTPUT); digitalWrite(BP4,LOW); //set BP4 1st half of its cycle
        digitalWrite(S1,LOW); //ensure segment 1 stays blank
        digitalWrite(S2,(dst[digit]&0x10)>>4); //activate segment 2 if needed
        digitalWrite(S3,(dst[digit]&0x01)>>0); //activate segment 3 if needed
        break;
      case 7:
        pinMode(BP4,OUTPUT); digitalWrite(BP4,HIGH); //set BP4 2nd half of its cycle
        digitalWrite(S1,HIGH); //ensure segment 1 stays blank
        digitalWrite(S2,!digitalRead(S2)); //toggle segment 2
        digitalWrite(S3,!digitalRead(S3)); //toggle segment 3
    }
  stateprev=statenow;
  }
}




CrossRoads

Nice work figuring  that out. Gonna check my local staples, see if they have any of those.
Designing & building electrical circuits for over 25 years.  Screw Shield for Mega/Due/Uno,  Bobuino with ATMega1284P, & other '328P & '1284P creations & offerings at  my website.

bill2009


Nice work figuring  that out. Gonna check my local staples, see if they have any of those.


Thanks - yes there's lots of stuff in there. besides the lcd, motors and wheels there's some nice momentary switch buttons and a speaker! 

I bought three because: Hey, it's an alarm clock that runs away when you push the snooze bar!

jumpjack



Uploaded with ImageShack.us

This is the circuitry of a programmable remote control.
The pins in the lower part of the picture are connected to a 2-lines back-lighted alphanumeric LCD; as the remote control just costs,brand new, 8 Euros, I'd like to figure out if and how I can access and drive the display to use it with an Arduino.
The pins in upper part of picture are clearly available for external access, but.... how to figure out their use (if possible)?

bill2009

i see the pins near the top of the pic - between the labels GND on the right and 3V on the left.  I don't see the ones at the bottom.

do you have a scope available?

bill2009



I don't look at hack-a-day every day so I was just bumping down through old posts when i came on my very own thingie.

Ok, I'm easily amused, but i love it.  some good ideas in the comments too.

http://hackaday.com/2011/02/10/driving-a-salvaged-lcd/

cr0sh

I went to one of my local Staples to try to find this clock; I was more interested in the gear motors and wheels!

Unfortunately, they didn't have any, which is too bad - that's a great price for such robotics components for small desktop rovers...

:P
I will not respond to Arduino help PM's from random forum users; if you have such a question, start a new topic thread.

CrossRoads

Not shown on line either. Maybe it was a local thing?
Designing & building electrical circuits for over 25 years.  Screw Shield for Mega/Due/Uno,  Bobuino with ATMega1284P, & other '328P & '1284P creations & offerings at  my website.

bill2009


Not shown on line either. Maybe it was a local thing?


Apologies if i misled anyone, I'm in Ottawa so there's probably a whole Staples Canada thing going on.  I bought three and there were a few left but probably not worth mailing to anyone.  They were up at the checkout as christmas gimmicks so i think they could well be a local thing.


Valalvax

LOL!!

I read through this thread, scrolled back up to the top and clicked to go back to the parent forum, and right as the thread went poof and I was there, I read "A... Pikachu" on the chip

Go Up