# Specific 3D Printers, Scanners, & Hardware > RepRap Format Printer Forum > Firmware Enhancements to Marlin >  Garbled LCD screens

## printbus

How prevalent is the problem of the Marlin LCD panel displaying garbled data?  My MakerFarm 8-inch i3v does it once in a while - often enough to just be annoying.  

Having written LCD interface code before, I've looked at what is supposed to be displayed and the actual garbled display.  Turns out the screen effect is very predictable once it gets into this garbled mode.  I have an idea for a firmware change that would recover from this, but I don't want to futz with it if this isn't a common problem.

EDIT: My reluctance to futz with this is simply that I'm new to looking at the Marlin software and it would take me some time to figure out how the LCD interface is implemented. If there's someone out there that already understands the interface, I could share what I think we could do to fix this so that person could give it a whirl.

----------


## Roxy

Unfortunately for you....  I don't have an LCD Panel or I would jump in and help you!   There are a lot of different modules and communication methods for the different panels.   It might make sense to see which panels are 100% reliable and compare their interface code against what you have.   If you can get consensus on what the most reliable one is...  I'll take a look.  It might be they have pushed the timing or something a little bit too far and warming over the interface code makes things better.  But that is pure speculation.

----------


## Mjolinor

> But that is pure speculation.


That is a whole lot more than speculation, it is years of hands on experience.  :Smile:

----------


## printbus

What I've seen so far in the code is pretty generic, thanks to the Hitachi controller chip and clones that pretty much every LCD uses.  The Marlin code quickly leverages Arduino library stuff for the LCD functions.

----------


## printbus

Oh, what the heck.  I have a firmware change uploaded to test.  I'll post details after I run this a while to make sure there are no ramifications of the change and after I witness the display recovering from "garbled mode".

The fix is oriented around LCD interfaces that leverage the 4-bit or nibble mode to send data to the displays.  As best I can interpret the possibly dated code base from MakerFarm that I'm working with, this will be the case for those with a configuration.h file that has #define statements for ULTIPANEL, REPRAP_DISCOUNT_SMART_CONTROLLER, G3D_PANEL, or ULTIMAKERCONTROLLER. These in turn will invoke the ULTRA_LCD stuff that is important here.  

In the 4-bit data mode, two transfers to the LCD display are required for most commands and data characters.  The problem is that if we miss a transfer or double-clock one due to static, noise, firmware timing, or whatever, the data being sent to the display gets out of sync.  For display characters, data gets displayed that is say the last four bits in one character and the four bits from the next character.  This out-of-sync error will remain until the Arduino board is restarted or reset.  

There's an easy way to prove this theory for those running the printer from a host like Repetier that allows you to send G-code commands in real time.  If you see the display garbled, send this to the printer without the quotes:  "M117 ccccccccc" (be sure it is lower case).  When things are working properly, this should cause the string of c's to be written to the status line at the bottom of the screen.  In garbled mode, a string of 6's will be printed somewhere instead.  Why 6's?  The character address code for "c" is binary 01100011, and is sent to the display in two transfers consisting of 0110 and 0011.  When things get out of sync the LCD will read these repetitive transfers in as 0011 and 0110 instead, or 00110110 combined.  That's the character address code for the number 6.  The location of the 6's may be somewhere other than the bottom row; it's likely that command messages can get messed up just like the character address messages.  

The display modules support 8-bits of character codes.  The predefined character sets in the display modules supplement the normal 7-bit ASCII alpha-numeric character set with 128 Greek and other symbols.   Once the character data transfers get messed up, it doesn't take much for characters to be selected from the extra symbols.  If you have a font table for one of the Hitachi-based LCD modules and the display is garbled, you can use the M117 command to play around with how different "intentional" characters get misinterpreted as stuff in the extended character set, etc.  You could even use the font table to reverse things and decode what a garbled display is trying to tell you. 

 What I've uploaded to test is a one-line code change that reinitializes the LCD interface whenever the display will revert back to the main status screen.  When the garbled display occurs, simply letting the display timeout should restore things.  If the main display itself is what's garbled, pressing the panel knob and then waiting for the timeout that returns to the main status display should restore things.

----------


## Roxy

> That is a whole lot more than speculation, it is years of hands on experience.


OK....  I believe its real....  But it might not be the interface  code...   I'm just making stuff up...  If there is a stack overflow  condition or a bad pointer being de-referenced in a loop,  you can make  all kinds of data corruption happen....    My guess is they are pushing some I^2C timing  or something too hard.  What happens a lot of time is people make firmware based timing loops and when the processors speed up, the timing doesn't work any more.   I really don't know at this point.   The good  news is, I don't have an LCD Panel to look at...   I can just sit here  and speculate!   What a sad world!

----------


## printbus

To clarify for the interested, the interface involved with at least these display panels consists of six dedicated pins on the Arduino processor. i2c isn't involved.  SPI is ran to the panel on at least the RepRapDiscount smart controller, but it is used with the SD card, not the LCD module.  The six pins consist of an enable, a register select, and four parallel data lines.  Low level operations involved with setting the data lines and toggling the enable and register select pins are accomplished through Arduino LiquidCrystal library functions.  Marlin code takes care of higher level stuff like menu structure.

It could be there's more than one thing going on, but static discharge is definitely a way I've seen my display mess up.

----------


## Roxy

> To clarify for the interested, the interface involved with at least these display panels consists of six dedicated pins on the Arduino processor. i2c isn't involved.  SPI is ran to the panel on at least the RepRapDiscount smart controller, but it is used with the SD card, not the LCD module.  The six pins consist of an enable, a register select, and four parallel data lines.  Low level operations involved with setting the data lines and toggling the enable and register select pins are accomplished through Arduino LiquidCrystal library functions.  Marlin code takes care of higher level stuff like menu structure.
> 
> It could be there's more than one thing going on, but static discharge is definitely a way I've seen my display mess up.


I don't remember why I was thinking i^2c was used.   I think I was looking at some of the smaller Arduino boards that had less I/O pins and that ended up being how a given LCD Panel worked with it.   Your explanation about each character being transferred as 2 nibbles is helpful.  I think what you are saying is there is no signalling to the LCD Panel to tell it which 1/2 of the character it is receiving.   It just starts in the right state and every other nibble that is transferred to it is the start of another character.   That seems like it is just asking to get out of phase if anything unexpected happens.

It would seem they should have some way to reset the panel and get it to a known state???

Another question is this:  Since a lot of the LCD Panels use the same support chip, does this happen equally often with all of them?  Or does it mostly happen with specific Arduino boards?   Is there some combination that is more prone to the display getting out of sync?   Is it at all related to how clean the power is?  I know my PrintrBoard had trouble powering the Servo for Auto Bed Leveling.  Do the LCD Display boards grab a lot of power from the Arduino board?

The reason for the questions is if the root cause of the LCD Panel getting out of sync is because of missing or double clocking of the nibbles...  It would seem slowing that down and making sure there are nice clean edges to the Enable and Select lines after the data is stable would help.   Right?   But if the corruption happens because of noisy power or something else, the solution will be doing things to clean that up.

*UPDATE:*   And the more I look at this, the more I don't know.   Pulling up this link:  http://www.reprap.org/wiki/RAMPS_LCD it shows how to build the LCD Panel and it claims it is enabled by taking the comments off of the #define ULTRA_LCD line.   But when you look at their directions, they are saying the LCD Panel has 8 data lines and they only hook up 4 of them????   It would seem they should have some 'illegal' combination of RS, R/W and Enable that causes the display chip to reset????

Oh and here is at least one example of an LCD Panel using i^2c:   Check out: http://blog.reprap.org/2008/10/new-b...oller-v10.html   That must be why I was thinking they were using i^2c in general for this stuff.

----------


## printbus

> ...Pulling up this link:  http://www.reprap.org/wiki/RAMPS_LCD it shows how to build the LCD Panel and it claims it is enabled by taking the comments off of the #define ULTRA_LCD line.   But when you look at their directions, they are saying the LCD Panel has 8 data lines and they only hook up 4 of them???? ...


The display modules DO have 8 data lines, but the controller chip supports a data transfer mode that only uses four of them.  The modules also have a read/write signal, but common applications don't need to read anything back from the display so they're hardwired for write-only.  Using the 4-bit mode saves Arduino pins.  (I'll get to i2c savings later)




> It would seem they should have some way to reset the panel and get it to a known state???  ...It would seem they should have some 'illegal' combination of RS, R/W and Enable that causes the display chip to reset????


One would think, but no.  "Initialization" involves sending a particular sequence of commands to the display module, with specific timing constraints on the transfers.  That's all my "fix" is doing - periodically reinitializing the display by going through that command sequence again.  There's a bit of delay in doing this, but I don't notice it on my printer. If I understand Marlin right, any printing going on should be handled in interrupts, so the additional time spent reinitializing the display shouldn't affect anything.




> Since a lot of the LCD Panels use the same support chip, does this happen equally often with all of them?  Or does it mostly happen with specific Arduino boards?   Is there some combination that is more prone to the display getting out of sync?   Is it at all related to how clean the power is?  I know my PrintrBoard had trouble power the Servo for Auto Bed Leveling.  Do the LCD Display boards grab a lot of power from the Arduino board?


I think there's too many variables here.  I've had static issues on non-printer and non-Arduino designs using the modules, minimized by simply putting the display behind a bezel.  They don't all use the same Hitachi HD44780 controller chip.  There are clone chips out there. Older boards have discrete chips. Newer boards have the substrate right on the board and coated over. They just all support the same command set as the original HD44780 chips.  Then, there's different module circuit board layouts that could lead to differences - maybe trace routing differs, different ground distribution, or maybe some include decoupling capacitors, who knows. Also, maybe some of the Arduino clone boards are better quality than others.  Cleanliness of the power supply could make a difference.  Wire routing in the printers could make a difference.  

The core of the LCD modules I've used only need a couple of milliamps of power.  If used, a backlight will draw more, but displays with the typical LED backlighting will still be relatively low.  I would assume that those reprap displays with the rotary encoder and SD card still draw minimal power.

---------------

Rather than ramble on here, I'll touch on i2c in another post.

----------


## printbus

On to the i2c or i^2c stuff.  For the unfamiliar reader, a simple overview first. 

The larger Atmel AVR microcontrollers support a serial transfer over what Atmel calls the two-wire interface, or TWI.  You can read about TWI in the AVR ATMEGA datasheet of your choosing.  This is compatible with the Inter-Integrated Circuit (i2c or i^2c) interface. Read about THAT on wiki or other resource. It's a slick interface that allows support chips to interface with a microcontroller through serial data transfers and device addressing. Communication only requires a couple of pins, and addressing means you share the same signal pins for multiple devices.  The Arduino world took this a step farther.  The Wire library allows you to perform i2c communication but without committing to having or using the TWI function in the ATMEGA chip, albeit with a substantial amount of software overhead.  

Functionally, there's no reason why you couldn't use TWI/i2c for the LCD interface. In fact, there are i2c "LCD backpacks" from sources like Adafruit and Sparkfun that solder directly onto the pins of the LCD module and turn it into an i2c node.  The one's I've seen of these still require you to use the LCD in 4-bit mode.  Why?  The i2c adapters use a shift register chip that decodes the serial data stream into the parallel lines needed to drive the display.  This chip can only accept a number of bits at a time.  In addition to data lines, the RS signal, E signal, and usually a backlight on/off signal have to be sent.  There aren't enough shift register bits to send 8 bits of data, so only 4 get sent.  RS and E aren't passed over discrete wires subject to noise and static, so maybe this is still an improvement with regards to the garbled display issue with nibbles getting out of sync. I don't know.  

Personally, however, I think it is hard to have an LCD interface that is efficient over i2c, and incredibly so with the Arduino library if it is used.  Remember that we need to be setting data lines and toggling RS and E pins to send data and commands to the display.  The flexible bit-bang nature of Arduino means everything is being done in software (ie, the ATMEGA TWI hardware isn't used), and there's also i2c overhead involved in setting up each transfer.  Send an i2c command to confirm the bus is available.  Send i2c commands to address a specific device and set up a data transfer with it. Send four of the display data bits with RS set to the desired level and E not asserted. Resend the same data bits but with E now asserted. Resend the data bits but now toggle E back to inactive.  Send the next four data bits with E de-asserted. Send them again with E asserted. Again with E now toggled off.  This is coming from dated memory and might not be totally correct, but this should convey a sense of the number of transfers required to send simple messages to the display.  BTW, then when done with the transfer, send an i2c command to relinquish the i2c bus. And if I recall my dated research into the Arduino Wire library, acquisition of the i2c bus and addressing a device occurs on every *byte or display character* sent over the Wire library. Keep in mind that software is dealing with all this one serial bit at a time. Yes, one bit at a time. Very inefficient from a software overhead perspective.  I've never used the Wire library, but I've read how this leads to a really slow update for anything but the smallest size display.

FOLLOWUP COMMENT: To be fair, not all of my concerns are with the Arduino Wire library.  The software-intensive effort in handling i2c is exasperated by the need to toggle control pins on the LCD display - that's driven by the nature of the LCD modules, not the Wire library.  After knocking the dust off more brain cells, I also now remember that the i2c bus acquisition on every character was something done in sample software provided by AdaFruit for their i2c LCD backpack board.  The Wire library wouldn't likely require every byte to be handled individually.

----------


## Roxy

> One would think, but no.  "Initialization" involves sending a particular sequence of commands to the display module, with specific timing constraints on the transfers.  That's all my "fix" is doing - periodically reinitializing the display by going through that command sequence again.  There's a bit of delay in doing this, but I don't notice it on my printer. If I understand Marlin right, any printing going on should be handled in interrupts, so the additional time spent reinitializing the display shouldn't affect anything.


OK...   But here is the next question...  If you are sending some 'Initialization' sequence, does that involve sending it bytes of data to give it commands?  Because if it does and the LCD Panel is out of sync, aren't the 'Initialization Commands' scrambled?

----------


## printbus

> OK...   But here is the next question...  If you are sending some 'Initialization' sequence, does that involve sending it bytes of data to give it commands?  Because if it does and the LCD Panel is out of sync, aren't the 'Initialization Commands' scrambled?


Aw, man.  I guess I should have known better than to gloss over details.  State of the RS (register select) pin when the E pin is strobed is how the LCD module differentiates commands from data. At the start of the initialization sequence the LCD module doesn't know if the transfers will be 4-bit or 8-bit, but the first commands used only have four valid bits, and the others are don't care. So, the multiple-nibble synchronization problem can't occur on those first commands.

EDIT: I'd summarize the interface these modules have as fairly clunky by today's standards.  I don't know how long the interface has been out there - I bought my first module off the surplus market in 2004, so I'm guessing it's been out there 15 years or so.

----------


## Mjolinor

I think much older than that. Being an old git my mind is unclear but I am sure I remember using a Z80 to talk to them possible as early as 1980.

----------


## printbus

> I think much older than that. Being an old git my mind is unclear but I am sure I remember using a Z80 to talk to them possible as early as 1980.


You could be right.  I just figured that if I got one surplus in 2004, they were likely out at least 5 years prior to that. Digging into my displays box, I now see one of them that I bought at the same time in 2004 has what is likely a date code of 1991 on it.

----------


## printbus

Looking good. Should someone want to add the display auto-recovery, here's the change. In file ultralcd.cpp, look for...



```
#ifdef ULTIPANEL
static void lcd_return_to_status()
{
      encoderPosition = 0;
      currentMenu = lcd_status_screen;
}
```

and add one line to it...



```
#ifdef ULTIPANEL
static void lcd_return_to_status()
{
      encoderPosition = 0;
      currentMenu = lcd_status_screen;
      lcd_implementation_init();    // added; reinitialize the display module to recover from garbled display mode if happening
}
```

The lcd_implementation_init function already exists.  It calls the lcd.begin Arduino LiquidCrystal library function that takes care of initializing the display module. It also sets up a handful of custom character bitmaps like the thermometer symbol, and then it clears the display.  I found that just calling lcd.begin would sometimes leave the custom character bitmaps incorrect, so I ended up adding the full init.  The only time this additional code is executed is when the LCD display is about to return to the top status screen.  The change won't be incorporated unless your configuration.h file invokes the #define for ULTIPANEL.  

FOLLOWUP COMMENT: Looking into the LCD code some more, I see the same lcd_implementation_init is already included as part of software detecting SD card insertion and removal. That code even has a comment with it that talks about how it is an attempt to recover the display from a possible static discharge. So, for a printer standing around doing nothing, just inserting or removing the SD card will also reinitialize the display module, without having to make this change.

----------


## JimG

Sorry to bring up an old thread. But I'd like to know how well this fix has worked?I've been fighting this problem for years on other projects.Jim

----------


## printbus

> Sorry to bring up an old thread. But I'd like to know how well this fix has worked?I've been fighting this problem for years on other projects.Jim


I've used the trick maybe twice to recover from a garbled screen since I made the firmware change.  Although the screen isn't readable when it occurs, I just hit the button on the smart panel and let Marlin time out and return to the main menu to reinitialize the display interface.  I haven't described it in my MakerFarm i3v build thread yet, but I've also added a bezel over the LCD. I learned in other projects a long time ago that having these type of LCDs behind a bezel can do wonders in protecting them from going nuts after inadvertent static discharge.  

As I update other projects using the LCDs in 4-bit transfer mode, I'll be looking for ways that I can automatically do the interface reinitialization periodically now that I understand how the data nibbles can get out of sync.

----------


## printbus

Evolution of Marlin took a different approach to the garbled LCD screens that negates the need for the fix proposed here.  I don't know when it was changed in Marlin, but the Sept 28 2014 MakerFarm dacb fork now calls the lcd_implementation_init() whenever the printer is displaying the status screen and the LCD panel button is pressed. So, the display recovery occurs as soon as you press the button - you don't have to wait for the display to timeout before the LCD interface is reinitialized like my fix did.  The additional delay spent reinitializing the interface before the top menu comes up isn't significant.    

So, if you get the garbled LCD display on your printer with a fairly current version of Marlin, you can either just press the knob on the panel or you can insert/eject the SD card.

----------


## ESS

I don't really think that the screen get garbled due to timings or ESD.
I never supposed that anybody could connect something directly to an MCU pin with a half-meter wire, but they did it... And that single thin GND wire (yep, only one of 20 wires is a GND) only aggravates the situation.

This garbling issue can be fixed by adding a serial resistor to each MCU output connected to the LCD. These resistors should be placed as close as possible to the signal source (i.e. to the MCU in our case case) and by routing a reliable ground wire to the LCD board.

But I'm to lazy to do all these things, so I've just cut the LCD cable (there are two cables - one for LCD and power, and another one for SD card) at the mainboard side and solder 47 Ohm resistors there. This appears to be enough to get rid of LCD screen garbling.
lcd1.jpg

----------


## printbus

> This garbling issue can be fixed by adding a serial resistor to each MCU output connected to the LCD. These resistors should be placed as close as possible to the signal source (i.e. to the MCU in our case case) and by routing a reliable ground wire to the LCD board.


Interesting.  Be sure to report back after a while to confirm whether or not the series termination resistors solved your garbled display problem.  I'd try the fix myself, but I've eliminated the nibble transfer display as part of migrating to Smoothieboard on my i3v.  

Technically, the bulk of the benefit is likely obtained by adding the termination resistor in the E signal line to the display. IIRC, that is the signal that is pulsed to latch each nibble data transfer into the display module.  Ringing on any other pins likely wouldn't matter as long as they're stable when the E pin is pulsed, but there's no reason the termination can't be added in all the data lines.  Also note that some of the data lines (encoder, SD reader) on the two cables are driven by the smartpanel and not the ATMEGA2560. 




> I don't really think that the screen get garbled due to timings or ESD.


While ESD may not be the cause in all cases, it definitely played a role on my printer.  I'd occasionally see the printer garble the display all by itself, but most of the time it would happen when I'd reach for the knob - especially if a finger wrapped around the panel and touched one of the smartpanel circuit boards. EDIT: And BTW, the Marlin code change mentioned in post #18 even has a comment associated with it that says the change is an attempt to recover from a static hit...

----------


## ESS

During 3 months after adding the serial resistors I caught garbled display only once (without the resistors display was garbled every few minutes).

If I was designing a new controller board, I would further improve LCD interface, but there are a lot of other terrible things in cheap 3D printer electronics, like MOSFETs driven directly from controller outputs, endstops with NO switches, or electrolytic capacitors placed directly under hot stepper motor drivers.
So taking into account all these potential problems, I would say that 1 LCD error during 3 months is acceptable for me.

----------


## Mjolinor

The whole world drives MOSFETs from micro outputs now. Good design it isn't, cheap it is.

----------


## ESS

But the whole world doesn't use PWM with MOSFETs driven directly from MCU outputs...

----------


## 3DPBuser

My display only garbles, sometimes, when inserting/removing the SD card while powered on. One button push fixes it. I know it should be powered off.

More interesting is that the other functions that the button controls sometimes takes repeated button pushes to activate; I know each push is working because it makes it's little click, but sometimes five pushes are needed for the function to activate.

----------


## aeropic

> Interesting.  Be sure to report back after a while to confirm whether or not the series termination resistors solved your garbled display problem.  I'd try the fix myself, but I've eliminated the nibble transfer display as part of migrating to Smoothieboard on my i3v.  
> 
> Technically, the bulk of the benefit is likely obtained by adding the termination resistor in the E signal line to the display. IIRC, that is the signal that is pulsed to latch each nibble data transfer into the display module.  Ringing on any other pins likely wouldn't matter as long as they're stable when the E pin is pulsed, but there's no reason the termination can't be added in all the data lines.  Also note that some of the data lines (encoder, SD reader) on the two cables are driven by the smartpanel and not the ATMEGA2560.


Printbus and ESS, I cannot say thanks enough to you both. I had already shielded the LCD ribbon of my ANET A8 but the screen still failed once every 3 min or so. I then installed only one 47 Ohm resistor directly on the LCD PCB in serial of the ENABLE signal and combined with the shielding connected to ground, it's now working very very well.
I have not yet the feedback over a long print but definitely it helps a lot.
But ENABLE+47Ohm alone or shielding alone is not enough (for me)
ANET_LCD_solution.jpg

----------

