Enhanced LiquidCrystal

Modifications to LiquidCrystal for the Arduino with callback busy test

I made several modifications to the LiquidCrystal library module from Arduino17:

40x4 LCDs
I added support for an LCD of 4 LInes and 40 characters. It worked with a 27x4 LCD. The 40x4 LCD (and any HD44780 based LCD with between 81 and 160 characters) will have 2 enable lines. To use an LCD with 4 lines and 40 columns you would declare your LiquidCrystal object as:
LiquidCrystal lcd(RS,RW,Enable1,Enable2, data3,data2,data1,data0); at this time I don't support 8 data lines. (You can pass 255 as the RW item, ground RW and save an Arduino pin.)
Then in the setup function you would call:
lcd.begin(40,4);

Linewrap
When you declare the dimensions of the LCD in your begin call, the LiquidCrystal library remembers how long the lines are. Now when it reaches the end of line 1, text wraps onto line 2 (not line 3 as previously).

println
Although print has worked properly in the past, println has not. Now the '\r' and '\n' characters are not sent to the screen as though they were visible characters and the '\r' resets the character position to the top of the next line.

16x4 LCDs
The begin statement also correctly positions text at the beginning of the line on 16x4 (and 40x4) LCDs, which were not correctly handled before.

setCursor
In the past setCursor selected a location in the HD44780's RAM not actually a screen location. If you use any of the commands that shift the display left or right with the previous routines, then setCursor and print, text appears in an unexpected location on the screen. With the new software, if you call either scrollDisplayLeft() or scrollDisplayRight(), the LiquidCrystal package keeps track of the relationship between RAM and the LCD so that setCursor coordinates are pegged to a specific spot on the screen, rather than a spot in RAM. The sotware does not handle autoScroll, however. Call home() after autoScroll to restore the expected relationship between setCursor and the LCD screen.

Testing the LCD Busy Flag
Previous versions of LiquidCrystal always used timed delays on the Arduino side of the interface to give the LCD module enough time to complete its operation. This version still does that if you tie the RW pin to ground and do not tell LiquidCrystal what that pin number is or pass it the address of a user routine to test the busy flag. If you do specify RW now, however, the software will poll the busy flag on the LCD module. Arduino operations may thus overlap LCD operations and potentially things may go a little faster.

Syntactic Sugar
#include <Streaming.h> from New Streaming Library | Arduiniana
Then you can combine that with an overloading of the () operator in this code. This lets you specify screen location and chain print commands together by writing: lcd(column,line)<<“a=”<<a;
Streaming.h is so efficient you may actually save a few bytes of memory!

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 than LCD work. 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 1491 milliseconds | nonAxman 1491
Axman 4 data pins + RW 774 milliseconds | nonAxman 679
Axman 8 data pins no RW 1407 milliseconds | nonAxman 1407
Axman 8 data pins + RW 633 milliseconds | nonAxman 620
Axman 4 pins + user busy 510 milliseconds | nonAxman 441

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 1289 milliseconds | nonAxman 1289
Axman 4 data pins + RW 369 milliseconds | nonAxman 331
Axman 8 data pins no RW 1251 milliseconds | nonAxman 1251
Axman 8 data pins + RW 423 milliseconds | nonAxman 394
Axman 4 pins + user busy 361 milliseconds | nonAxman 252

Crazy 8 Addressing
16x1 LCDs often have an unusual address layout; these modules often have two 8 character halves and work best with this software if you declare them as lcd.begin(8,2); if you do that, then you can print(“abcdefghilklmno”); and have all the characters appear as you would like across the screen. If you use any of the scrolling commands, the bizarre addressing of these modules will manifest itself. For details follow the LCD Addressing link at web.alfredstate.edu/weimandn

User callback busy test
Get LiquidCrystal running without this first; setting up this complicated option is error-prone and this should be left for last, if implemented at all.