We really like to see hardware hackers stepping out of the safe and polished boundaries of available Arduino libraries. One example of this is a project which [Matteo] thought worked: using a shift register to drive a character LCD. This can be a desirable way to do things, because it takes the GPIO usage down from six to just three connections. If you don’t remember seeing that one earlier this month take another look. The gist of it is that [Matteo] hacked one function in the LiquidCrystal library to make it happen.
What makes this a truly great fail is that the problem was not immediately apparent, and is difficult to reliably reproduce. The LCD is unstable depending on how the Arduino board is reset. When connecting the Arduino to a computer the screen doesn’t work until you press the reset button. But press the reset button repeatedly and you get a non-functional screen plus the gibberish seen above.
There’s not much to go on here, but we think it’ll be a lot of fun to state your theory on the malfunction and suggesting for testing/fixing the issue. This could be a lot of things, the controller on the display getting mixed-up, the 595 missing an edge (or something along those lines). Do you fix this with hardware (ie: capacitor to avoid voltage dip), a software issue (need a longer delay after startup), or a combination of the two?
Fail of the Week is a Hackaday column which runs every Wednesday. Help keep the fun rolling by writing about your past failures and sending us a link to the story — or sending in links to fail write ups you find in your Internet travels.
Sounds like a grounding issue to me.
Exactly. Every time that I’ve had an issue that manifests itself depending on what the device is connected to it has always been a grounding issue. I would check the ground and the reset pins.
I would suggest repeating the display reset sequence occasionally, e.g. each 10-30 seconds. The cost is a (barely perceptible) blink (blanking) of the display during the sequence. The benefit is automatic resync of any problem with the display; even hotplugging the display becomes possible.
I have ran in to same issue once, while writing LCD library for Beaglebone in Python, my solution was to send reset sequence before resuming lcd operation in 8 bit mode it would be: CLK (00000001) CLK, in 4 bit mode it would be CLK (0000) CLK (0001) CLK
or completely re initialize it. I hope it helps.
I’m going for voltage dropoff and a capacitor to fix. some of those controllers get a little perturbed when the voltage isn’t consistent
When you work with these displays in 4 bit mode, you could get out of sync as to which nibble is being sent to the display – you need to send it several [3 or 4] of the set function commands to tell it it is in 8 bit bus mode, and then re-program it to 4 bit bus mode – otherwise you could get out of sysnc, ans the display stays in the 4 or 8 bit bus mode it was last programmed to, and if in 4 bit mode, you could be out of step when programming.
I agree with this. Reset != Power Off. The AVR is being reset however the display is still powered so it is in the state that it was last set. I would check the reset/initialization sequence in the code.
Sounds highly likely. Additionally, the registers in the AVR itself aren’t automatically cleared on reset. It’s possible for the contents to persist through power down, especially if parasitic power is available through IO pins. I’m not sure if avr-gcc or Arduino take care of this for you, but when using assembly language it’s important to initialize variables/registers to a desired value.
I wrote a driver for an HD44780 clone and had the same problem on board reset. The only solution I found was to transistorize the power to the display, and turn it on with software after the mcu (PIC and ARM versions both had same issue). I did some debugging and eventually figured out it was the sending the first nibble before the display finished resetting.
EDIT: I also had to delay slightly, I think a few milliseconds, from display power on to sending commands.
Personally I’d just add a 2nd 595 (they *ARE* cheap and extend with no extra lines required) then operate the display in 8bit mode. I’ve had instances in 4bit mode where the controller gets confused, and without anyway to brown it out for a reset you’re still kinda guessing if the display is in sync anyways (since you can’t read from it in this configuration). In 8bit mode commands are simpler, leave no ambiguity to timing, and since you’re waiting for the display anyways before sending the 2nd nibble I don’t think you save any CPU time (from only having 8 cycles instead of 16).
You do save wires (and a chip), which is a popular thing to do though.
As an addendum to my own post, my experience with display modules (the 3 or 4 different models I’ve used–driving them at the maximum refresh from an FPGA) has been that they don’t really care how craptacular their supply is, if supply noise is an issue, you’ve got major power supply problems already.
My guess, the inputs on the 595 are floating when the AT Mega resets, causing the unstable behaviour. Add a few pull up or pulldown resistors on those lines and the problem will possibly disappear.
Looks like he needs a little more practice on soldering, the solder work looks a bit uneven.
Why a shift register? get an i2c IO chip for $1.95 and use only 2 pins. MCP23017 FTW and have a bunch left over for buttons or backlight control.
I agree with this gentleman (with a charming name).
And with I2C adapters for these LCD, you can operate in 8bit mode. And still add some sensors to your I2C lines.
Relative to the ~$2.50 cost of a 1602A, an extra $1.95 is a lot.
If you really want to add a chip that can talk i2c, go with an ATtiny88-AU. 88c/qty 1
Hand-soldering the .8mm pitch pins is easier than you might think if you flux the pins and use 30AWG wire-wrap wire.
fartface said something productive. I think I need to go buy a lottery ticket.
Apart from all the other suggestions, I’d like to add that some of these LCD modules are really poorly made. I once had one that I could mess up just by tapping the bezel with a screwdriver. The screwdriver wasn’t even touching anything else. Also, pay close attention to the init sequence.
Can I be the first to blame the colour of the wire… or will that result in an instant ban from HAD for stealing steves joke. (http://hackaday.com/2014/02/03/controlling-alphanumeric-lcds-with-three-wires/)
These LCDs are really picky about the reset/power up sequence. When powering up the display it takes tens of milliseconds for them to be ready to receive commands.
Additionally as others have said the reset sequence should reliably get the controller into 4 bit mode, including the AVR waiting until the controller is ready (the AVR powers up and reaches the init code in under a millisecond).
This. I have found that there is a *huge* range in the time it takes for HD44780 LCDs to start up. Some start up very quickly, others are actually out of spec. I have seen quite a number of libraries that do not even wait the specified startup time before sending commands. While this may be fine on a large number of devices, you will still find some that fail mysteriously. When in doubt, always wait at least twice the specified time at startup before sending any commands.
Also note that you must power cycle the LCD prior to each test when developing.
Also note that the window of the contrast setting is often very narrow. If you do not have the contrast set properly, you won’t even know when you get the software working.
The first HD44780 I ever played with took a long time to start up. It was within spec, but only barely. It was a long day of frustration to get it working.
Since we’re talking about what makes LCDs wonky, I have a “discussion question.” I have a Newhaven NHD-C0216CZ-FSW-FBW-3V3 display I’m using on a project. I discovered that if you hold one of those “long lighters” a few inches away and click the piezo to light the lighter by display goes black. It stays that way until I give it another reset sequences. Any thoughts about that?
Congrats, you have just done some ESD testing on your setup, and it failed.
Try grounding the sheetmetal of the display.
Actually, I found the cause. A sloppy solder connection was very nearly or very slightly bridging the reset pin to ground. It must have been reacting to the impulse of the piezo, because once I removed the errant hair of solder, the LCD became reliable.
FYI, Some of those lighters do not have/use a piezo, they snap a magnet through a HV coil to generate the spark.
Floating pins could be driving the shift register causing it to send crap to the LCD, including getting your nibbles out of sync as suggested.
I had this on an LED cube with ‘595 shift registers, after a reset the pins would be in a random state.
It sounds to me that there may be problems with your LCD init code. As several people pointed out already, you are using 4-bit mode, which can leave you out of sync if you are in the middle of a transfer. Also, after reset, all the pins on the uc are input (hi-z) so the inputs to the shift register may be picking up noise. You also may need to check your init code to make sure that it follows the correct HD44780 procedure – software reset into 8-bit mode via three timed writes and then set the mode.
One thing that I just thought though, if the display has already been configured for 4-bit mode (and after the uc has been reset) then will you have to send the first reset as 2 nibbles? I guess it never hurts to do the reset sequence a few times just to make sure.
Anyway, I used i2c to talk to a HD44780 and wrote my own routines to do it and followed the init procedure from the data sheet exactly and have had no problems, even after flashing a new program where power is never disconnected but the uc is reset – the display comes right up and works perfectly.
Good luck!
I have several Arduinos that perform routine resets (like every minute or two) when powered over USB (plugged into a PC or in communication over USB.. not just a USB power brick). Not sure if it is a firmware, driver, hardware issue or my computer. But it seems like a watchdog type of thing. I have not confirmed it on all Arduinos, but have noticed it on certain types of projects, especially ones that are using serial monitor. When powered on an external source, I have no problems whatsoever.
So, if the project is connected to a computer, you might want to confirm that it IS or IS NOT routinely resetting on its own.
USB has notoriously dirty power. I learned this the hard way when doing a bunch of ADC with an AVR. I discarded the Arduino platform from the getgo and spent a couple of months writing a rock solid ADC routine in assembly that could probably take samples during an EMP blast before I someone clued me in on USBs dirty power.
When I switched to a clean power supply, even my earliest code worked as intended. Cest la vie, at least I have good solid ADC handling code now.
USB Specs 2.0 (usb_20_012314) page 203 of 650, Figure 7-47. Worst-case Voltage Drop Topology (Steady State)
After a bus-powered hub, your worse case voltage is 4.375V at the end of the connector in your device. There is a note there that say “*Under transient conditions, supply at hub can drop from 4.400V to 4.070V”
So basically any USB bus powered device have to be able to operate down to 4V and not just assume that it is 5V. Probably someone set the brownout fuse on the AVR chip to the 4.3V (typ).
tl;dr Blame it on bad designers who don’t read the USB specs.
When the Arduino starts up the outputs on the pins float up and down randomly.
What is needed is to connect all the pins to a pull up or pull down resistor that prevents the pins from having a random value when they are not being driven by the device.
I would also stay away from pins 1 and 2 on the Arduino as these are connected to the serial output.
You don’t need pull-ups on *all* the pins, just the critical pins that drives the latch enable.
Things I *always* do is to check the I/O pins I am using and find out what states they are at when the part is in reset (and when the part is unprogrammed from the factory). Put pull ups and pull downs *if* you expect it to be at a certain level and don’t assume anything.
I have used these LCD module before and I followed the datasheet to the letter on the initialization and never had a problem with garbage on the display.
The problem probably lies in the misleading data from this link that you featured earlier
http://www.alpheratz1991.com/2014/02/arduino-3-wires-hd44780-lcd-display.html
The picture on this site shows the LCD being wired up completely differently to the 595 versus the way it is defined in the shiftlcd595 library. I found this out after hours of jibber jabber on the LCD.
What I’m saying is, if you follow the directions to the t on that site, and download the code from his github; It will give you similar problems, until you rewire it to match up with the code in the library.
As far as the boot up sequence issues, I just unplug the whole arduino, so everything boots up together. Slap in a delay if needed for the shift register / lcd.
I have the same problems. I control it straight out of the GPIO of a Raspberry Pi (no serialisation) in 4bit mode. My product works fine from a power up, but if the host MPU is restarted, it seems the re-performing of the initialisation sequence intermittently fails and gets the high/low nibble confused which causes corruption just like you show. However, it’s not that straightforward… The commands work correctly in the 4 bit mode everytime, but the Display data does not! You can still control it and even get sensible data by deliberately swapping data nibbles. Hack: You can actually re-synch nibbles by sending a single data nibble and then re-initialising it (to re-sync the command nibbles). I am convinced there is a generic small bug in the firmware of the display as the commands still work, but not the data. I suspect the internal data hi/lo reg bit is Not reset by a re-innit. The problem with my hack is that the program cannot determine if it is in our out of synch. Solution — power recycle the LCD as well.
Keep posting, keep not seeing my comment, and it keeps saying “Duplicate comment detected; it looks as though you’ve already said that!” BUT WHERE IS MY COMMENT? I’m sure it’s being moderated or something but .. FAIL OF THE WEEK BELONGS TO THIS SOFTWARE.