USE UPS NEXT DAY AIR FOR ANY USA ORDER BEFORE 11AM ET *TODAY* 12/19/2014 TO GET YOUR PACKAGE IN TIME FOR XMAS - PLEASE SEE OUR SHIPPING DEADLINE NOTICE FOR MORE DETAILS!

LiquidTWI: High-performance LCD library for I2C Backpack Module
Moderators: adafruit_support_bill, adafruit

LiquidTWI: High-performance LCD library for I2C Backpack Module

by FalconFour on Wed Jun 15, 2011 6:24 am

I like fast things. And I like clean code. Often, the two go hand-in-hand ;)

http://www.youtube.com/watch?v=IpwqGJwn1FY

After looking through the modified LiquidCrystal library for use with the i2c backpack and darn near crying when I saw all the faux digitalRead() and pinMode() being done on each transfer, I was bound and determined to never let that happen to another friendly Arduino user again. I first made a proof of concept modification to the library to "burst" all the "LiquidCrystal::send" bits instead of digitalWrite()'ing them out one at a time (read I2C, modify, write... read, modify, write... read, modify, write... read, modify, write - over 16 I2C commands for each single character). It worked great. I could do animation on the screen once again, and it was smooth.

OK, so the next step... package it up into something usable. I kept running into issues where Wire.h needed to be part of every program I use LiquidCrystal with. It just had to be "forked" to its own library. I'm sure C++ will allow a typedef alias for any libraries/sketches that have LiquidCrystal hard-coded into them... I just haven't had a need yet. I fully gutted LiquidCrystal of all functions relating to digitalRead/digitalWrite, and made it 100% pure i2c. What a sleek beauty... just watch the video.

Of course, next on my to-do list is a proper animation library for character LCDs. :)

LiquidTWI library is attached to this post, also mirrored here: http://dl.dropboxusercontent.com/u/3528 ... -1.5.1.zip

Hope it helps! :D

Changelog:
  • 1.5.1 / 8-7-2013:
    Merged with changes from Stephanie Maks which provides compatibility with old IDEs as well as new. Also has a better init sequence. Shortened init delay back down to 50ms.
  • 1.5 / 8-7-2013:
    Finally... finally wired up the test board again and resolved problems with new 1.x Arduino IDE. write() needs to be a size_t to mesh with Print. Also increased initialization delay from 40ms to 100ms to prevent bad initialization on first power-up.
  • 1.1 / 6-17-2011:
    Oops... initial bugchecking was done on one program (performance test). LCD_DISPLAYCONTROL functions were sending bit 7 (backlight) to the LCD as part of the command, invalidating most commands and setting the cursor to address 0 instead of doing their function. That also screwed up the initialization routine something fierce. A miracle this slipped by testing.
  • 1.0 / 6-12-2011:
    Initial release

Distributed with as free-will a license as is available given this code's long associative chain of licenses (LiquidCrystal -> Arduino -> Wiring -> ...?). Use it in any way you feel fit, profit or free, provided it fits in the licenses of its associated works.

Usage:
Code: Select all | TOGGLE FULL SIZE
  Attach CLK pin to ANALOG 5 pin (remember: analog pins double as digital!),
  Attach DAT pin to ANALOG 4 pin,
  Give it 5V using    5V     pin,
  Then,  GND it with  GND    pin, and you're all set!

  Replace LiquidCrystal in your sketch directly with LiquidTWI, and modify the "LiquidCrystal lcd(...)" line as follows:

  LiquidTWI lcd(byte i2cAddr)
    i2cAddr = the address of your backpack device (typically 0)

  The rest of the commands are straight out of LiquidCrystal:
  void setup() { lcd.begin(16,2); }
  void loop() { lcd.print("Happy!"); delay(500); lcd.clear(); delay(500); }


If you changed the i2c address of the board (multiple LCDs? I dig it!), set "lcd(0)" to your new 3-bit address. If you have more than a 16x2 LCD, change "lcd.begin(16,2)" to reflect the columns and rows of your LCD.
Attachments
LiquidTWI-1.5.1.zip
LiquidTWI 1.5.1 with bug-fixes merged from Stephanie Maks and better initialization process
(7.77 KiB) Downloaded 1185 times
Last edited by FalconFour on Thu Aug 08, 2013 3:25 am, edited 5 times in total.
User avatar
FalconFour
 
Posts: 14
Joined: Sun Jun 12, 2011 9:49 am
Location: Fresno, CA

Re: LiquidTWI: High-performance LCD library for I2C Backpack Module

by adafruit_support_bill on Wed Jun 15, 2011 7:15 am

Nice work! Impressive :D
User avatar
adafruit_support_bill
 
Posts: 32617
Joined: Sat Feb 07, 2009 10:11 am

Re: LiquidTWI: High-performance LCD library for I2C Backpack Module

by adafruit on Wed Jun 15, 2011 12:55 pm

thanks! we wanted to keep the modification as simple as possible but your version is topnotch! thanks :)
User avatar
adafruit
 
Posts: 11778
Joined: Thu Apr 06, 2006 4:21 pm
Location: nyc

Re: LiquidTWI: High-performance LCD library for I2C Backpack Module

by FalconFour on Wed Jun 15, 2011 2:04 pm

adafruit wrote:thanks! we wanted to keep the modification as simple as possible but your version is topnotch! thanks :)

Hey, I'm honored to be hearing from the legendary adafruit herself! It only took about half an hour to write up and comment - about 2 hours of debugging afterward, not getting any signals at all from the i2c chip (and finding a MUCH deeper complication regarding constructors in Arduino)... but it was worth it :)

Of course I think that constructor issue is worth bringing up... was originally going to post it in here but thought the Arduino forum is more suited: http://arduino.cc/forum/index.php/topic,64066.0.html

edit: BTW, of course you're welcome to use that however you like, commercially or otherwise, I kinda formally-informally dub it with the "most freely usable license legally available to this type of code", whatever that may be - not sure how the long chain of related licenses handles "loosely related but mostly new work" code! It makes use of a lot of definitions from the MCP23008 files, but not the code, so I'm not sure how that fits in... any way it goes, though, I just wrote it so people could use it :)
User avatar
FalconFour
 
Posts: 14
Joined: Sun Jun 12, 2011 9:49 am
Location: Fresno, CA

Re: LiquidTWI: High-performance LCD library for I2C Backpack Module

by adafruit on Wed Jun 15, 2011 2:17 pm

we've updated the product tutorial to include a link to your code (this thread) & will post about it on the blog
User avatar
adafruit
 
Posts: 11778
Joined: Thu Apr 06, 2006 4:21 pm
Location: nyc

Re: LiquidTWI: High-performance LCD library for I2C Backpack Module

by FalconFour on Wed Jun 15, 2011 2:23 pm

adafruit wrote:we've updated the product tutorial to include a link to your code (this thread) & will post about it on the blog

Wow... thanks! Talk about an honor! Glad to help out. Hopefully it'll make the i2c backpack a more attractive option since we can now use an LCD with only 2 pins, and still be at about full speed :)

Of course, if I could implement it inside a timer interrupt, it could be even faster by turning the LCD into a sort of streaming output device (lcd.print() returns immediately, adds to a buffer, sends to LCD when the interface is free), and I can even see how that code could work out. Maybe I might just try my hand at completely rewriting LiquidCrystal itself (and still being backwards compatible, I don't see any functionality that's tied to its "blocking" characteristic), of course if this proves to be a popular project!
User avatar
FalconFour
 
Posts: 14
Joined: Sun Jun 12, 2011 9:49 am
Location: Fresno, CA

Re: LiquidTWI: High-performance LCD library for I2C Backpack Module

by TheWag on Thu Jun 16, 2011 10:32 pm

Oh So Sweet! Downloaded and changed minimal code and I've see update times in my script go from 135ms to 35ms. Excellent work! If you decide to go with the interrupt/timer idea, please make it optional or separate package.

Thanks!
TheWag
 
Posts: 4
Joined: Sun Nov 28, 2010 10:46 am

Re: LiquidTWI: High-performance LCD library for I2C Backpack Module

by FalconFour on Fri Jun 17, 2011 8:44 pm

Well, somehow I managed to let a pretty big bug slip through the cracks... I used a bit in "_displaycontrol" to store and retrieve if the LCD backlight should be enabled, and I used the same bit that's used on the I/O expander to denote it (bit 7, 0x80). Clever, right? Well, not if that byte is being sent as an 8-bit command... as it turns out, that ended up sending the DDRAM address command to the LCD instead of the display control command. Oops!! I relocated the bit to the bit used for the displaycontrol command (bit 3, 0x08) which will always be masked by the command (as it was originally intended), and fixed that up.

tl;dr: v1.0, your cursor() and blink() commands won't work. v1.1, they will. :lol:

Updated in original post, go grab the new version!
User avatar
FalconFour
 
Posts: 14
Joined: Sun Jun 12, 2011 9:49 am
Location: Fresno, CA

Re: LiquidTWI: High-performance LCD library for I2C Backpack Module

by micsaund on Thu Aug 11, 2011 9:37 pm

Hi,

Forgive my possibly n00bish mistake, but I'm having a bit of trouble with the LiquidTWI lib.

First, I took the Hello World I2C example from Ada's library, changed the include and instantiation line to reference LiquidTWI and it works. My newly assembled backpack kit works :D

So, I figured I'd get a bit feisty and try some of the other demo apps out of the Ada lib's Examples dir. Now, stop me if the TWI lib isn't meant to be a drop-in replacement for LiquidCrystal, because that's the assumption I'm working under.

I took the AutoScroll example, and did similar changes to the include and instantiation line so that TWI is used instead:

Code: Select all | TOGGLE FULL SIZE
// include the library code:
#include <LiquidTWI.h>

// initialize the library with the numbers of the interface pins
LiquidTWI lcd(0);



However, when I try to compile it (using the 'play' button in the Arduino IDE), I get the following:

Code: Select all | TOGGLE FULL SIZE
/Users/mike/Documents/Arduino/libraries/LiquidTWI/LiquidTWI.cpp:45:18: error: Wire.h: No such file or directory
/Users/mike/Documents/Arduino/libraries/LiquidTWI/LiquidTWI.cpp: In member function 'void LiquidTWI::begin(uint8_t, uint8_t, uint8_t)':
/Users/mike/Documents/Arduino/libraries/LiquidTWI/LiquidTWI.cpp:80: error: 'Wire' was not declared in this scope
/Users/mike/Documents/Arduino/libraries/LiquidTWI/LiquidTWI.cpp: In member function 'void LiquidTWI::burstBits(uint8_t)':
/Users/mike/Documents/Arduino/libraries/LiquidTWI/LiquidTWI.cpp:278: error: 'Wire' was not declared in this scope

I remember reading your write-up that you tried to get rid of every reference to Wire.h (or something like that -- again, possibly a n00bish interpretation), yet this seems to indicate that it's being called from the TWI lib.

So, I guess the first question is: 1) Is the TWI lib intended to be a drop-in replacement for LiquidCrystal and 2) is this error I'm getting expected due to some silly mistake I made?

Thanks for the help (and the i2c lib)!

Mike
www.micsaund.com
micsaund
 
Posts: 2
Joined: Sat Jul 30, 2011 12:07 am

Re: LiquidTWI: High-performance LCD library for I2C Backpack Module

by FalconFour on Thu Aug 11, 2011 9:55 pm

Wire is still the low(ish)-level communication library that allows LiquidTWI to "talk" to the I2C GPIO controller that then drives the LCD... long story short, yeah, you still need to #include <Wire.h> in your programs with LiquidTWI :)

Thanks for the feedback though, it's really cool to see someone else using something that came off my desktop :D
User avatar
FalconFour
 
Posts: 14
Joined: Sun Jun 12, 2011 9:49 am
Location: Fresno, CA

Re: LiquidTWI: High-performance LCD library for I2C Backpack Module

by micsaund on Thu Aug 11, 2011 10:41 pm

Ahh, OK - so, as I expected, a dumb mistake on my part :)

Thanks for getting back so quickly!

Mike
www.micsaund.com
micsaund
 
Posts: 2
Joined: Sat Jul 30, 2011 12:07 am

Re: LiquidTWI: High-performance LCD library for I2C Backpack Module

by kch on Fri Sep 02, 2011 8:53 am

I was having problems with this library when using the serial monitor functionality of the Arduino IDE.

The problem was that the 'begin' function was making the assumption that the LCD display was in a 'power-on reset' condition. Since an arduino reset does not power-cycle the display, it appeared that the display would receive garbage during the power-up process and would get into an undefined state.

Here is my modification to the library that does a software reset of the LCD display whenever 'begin' is called.

This is the extract from the 'begin' function in the LiquidTWI.cpp file.

Code: Select all | TOGGLE FULL SIZE
        // for some 1 line displays you can select a 10 pixel high font
        if ((dotsize != 0) && (lines == 1)) {
                _displayfunction |= LCD_5x10DOTS;
        }

        //put the LCD into 4 bit mode
        // start with a non-standard command to make it realize we're speaking 4-bit here
        // per LCD datasheet, first command is a single 4-bit burst, 0011.

======= snip ========
        //-----
        //  we cannot assume that the LCD panel is powered at the same time as
        //  the arduino, so we have to perform a software reset as per page 45
        //  of the HD44780 datasheet - (kch)
        //-----
        // bit pattern for the burstBits function is
        //
        //  7   6   5   4   3   2   1   0
        // LT  D7  D6  D5  D4  EN  RS  n/c
        //-----
        burstBits(B10011100); // send LITE D4 D5 high with enable
        burstBits(B10011000); // send LITE D4 D5 high with !enable
        burstBits(B10011100); //
        burstBits(B10011000); //
        burstBits(B10011100); // repeat twice more
        burstBits(B10011000); //
        burstBits(B10010100); // send D4 low and LITE D5 high with enable
        burstBits(B10010000); // send D4 low and LITE D5 high with !enable
====== snip =======

        command(LCD_FUNCTIONSET | _displayfunction); // then send 0010NF00 (N=lines, F=font)
        delay(5); // for safe keeping...
        command(LCD_FUNCTIONSET | _displayfunction); // ... twice.
        delay(5); // done!


So far, I have not been able to get the display to mess up after sending this sequence.

I hope this helps others with their projects

Keith
ph1x3r
kch
 
Posts: 16
Joined: Tue Nov 23, 2010 3:29 pm

Re: LiquidTWI: High-performance LCD library for I2C Backpack Module

by jpm32526 on Fri Sep 02, 2011 1:57 pm

Keith, you nailed the problem I was having with this library. This patch makes the library useful for unattended operation. Before, the LCD would only indicate garbage when the system was reset.

Regards,
jpm32526
jpm32526
 
Posts: 2
Joined: Fri Mar 04, 2011 1:57 pm

Re: LiquidTWI: High-performance LCD library for I2C Backpack Module

by kch on Sat Sep 03, 2011 9:27 am

Glad I could provide something back to the community.

My project involves the Pixel LED strings. I hope to post some info on it in the near future. I am using the LCD panel so that I can see where the program is in its sequence.

--
Keith
kch
 
Posts: 16
Joined: Tue Nov 23, 2010 3:29 pm

Re: LiquidTWI: High-performance LCD library for I2C Backpack Module

by throwaway on Sun Oct 16, 2011 5:45 pm

Here is my modification to the library that does a software reset of the LCD display whenever 'begin' is called.


kch... Thank you so much for posting this. The LiquidTWI library spits out garbage 6 times out of 10, I was guessing it was an initialization issue with the LCD. Not only was this confirmed, but you saved me quite a bit of time and effort by posting your fix!
throwaway
 
Posts: 2
Joined: Wed Oct 05, 2011 11:53 am