Notifications
Clear all

Adafruit 1602 LCD and I2C BackPack

11 Posts
4 Users
0 Likes
3,990 Views
Berner
(@berner)
Member
Joined: 5 years ago
Posts: 31
Topic starter  

I have the following components and am trying to make them work following the "Using LCD Displays with Arduino" DBWS tutorial. 

 
I have no issues making this work using the Adafruit example sketches, but I am struggling using the project code. I ran the I2C scanner and verified that I am using the correct address, so I am kind of at a loss on how to proceed. I am not much of a programmer, so my super-human troubleshooting skills are of no use to me ?. Any tips on how to resolve this?
 

   
Quote
(@pugwash)
Sorcerers' Apprentice
Joined: 5 years ago
Posts: 923
 

Unfortunately, I find your query a little vague!

Below is the very basic code needed to run the I2C/LCD, this a boilerplate file that I use as a jumping-off point to start projects requiring LCD output. Why code things twice?

 

// LCD_I2C_boilerplate.ino

#include <Wire.h>
// Include NewLiquidCrystal Library for I2C
#include <LiquidCrystal_I2C.h>

// Define LCD pinout
const int en = 2, rw = 1, rs = 0, d4 = 4, d5 = 5, d6 = 6, d7 = 7, bl = 3;
// Define I2C Address - change if reqiuired
const int i2c_addr = 0x27;

LiquidCrystal_I2C lcd(i2c_addr, en, rw, rs, d4, d5, d6, d7, bl, POSITIVE);

void setup() {

Serial.begin(9600);
Serial.println("LCD_I2C_boilerplate.ino");

lcd.begin(16,2);
lcd.setCursor(0,0);
lcd.print("Starting.......");
delay(2000);

}

void loop() {

// this is where you do all the other things that
// get the data to show on the LCD display

lcd.clear();
lcd.setCursor(0,0);
lcd.print("LCD Boilerplate");
lcd.setCursor(0,1);
lcd.print("Now add code..");

}

If you could provide a bit more detail of your problem, I am sure there are enough guys around that could point you in the right direction.


   
ReplyQuote
(@pugwash)
Sorcerers' Apprentice
Joined: 5 years ago
Posts: 923
 

Just as an afterthought, I would only use the above setup for initial testing purposes. In real-life projects, I would use the following code.

 

// LCD_I2C_boilerplate.ino

#include <Wire.h>
// Include NewLiquidCrystal Library for I2C
#include <LiquidCrystal_I2C.h>

// Define LCD pinout
const int en = 2, rw = 1, rs = 0, d4 = 4, d5 = 5, d6 = 6, d7 = 7, bl = 3;
// Define I2C Address - change if reqiuired
const int i2c_addr = 0x27;

LiquidCrystal_I2C lcd(i2c_addr, en, rw, rs, d4, d5, d6, d7, bl, POSITIVE);

void displayValues(){

lcd.clear();
lcd.setCursor(0,0);
lcd.print("LCD Boilerplate");
lcd.setCursor(0,1);
lcd.print("Now add code..");

}

void setup() {

Serial.begin(9600);
Serial.println("LCD_I2C_boilerplate.ino");

lcd.begin(16,2);
lcd.setCursor(0,0);
lcd.print("Starting.......");
delay(2000);

}

void loop() {

// on condition X run function displayValues()
// this could be time controlled with the millis() function
// or conditional, if some value has changed

}

 

Coding this way stops the LCD being unnecessarily refreshed in every loop and stops the associated flickering.

 


   
ReplyQuote
(@pugwash)
Sorcerers' Apprentice
Joined: 5 years ago
Posts: 923
 

I am not much of a programmer, so my super-human troubleshooting skills are of no use to me ?. Any tips on how to resolve this?

Start by investing an hour, watching this! I think it may help, as there is no way of getting around improving your programming skills if you want to use the Arduino for any practical purposes.


   
ReplyQuote
Berner
(@berner)
Member
Joined: 5 years ago
Posts: 31
Topic starter  

Thanks for the reply, here are more details. I assemble the 1602 and the backpack following the tutorial from Adafruit. I load the following sketch and it runs fine:

/*
 Demonstration sketch for Adafruit i2c/SPI LCD backpack
 using MCP23008 I2C expander
 ( http://www.ladyada.net/products/i2cspilcdbackpack/index.html )
 This sketch prints "Hello World!" to the LCD
 and shows the time.
 
  The circuit:
 * 5V to Arduino 5V pin
 * GND to Arduino GND pin
 * CLK to Analog #5
 * DAT to Analog #4
*/
// include the library code:
#include "Wire.h"
#include "Adafruit_LiquidCrystal.h"
// Connect via i2c, default address #0 (A0-A2 not jumpered)
Adafruit_LiquidCrystal lcd(0);
void setup() {
  // set up the LCD's number of rows and columns:
  lcd.begin(16, 2);
  // Print a message to the LCD.
  lcd.print("hello, world!");
}
void loop() {
  // set the cursor to column 0, line 1
  // (note: line 1 is the second row, since counting begins with 0):
  lcd.setCursor(0, 1);
  // print the number of seconds since reset:
  lcd.print(millis()/1000);
  lcd.setBacklight(HIGH);
  delay(500);
  lcd.setBacklight(LOW);
  delay(500);
}
 

Now from what I can see, the way this code calls out the I2C address is a bit different, perhaps the dec notation and not hex, but just a guess. In my case, the I2C address is 0x20, and I confirm this with the I2C scanner sketch. When I try to run the code from the DWBS, I edit the address, compile, and nothing happens. No backlight, no characters, nothing. I play with my contrast to see if anything is happening, but I see nothing. So my next thought was maybe the lcd pinout (const int  en = 2, rw = 1, rs = 0, d4 = 4, d5 = 5, d6 = 6, d7 = 7, bl = 3;) does not match my hardware. I tried the other one suggested in the DWBS article, but no result. Next I found the datasheet on the 1602 from Adafruit and it has the following: 

Pin Symbol
1 VSS 
2 VDD
3 V0
4 RS
5 R/W
6 E
7 DB0
8 DB1
9 DB2
10 DB3
11 DB4
12 DB5
13 DB6
14 DB7
15 LED+
16 LED-

I immediately notice the lcd pinout does not match this chart, but I am not sure if I am reading/thinking it right. For example, rs=0, but my datasheet says rs=4, but my datasheet goes from 1-16, and I am guessing the code assumes 0-15? 


   
ReplyQuote
(@pugwash)
Sorcerers' Apprentice
Joined: 5 years ago
Posts: 923
 

@berner

First, the "Pin symbol list" is standard for all LCDs and has nothing to do with

const int  en = 2, rw = 1, rs = 0, d4 = 4, d5 = 5, d6 = 6, d7 = 7, bl = 3;

These integers are, I believe, register addresses used by the Adafruit library to send data using the wire.h library.

This line defines the object with all necessary constants.

LiquidCrystal_I2C lcd(i2c_addr, en, rw, rs, d4, d5, d6, d7, bl, POSITIVE);

AdaFruit has basically hidden all this work within the library by using

Adafruit_LiquidCrystal lcd(0);

to create the object.

I believe this is leading to some confusion!

 

It might be an idea not to use the Adafruit Library and use LiquidCrystal_I2C.h instead.


   
ReplyQuote
codecage
(@codecage)
Member Admin
Joined: 5 years ago
Posts: 1038
 

In my experience those 16 pins listed in the @berber code above only come into play if you are using an LCD display that doesn't have the I2C backpack installed.  Then you need to wire those pins (4 of the data pins are usually left with no connections) to work directly with the display since the I2C backpack isn't in the picture.

I agree with @pugwash, maybe drop the Adafruit library and just use the LiquidCrystal_I2C.h library as he suggests.

It might be a worthwhile experiment to get a plain LCD display (without the I2C backpack) and learn how to use that as well.  Never can tell when that might come in handy.  Like maybe the bug hits you to put something together quickly and you find that you have no spare LCD displays available but do have the one without the I2C backpack from your earlier experiment and now you don't have to wait on a new one with the I2C backpack to arrive.

SteveG


   
ReplyQuote
Berner
(@berner)
Member
Joined: 5 years ago
Posts: 31
Topic starter  

Thanks for all the replies, I have been grinding on all of this for a few hours, and still cannot get my Adafruit 1602/I2C backpack to work with any of the code except for the stuff in the Adafruit LCD Example libraries. I did buy a few 1602 LCD's with a different I2C backpack and they work exactly as described in the DBWS projects, and also with the code samples Pugwash provided. At this point I am left to believe that not all I2c backpacks are equal, and the one from Adafruit is not going to work with the code. I am thinking it has to do with the include libraries not being compatible (am I thinking this right?) Its not a big deal for me to set aside the Adafruit backpack and continue on with the ones that work for me. Thoughts?


   
ReplyQuote
Spyder
(@spyder)
Member
Joined: 5 years ago
Posts: 846
 
Posted by: @berner

set aside the Adafruit backpack and continue on with the ones that work

Agreed

I'm a big fan of Adafruit, but, it seems that not all ICs are created equal

I recently bought a batch of ESP32-cams and couldn't get a single one to spit out anything but errors no matter which sketch I tried. I finally broke down and ordered a few with a brand name IC, and viola, they worked fine

I'm, of course, keeping the ones I couldn't get to work, in the hopes that some day I might run into a fix, but, until then, I'm gonna use the ones that I was able to coax pictures out of

Throw them into a box labeled "Things to ignore until I run out of other things to ignore"


   
ReplyQuote
(@pugwash)
Sorcerers' Apprentice
Joined: 5 years ago
Posts: 923
 

@spyder

I'm a big fan of Adafruit, but, it seems that not all ICs are created equal

I disagree with the latter part of your statement. I don't think AdaFruit are producing their own ICs, instead taking commercially available standard components and packing them on their own PCBs.

What they are doing is supplying seemingly standard parts with their own proprietary libraries, it has the effect that newbies and less experienced hobbyists become more and more dependant on AdaFruit.

Sounds to me like a typical Chinese marketing ploy to me!

To get a much better understanding of how the LCD works, perhaps, as suggested earlier in the thread, you should start by hooking the LCD module to an Arduino without using I2C. I have been looking around the net to find any reference to addressing the registers directly, to no avail. It might just come down to wading through the Library file to find out what it does.

Dear God, one lifetime is not enough! (a hobbyists prayer)


   
ReplyQuote
Berner
(@berner)
Member
Joined: 5 years ago
Posts: 31
Topic starter  

@pugwash

Upon further review, and reading up on similar posts in the Arduino forums, I  believe that the Adafruit I2C is not compatible with the NewLiquidCrystal or LiquidCrystal libraries. The Adafruit uses the MCP23008 I2C chip, and most others use the PCF8574 or PCF8574A, which I believe is the "official" Phillips one. I am no dissing on the Adafruit/MCP23008, but my take away on this is to pay closer attention to hardware/library choices if I need to depend on code others have written. I am an IT guy, so to me this is similar to installing a Netgear network card, and installing TPLink drivers. 


   
ReplyQuote