Writing to a 20x4 LCD, ok but weird characters

Gday guys, need help please. Just rigged up this simple two button counter with a 20x4 LCD display.
I have attached an I2C interface from Jaycar onto the back of this LCD.
Code is below.
I have changed LCD address to suit (from 0x3F) and made it 20x4 (from 16x2) display. Plus changed lcd.init to lcd.begin.
Anyway, the display is giving weird ghosting or characters, as shown in attached photo. Any ideas?
Using a genuine UNO.

//YWROBOT

//Compatible with the Arduino IDE 1.0

//Library version:1.1

#include <Wire.h>

#include <LiquidCrystal_I2C.h>



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





// this constant won't change:

const int  Up_buttonPin   = 2;    // the pin that the pushbutton is attached to

const int  Down_buttonPin = 3;



// Variables will change:

int buttonPushCounter = 0;   // counter for the number of button presses

int up_buttonState = 0;         // current state of the up button

int up_lastButtonState = 0;     // previous state of the up button



int down_buttonState = 0;         // current state of the up button

int down_lastButtonState = 0;     // previous state of the up button

bool bPress = false;



void setup()

{

  Serial.begin(9600);

  pinMode( Up_buttonPin , INPUT_PULLUP);

  pinMode( Down_buttonPin , INPUT_PULLUP);

 

  lcd.begin();                      // initialize the lcd

 

  // Print a message to the LCD.

  lcd.backlight();

  lcd.setCursor(0,0);

  lcd.print("Please Select:");

  lcd.setCursor(2,1);

  lcd.print(buttonPushCounter);

 

}





void loop()

{

   checkUp();

   checkDown();



   if( bPress){

       bPress = false;

      lcd.setCursor(2,1);

      lcd.print("               ");

      lcd.setCursor(2,1);

      lcd.print(buttonPushCounter);

   }

 

}



void checkUp()

{

  up_buttonState = digitalRead(Up_buttonPin);



  // compare the buttonState to its previous state

  if (up_buttonState != up_lastButtonState) {

    // if the state has changed, increment the counter

    if (up_buttonState == LOW) {

        bPress = true;

      // if the current state is HIGH then the button went from off to on:

      buttonPushCounter++;

      Serial.println("on");

      Serial.print("number of button pushes: ");

      Serial.println(buttonPushCounter);

    } else {

      // if the current state is LOW then the button went from on to off:

      Serial.println("off");

    }

    // Delay a little bit to avoid bouncing

    delay(50);

  }

  // save the current state as the last state, for next time through the loop

  up_lastButtonState = up_buttonState;

}

void checkDown()

{

  down_buttonState = digitalRead(Down_buttonPin);



  // compare the buttonState to its previous state

  if (down_buttonState != down_lastButtonState) {

    // if the state has changed, increment the counter

    if (down_buttonState == LOW) {

        bPress = true;

      // if the current state is HIGH then the button went from off to on:

      buttonPushCounter--;

     

      Serial.println("on");

      Serial.print("number of button pushes: ");

      Serial.println(buttonPushCounter);

    } else {

      // if the current state is LOW then the button went from on to off:

      Serial.println("off");

    }

    // Delay a little bit to avoid bouncing

    delay(50);

  }

  // save the current state as the last state, for next time through the loop

  down_lastButtonState = down_buttonState;

}

FWIW, it works fine for me on a 16x2 with your code untouched apart from changing it from 20x4.

Not getting this:

Do you get any funnies if you run it with just the "Please select" in setup() and loop() empty?

I deleted all code in loop; still bad.
Then I deleted 'lcd.print(buttonPushCounter);' from setup() and it displays fine.

//lcd.begin(); 
lcd.init();

Try changing the initialization. You code is working for me with this change. The library examples use the .init().

I would install the hd44780 library and use that library and its hd44780_I2Cexp i/o class instead.
The hd4478 library includes a diagnostic test, I2CexpDiag, that can test the h/w for any issues.

Depending on what it reports, you can then look further at any issues.

--- bill

pjuno:
I deleted all code in loop; still bad.
Then I deleted 'lcd.print(buttonPushCounter);' from setup() and it displays fine.

This does not work for me as it errors with:

exit status 1
'class LiquidCrystal_I2C' has no member named 'init'

bperrybap:
I would install the hd44780 library and use that library and its hd44780_I2Cexp i/o class instead.
The hd4478 library includes a diagnostic test, I2CexpDiag, that can test the h/w for any issues.

Depending on what it reports, you can then look further at any issues.

--- bill

OK after a lot of playing around, I can't get the LCD displaying anything using your examples, but I did upload your diagnostics program.
Results are below, the backlight does do what it should, but it still mostly displays gibberish, although on line 0 I can see at the end 'x27)' and on line 1, what mostly looks like a timer counting up.
I have only the LCD module connected to the Uno, using this module: https://www.jaycar.com.au/medias/sys_master/images/images/9376230899742/XC3706-manualMain.pdf


Serial Initialized

I2CexpDiag - i2c LCD i/o expander backpack diagnostic tool

hd44780 lib version: 1.1.1

Reported Arduino Revision: 1.8.12
CPU ARCH: AVR - F_CPU: 16000000

SDA digital pin: 18 A4
SCL digital pin: 19 A5

Checking for required external I2C pull-up on SDA - YES
Checking for required external I2C pull-up on SCL - YES
Checking for I2C pins shorted together - Not Shorted

Scanning i2c bus for devices..
i2c device found at address 0x27
Total I2C devices found: 1

Scanning i2c bus for all lcd displays
LCD at address: 0x27 | config: P01245673H | R/W control: Yes
Total LCD devices found: 1

LCD Display Memory Test
Display: 0
Walking 1s data test: PASSED
Address line test: PASSED

Each working display should have its backlight on
and be displaying its #, address, and config information
If all pixels are on, or no pixels are showing, but backlight is on, try adjusting contrast pot
If backlight is off, wait for next test

Blinking backlight test: to verify BL level autodetection
If backlight is mostly off but
you briefly see "BL Off" on display with backlight on,
then the library autodetected incorrect BL level
and the library cannot autoconfigure the device

Displaying 'uptime' on all displays

Given the diagnostic passes, that means

  • the i2c signals tested ok
  • the hd44780 library can communicate with the PCF8574
  • I2CexpDiag was able to write and read memory correctly and passed a full internal memory test of DDRAM and CGRAM.

This means that the issue is with the LCD module and not the backpack or any connections between them.

It looks like it may be an issue in the LCD glass itself or the connections to it.
At this point it looks like you got a bad LCD module.

It could be a zebra strip issue.
You can google a bit about it.
You might see it change a bit if press on the LCD or if you squeeze the frame.
Sometimes you can fix it by taking the LCD apart and repositioning the zebra strip or re-seating it.

Did it ever get wet?

--- bill

I think my LCD is fried as you say. Was brand new from years ago in my box of random robotics. Never been wet.
Will just buy a small LCD touch screen tomorrow, they cheap.

Cheap, but not fast - unless you are in Shenzhen!