This page may contain affiliate links. As an Amazon Associate I earn from qualifying purchases.
Thursday, August 27, 2020
Control a Bare LCD with Just an Arduino
Yes, you can control simple bare-bones LCD displays using just an Arduino. No
driver boards or additional chips are required. If you have controlled a
7-segment LED display directly from an Arduino, you can do the same with an
LCD.
However, there are a few tricks to doing it correctly. It's easy really. But I was trying to do it with mystery, undocumented displays. As you might guess, much fun and hilarity ensued.
This LCD is being controlled with just an Arduino. There are no additional chips or driver boards, just the bare LCD and an Arduino. The LCD was scavenged from an old CD player. It has a 7-segment display as well as icons and animations. Using salvaged LCD screens can lead to all sorts of surprises. This tiny display, with only nine pins, is actually quite complex to control. It has multiple layers of displays that are controlled by changing which pin you use as the common pin.
Why a Bare LCD
I have plenty of working LCD displays in all sizes and types. They are easy to
hook up and simple to control with an Arduino. Why would I want to use a bare
LCD instead?
Well, because I have them and because I didn't know how to use them. It was a
challenge.
Over the years I have scavenged a large collection of LCD displays out of
broken electronic devices. They still worked when I salvaged them, but I had
no idea how to
power them or control their displays. They have no chips or
circuitry attached. They are just the bare LCD display with a bunch of pins
sticking out.
I wanted to use them in an Arduino project, but it turned out to be a little
more difficult than I expected. The process itself is not very
difficult. But there is a lack of information about using them. While there
are thousands of tutorials on using the equivalent LED versions, there are
only a handful of good tutorials about driving bare LCDs.
TOO COMPLEX: Reusing the complex graphical LCDs is beyond my
current skill level, so I mostly use them for my
craft projects
They have a unique, shaded and semi-transparent appearance that's
difficult to find in commercial craft supplies. And some of them contain
lots of hidden diffusing and reflective sheets as well as Fresnel lens,
all useful items for a crafter. The LCDs are also polarizers, a fun thing
to play with.
I have salvaged a large collection of LCD displays over the years. Some are very simple, some are complex, and some are way beyond my ability to re-use. I finally decided to see if I could use any of them in an Arduino project. It took some research, but I did get several of them to work using nothing but an Arduino.
First Tests
One day, with a pile of those stripped down LCD displays sitting on my
workbench, I decided to apply some power to them just to see what happened.
They were, for my purposes, already dead so I couldn't hurt them any more. I
was just curious to see if I could revive them and maybe use them in a
project.
I used the same technique as I do when I'm trying to a reverse-engineer a
mystery LED display. I attached the ground wire from one battery to a pin on
the LCD, then dragged the positive wire quickly along the other pins of the
LCD.
To my surprise and delight, it worked. I saw a flicker on some of the
segments. So I upped the power to two batteries (3v instead of 1.5v) and
repeated the process. More segments darkened, and it worked on several
different displays. So I tried three batteries (for 4.5v) and tried again.
None of them exploded or emitted smoke (better than some of my experiments
with mystery LEDs).
Now that I was sure the displays still worked, I needed to find out more
information about them. Is the voltage standard, do I need a current limiting
resistor for each segment (like for an LED), is it safe to apply
continuous power or do I need to pulse it? I started googling and came
up empty for quite a while. I was beginning to wonder if there was a reason
everyone used LEDs instead of LCDs. Maybe it was really difficult.
Voltages and Waveforms
I learned a lot about LCDs in general. But none of my usual mentors for hobby electronics had detailed instructions for controlling bare LCD displays. The closest I could find was
Adafruit's tutorial
on using their "LCD light valves" (also available at Amazon)
The light-valve is like one big LCD segment (pixel), basically the
lens from from welding helmets
(affiliate links).
It was helpful information, but it wasn't really what I was looking for.
However, if I could figure out how to correctly turn on one segment, I could
probably use the same techniques with a 7-segment display. In the Adafruit tutorial,
they simply attach a battery to to the display. A resistor bridges the +/-
wires. However, they also caution against running the valves for more than a
few minutes without using an AC square wave. They linked to some
instructions on driving TN shutters. I didn't even know what a TN shutter was and I didn't understand the
schematics or the notes about digital logic. But it was enough to improve my
Googling.
Next, I
filtered Digikey results
to show me bare bone LCD displays and looked at their datasheets. Most
operated on 3v or 5v, so maybe these voltages were standard for powering
LCD displays. And LCDs draw a tiny amount of power, like microamps or even less. That was good. I have Arduinos that can output 5v and 3v at several milliamps, so I had the power requirements met.
The datasheets also said I had to send the LCDs a waveform (square) of some sorts in order to operate them safely. They also seemed to indicate that the waveform had to be AC, not the DC that Arduinos use. While I understood the concept, I had no idea how to generate an AC waveform with an Arduino. Maybe I was going to have to buy a special chip or board.
Doing It With Chip Assist
Luckily, my Googling and YouTubing improved with my new, yet still basic, understanding of LCDs. I found a
video from David Watt about driving
a bare LCD with an Arduino that sent commands through a "4055 BCD to 7-segment"
chip. He also noted that the LCD display requires an oscillator to create a
waveform.
Robert's Smorgasbord provided a detailed example of using an Arduino to control a specialized LCD driver
chip (the AY0438). The explanation of how to use registers and trigger signals
to load data into the chip then send it to the LCD for display is particularly
helpful. He has a
second video where he experiments
with voltage and frequency to see their effect on the displays.
The videos were very informative, but both examples required the use of a chip
in addition to the Arduino. That extra component bothered me. If I needed
another component why not just use an LCD display that already had the driver
chip and a library to run it? I already had several of those, and they worked
great. But that wasn't the point.
I still wanted to know if I could drive a bare LCD with just an Arduino. If I
was going to drive a display with 40, 50 or 100 segments I would definitely
need specialized driver chips. But I only wanted to control a single digit
display (maybe two), so I should only need seven I/O pins plus maybe power and ground.
Even my tiny microcontrollers have that many pins.
Only Using an Arduino
Maybe my vocabulary was getting better, or maybe the GooTube algorithms figured out what I was looking for. Either way, they led me to the EEVblog. As part of making a custom LCD screen, he explains (in his excited, entertaining way) the
process of how LCDs are powered and controlled.
His explanation of these
foundations of LCD operations taught me the final pieces about how to
correctly power and drive a bare LCD display. It took multiple watchings of
two of his videos, but I finished with enough knowledge to successfully power
and control a 7-segment LCD screen using nothing more than an Arduino.
The first video explains the basic
types of LCDs and talks about how to power them. It confirmed that they have a "common" pin just like LEDs. It also confirmed that LCDs
need an AC current. Or, as he hinted, maybe just a workable equivalent. More importantly, he
explained why.
LCDs are capacitive, they hold a charge. That's why they sometimes stay opaque for a short while after power is removed. Even though the charge dissipates after a
short time, it is better to send a reverse polarity charge. If the positive
and negative signals average out to zero over time, the LCD will not build up
a charge. You probably won't damage the LCD by short tests with a single
polarity. But the LCD can be damaged by driving it with a
single polarity for a long time. That made sense to me.
He also promised to explain exactly how to drive an LCD display with nothing
but an Arduino in the next video. I watched it immediately.
And as promised, in his
video on how to drive an LCD (after more info about driver chips) he does explain in detail how to
use an Arduino to directly control and power an LCD display using no additional
chips or circuits.
The part I needed, driving LCDs directly from an Arduino, is at the very end of the video and only takes a few minutes to explain. But the entire video is very informative and worth
watching. (BTW, he also has an excellent tutorial on
driving old VFD displays with an Arduino)
Go For It
I finally understood LCDs, or so I thought. All I needed to do was quickly
toggle the digital I/O pins back-and-forth between input and output modes.
That would create a square wave that operated like an AC current, at least as
far as the LCD was concerned.
I mounted a simple LCD display (only 9 pins) on a breadboard. Then hooked
up what I had determined to be the common-pin plus one other pin to an UNO. I
wrote some simple code to toggle the two Arduino pins between input and output
mode. In theory, I should now see one segment turn black.
Nothing happened.
I checked my wiring and code, still nothing. I was very disappointed.
Just for fun I connected one wire to the UNO's ground. A few of the segments darkened. I was happy it worked, but it wasn't using the circuit he described. And I could tell that the
wiring wasn't correct from the way the LCD behaved.. I changed the timing frequency to about a second per cycle and added an unpowered cycle to confirm my suspicions. The segment stayed on too long after power was cut. I was just pulsing the
power like a PWM signal, not sending it the pseudo-AC square wave I needed.
I thought about it for a minute and remembered that an input with no steering
resistor can "float" and give erroneous results. Maybe it also affected the
capacitive LCD screen. But none of the videos showed resistors in their
circuits, so there must be another solution.
I changed the pinMode() of the INPUT side to "INPUT_PULLUP" and changed the
digitalWrite() from HIGH to be LOW on the OUTPUT side. I tested the circuit to
be sure it worked like I thought it would. I set the delay() between
flip-flops of the input/output modes to a full second (1000) and put a
multimeter across the wires.
The meter showed a dependable toggling between
plus and minus 4.8v. I reset the delay to 10 and hooked up the
display again. Everything worked much better. The segments were darker and
steadier, and they disappeared immediately when I removed the power.
The code for controlling one segment looked like this:
void loop() {
pinMode(2, INPUT_PULLUP);
pinMode(3, OUTPUT);
digitalWrite(3, LOW);
delay(10);
pinMode(2, OUTPUT);
pinMode(3, INPUT_PULLUP);
digitalWrite(2, LOW);
delay(10);
}
Success, my first real success. Yay me!
They weren't perfect yet, I had some "ghost" segments that randomly flickered
into partial opaqueness. A note from my research said ghosting and flickering
issues could be caused by several things. You can actually set the frequency
too high and cause adjacent pixels to activate (ghosting). Running a 3v
display at 5v can also cause ghosting. And since the displays are capacitive,
you can get random segments showing if your finger is too close, or even from wires
being too close together.
I was beginning to realize a dependable, commercial
quality display took some effort. But I was definitely on the right track.
Tricky Tricky
I was pretty sure I had the power and waveform correct now. But there was
still weird things going on. I was about to discover the many wonderful ways
that undocumented, mystery LCDs can fool you.
These mystery LCDs have quirks and gotchas
hidden all over, and I wasn't prepared for them. I spent a lot of time trying
to fix things that didn't need to be fixed. If I had just slowed down and been
more observant I could have saved myself some headaches.
For instance, I discovered that one of the displays had more than one common pin and could
display two different sets of characters. My "simple" single-digit LCD turned out to be a specialized displays with multiple layers of symbols and icons.
No matter how I wired it, I was
getting multiple segments lighting up and a gibberish display. Imagine my
surprise when I finally realized that, if I turned the display upside down, those odd multi-segment gibberish errors were
actually an upside down letter F. I had not wired it wrong. All those
multiple segments were meant to be controlled with one pin. As I explored, trying different pin combinations, I realized that there were symbols and animations for Forward, Fast Forward, Reverse, Skip, Repeat Loop, etc. This wasn't a simple 7-segment display, It was from an old CD player. And those nine pins could be hooked up in multiple configurations.
That taught me
something, I can be a real idiot.
However, that experience prepared me for other displays with paper-feed and ink-status icons, clouds and lightening glyphs, or battery status bars. At first I was annoyed. All I had really
wanted was an alpha-numeric display. That's why I had gone to all this trouble and
I still didn't have one.
Then I realized these odd displays would be perfect for cosplay, kitbashing,
miniature models or even as a backing for jewelry. Imagine a Borg costume with
odd symbols blinking on a control panel, or segments flashing randomly behind
a big faceted gem. Yes, I could find uses for these oddball displays.
I did find a 7-segment display eventually. The display I thought would be the most difficult to use was actually the only
one that worked the way I expected. It is
similar to this one (affiliate link). It had a single common pin with three 7-segment digits, decimal points,
colon and some icons. It was easy to reverse engineer the pin layout. Each pin only had one function, only darkened one segment (no mult-layered combination/permutation/animation madness to contend with.
But there are forty of those pins, and each has to be hand wired. That's way too many connections to drive
from a typical microprocessor., and more than I want to deal with. I've done it for LEDs. and it was a good learning exercise. The techniques appear to be the same.
Now that I know how
to safely and correctly drive one an LCD, I can use the bare, scavenged ones as I need. But I can also return to using pre-made ready-to-go displays without any emotional turmoil. I know how they work so I'm free to buy a commercial package.
I also discovered several more of this type of LCDs attached to small PCB
boards. The displays can be cut away from the PCB boards and used as nice 3
digit displays. I think, with a little more research, I could find an easy
standardized way to send a serial signal to the driver board. That would
definitely use fewer pins on the microcontroller. So I'm going to save a few
of these displays intact.
The LCD at the bottom was scavenged from a PCB like the one at top. If you have a mystery PCB driver that you can't find information about or reverse engineer, you can always cut the LCD screen itself away from the board and hook your Arduino directly to it. Note the blue mark at the upper left of the bare LCD. It indicates the common pin for this screen. All three 7-segment digits are controlled from that one common pin and activated by powering the other pins to activate individual segments. That makes it simple, if a bit time consuming, to wire and program/
Coding, Arrays and Bit Banging
I strongly recommend that you understand how to control LED displays before you attempt an LCD. There are thousands of tutorials on controlling all kinds and flavors of LED 7-segment and 8x8 displays. These tutorials cover the wiring, typical coding patterns, as well as using shift-register and specialized chips.
Once you are comfortable with LEDs, you can adopt the code and add the constant toggling between ground/power (input/output).
The EEVblog linked to some code for driving the displays. But it was the
complex, arcane, bit-banging style of code that toggled stuff at the register
level. Don't understand what I mean? Then the code probably won't make sense
either.
I prefer the more verbose style of code that I can actually read. But there
are multiple strategies even with this simplified style of code. And you also
need to decide if you will hardwire the segments in order, or use software to
re-map pins to segments.
Most approaches use similar underlying strategies. They create an array that
describes which segments need be turned on in order to draw each numeral or
letter. Then the code transposes that arrangement to the different "slots" on
the display. "Draw the number 2 by turning on these segments and do that for
the slot second from the left."
But, do you turn on the segments all at the same time or do you quickly draw
one character then the next? It's not that important with only one or two numerals. But when you try to control 3,4 or 8 numerals at the same time things can get complicated. At that level of complexity you may require multiple shift registers and you might need to employ some POV (persistence of vision) trickery - basically drawing one character at a time, then the next, then the next and so on - but doing it really fast so that it looks like all the characters are on at the same time.
It's not really that difficult, but it is time consuming. Everyone should do it once, then after that, you can freely buy control boards that do the same thing with only a few wires and a few lines of code - but you will understand what is going on in the background.
Starting with an LED version can really help you understand the process, get your LCD working, and help you select the correct driver chip for more complex problems. But like the LEDs, after the first few times doing it, you will probably see the cost and time savings of buying a pre-made LCD board. But that's not the point at this level. For now, we just really want to understand how they work..
Summary
This is my current and still very basic understanding of how to correctly
power and control simple 7-segment LCD screens. I do NOT guarantee that all information is correct or represent best practices.
You can power and control bare 7-segment LCD displays using only an Arduino
Many LCDs operate on 3v to 5v at the microamp level or lower
Over powering an LCD can cause ghosting and damage the display over time, but it probably will not go "Pop!" and start smoking like an LED
None of the tutorials show current limiting resistors like with LEDs
Many LCDs, especially simple 7-segment displays, have a single "common" pin, much like the similar LED display
Others have multiple common pins to control multiple layers of displays
The common pin(s) can be used for power or for ground
The pin-out and wiring for LCDs is similar to the equivalent LED display
LCDs need a square wave that averages to 0v (Applying steady or pulsed power will eventually kill an LCD)
You can create a square wave that is safe for LCDs by toggling the digital I/O
pins of an Arduino
First, set the common pin to pinMode(#, INPUT_PULLUP) and set the segment's
pin to pinMode(#, OUTPUT) and send a digitalWrite(#, LOW)
Then flip the input to an output and vice-versa.
Use a delay() value that gives you a steady display (2-8 works for most)
Invert the pinMode() of both the common and segment pins
Coding the Arduino to control an LCD is very similar to controlling the equivalent LED version, except you have to constantly toggle between input/output modes
You can do the same thing with a Raspberry Pi
Look for a part # and find a datasheet for your display if you can, it will save you lots of time
Conclusion
Once I found some good tutorials, it wasn't that hard to get an Arduino to control a bare LCD. I learned a lot and feel a lot more comfortable with LCDs, even the pre-made plug-n-play versions. Now, I can not only safely control an LCD to display the data I want, I can use almost any basic display in craft and cosplay projects.
Now that I can control both LEDs and LCDs, my next project might be getting some old VFDs up and running. Stay tuned.
I see that you did INPUT_PULLUP as a substitute for OUTPUT and HIGH. While it does make sense if you don't want an accidental short circuit to harm your Arduino, it's not strictly necessary here. Using OUTPUT and HIGH will allow the segment to "turn on" a little faster too and not have the internal resistor dissipate power.
Yes, that absolutely should work. It's much simpler and it was the first thing I tried. But I was getting odd behavior. The display did not update reliably. Some elements would keep displaying light gray "ghost" lines. It's like there was still a capacitive charge that had not been completely drained. So, I tried the INPUT_PULLUP technique and that worked. I did not have datasheet for the displays I was working with, so I wonder if there wasn't a master drain or reset line I needed to toggle.
I see that you did INPUT_PULLUP as a substitute for OUTPUT and HIGH. While it does make sense if you don't want an accidental short circuit to harm your Arduino, it's not strictly necessary here. Using OUTPUT and HIGH will allow the segment to "turn on" a little faster too and not have the internal resistor dissipate power.
ReplyDeleteYes, that absolutely should work. It's much simpler and it was the first thing I tried. But I was getting odd behavior. The display did not update reliably. Some elements would keep displaying light gray "ghost" lines. It's like there was still a capacitive charge that had not been completely drained. So, I tried the INPUT_PULLUP technique and that worked. I did not have datasheet for the displays I was working with, so I wonder if there wasn't a master drain or reset line I needed to toggle.
ReplyDeleteNice Blog. Thanks for sharing with us. Keep sharing.
ReplyDeleteDo you want to Buy 3D LCD Screen Displays Online?
Buy 3D LCD Screen Displays Online