Pages: [1]   Go Down
Author Topic: Faster communication to the LCD shield?  (Read 1525 times)
0 Members and 1 Guest are viewing this topic.
0
Offline Offline
Newbie
*
Karma: 0
Posts: 30
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hallo I have a question about the 'speed' at which Arduino communicates with the LCD shield.
I have this LCD shield http://www.nuelectronics.com/estore/index.php?main_page=product_info&products_id=2

I use this code:

#include <LCD4Bit_mod.h>
LCD4Bit_mod lcd = LCD4Bit_mod(2);
char buf[6]; // int has up to  5 digits plus terminating 0
int val = 0;

void setup()
{
  lcd.init();
  lcd.clear();
}

void loop()
{
  lcd.cursorTo(1,0);
  lcd.printIn(itoa(val, buf, 10));
  val = val + 1;
}


You see it displays the value of 'val' on-screen. Which works good.
The code takes the value of 'val' and counts (adds) 1 to it each loop.
The code is not limited by any delay() or something, so it should run as fast as it can.
But when I run the code the counting val on screen it somewhat slow, meaning that it takes about a second to count from 0 to 100. So why is this calculation so slow? Is the LCD communication hindering the code to run fast, I mean it should be able to count much much faster right?

Thanks.
Regards,
Steven

Logged

Global Moderator
Netherlands
Offline Offline
Shannon Member
*****
Karma: 217
Posts: 13739
In theory there is no difference between theory and practice, however in practice there are many...
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

why not print the value directly as print can handle integers. Also using print iso printLN as this latter adds an extra return which is not needed (the return adds up 10 to 50% communication overhead! depending on the number of digits)

Code:
#include <LCD4Bit_mod.h>
LCD4Bit_mod lcd = LCD4Bit_mod(2);

int val = 0;

void setup()
{
  lcd.init();
  lcd.clear();
}

void loop()
{
  lcd.cursorTo(1,0);
  lcd.print(val);
  val++;
}

I'm curious how far this will run in a second, let us know.
Logged

Rob Tillaart

Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -
(Please do not PM for private consultancy)

0
Offline Offline
Newbie
*
Karma: 0
Posts: 30
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi Robtillaart,
Thanks for the reply. I tried your code but it only displays only one counting digit values.
It displays it too fast to see what is really being displayed but it appears there are letters and numbers as well as other signs displayed.

Any idea?
I'm all very new to this.

Thanks.
Regards,
Steven

« Last Edit: February 15, 2011, 08:12:48 am by nali2001 » Logged

0
Offline Offline
Newbie
*
Karma: 0
Posts: 30
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I use your code, only a bit modified to display a static digit 1:
Val value is 1 so only 1 should be seen on the lcd.
But what actually is displayed is an odd character.

Code:
#include <LCD4Bit_mod.h>
LCD4Bit_mod lcd = LCD4Bit_mod(2);

int val = 1;

void setup()
{
  lcd.init();
  lcd.clear();
}

void loop()
{
  lcd.cursorTo(1,0);
  lcd.print(val);
}


Logged

0
Offline Offline
Newbie
*
Karma: 0
Posts: 30
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

It's about 5 times faster than the first code I used.
It now counts to 500 in one second or so. Still not really fast should it not be able to count to thousands in a second?
Ok I now changed the code to:

Code:
#include <LiquidCrystal.h>
LiquidCrystal lcd(8, 9, 4, 5, 6, 7);
int val = 0;

void setup()
{
  lcd.begin(16, 2); // set up the columns and rows
  lcd.clear();
}

void loop()
{
  lcd.setCursor(0,0);
  lcd.print(val);
  val = val++;
}
Logged

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

Switching from LCD4bit to LiquidCrystal was a good choice but both libraries use software time delays to implement the LCD display.  This is fine most of the time, but if you want the LCD display to run as fast as possible you have to implement the R/W line and use the 'busy flag' instead of time delays.  This is not possible with the (current) LiquidCrystal library.  Although that library does allow you to connect the R/W line it does not use it in any way.  You should look into the LiquidCrystal440 library which does use the busy flag when the R/W line is implemented.

Don
Logged

Global Moderator
Netherlands
Offline Offline
Shannon Member
*****
Karma: 217
Posts: 13739
In theory there is no difference between theory and practice, however in practice there are many...
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
It displays it too fast to see what is really being displayed ...
As displays are needed to read by humans, normally they only need to be updated in the range 1-5 times / second (unless video is displayed) That means for practical purposes the display is fast enough. Just make a separate function that updates the display after some time has passed, there is no need to update it every loop..

Code:
void loop()
{
  // ..
  if (millis() - prevTime > 500)  // refresh rate 2x per sec
  {
    updateDisplay();
    prevTime = millis();
  }
  // .. do the rest
Logged

Rob Tillaart

Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -
(Please do not PM for private consultancy)

Central MN, USA
Offline Offline
Tesla Member
***
Karma: 73
Posts: 7197
Phi_prompt, phi_interfaces, phi-2 shields, phi-panels
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

I recall some other guy working on a cnc mill project had the same experience but he didn't have to print on lcd that often either. Use a function like this:

if (millis()%250) print_stuff(); in your loop. It will only print 4 times a second, fast enough.
Logged


Global Moderator
Netherlands
Offline Offline
Shannon Member
*****
Karma: 217
Posts: 13739
In theory there is no difference between theory and practice, however in practice there are many...
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

@liudr

Quote
if (millis()%250) print_stuff(); in your loop. It will only print 4 times a second, fast enough.

Sorry to say but :    Don't do this!   it fails!

Reason: it will only work when   millis() % 250 is exactly  0,   so if the millis() is one micro ahead or too late you will miss the printstuff() then it will be no_stuff()   resulting in many  questions on the forum why the code doesn't print anything. When dealing with millis() follow the famous - http://arduino.cc/en/Tutorial/BlinkWithoutDelay
Logged

Rob Tillaart

Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -
(Please do not PM for private consultancy)

Central MN, USA
Offline Offline
Tesla Member
***
Karma: 73
Posts: 7197
Phi_prompt, phi_interfaces, phi-2 shields, phi-panels
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Oops, sorry for the bad suggestion. Go get yourself an iterator variable like
unsigned long i1=0;
void loop()
{
i1++;
//rest of code
if (i%10) print_stuff();
}

This will print every 10 iterations.
Logged


Global Moderator
Offline Offline
Brattain Member
*****
Karma: 485
Posts: 18807
Lua rocks!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

It now counts to 500 in one second or so. Still not really fast should it not be able to count to thousands in a second?

Let's put things into perspective here. The I2C protocol can address a device and send a single byte in about 0.2 ms. That's like sending 5000 bytes per second. But to do something like set the cursor itself will take something like 4 bytes (command "set-x", X location, command "set-y", Y location).  Then it needs to send (say) a 4-digit number. That will be four lots of (command, byte). So to send a 4-digit number, we then are sending 12 bytes to the display, which can theoretically handle 5000 bytes per second. That's only 416 times a second. And that isn't taking account timing delays that the display may require, the time taken to actually convert your value into digits (the print statement). And maybe the library sets the location per character which adds another fairly big overhead.

So really, a couple of hundred updates a second is what you expect. Plus, who can read that fast?
Logged


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

Quote
Let's put things into perspective here. The I2C protocol ...

But I2C (or any other serial) protocol is irrelevant in this particular situation.

Don
Logged

0
Offline Offline
Newbie
*
Karma: 0
Posts: 30
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Ok thanks all!
Yeah I understand somewhat better now.
Not that I obviously really have a use for a few thousand counts realtime on screen.
Just wondered about the speeds involved and the limitations.

Logged

Global Moderator
Offline Offline
Brattain Member
*****
Karma: 485
Posts: 18807
Lua rocks!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

But I2C (or any other serial) protocol is irrelevant in this particular situation.

Oh I see. It directly manipulates the pins. Sorry about that. I had just been working on a library that uses I2C and had it on the brain. smiley-wink

In any case, the specs for the LCD will specify delays while the LCD is busy doing stuff. The exact delay can be worked out by reading the busy status as an earlier poster said. Or the library writers may have just used a fixed delay, for simplicity.

Judging by the data sheet the delay for many operations is around 40 microseconds (0.04 ms). Still, that's only 5 times faster than the 0.2 ms I quoted which would be imposed by the I2C protocol. 

And when I glance at the library itself, I see that they have added a 1 ms delay every time the Enable pin is pulsed, which is probably quite a lot longer than required. Plus a few other delays scattered here and there.

Also since they are using 4-bit mode, it takes two pulses to get a single data byte transferred, so for each byte sent to the display that is 2 ms minimum. So disregarding all the other overheads (which in practice you can't, because you need to send cursor positioning, etc., and the code itself takes time to execute) you will send a maximum of 500 characters per second to the display (500 x 2 ms delays) using this library.
Logged


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

Quote
And when I glance at the library itself, I see that they have added a 1 ms delay every time the Enable pin is pulsed, which is probably quite a lot longer than required.

Why quibble?  It's only 2000 times more than is required.

Don
Logged

Pages: [1]   Go Up
Jump to: