I just received a 16x2 SerLCD (LCD-14073) and I’m controlling it with a Teensy 4.0 over I2C. The HelloWorld example (in the library download) worked fine, but as soon as I started making changes to the example, I started seeing storage behavior. Basically, the characters I was writing were showing up locations that I had not addressed using lcd.setCursor(). The example is based on a tight loop that writes to the display multiple times per loop iteration, but the display content is changed only every 1 second. Not something you’d do in the real world, but it raises questions. It wasn’t until I added a 200ms delay at the end of the loop before I got the expected behavior. I’m not familiar with how the SerLCD and I2C Wire libraries are written, but I’m guessing the issue is with the timing of I2C writes to the display. Perhaps a buffer is overflowing, either in the (very fast) Teensy 4.0 or in the (much slower) SerLCD controller? Anyone familiar with this problem? Are there any guidelines for the maximum rate at which various SerLCD library calls should be used? Thanks!
Hello, and thanks for posting your question.
These LCDs use a Hitachi HD44780 controller IC in them and that controller IC has some limits on how fast it can execute instructions. Unfortunately the firmware on the board doesn’t take into account how much time each instruction takes so it’s possible to send data to the LCD faster than it can be processed. I don’t have a listing of how long each instruction takes to process, but the [HD44780 datasheet would be a good place to start if you’re looking for hard numbers. Otherwise, I’d just add a small delay between commands being sent and see if that clears things up.](https://www.sparkfun.com/datasheets/LCD/HD44780.pdf)
Thanks for this thread! I was about to go nuts on my very first project. I’m using a RedBoard Artemis, which has a higher clock speed, IIRC. The “Hello, World!” example shows a bug right off the bat, printing “Hello, World!0”. I futzed around with the code, trying to figure out what was going on, and got various weird behaviors… until I inserted some delays, as you suggest, here. Basically, after every print or setCursor statement sent to the screen, I inserted a delay(200), and now everything works as expected.
I wonder if this isn’t an appropriate enhancement to send over to OpenLCD firmware or SerLCD. Basically, have it calculate clock speed and compare against the HD44780’s command speed, and basically not send things too quickly? I think I can mitigate this easily in my code, but it was entertaining.
I did find the following on line 90 of https://github.com/sparkfun/OpenLCD/blo … _Basic.ino
delay(50); //The maximum update rate of OpenLCD is about 100Hz (10ms). A smaller delay will cause flicker
Note that you can set the I2C clock on the bus to 400Hz via:
Wire.setClock(400000);
That doesn’t change the speed of the backing hardware, but if we’re overrunning the I2C bus, setting the clock speed higher, and then delaying by 3ms should work around that situation?
It might be possible to over run the I2C buffer on the display, but the part that really causes the issue is the LCD controller itself. That take time to execute instructions and if you send a command before the LCD has completed the previous instruction, unpredictable things happen on the display.
I don’t think we take into account how long the various commands take to process, (by the LCD controller, not the ATmega on the LCD) but that might be a good addition to future firmware revisions.
TS-Chris:
It might be possible to over run the I2C buffer on the display, but the part that really causes the issue is the LCD controller itself. That take time to execute instructions and if you send a command before the LCD has completed the previous instruction, unpredictable things happen on the display.
That makes sense.
I don’t think we take into account how long the various commands take to process, (by the LCD controller, not the ATmega on the LCD) but that might be a good addition to future firmware revisions.
That’d likely be a firmware enhancement, not something against the SerLCD library, right?
It could actually happen in either, but putting it in firmware would be a better solution since some people might not be using the SerLDC library.
Well, I’m coming to the conclusion that this display is unusable in any kind of real-time application. I thought the whole idea of a “smart” display was to offload the host processor. Discovering that the processor needs to “pace” commands sent to the display was disappointing but not a showstopper. But now as I was trying to figure out why my main loop was running so slow, I was horrified to find that the SerLCD library code is littered with delay(50) and delay(10) calls.
Since my main loop runs at 30 Hz, I can never call even the most basic SerLCD library function without causing a huge timing overrun.
Why, why, why does the library hijack my 600 MHz processor just to sit in a delay loop?
I suppose I could try to rewrite the library to use a different timing approach, but that would defeat the purpose of buying a “smart” display so that I could focus on my actual application…