There is constructor that will create lcd object. There is also required to provide I2C address of LCD display (example for 0x3F):
LiquidCrystal_I2C lcd(0x3F, 16, 2);
I am using many displays. Some of them have address 0x27, other 0x3F. Also if there are soldered A0, A1, A2 pins on I2C module, addresses are different too. So I would like to automatize that using I2C Scanner and then use that address in constructor.
But there is problem. How to create object lcd in setup() to have it also accessable in loop()? I have tried things such as define it as extern butno success on compilation. It says: "'lcd' has both 'extern' and initializer".
Can you provide me some example how I should solve this problem?
Only solution I see based on my programming skills is to create that object in loop() using some one-time if statement that will execute I2C scanner and will initialize display...
There are only 16 addresses for the two PCF8574.
I would only scan these addresses.
tested with 1.1.2 Frank de Brabander
// https://forum.arduino.cc/t/create-lcd-object-after-i2c-scanner/1017496/4
// scan I2C for PFC8574 and init LCD if found
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C *lcd;
void setup() {
Serial.begin(115200);
Serial.println(F("\nScan for LCD PCF8574"));
Wire.begin();
byte error = 0, address = 0x20;
for (address = 0x20; address <= 0x3F; address++)
{
Serial.print(F("check PCF8574 0x")); Serial.println(address, HEX);
Wire.beginTransmission(address);
error = Wire.endTransmission();
if (error == 0)
break; // success, continue code
if (address == 0x27) address = 0x37; // jump to other PCF version
else if (address == 0x3F)
{
Serial.println(F("No display found")); // inform user
for (;;); // hang forever
}
}
Serial.print(F("start LCD 0x")); Serial.println(address, HEX);
lcd = new LiquidCrystal_I2C(address, 16, 2);
lcd->init(); // lcd->begin(); // start method fitting to your library
lcd->backlight();
}
void loop() {
static int val = 0;
lcd->clear();
lcd->setCursor(0, 0);
lcd->print(val, DEC);
delay(1000);
val++;
}
imho it would even make sense to start with the last address (0x3F) and decrement down to 0x20 under the assumption, that the most used addresses are 0x3F or 0x27.
What if you use pcf8574/5 for some other purpose in a future project? For example scanning a 4x4 keypad or controlling some LEDs or relays. Then your code would misidentify these chips as displays and malfunctions can happen. I cannot think of a way that the Arduino can know that the pcf chip is attached to an lcd. I don't think the pcf chip can read anything back from the lcd on the commonly available i²c adapters.
In my project there will not be any other I2C device or multiple I2C modules that can cause problem with this. It is RFID Domination Timer for Paintball and similar sports , it have also PCB, so there will not be added any other peripherals. Also as @sterretje mentioned about problem if display (I2C module) is not detected, it will set NULL. But that isn't problem... If display will not work, game will not run for people.
Oh, it will run. But you don't know what the behaviour will be. Worst case scenario, it might set a pin on the micro that is supposed to be an input as output (e.g. MISO or RX) and next something might give eventually in.