New LiquidCrystal library - LCD library

dweston,
I'm so sorry on both counts.

write() wants an unsigned char. Shame on me. I should have looked to make sure and then tested it.

The proper code would be:

xxx.write((uint8_t) 0);

or
xxx.print((char) 0);

moral of the story: print "char"s and write "bytes".

I tested your exact example sketch after changing the
lcd.write(0); to lcd.write((uint8_t) 0);

It worked on my lcd shield. (mine is same pinout as the DFR)

I'm not sure what the issue is about not running.
Which version of the library are you using? The tip of the tree?
with backlight control?
Are you using the backlight control?
(in RC5 library will use it during begin() if it is in the constructor)
Was the shield working ok with backlight control after the mod?

--- bill

Bill

  lcd.write((uint8_t) 0);

works perfectly on my DFRrobot-007 LCD keypad shield. Thank you.

I am indeed using back light control now that the cct. error has been corrected. A working code example involving back light control is:

//Sample using LiquidCrystal library
#include <LiquidCrystal.h>

/*******************************************************

This program will test the LCD panel and the buttons of
the DFRobot LCD Keypad Shield for Arduino
Product code : RB-Dfr-07
http://www.robotshop.com/dfrobot-lcd-keypad-shield-arduino-1.html

Note cct error identified by Arduino forum discussion at:
http://arduino.cc/forum/index.php/topic,96747.0.html
which advises insertion of a Germanium 1n34a or a Schotky 1N5819
diode between pin 10 and the base of Q1 (K to pin 10).

sample code originally by Mark Bramwell, July 2010
modifications by Dion Weston, March 2012



********************************************************/

// select the pins used on the LCD panel
LiquidCrystal lcd(8, 9, 4, 5, 6, 7);

// define some values used by the panel and buttons
int backLight   = 10;    // LCD Panel Backlight LED connected to digital pin 10
int lightLevel  = 255;   // Initialise light full on
int lcd_key     = 0;
int adc_key_in  = 0;
#define btnRIGHT  0
#define btnUP     1
#define btnDOWN   2
#define btnLEFT   3
#define btnSELECT 4
#define btnNONE   5

// read the buttons
int read_LCD_buttons()
{
 adc_key_in = analogRead(0);      // read the value from the sensor 
 // my [Mark Bramwell's] buttons when read are centered at these values: 0, 144, 329, 504, 741
 // we add approx 50 to those values and check to see if we are close
 if (adc_key_in > 1000) return btnNONE; // We make this the 1st option for speed reasons since it will be the most likely result
 if (adc_key_in < 50)   return btnRIGHT;  
 if (adc_key_in < 195)  return btnUP; 
 if (adc_key_in < 380)  return btnDOWN; 
 if (adc_key_in < 555)  return btnLEFT; 
 if (adc_key_in < 790)  return btnSELECT;   
 return btnNONE;  // when all others fail, return this...
}

void setup()
{
 lcd.begin(16, 2);              // start the LCD library
 lcd.setCursor(0,0);            // move cursor to beginning of line "0"
 lcd.print("Backlight adjust"); // print a simple message
// Serial.begin(9600);            // initialise serial communications:

}
 
void loop()
{
 analogWrite(backLight, lightLevel);
 lcd.setCursor(13,1);            // move to position 13 on the second line
 lcd.print(lightLevel);

 lcd.setCursor(0,1);            // move to the beginning of the second line
 lcd_key = read_LCD_buttons();  // read the buttons

 switch (lcd_key)               // depending on which button was pushed, we perform an action
 {
   case btnRIGHT:
     {
     lcd.print("LED On          ");
     lightLevel = 255;
     break;
     }
   case btnLEFT:
     {
     lcd.print("LED Off         ");
     lightLevel = 1;
     break;
     }
   case btnUP:
     {
     lcd.print("LED Fade Up     ");
     if (lightLevel < 255) lightLevel += 1;
     break;
     }
   case btnDOWN:
     {
     lcd.print("LED Fade Down   ");
     if (lightLevel > 1) lightLevel -= 1;
     break;
     }
   case btnSELECT:
     {
     lcd.print("Select          ");
     break;
     }
     case btnNONE:
     {
     lcd.print("                ");
     break;
     }
 }
 
}

Hi folks,

I have just published release 1.2.1 of the New LiquidCrystal library. So what do we have on this release:

  • improved backlight control
  • enhanced support for shift register control: 2 wire, 3 wire and 1 wire (preview)
  • if it was fast, now is even faster: for the shift register configurations, in some cases 5.55 times faster than the standard (courtesy of bperrybap)
  • reorganized and cleaned up a bit
  • gone through intensive testing

Check it out @ https://bitbucket.org/fmalpartida/new-liquidcrystal/wiki/Home
Download it @ https://bitbucket.org/fmalpartida/new-liquidcrystal/downloads

Within the coming days I will be updating the wiki to improve the schematic section, it will also have for each library a description as to how to configure it.

All this with the contribution of:

  • bperrybap
  • piccaso

The latest library also works on Chipkit.
(Has been tested on the Uno32)
So you can use the same LCD interfaces and backlight control on the pic32 based
Arduino boards using mpide.

There are also some new examples.
LCDiSpeed can be used to show the speed of the LCD interface.
It will tell you how fast a single character and how fast the full
display can be updated.
(See the sketch for details)

--- bill

Thanks again fm, bperrybap and piccaso

@bperryap

For what it may be worth I obtained the following speeds using a DFRrobot-007 LCD keypad shield coupled to an Arduino Duemilanove using the LCDiSpeed sketch:

(ByteXfer) 85uS
Frame/Sec (FPS) 345.78
Frame Time (Ftime) 2.89mS

Am I right in assuming the new Liquidcrystal library doesn't support event handling as in: addEventListener in the old version?
Also, prior to writing to LCD (write/print), port pins are not set/reset so as to allow usage of pins by other device (multiplexing)?

All these features would have to be built around it. See the library as a generic LCD driver, adding a listener in the application and callbacks is a trivial task. Arbitrating pin usage is also trivial and the library doesn't constrain you, further more this is application dependent, not the responsibility of the driver. Why do you want to penalise users if they don't use muxing, for example?

My apologies, I posted out of context...

In agreement in relation to the first point, it doesn't need it, as to multiplexing, the driver already ensures the pins are set prior to writing therefore it already supports multiplexing...

I incorrectly assumed the new driver did do pin assignment before writing as a sketch (using shared/mulitplexed pins), that worked with the old library did not work on the new... I now need to determine the real problem...
Mike

No apologies needed at all.

As with all good software, you need to arbitrate the usage of shared resources. It is not good practice at all to assume that when you allocate the resources to a particular device/variable, later on someone else has changed it and hence you write it back just in case. Since you are in control of the application, it is up to the application to share a resource and hence to manage it. There are several ways you can do that, for example a software "mux" (a monitor) that reconfigures the IOs before executing a transaction over the share resource.

This is more evident when you work with concurrent systems or multi-threaded environments.

Thanks for the update!

When using a shift register in 2-wire mode, is it possible to control the backlight with bit 1 of the shift register? My backlight is hooked up according to this schematic.

Thanks!

Woobatron,
yes, you can.
While the SR interface code supports both 2 wire and 3 wire modes,
currently only the SR2W interface code has support for backlight control.
From your link to the schematic it looks like you are using a unlatched SR register like the 74LS164 vs using
a 74HC595 in a "non latched" mode (you can see my version of that just a bit lower on the same page
you linked to)

If you look in the header file LiquidCrystal_SR2W.h you will see a detailed explanation
along with ASCII art of how to hook up either SR register for backlight control using bit 1 of the SR.
If you are looking for a simpler anti-flicker circuit, I also included a diagram for simple backlight control circuit that
also removes the flicker. It uses a FET but is simpler
and more power efficient than the one in the schematic you linked to.

Note:
The ascii art in the header file needs a bit of an update.
I'm now using 4.7k resistors for all resistors except the current limiting resistor
and the diode is a 1N4148.

--- bill

Hi Bill
Thanks for the quick reply! Indeed I am using a 74HC595 in 'non-latching' mode. Thanks for that FPS sketch, it's really neat. I didn't know you could use if and elif statements for defined objects like that, super cool.

Anyhoo, I made a harness at work that has a 2x16 connector on one end for the LCD and the SR and everything else soldering in the middle, so I'd just have 4 wires going to the controller on the other end. I used the backlight anti-flicker with the series diodes and transistor but it doesn't seem to be working. Too bad I heat shrunk it all up before testing...d'oh! I can just snip off the LCD part though and try out your FET version.

You mention using a 1n4148, but I don't see it in your ASCII diagram:

// (LCD BL anode)---[ resistor ]---(vcc)
//
// (LCD BL cathode)-------------------------------+
//                                                |
//                                                D
//                                                |
// (BL input)----[ 4.7k Resistor ]----+-------G-|-<  (2N7000 FET)
//                                    |           |
//                          (0.1uf)   =           S
//                                    |           |
//                                  (gnd)        (gnd)

Would it go between the 4.7k/0.1uF and the gate of the FET (cathode towards the FET)?

There is quite a bit of "magic" that can be done using the C pre-processor.

Sorry for the confusion. The diode isn't part of the backlight circuit.
The backlight circuit is as shown in the backlight ascii art.
If you look above the backlight ascii art in the header file you will see the ascii art for the 595 circuit.
That includes a diode but it didn't say or recommend one. That is where I'm using a 1n4148.

--- bill

Clear as mud 8)

I got 'er going now, thanks a tonne Bill.

Hello,

i installed the library and used your I2C Board.
I'm getting this error message: HelloWorld_i2c:10: error: redefinition of 'LiquidCrystal_I2C lcd'

Can you help me?

What version of the IDE are you using?
Did you remove from the library directory the stock LiquidCrystal library that comes with the Arduino IDE?

Sounds more like the second constructor in the demo code was uncommented
which would then mean there would be two declarations for the constructor.


fm,
On a somewhat unrelated note, this brings up an interesting "issue" in the current library.
Currently the function setBacklightPin() is used to set the bit within the output latch
on the communication interface.
i.e. in the I2C code it is a bit that is used on the other side of the i2c interface
and in the SR3W code it is a bit on the SR output latch. (SR and SR2W don't support this function)
But the potential issue is that some boards, like the I2C extra I/O LCD board don't support
controlling the backlight through the interface, they require using an additional Arduino pin.
The library "as is" has no support for this mode of operation, so users are left to having
to use Arduino core functions like digitalWrite()/AnalogWrite() to control the backlight rather
than being able to use the library functions like backlight(),noBacklight() and setBacklight().

What might be nice would be if the code supported using both modes of operation.
i.e. it could use an output pin within the existing interface or assign an Arduino pin
that works outside the interface.

In the glcd library I use some argument overloading (hidden from c++) to handle a few complex arguments.
While it does side step the normal C++ typechecking, it is easy to do and this library could do the same.
It uses a macro to alter the parameter in a way that it can be distinguished.
So for example, it would be possible to do something like:

LiquidCrystal_I2C lcd(0x38, LCD_ARDUINO_PIN(BACKLIGHT_PIN), POSITIVE);  // Set the LCD I2C address

This would allow the constructor or other functions to be able to tell if the argument
is a bit on the output latch or an actual Arduino pin.
The glcd library version of this type of macro simply negates the value by inserting a minus sign.
This allows to code to quickly and easily detect which type of argument is desired.
In this example it would be:

#define LCD_ARDUINO_PIN(pin) (-pin)

The code receiving the argument can simply look if the argument is negative to tell
if it indicates and Arduino pin vs an interface output latch bit.

Some of the needed support for this would move up to the LCD common code and then depending on the
type of backlight "pin" control selected, it would either handle itself , in the case of an arduino pin, or call
the device layers backlight functions.

It is all doable and not very much code, and while it would allow the existing I2c Extra I/o board
to have backlight control, I haven't seen any other boards out there that use a latching interface
to the LCD and then use a separate Arduino pin for backlight control so
it may not be worth the effort to add this support.

--- bill

Hi Bill, sound very good the proposal.

I was thinking of doing an upgrade to de library over Christmas to abstract out the I2C class so that it can be extended to support multiple I2C devices. It might be a good time to also introduce the backlight mod.

Could you add the "issue" in the bitbucket repository so that I don't forget.

Hi, I think you've done an excellent work. I plan to give it a test ASAP.

I looked at the code but did not find something like getNumRows() or getNumCols(). Quick oneliners that I sometimes missed when playing around with lcds. I think their place would be the LCD class.

Also I noticed a little inconsistency in cols/rows variable naming:
uint8_t _numlines;
uint8_t _cols;
IMVHO they should be called _rows, _cols, or _numrows, _numcols or _numlines, _numcols.

My 0.01 cents :slight_smile:

PS: kudos for the docs (and doxygen), not many libraries are that well documented :slight_smile:

@tuxduino - thanks for the comments, very much appreciated. bperrybap is another contributor for the library.
I will note down your coments for the next up date.