Disclaimer and Social

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.

Power control and drive a bare LCD with an Arduino
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.

Salvaged and scavenged LCD displays can still be used with an arduino.
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.

Salvage scavenge bare LCD from PCB for use with Arduino or raspberry Pi
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.

Learning about Electronics has a great tutorial on controlling a single 7-segment LED. 
* Circuit Basics has a fantastic tutorial that also covers working with 4 digit LED displays

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.


As an Amazon Associate, I earn from qualifying purchases.

Also find me on:

2 comments:

  1. 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.

    ReplyDelete
  2. 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.

    ReplyDelete