i2c LCD...

Hi Folks,
Hoping someone can help me!! Yes I have searched and looked at many threads and bits of code, this seems a common problem, but unlike a cold! no common cure. The LCD is a very common 2x16 using the HD chip the 447..? and that works fine.
I purchased from eBay this i2c backpack, used the i2c scanner to find the address at 0x27, Installed the latest up to date Libraries, I could find for LCD & LCD_i2c...

But getting no luck it's just a solid line of blocks, tried the contrast, etc, it doesn't even look like it's been touched.
This bit of simple code does nothing that you can see, other then the back-light coming on!

#include <Wire.h> 
#include <LiquidCrystal_I2C.h>

LiquidCrystal_I2C lcd(0x27,16,2);  // set the LCD address to 0x20 for a 16 chars and 2 line display

void setup()
{
  lcd.init();                      // initialize the lcd 
 
  // Print a message to the LCD.
  lcd.backlight();
  lcd.print("Hello, world!");
}

void loop()
{
}

This code and others like it don't compile but complain of NEGATIVE or POSITIVE in indicated line. <<<< I also installed the LCD_i2c library indicated here.

/* YourDuino.com Example Software Sketch
 20 character 4 line I2C Display
 Backpack Interface labelled "LCM1602 IIC  A0 A1 A2"
 terry@yourduino.com */

/*-----( Import needed libraries )-----*/
#include <Wire.h>  // Comes with Arduino IDE
// Get the LCD I2C Library here: 
// https://bitbucket.org/fmalpartida/new-liquidcrystal/downloads    <<< Downloaded and installed this library
// Move any other LCD libraries to another folder or delete them
// See Library "Docs" folder for possible commands etc.
#include <LiquidCrystal_I2C.h>

/*-----( Declare Constants )-----*/
//none
/*-----( Declare objects )-----*/
// set the LCD address to 0x27 for a 20 chars 4 line display
// Set the pins on the I2C chip used for LCD connections:
//                    addr, en,rw,rs,d4,d5,d6,d7,bl,blpol
LiquidCrystal_I2C lcd(0x27, 4, 5, 6, 0, 1, 2, 3, 7, NEGATIVE);  // Set the LCD I2C address  <<<<< IDE complains of NEGATIVE


/*-----( Declare Variables )-----*/
//none

void setup()   /*----( SETUP: RUNS ONCE )----*/
{
  Serial.begin(9600);  // Used to type in characters

  lcd.begin(16,2);         // initialize the lcd for 20 chars 4 lines

// NOTE: Cursor Position: CHAR, LINE) start at 0  
  lcd.setCursor(3,0); //Start at character 4 on line 0
  lcd.print("Hello, world!");
  delay(1000);
  lcd.setCursor(2,1);
  lcd.print("From YourDuino");
  delay(1000);  
  lcd.setCursor(0,2);
  lcd.print("20 by 4 Line Display");
  lcd.setCursor(0,3);
  delay(2000);   
  lcd.print("http://YourDuino.com");
  delay(8000);
// Wait and then tell user they can start the Serial Monitor and type in characters to
// Display. (Set Serial Monitor option to "No Line Ending")
  lcd.setCursor(0,0); //Start at character 0 on line 0
  lcd.print("Start Serial Monitor");
  lcd.setCursor(0,1);
  lcd.print("Type chars 2 display");   


}/*--(end setup )---*/


void loop()   /*----( LOOP: RUNS CONSTANTLY )----*/
{
  {
    // when characters arrive over the serial port...
    if (Serial.available()) {
      // wait a bit for the entire message to arrive
      delay(100);
      // clear the screen
      lcd.clear();
      // read all the available characters
      while (Serial.available() > 0) {
        // display each character to the LCD
        lcd.write(Serial.read());
      }
    }
  }

}/* --(end main loop )-- */


/* ( THE END ) */

I'm sure it's me and my lack of understanding, especially with C!
Lastly here's a pic of the i2c board.
Any help or advice would be very welcome.
Thanks and regards

Mel.

Hoi,
at the first look i am missing the wire.begin(); command

The second block of code will only work with this highly modified version of LiquidCrystal_I2C:

https://bitbucket.org/fmalpartida/new-liquidcrystal/downloads

To use this, you would have to remove other LiquidCrystal_I2C libraries, and place this one appropriately.

Hopefully someone can help you get the first block of code working however.

Cactusface:
I purchased from eBay this i2c backpack, used the i2c scanner to find the address at 0x27, Installed the latest up to date Libraries, I could find for LCD & LCD_i2c...

Trouble is, "this i2c backpack" does not cut it as a description - there are at least two common - and quite different - variants, the LCM1602 and the "www.mjkdz.com", your picture is of the LCM1602 (though board is a different one from mine but vaguely similar layout and yours also has the address select jumpers on the accessible side, writing may be on the other side?) in which case (and given that it does not recognise "NEGATIVE or POSITIVE", you may need the updated library as per arduinodlb) this code should work as a test:

#include <Wire.h> 
#include <LiquidCrystal_I2C.h>

#define lcdAddr 0x27 // set the address of the I2C device the LCD is connected to

// create an lcd instance with correct constructor for how the lcd is wired
//  to the I2C chip.  In this case, the LCM1602 module
LiquidCrystal_I2C lcd(lcdAddr, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE); // addr, EN, RW, RS, D4, D5, D6, D7, Backlight, POLARITY

// Creat a set of new characters
const uint8_t charBitmap[][8] = {
   { 0xc, 0x12, 0x12, 0xc, 0, 0, 0, 0 },
   { 0x6, 0x9, 0x9, 0x6, 0, 0, 0, 0 },
   { 0x0, 0x6, 0x9, 0x9, 0x6, 0, 0, 0x0 },
   { 0x0, 0xc, 0x12, 0x12, 0xc, 0, 0, 0x0 },
   { 0x0, 0x0, 0xc, 0x12, 0x12, 0xc, 0, 0x0 },
   { 0x0, 0x0, 0x6, 0x9, 0x9, 0x6, 0, 0x0 },
   { 0x0, 0x0, 0x0, 0x6, 0x9, 0x9, 0x6, 0x0 },
   { 0x0, 0x0, 0x0, 0xc, 0x12, 0x12, 0xc, 0x0 }
   
};

void setup()
{
   int charBitmapSize = (sizeof(charBitmap ) / sizeof (charBitmap[0]));

  lcd.begin(16,2);  // initialize the lcd as 20x4 (16,2 for 16x2)
  
  lcd.setBacklight(1); // switch on the backlight

  for ( int i = 0; i < charBitmapSize; i++ )
   {
      lcd.createChar ( i, (uint8_t *)charBitmap[i] );
   }

  lcd.home ();  // go home to character 0 on line 0 (1st line)
  lcd.print("Hello, ARDUINO ");  
  lcd.setCursor(0,1);  // character 0 on line 1 (2nd line)
  lcd.print (" FORUM - fm   ");
/*
  lcd.setCursor(0,2); // character 0 on line 2 (3rd line)
  lcd.print("This is line 2");
  lcd.setCursor(0,3); // character 0 on line 3 (4th line)
  lcd.print("This is line 3");
*/
delay(4000);
}

void loop()
{
   lcd.clear();
   lcd.home ();
   // Do a little animation by writing to the same location
   for ( int i = 0; i < 2; i++ )
   {
      for ( int j = 0; j < 16; j++ )
      {
         lcd.print (char(random(7)));
      }
      lcd.setCursor ( 0, 1 );
   }
   delay (200);
//   lcd.setBacklight(1); // switch on the backlight
//   delay (200);
//   lcd.setBacklight(0); // switch off the backlight
}

Cactusface:
I purchased from eBay this i2c backpack,

Which i2c backpack? I can't see it from here...

Mel,
The issue here is that while i2c is standarized, and hd44780 (the pins on the LCD module)
is standardized, there is no standard of how to hook a PCF8574 i2c i/o expander chip
up to a HD44780 LCD. (that is the chip on your ic2 backpack)
Because of that, different makers of "i2c backpack" devices, wire up the connections
differently.

There are several different Arduino libraries out there for using i2c PCF8574 expander chips
to talk to an LCD.
The problem is that many of them hard code how the expander chip is wired up.
The issue with that solution, is that it works great if the right library is matched
to the right i2c backpack. But if not matched, then it doesn't work.

fm's library on the other hand does not hard code how the PCF8574 is wired up to the LCD.
However, it requries that you tell it how it is wired up in the constructor.
(Those are the pin/bit numbers in the lcd object declaration)
So while fm's library will run any PCF8574 based i2c lcd backpack, if the constructor
is not properly filled in to specify how it is wired up, it will not work.

You need to know how the pins of the i/o expander chip is wired up to the hd44780 pins.
Normally, it isn't hard to figure out, you can look at the board, and follow the traces.

If you want, you can run my i2cLCDguesser sketch and it will walk through many of the
more common pin/wiring possibilities and you will see what the constructor parameters need
to be on the LCD display when the "guess" is finally correct.
Here is a link to the thread with the guesser sketch:
http://forum.arduino.cc//index.php?topic=157817.msg1235230#msg1235230

Just remember that this sketch uses fm's LiquidCrystal library.

Instructions for using the sketch are in the sketch itself.

--- bill

fungus:
Which i2c backpack? I can't see it from here...

That's funny. I can!

bperrybap:
If you want, you can run my i2cLCDguesser sketch and it will walk through many of the
more common pin/wiring possibilities and you will see what the constructor parameters need
to be on the LCD display when the "guess" is finally correct.
Here is a link to the thread with the guesser sketch:
[SOLVED] MJKDZ brand I2C Controller working with 1602 LCD - #12 by bperrybap - Displays - Arduino Forum

Hi Bill,
Didn't know this was available.
Haven't tried it yet, as my guess for the backpack i've been using was right the first time.
But thanks for this tool for future use.
And thanks for your very clear explanation of how these backpacks work.
I already knew about this, but your explanation is just great.

Hi All,
And many thanks for your help and advice, yes I soon became aware that there was more then one version of this handy little device, in fact I have another one winging it way to me just now. But many thanks to you Bill as your 2cLCDguesser sketch which after about 8 tries came up with the right connections which once put into the constructor got my LCD displaying text. I better make a note of that. So for anyone else my i2c address is 0x27 and pins 2,1,0,4,5,6,7,3 POSITIVE. Now I will have to go and play with the back-light and other commands..

Again, thanks to all! I think we can call this one SOLVED? Here's a picture of the LCD displaying the result of Bill's i2cLCDguess sketch.

Regards
Mel.

If that is the descriptor you eventually found to work, why did not the sketch that I provided to you before, work? :~

Paul,
Good question.
If you look at the original post, the constructor was different.

One thing that I want to point out,
Is that the example you have posted has some errors in it.

Specifically these lines:

  lcd.setBacklight(1); // switch on the backlight
//   lcd.setBacklight(1); // switch on the backlight
//   delay (200);
//   lcd.setBacklight(0); // switch off the backlight

I keep seeing these incorrect usages of setBacklight()
and I try to stomp them out whenever I see them.

SetBacklight() does not take a boolean value.
SetBacklight(brightness) takes a brightness value.
It is somewhat coincidence that it works on the i2c boards.
It works because the library understands that the i2c boards do not support PWM dimming
and turns on the backlight for any non zero brightness value, overriding the default
Arduino behavior which turns off a pin when a PWM value is below 128 and PWM
is not supported.

The overall idea behind fm's library is that the API should work consistently across
all interfaces. This allows a sketch to be written once than then simply change
the constructors to get it work on another interface.
If a sketch uses SetBacklight(1) and then changes to an interface/LCD that supports
PWM dimming, the backlight will be very dim and more than likely appear to be off.

For on/off control use:

backlight(); // turn on backlight
noBacklight(); // turn off backlight

setBacklight(brightness) can also be used for on/off control
rather than the above functions.
The proper calls for on/off control are:

setBacklight(BACKLIGHT_ON); // turn on backlight with full brightness
setBacklight(BACKLIGHT_OFF); // turn off backlight

Another thing to keep in mind is that begin() will
also automatically turn on the backlight when the backlight parameters are provided
in the constructor. So in the example above, this would be a better comment:

  lcd.begin(16,2);  // initialize the lcd as 20x4 (16,2 for 16x2), and turn on the backlight

The setBacklight() does not need to be corrected or replaced with a backlight() call.
It can be totally eliminated.

--- bill

bperrybap:
I keep seeing these incorrect usages of setBacklight() and I try to stomp them out whenever I see them.

Excellent point.

I will happily alter my test sketch accordingly, so that whenever in future I cut and paste it to prompt people who have this problem, it will be more strictly accurate.

Of course, I did not write it myself but (as one does) picked it up somewhere and adapted it to suit, adding the optional (commented) lines at the end to test the backlight control function as well as the particular descriptor corresponding to the "LCM1602" board. I simply used the code as it is without any research into the details or correct use of the libraries. Subsequent examination of the corresponding .h, .cpp files and such proves somewhat mind-bending.

Interestingly, I note some boards carry both "LCM1602" and "mjkdz" (without the ".com") markings.

Paul__B:
Interestingly, I note some boards carry both "LCM1602" and "mjkdz" (without the ".com") markings.

It's pretty crazy out there.
I've seen at least 3 different i2c backpacks that are easily visually different at first glance
(they have different chip placements, jumpers, & connectors)
that all are labeled with "mjkdz" and all 3 use different constructors from each other.

It's alot what drove me to create the guesser sketch.
I actually thought I could turn the i/o pins around and read the pins
to try to determine more about how it was wired up.
While I was able to pick out certain connections, it wasn't good enough
to determine all the connections, so now the code just does brute force guessing.

--- bill

i tried the guesser sketch, but with my 16x2 there is no solution.
lcd is initialized, 2. row with dark bars as usual.

just waiting for a 20x4 with build-in I2C....but thought, MAYBE this one will work, too 8)

A.R.Ty,
The guesser sketch only trys a limited number of combinations.
Perhaps your backpack uses one not in the table.
(I'm assuming the guesser sketch located the device an printed its i2c address?)
Do you have a link for the i2c backpack you are using?
Can you upost some photos of you backpack?

I'd like to get it resolved so I can update the guesser sketch to include
the device you have.

-- bill

Yo, i saw the "Restart" after some tryings.

Here is the board i bought:


and here the whole enchilada 8):
http://www.ebay.de/itm/251299939790?ssPageName=STRK:MEWNX:IT&_trksid=p3984.m1439.l2649

the display is an MDLS16265SS-07 (MDLS16265SS-LV-BB) - here is the datasheet:

shorted all adress "jumpers", so adress is 0x20 (from i2c scanner sketch)

i am working with lcd / glcds since over 12 years, but this one i cant get to work with i2c. ]:smiley:
directly connected (without the i2c interface) it works on an arduino.

A.R.Ty:
Yo, i saw the "Restart" after some tryings.

What does that mean?

Here is the board i bought:

but it really isn't a photo of the board you bought.

I guess what I meant was can you show a photo of your setup?
So we can see the backpack and how it is connected to the LCD.

You may have to ohm out the output pin connections on the PCF8574 to the
LCD. If you need help with this let me know.

--- bill

"Restart" meant the new beginning of the loop 8)

The board is the same as on the LCD - but i know what you mean:
i connected the parts with dupont wires, so i could change quickly configuration.

the direction is as show as in the pictures where a LCD is shown with backpack - so same direction, same pin orientation and direction, same backpack angle....shortly: Pin 1 of the adapter is pin 1 of the lcd, pin 2 of.......

i also tried to remove the jumper, but has no effect so far.

Hi A.R.TY,
That backpack has the same component layout as mine, the printing is slighty different, I left the address at 0x27, and as I have repeated elswhere on the forum Bill's i2cLCDguesser sketch soon solved the problem and had me up and running, but you need to be using the latest fm's LCD library.

Regards
Mel.

Hoi Mel,
i have/had the latest already in use