How do I address a 16x1 display

I am trying to get a 16x1 display working, in fact I have 2 to choose from but they both have the same problem.
According to this web site there are 2 types of 16x1, the second type shows the first 8 characters as dark when nothing is entered in the unit and the second 8 as light as mine both do.
I have taken a section from a longer program that works on its own (please don't bother commenting on the unused lines I was going to add them in to test further after getting this bit to work).

#include <IRremote.h>//remove the robot libraries and include kens from here  https://github.com/shirriff/Arduino-IRremote
#include <Wire.h>
#include <LiquidCrystal_I2C.h>  // F Malpartida's NewLiquidCrystal library
#include "LedControl.h"//turns 8 digits off see lc.control below & next line
//LedControl lc=LedControl(7,8,6,1);//data,clock,latch,number of ics, see previous line
//LedControl lcmatrix=LedControl(2,4,3,2);
#define I2C_ADDR    0x27  // Define I2C Address for controller
#define BACKLIGHT_PIN  3
#define En_pin  2
#define Rw_pin  1
#define Rs_pin  0
#define D4_pin  4
#define D5_pin  5
#define D6_pin  6
#define D7_pin  7
//SDA A4.  
//SCL A5.
#define  LED_OFF  0
#define  LED_ON  1
LiquidCrystal_I2C  lcd(I2C_ADDR,En_pin,Rw_pin,Rs_pin,D4_pin,D5_pin,D6_pin,D7_pin,BACKLIGHT_PIN,POSITIVE);
//either use the line above and the defines or use  
//                    LiquidCrystal_I2C lcd(0x27,2,1,0,4,5,6,7,3,POSITIVE);
int RECV_PIN = 5;
IRrecv irrecv(RECV_PIN);
decode_results results;
int i=0;
void setup()
{
  Serial.begin(9600);
  irrecv.enableIRIn(); // Start the receiver
  lcd.begin (16,1);  // initialize the lcd
// Switch off the backlight
//  lcd.setBacklightPin(BACKLIGHT_PIN,NEGATIVE);
//  lcd.setBacklight(LED_OFF);
  lcd.clear();
  delay(100);
  lcd.home();  
  lcd.setCursor(0,4); 
  lcd.print("Hi");
  //lcd.setCursor(0,0xC0); 
  //lcd.print(" world");  
  //lcd.setCursor(1,9); 
  //lcd.print("my world!");
  Serial.begin(9600);
}
void loop() 
{
for (i=1;i<200;i++)
  {
    lcd.setCursor(i,0);
    lcd.print("hi");
    Serial.println (i);
    delay (200);
    lcd.clear();
  }
}

The sketch works correctly on the first 8 lines but nothing appears on the second 8. The website linked above also says the second half of the line starts at 40 which is why I have the program counting up to 200 just to try to get something on the second set. I find it hard to believe that both my units have partially died in the same way. Can this be true?

You should probably avoid using these pins as they are used by the serial monitor connection.

You do this twice.

Try printing "0123456789012345" to the LCD.

The output from the arduino is I2C, a4 and a5 the pins refer to the ones on the display using a I2C board

Try this:
https://techexplorations.com/guides/arduino/peripherals/find-i2c-addresses/#:~:text=Connect%20the%20device%20you%20want,of%20the%20address%20that%20worked.

It still works

I just get the first 8 numbers

I don't think there is much point, I have both displays showing a signal and each one is the only thing connected to the arduino when I am testing.

Are you sure you have the address correct? You are probably way more experienced than I but it was a thought. I had a similar problem without I2C and it turned out I had a cold solder joint.

doesn't look proper for i2c..
looks like 4 bit data..

I2C Screen sample

check above to see what i mean..

and here's a non i2c screen..

LCD Screen

different libs different constructs..
prefer i2c myself, less wires.. :slight_smile:

have fun.. ~q

Yes 0x27. I sometimes solder the first link and use 0x26 but if I do nothing appears and I am getting half my signal.

If your LCD has an I2C interface the declaration of lcd() is unusual

LiquidCrystal_I2C  lcd(I2C_ADDR,En_pin,Rw_pin,Rs_pin,D4_pin,D5_pin,D6_pin,D7_pin,BACKLIGHT_PIN,POSITIVE);

What if you try this

#define I2C_ADDR    0x27
#define LCD_COLUMNS 16
#define LCD_LINES   1

LiquidCrystal_I2C lcd(I2C_ADDR, LCD_COLUMNS, LCD_LINES);

I have the same as your link. I have addressed every pin as opposed to using

LiquidCrystal_I2C lcd(0x27, 16, 2);

but the result is the same. I think when I first did it the library didn't give you the option of just putting

LiquidCrystal_I2C lcd(0x27, 16, 2);

I could exeriment with

LiquidCrystal_I2C lcd(0x27, 16, 2);

and see if it works if I can get the display to work properly, a 16,2 works correctly.

See above: You configured the LCD for two lines with

LiquidCrystal_I2C lcd(0x27, 16, 2);

Did you try

LiquidCrystal_I2C lcd(0x27, 16, 1);

Well, that construct doesn't declare any pins.. 0x27 is address 16 chars by 2 lines..
you should only have to change the 2 to a 1 if you have a 1 line display..
but if you in fact do have all them wires hooked up, then you are not i2c..
post a pic of the current setup please??

~q

That is for a library that lets you specify the pin connections between the I2C backpack chip and the LCD display, the pins being referenced are NOT pins on the arduino itself.

To the OP:

Try installing the HD44780 library by Bill Perry, available in the Arduino IDE library manager.

Run the example sketch:
File > Examples > hd44780 > ioClass > hd44780_I2Cexp > I2CexpDiag

See if the sketch can find the display, and look in the Serial monitor to see the diagnostic messages.

1 Like

Thanks, good to know , the lcd's I used didn't require this ... But are we sure this is the right initialisation for the TO's 16x1 lcd?

Might help if the TO posts some details to the lcd used ...

I second this recommendation. I also think that the display needs to be initialized lcd.begin(8,2);

See this note from the example sketch LineWrap.ino.

// Special note for certain 16x1 displays:
// Some 16x1 displays are actually a 8x2 display that have both lines on
// a single line on the display.
// If you have one of these displays, simply set the geometry to 8x2 instead
// of 16x1. 
// In normal sketches, lineWrap() mode will allow this type of display to
// properly function as a 16x1 display in that it will allow printing up to
// 16 characters on the display without having to manually set the cursor
// position to print the right characters on the half of the display.
// However, when using this 8x2 display as a 16x1 display, 
// scrollDisplayLeft() and scrollDisplayRight() will not work as intended.
// They will shift the two halves of the display rather than the entire display.
// This is because the hd44780 chip is doing the shift and chip is hard coded
// internally for two lines.
1 Like

I tried this and it doesn't work for some reason?
Is it possible my I2C library is different and if so which one do you think I should use? I think the one I have is an adafruit one that is built into the libraries options, I didn't download anything different.
I have added my sketch and if you comment out the long LiquidCrystal and the LCD.begin(16,2) and replace it with your short LCD it fails to alter the screen?

#include <Wire.h>
#include <LiquidCrystal_I2C.h>  // F Malpartida's NewLiquidCrystal library
#define BACKLIGHT_PIN  3
#define En_pin  2
#define Rw_pin  1
#define Rs_pin  0
#define D4_pin  4
#define D5_pin  5
#define D6_pin  6
#define D7_pin  7
//SDA A4.  
//SCL A5.
#define  LED_OFF  0
#define  LED_ON  1
#define I2C_ADDR    0x26
#define LCD_COLUMNS 16
#define LCD_LINES   2
 // LiquidCrystal_I2C lcd(I2C_ADDR, LCD_COLUMNS, LCD_LINES);
LiquidCrystal_I2C  lcd(I2C_ADDR,En_pin,Rw_pin,Rs_pin,D4_pin,D5_pin,D6_pin,D7_pin,BACKLIGHT_PIN,POSITIVE);
int i=0;
void setup()
{
  Serial.begin(9600);
  lcd.begin (16,2);  // initialize the lcd
  lcd.clear();
  delay(100);
  lcd.home();  
  lcd.setCursor(4,1); 
  lcd.print("Hi");
}
void loop() 
{
    lcd.setCursor(0,0);
    lcd.print("123456789abcdef");
}

See post#16 from @david_2018 ... !

Seems you might have an LCD with I2C support where the pins on the I2C expansion board have to be handed over to the LCD driver software ...

Did you try the suggestion of david_2018 in post '17?

All depends on the hardware you have, therefore it would be helpful if you post a datasheet, a link to the product or at least a picture..