Pages: 1 ... 5 6 [7] 8 9   Go Down
Author Topic: Enhanced LiquidCrystal  (Read 12877 times)
0 Members and 1 Guest are viewing this topic.
Minnesota USA
Offline Offline
Sr. Member
****
Karma: 1
Posts: 323
Made it mahself outta sand 'n wahr.
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I am starting through the test process with each of the different size LCDs and each of the interfaces; I do see one change in the way this version works on the 40x4: with the 40x4 you have always had to specify an argument for RW. If you want to ground the RW pin, rather than omitting the argument, you specify 255. In the past if you specified a userBusy argument and a (non-255) RW argument, it used userBusy.

With the version I'm testing now you will need to specify 255 for RW on the 40x4 (and 27x4) LCDs if you want it to use a userBusy routine. You will also have to digitalWrite LOW to the RW pin before you call lcd.begin(40,4).

We've changed the order of testing for the different options and in every other case, the new order is what makes sense. It is a little faster for the more common and easy to use option.
« Last Edit: May 31, 2010, 05:45:08 am by jrraines » Logged

Minnesota USA
Offline Offline
Sr. Member
****
Karma: 1
Posts: 323
Made it mahself outta sand 'n wahr.
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Other than the change described in my last post there are no new features in this version:

Speed testing
All of the interface modes go faster than the eye can follow.  This version of the software is significantly slower than previous versions when using timed delays. I found an LCD (Axman) that needed longer delays and in the interests of making the code foolproof, I lengthened the delays to make that LCD work. However Paul Stoffregen has significantly speeded up the code when testing the busy flag and so those options run significantly faster than before. I compared the speeds of the different interfaces--writing 80 characters to the screen then 80 blanks and looping through that 20 times. The results  on a Mega are:
Axman 4 data pins no RW 1349 milliseconds  |  nonAxman 1349
Axman 4 data pins  + RW  565 milliseconds  |  nonAxman  468
Axman 8 data pins no RW 1314 milliseconds  |  nonAxman 1314
Axman 8 data pins  + RW  520 milliseconds  |  nonAxman  500
Axman 4 pins + user busy 369 milliseconds  |  nonAxman  316

I also have a Teensy++2.0 board. One of the interesting things about that board is that the software that comes with it includes considerable optimization of digitalRead, digitalWrite etc. The board runs at 16 megaHz, just like the Mega, but speeding up those commands results in an impressive change in the benchmarks:
Axman 4 data pins no RW 1207 milliseconds  |  nonAxman 1207
Axman 4 data pins  + RW  327 milliseconds  |  nonAxman  219
Axman 8 data pins no RW 1212 milliseconds  |  nonAxman 1212
Axman 8 data pins  + RW  361 milliseconds  |  nonAxman  296
Axman 4 pins + user busy 241 milliseconds  |  nonAxman  189

This version is available at:  
http://www.healthriskappraisal.org/LiquidCrystalFastWith8bit.zip
Logged

Cape Town, South Africa
Offline Offline
Full Member
***
Karma: 0
Posts: 177
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Interesting speeds.

I made an i2c backpack for my LCD* this weekend. After some tweaking, and boosting the TWI speed to 300kHz, I can do a single command in 384us.

That translates to 1229 ms for a (80 chars + 80 blanks) * 20 reps.

I could take the TWI speed higher, but then I would have to start adding delays, and separate commands.

Currently, I can send an LCD command with single TWI  transmission. Just 3 bytes (excluding address).


* Used a MCP23016 and 8-bit LCD interface. With no RW, although it is connected, not used.
« Last Edit: May 31, 2010, 02:51:38 am by leppie » Logged

Minnesota USA
Offline Offline
Sr. Member
****
Karma: 1
Posts: 323
Made it mahself outta sand 'n wahr.
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Does the I2C controller check the busy flag or just use a timed delay or is all of the delay on the arduino side?
Logged

Cape Town, South Africa
Offline Offline
Full Member
***
Karma: 0
Posts: 177
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
Does the I2C controller check the busy flag or just use a timed delay or is all of the delay on the arduino side?

Due to the slow speed of I2C, I dont even need a single delay/busy check except at initialization  smiley

From my testing it is stable without using delay up to 300kHz i2c speed, but it works ok @ 100kHz (the default in Arduino) too. Time per command at that speed is just under 700us.

I am going to see if I can get higher rates (eg 1mHz) using delays and multiple commands to to if it is worth it. I dont think using the busy check will be worth it due to the overhead of i2c.

Edit: I'll also do a proper bench timing to make sure my calculations are in fact correct smiley  I am bit surprised at the good speed I am getting.
« Last Edit: May 31, 2010, 06:56:46 am by leppie » Logged

Cape Town, South Africa
Offline Offline
Full Member
***
Karma: 0
Posts: 177
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
That translates to 1229 ms for a (80 chars + 80 blanks) * 20 reps.
Quote
I'll also do a proper bench timing to make sure my calculations are in fact correct Smiley  I am bit surprised at the good speed I am getting.

Good thing I did!  Your benchmark code posted on the previous page runs in 611 ms!  Half the expected time... Something is probably not right...

Gonna check the code, I am also getting some unexpected output.  smiley-sad

Edit: Found the bug! Was running out RAM on the 328p. Shortened strings, running again now.

Edit 2: Now getting 1229ms just as initially expected  smiley

I looked at the MCP23016 datasheet, and it only does up to 400kHz. Not sure if it will be worth boosting it more.
« Last Edit: May 31, 2010, 08:28:58 am by leppie » Logged

Cape Town, South Africa
Offline Offline
Full Member
***
Karma: 0
Posts: 177
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
Your benchmark code posted on the previous page

It does not seem to cause instability issues like the following does.

Code:
void loop()
{
  static int line = 0;
  static int col = 0;
  static char c = 'a';
  
  lcd.write(c);
  
  col++;
  
  if (col == 20)
  {
    col = 0;
    line++;
    lcd.setCursor(col, line);
    
    if (line == 4)
    {
      line = 0;
      
      c++;
    }
    
  }
}

Anything above a 300kHz TWI frequency and it crashes after a few minutes.
Logged

Minnesota USA
Offline Offline
Sr. Member
****
Karma: 1
Posts: 323
Made it mahself outta sand 'n wahr.
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

deleting code goes much faster than writing code.

It seems like I already have something working, about 700 bytes less flash memory usage. At least 5 bytes less RAM usage.

If I do sizeof(lcd) it gives me a number (30 for the 4 bit version I'm working on today) that includes the RAM used for instance variables. The compiler gives a size for a compiled sketch's total flash memory usage. Is there an easy way to see the amount of flash memory LiquidCrystal itself uses? I honestly didn't make note yesterday of sketch sizes for the various options, it seems excessive to reinstall yesterday's code just to measure those, but it would be interesting to see a percentage difference in static memory usage.
Logged

Minnesota USA
Offline Offline
Sr. Member
****
Karma: 1
Posts: 323
Made it mahself outta sand 'n wahr.
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I found that I needed to increase the per character delay a little more to get the Axman LCD to work using timed delays. When the delay was 320 usec I was seeing maybe one error in 100 characters. quite posibly the vesion I posted on 5/30 needed a longer delay, too. I did the Axman LCD last that time and I was tired.

When I get a chance I think I will compare the length of this version of LiquidCrystal with Arduino-17/18. I suspect the length is pretty comparable now even with the bug fixes and additional modes and features.

I did change all of the items that were 'private' to 'protected'. I think that will allow what Paul was suggesting; writing a class that inherits from LiquidCrystal and then providing a new send()  that has the pin numbers hard coded so that PORT type instructions or digitalWriteFast can be used to speed things up.

http://www.healthriskappraisal.org/LiquidCrystal4Bit.zip
Logged

North Yorkshire, UK
Offline Offline
Faraday Member
**
Karma: 104
Posts: 5531
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I have a quick quesion... I did PM you but maybe you didn't get it...

With the 40x4 that has dual HD44780 chips, does that mean that you could have 16 custom characters, just 8 in the top half and 8 in the bottom half?

Mowcius
Logged

0
Offline Offline
God Member
*****
Karma: 25
Posts: 602
Always making something...
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Very nice.  The code's looking very good.  I'll try to come up with a subclass example on send().

Here's a list of minor little things I noticed looking at the latest code.  Nothing's critical, just little things.


_busyPin seems to always be _data_pins[3].  Eliminating it might reduce code size, and save an extra byte of per-instance RAM.

rwSave save in init() appears to be unused now.

Inside init(), should en2 be checked for 255 instead of 0 to see if it's unused?

Inside init2(), it would be advisable to call delayMicroseconds with only 15000 and do the loop 9 times instead of 3.  Even though delayMicroseconds takes a 16 bit input, it doesn't actually work properly beyond 16383.  In fact, limiting your call to 8191 us might be a good idea, in anticipation of a 32 MHz AVR (eg, the xmega chips).

Can _displayfunction become only a local variable inside begin2(), possibly saving code side and one more byte of per-instance allocated RAM?
« Last Edit: June 02, 2010, 06:40:27 am by pjrc » Logged

Minnesota USA
Offline Offline
Sr. Member
****
Karma: 1
Posts: 323
Made it mahself outta sand 'n wahr.
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Mowcius: the hardware would let you do that. My software, however, sends the user defined characters to both hd44780s. My philosophy has been to try to make the software for the 40x4 act like its one device. You'd have to change the API if you wanted to be able to tell the software which lines you were defining the characters for. I suppose you could write your own code outside LiquidCrystal (or subclass it!) to LOAD the user definitions and LiquidCrystal would never know the difference.

Paul: thanks for the tips I will look at those, probably in a few days.

I will spend a little time poking into the Axman timings. something seems fishy.
Logged

North Yorkshire, UK
Offline Offline
Faraday Member
**
Karma: 104
Posts: 5531
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
Mowcius: the hardware would let you do that. My software, however, sends the user defined characters to both hd44780s. My philosophy has been to try to make the software for the 40x4 act like its one device. You'd have to change the API if you wanted to be able to tell the software which lines you were defining the characters for. I suppose you could write your own code outside LiquidCrystal (or subclass it!) to LOAD the user definitions and LiquidCrystal would never know the difference.

I knew you would have the answer smiley-razz
Right. I might look into it. I think it might be useful for a few projects I have in mind.

Thanks,

Mowcius
Logged

Minnesota USA
Offline Offline
Sr. Member
****
Karma: 1
Posts: 323
Made it mahself outta sand 'n wahr.
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
Inside init(), should en2 be checked for 255 instead of 0 to see if it's unused?

That one looks like an actual bug to me. It would only show up if someone passed pin 0 for en2, but a bug nonetheless.

Thanks for pointing this out!!
« Last Edit: June 05, 2010, 05:51:56 am by jrraines » Logged

Minnesota USA
Offline Offline
Sr. Member
****
Karma: 1
Posts: 323
Made it mahself outta sand 'n wahr.
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I updated the zip file with the changes Paul pointed out:
http://www.healthriskappraisal.org/LiquidCrystal4Bit.zip
Logged

Pages: 1 ... 5 6 [7] 8 9   Go Up
Jump to: