Loading...
Pages: [1]   Go Down
Author Topic: Issue with 40x2 display fixed; need to fix LiquidCrystal library?  (Read 281 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Newbie
*
Karma: 0
Posts: 2
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I ran into an issue with my 40x2 displays. "hello, world" was garbage. Nibbles were being swapped. Found a fix by  changing the 2000 µSecond delay in clear() to 2500.
« Last Edit: March 01, 2013, 02:26:19 pm by kenthompson » Logged

Netherlands
Offline Offline
Tesla Member
***
Karma: 90
Posts: 9421
In theory there is no difference between theory and practice, however in practice there are many...
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Thanks for this tip!

What is the name of the library used? there are several libs...
Which display did have this problem? type ?

I expect that the delay in clear() depends on the size of the display
Probably it is a start time + a fixed time per char
Assuming the start time is zero the time per char is about 30 µSec.

In code that might become something like :
Code:
void LiquidCrystal::clear()
{
  command(LCD_CLEARDISPLAY);  // clear display, set cursor position to zero
  delayMicroseconds( 100 + _numLines * _numColums * 30);           // this command takes a long time!
}

Worth investigating if there is a relation between size and clear() time for different LCD's.

BTW same problems with Home command? it also waits 2000uSec
Code:
void LiquidCrystal::home()
{
  command(LCD_RETURNHOME);  // set cursor position to zero
  delayMicroseconds(2000);  // this command takes a long time!
}


A less blocking way to solve it is to make the blocking conditional.
The clear function remembers when it was called and becomes non-blocking!
The send function blocks only if it was not long enough ago.

If there is a lot of math/manipulation or sensor reading to be done before writing the blocking time might even be zero!

Code:
[code]void LiquidCrystal::clear()
{
  command(LCD_CLEARDISPLAY);
  lastTime = micros();                     // remember
}

....

void LiquidCrystal::send(uint8_t value, uint8_t mode)
{
   while (micros() - lastTime < 2500); // blocks for the remainder of the time   (and yes the 2500 could be a function of the size of the display)

  digitalWrite(_rs_pin, mode);

  // if there is a RW pin indicated, set it low to Write
  if (_rw_pin != 255) {
    digitalWrite(_rw_pin, LOW);
  }
 
  if (_displayfunction & LCD_8BITMODE) {
    write8bits(value);
  } else {
    write4bits(value>>4);
    write4bits(value);
  }
}

Note tested the above, just thinking out loud!
[/code]
Logged

Rob Tillaart

Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -

Western New York, USA
Offline Offline
Faraday Member
**
Karma: 17
Posts: 3462
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
I ran into an issue with my 40x2 displays ....
As you have discovered, the LiquidCrystal library provides an extra 2000 microsecond delay for the clear command over and above the default 100 microsecond delay used for most of the other commands.  It would seem that this, along with the time it takes for the Arduino to actually send the commands to the LCD, should be sufficient to meet the 1520 microsecond (1.52 ms) requirement in the data sheet ... BUT there are some other factors to consider.

The Instruction Set has a column which lists 'typical' instruction execution times and those times are for a 'typical' clock speed (the clock in the LCD controller, not your Arduino).  At the bottom of that column, usually on the next page, it tells how to modify the time requirement for other clock speeds.

Elsewhere in the datasheet the clock specifications indicate that it may legitimately run as low as 190 KHz, which would increase the instruction execution time from 1520 microseconds to 2160.  Now it is only the time it takes the Arduino to send the commands that may allow the actual delay to meet the datasheet requirements - and most of the time it works.

Another thing to consider is the fact that some of the displays purchased by Arduino users, especially those purchased at rock bottom prices on the internet, may actually be out of specification units that have an even lower clock speed.

So - your modification to the library is based on a legitimate problem and is something that should be fixed, but don't hold your breath.  They haven't bothered to fix the improper step in the initialization routine or the faulty cursor positioning on the 16x4 displays.  The initialization error is actually insignificant (but still incorrect) but the cursor positioning is a real problem.


Quote
I expect that the delay in clear() depends on the size of the display...
I don't think so.  There is no way to tell the LCD controller what size display it is driving so it would always have to clear all 80 bytes of RAM.

Don
Logged

Netherlands
Offline Offline
Tesla Member
***
Karma: 90
Posts: 9421
In theory there is no difference between theory and practice, however in practice there are many...
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

@Don
Thanks for this explanation, clearly you have dived deeper in this matter than I did.
A question comes up, are there (un)documented commands to affect that LCD clock speed e.g setting a divider or so?
(I assume no)
Logged

Rob Tillaart

Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -

Western New York, USA
Offline Offline
Faraday Member
**
Karma: 17
Posts: 3462
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I don't know of any commands (documented or undocumented) that do anything more than those shown on the actual HD44780U Datasheet. 

There are some newer LCD controllers that have an expanded instruction set but I don't think that is what you mean.


Don
Logged

Pages: [1]   Go Up
Print
 
Jump to: