Detectin LCD ID at Runtime

Hi, I have several LCD 20 x 4 screens. Most of them have 0x27 as the ID, but a few have 0x3f.
Currently I am doing this...

#include <LiquidCrystal_I2C.h> 
  LiquidCrystal_I2C lcd(0x3f,2,1,0,4,5,6,7,3,POSITIVE);  // Set the LCD I2C address
//  LiquidCrystal_I2C lcd(0x27,2,1,0,4,5,6,7,3,POSITIVE);  // Set the LCD I2C address

But it is a royal pain to try and keep up with what ID is where and remembering to change the REM-line.

I found a very basic code-scanner and it finds the ID just fine, but have no idea how to use it within a Sketch.

Is it possible to reassign the ID before calling "lcd.begin(20,4);" in Setup?

How do I do that?

Sorry for being a bit dense on this but I am quite new to C++ and looking in the wire.h and wire.cpp files is not making it clear to me.


You could use the preprocessor #ifdef at the top of the sketch to enable one of two lines of code depending on what you define.


Is it possible to reassign the ID before calling "lcd.begin(20,4);" in Setup?

No, but you could change the type of lcd, and a bit of code.

  LiquidCrystal_I2C *pLCD = NULL;

Then, in setup(), after you have the proper address, in a variable called lcdAddr (or whatever name you like):

  pLCD = new LiquidCrystal_I2C(lcdAddr, 2,1,0,4,5,6,7,3,POSITIVE);
   pLCD->begin(20, 4);

All other uses of lcd. would need to change to pLCD->, too.

Awesome, thank you very much PaulS.

Obviously I am assuming that there is only one I2C within the application and that's OK for what I need right now. This will save what little hair I have left.

My code is probably a bit clunky but I have it working. Fortunately all of the calls to print stuff to the LCD are in just a few functions, so changing everything to "pLCD->" was pretty simple.

There are other ways to set the i2c address for the lcd object without using a pointer which would keep from having to mangle up all the existing code.

However, I think a better and easier solution would be to simply use my hd44780 library package.
It will not only auto detect the i2c address but will also auto detect the pin mappings and backlight active level.
If all that changed between your backpacks was the i2c address, you are lucky. There are several different pin mappings as well as backlight active levels used on various i2c backpacks.
Since the hd44780 library can figure out all the backpack configuration parameters at runtime you can swap out the LCD/backpack and it will "just work" without even having to re-compile the sketch regardless of i2c address, pin mappings or active backlight level as soon as the board is restarted.
note: it can also be explicitly told the parameters as well.

The hd44780 library package can be quickly and easily installed using the IDE library manager.
You can read more about it here: GitHub - duinoWitchery/hd44780: Extensible hd44780 LCD library

The i/o class for PCF8574 based backpacks is hd44780_I2Cexp
I would recommend that you first run the included diagnostic sketch (I2CexpDiag) to make sure the library is properly working with your backpack.
The diagnostic sketch will test your i2c signals and also verify the memory inside the LCD module.
If you have multiple LCD modules with different i2c addresses, the diagnostic will test them all in parallel.

You should find that the hd44780 library is faster than many other libraries regardless of i/o class used due to the way it optimizes the command execution as it allows the AVR to run in parallel to the LCD executing its commands.
It also has some additional capabilities not found in other libraries like the ability to read from the display as well as tell if API functions completed successfully.

--- bill