Go Down

Topic: i2c LCD... (Read 8628 times) previous topic - next topic

Cactusface

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! 



Code: [Select]

#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.
Code: [Select]
/* 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.
Open your mind! But not too far, your brains might fall out.
Also like Photography, model building and my 300+ Cacti and Succs.

A.R.Ty

Hoi,
at the first look i am missing the
Code: [Select]
wire.begin(); command
Dum spiro, spero - if you find my posting helpful, please click my Karma :)<br />~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~<br />Do you know A.R.T, the FREE Android Root Tool ?

arduinodlb

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.
Do not IM me. I will not respond. Ask questions in the forum.

Paul__B

#3
Nov 03, 2013, 10:39 pm Last Edit: Nov 03, 2013, 10:49 pm by Paul__B Reason: 1

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:

Code: [Select]

#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
}



fungus


I purchased from eBay this i2c backpack,


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

No, I don't answer questions sent in private messages (but I do accept thank-you notes...)

bperrybap

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

Paul__B


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


That's funny.  I can!

MAS3

Quote from: 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:
http://forum.arduino.cc//index.php?topic=157817.msg1235230#msg1235230


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.
Have a look at "blink without delay".
Did you connect the grounds ?
Je kunt hier ook in het Nederlands terecht: http://arduino.cc/forum/index.php/board,77.0.html

Cactusface

#8
Nov 05, 2013, 11:48 am Last Edit: Nov 06, 2013, 10:32 am by Cactusface Reason: 1
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.
Open your mind! But not too far, your brains might fall out.
Also like Photography, model building and my 300+ Cacti and Succs.

Paul__B

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

bperrybap

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:
Code: [Select]
  lcd.setBacklight(1); // switch on the backlight

Code: [Select]

//   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:
Code: [Select]

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:
Code: [Select]
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:
Code: [Select]
  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


Paul__B


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.

bperrybap


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


A.R.Ty

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)
Dum spiro, spero - if you find my posting helpful, please click my Karma :)<br />~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~<br />Do you know A.R.T, the FREE Android Root Tool ?

bperrybap

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

Go Up