NANO LiquidCrystal_I2C

Using an UNO board, "Hello World!" the LiquidCrystal I2C worked well using the code from the DroneBot Workshop. When I switched the UNO board to a NANO board, the display was gibberish. Is there a way to find out that the NANO is working properly?

Thanks,

BillRT

Would you show a picture of this? It might help answer the question.

You could send the "Hello, World!" to the Serial Monitor to see if the Nano is still working.

void setup() {
  Serial.begin(9600);
  Serial.println("Hello World!");
}

void loop() {}

Could you post an annotated schematic showing how you connected it and the power source and connections.

Hello xfpd,

Thanks for helping.

Here are some photos from the displays from a UNO board. The code is from the DroneBot Workshop, ‘Using LCD Displays with Arduino.’

Here is the code if you need it:

/*
LCD Display with I2C Interface Demo
lcd-i2c-demo.ino
Use NewLiquidCrystal Library
DroneBot Workshop 2018
https://dronebotworkshop.com
*/

// Include Wire Library for I2C
#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 = 0x3F;

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

void setup()
{

// Set display type as 16 char, 2 rows
lcd.begin(16,2);

// Print on first row
lcd.setCursor(0,0);
lcd.print("Hello world!");

// Wait 1 second
delay(1000);

// Print on second row
lcd.setCursor(0,1);
lcd.print("How are you?");

// Wait 8 seconds
delay(8000);

// Clear the display
lcd.clear();

}

void loop()
{

// Demo 1 - flash backlight
lcd.setCursor(0,0);
lcd.print("Backlight demo");
lcd.setCursor(0,1);
lcd.print("Flash 4 times");

delay(3000);
lcd.clear();

// Flash backlight 4 times
for(int i = 0; i< 4; i++)
{
lcd.backlight();
delay(250);
lcd.noBacklight();
delay(250);
}

// Turn backlight back on
lcd.backlight();

// Demo 2 - scroll
lcd.setCursor(0,0);
lcd.print("Scroll demo - ");
delay(1500);
// set the display to automatically scroll:
lcd.autoscroll();
// print from 0 to 9:
for (int thisChar = 0; thisChar < 10; thisChar++) {
lcd.print(thisChar);
delay(500);
}
// turn off automatic scrolling
lcd.noAutoscroll();

// clear screen
lcd.clear();

//Delay
delay(1000);

}

The DroneBot Workshop wanted the library from GitHub, ’Newliquidcrystal_1.3.5. This library opens 13 libraries. Initially there was a compilation error: exit status 1. I commented those libraries out one by one. Commenting the last one out actually worked!

#include <FastIO.h>
#include <I2CIO.h>
#include <LCD.h>
#include <LiquidCrystal.h>
#include <LiquidCrystal_I2C.h>
#include <LiquidCrystal_I2C_ByVac.h>
#include <LiquidCrystal_SI2C.h>
#include <LiquidCrystal_SR.h>
#include <LiquidCrystal_SR1W.h>
#include <LiquidCrystal_SR2W.h>
#include <LiquidCrystal_SR3W.h>
#include <SI2CIO.h>
//#include <SoftI2CMaster.h>

Then I removed the UNO and plugged in the NANO board but I removed the comments. There was a Compilation error, so I again commented the last library and compilation worked OK. Then I Uploaded and there was an uploading error. There were 5 possible Ports: 3, 4, 9, 12, and 21. Port 4 worked OK.

Here is the display:

The photo has a lot of glare but it does show the gibberish instead of 'Hello World!' and scroll from 1 to 10.

I tried using the Blink sketch on that NANO board and it worked OK. Does that mean the board is OK?

Finally, some time ago, I used this same code with a similar NANO board and it worked fine. This board itself also worked for a short time and then the gibberish began.

Thanks again for listening.

BillRT

Are you using I2C (SDA, CLK, Vcc, GND) or SPI (a bunch of wires) to talk to the LCD? (DroneBotWorkshop is my favorite Arduino maker)

Hello gilshulz,

Thanks for helping. Here are some poor photos that might help. The last one is from the NANO with the gibberish.

Connections

I2C UNO

GND GND
VCC Vin
SDA A4
SCL A5

I2C NANO

GND GND
VCC VIN
SDA A4
SCL A5

The only power source is in the computer. I tried a PC and a Mac but the gibberish displays are the same.

The voltage from the PC to the UNO is 4.225V and from the NANO, it is 4.325V.

I hope this helps.

Thanks again,

Bill RT

Hello xfpd,

With I2C, I use breadboard jumper wires. If this helps, I sent this to gilshulz.

BillRT

Hello gilshulz,

Thanks for helping. Here are some poor photos that might help. The last one is from the NANO with the gibberish.

Connections

I2C UNO

GND GND
VCC Vin
SDA A4
SCL A5

I2C NANO

GND GND
VCC VIN
SDA A4
SCL A5

The only power source is in the computer. I tried a PC and a Mac but the gibberish displays are the same.

The voltage from the PC to the UNO is 4.225V and from the NANO, it is 4.325V.

I hope this helps.

Thanks again,

Bill RT

From the photos, that doesn't look like a Nano 33 IoT. It looks like a classic Nano. Please confirm if it really is a Nano 33 IoT or you just posted in the wrong forum section.

Also please fix post #4 which is breaking forum rules because you did not use code tags.

I don't think that's correct for either type of Arduino. Try the 5V pin instead of Vin.

Hello PaulRB,

The NANO pictured is a NANO but not the 33 loT. The loT I have is not working but the Blink does work. You are correct, it is a different problem.

I went to the internet but still does not understand what 'code tag' means. I will fix it when I understand what it means.

Earlier I did try the 5V pin. I had the same result - gibberish.

When I use the UNO, it works perfectly. Switching the NANO (changing the board and the Port) but same compiling and same unloading produces gibberish.

If I go back to the UNO, it works fine again.

Thanks for the help,

BillRT

Edit your post, select the code and click on </co de> (maybe </>) in the editor's toolbar.

This is not good

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

change it to

LiquidCrystal_I2C lcd(i2c_addr, 16, 2);

And

lcd.begin(16, 2);

by

lcd.init()

I've moved your topic to the classic nano section.

Hello MaximoEsfuerzo,

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

changed it to LiquidCrystal_I2C lcd (i2c, addr, 16 2); and

lcd.begin(16, 2);

It compiled OK and it uploaded OK but the results were the same.

Then I switched the NANO to the UNO. The UNO compiled OK and uploaded OK but it didn’t show the display. BTW, the line lcd.begin(16, 2) was kept.

I switched the code back to the original and commented your new code and it worked OK.

I am a complete neophyte so I don’t understand what is happening. However, the code from the DroneBot Workshop works fine on the UNO board but not on the NANO board or the Nano board is bad. Blink did work on that board so I understand that that board is OK.

Thanks again,

BillRT

Hello @billrt - Would you paste your new code here? The code at the top of the thread is missing some stuff and I think I did not get all the changes. The image (below) is what you click to "paste your code between code tags."

I think this is the same thing I see... Let's grab a simple Nano-I2C-LCD sketch and leave the LCD address at 0x27... (simulation)

#include <LiquidCrystal_I2C.h>

LiquidCrystal_I2C lcd(0x27, 16, 2); // I2C address 0x27, 16 column and 2 rows

void setup()
{
  lcd.init(); // initialize the lcd
  lcd.backlight();
  lcd.clear();                 // clear display
  lcd.setCursor(0, 0);         // move cursor to   (0, 0)
  lcd.print("  Hello, World!");        // print message at (0, 0)
}

void loop(){}
1 Like

There are multiple libraries that contain a "LiquidCrystal_I2C.h" header file and a LiquidCrystal_I2C class.
Different libraries work different differently.
They can also use different constructors, and have different APIs.

Your comments in the sketch code state that you are using fm's newLiquidCrystal library.
This library contains several i/o classes for different h/w interfaces.
One of those i/o classes is LiquidCrystal_I2C

You appear to be using newLiquidCrystal (it is only library with all the header files listed in post #4) with LiquidCrystal_I2C i/o class which means you need to use the constructor and APIs from that library and i/o class.
Not what is mentioned by @MaximoEsfuerzo in post #10 nor @xfpd in post #13

newLiquidCrystal library LiquidCrystal_I2C i/o class is very flexible but is also very unforgiving. If you get the pin mapping parameters incorrect, you will see either nothing or perhaps giberish like what you are seeing.

The LiquidCrystal_I2C library uses a hard code pin mapping so it is easier to use.
HOWEVER... there is more than one i2c backpack design.
While the LiquidCryscal_I2C library uses the most common pin mappings,
different backpacks can use different pin mappings.
If the backpack you have doesn't match what is hard coded in the LiquidCrystal_I2C library, it won't work.

Also, due to the way the IDE works, there can be issues if multiple libraries that contain a LIquidCrystal_I2C.h header file are installed. This is because the IDE may get confused as to which one to use.

Two main things cause the gibberish you are seeing:

  • The pin mapping between the PCF8574 ad the LCD does not match the library configuration
  • The host and the LCD have lost nibble sync.

Nibble sync can be lost if there is noise or data corruption on the i2c bus.
This can happen from sever things including but not limited to poor connections in the cables, cables that are too long, noisy power supplies, bad power, noise on MAINs power.

If the LCD comes up and works for a bit then gets corrupted, that usually is an i2c communication issue that has caused a loss of nibble sync.
Once nibble sync is lost it will never recover until things are restarted from a power cycle or a reset.

Given you say you are a complete neophyte, then I'd suggest that you may want to switch to using the hd44780 library.
It is much easier to install than the newLiquidCrystal as you can install from the IDE GUI using the library manger which will do the download and install for you - no zip files are involved.

The hd44780 library is similar to the newLiquidCrystal library in that it has multiple i/o classes.
But the hd44780 library is much simpler to use when using an lcd with an i2c backpack.
The i/o class for you lcd is hd44780_I2Cexp.
The hd44780_I2Cexp i/o class will automatically locate the i2c address, and auto detect the pin mappings. This offers a "plug and play" capability that will work with any of the backpack designs at any i2c address without having to ever many configure anything or recompile the code.
Also, the hd44780 library has no issue coexisting with other LCD libraries.

The hd44780 library hd44780_I2Cexi i/o class includes a diagnostic sketch, I2CexpDiag, which will check to see if everything is working and does a memory check of the internal LCD RAM.
It will report an issues it finds.
Converting code to use the hd44780_I2Cexp i/o class is simple.
Just change your header files, and your constructor.

Here is a link to the hd44780 library hd44780_I2Cexp i/o class wiki for some additional information.

--- bill

If the library works correctly in "UNO" it must inevitably work correctly in "NANO".

1 Like

The code should be ok if it runs on the UNO, and if you are using the same display then there should be no difference there. That leaves the possibilities of a problem with the jumper wires being bad or not making good contact, or the header pins not being soldered properly onto the Nano.

If you look closely at the Nano, can you verify it has the atmega328 and not an atmega168? Can you measure the 5v pin of the Nano and verify you are actually getting 5 volts?

Hello@xfpd - Here is the code:

</*
LCD Display with I2C Interface Demo
lcd-i2c-demo.ino
Use NewLiquidCrystal Library
DroneBot Workshop 2018
https://dronebotworkshop.com
*/

// Include Wire Library for I2C
#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 = 0x3F;

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

void setup()
{

// Set display type as 16 char, 2 rows
lcd.begin(16,2);

// Print on first row
lcd.setCursor(0,0);
lcd.print("Hello world!");

// Wait 1 second
delay(1000);

// Print on second row
lcd.setCursor(0,1);
lcd.print("How are you?");

// Wait 8 seconds
delay(8000);

// Clear the display
lcd.clear();

}

void loop()
{

// Demo 1 - flash backlight
lcd.setCursor(0,0);
lcd.print("Backlight demo");
lcd.setCursor(0,1);
lcd.print("Flash 4 times");

delay(3000);
lcd.clear();

// Flash backlight 4 times
for(int i = 0; i< 4; i++)
{
lcd.backlight();
delay(250);
lcd.noBacklight();
delay(250);
}

// Turn backlight back on
lcd.backlight();

// Demo 2 - scroll
lcd.setCursor(0,0);
lcd.print("Scroll demo - ");
delay(1500);
// set the display to automatically scroll:
lcd.autoscroll();
// print from 0 to 9:
for (int thisChar = 0; thisChar < 10; thisChar++) {
lcd.print(thisChar);
delay(500);
}
// turn off automatic scrolling
lcd.noAutoscroll();

// clear screen
lcd.clear();

//Delay
delay(1000);

}>

I placed the Less than and greater than symbols between the code. Are those code tags?

BillRT

The "tags" are actually "THREE Back-ticks"... which once were literally < code > and < /code >

My "back-tick" is on the "tilde" key, next to the "1" - and the edit box has a < code > button for making those "code tags."

This is WITHOUT code tags.
This is WITH code tags.

@bperrybap - Would a Nano have a physical device to not accept a "working" I2C backpack? That is to say, could any Nano (this Nano-in-particular) be "wired" for a different communication purpose? Logic-levels? Pin re-assignment? Jumpers? Fixed baud (non-adjustable by software)?

@billrt - Can you verify the Nano GND you are using is a short to any other GND? Also, does the Nano GND short to the I2C GND?

@billrt - Also, try the Nano on the same port as the Uno.

@billrt - I think your nano needs a different address. This simulation has your code running with a couple modifications:

  1. I changed the address to 0x27
  2. I commented-out this line:
// const int en = 2, rw = 1, rs = 0, d4 = 4, d5 = 5, d6 = 6, d7 = 7, bl = 3;
  1. and changed these lines (the commented-out line starts with I2C but sends SPI pins)
// LiquidCrystal_I2C lcd(i2c_addr, en, rw, rs, d4, d5, d6, d7, bl, POSITIVE);
LiquidCrystal_I2C lcd(i2c_addr, 16, 2);