Comunicazione errata tra Esp32 e Display LCD 1602

Buonasera,

potrebbe sembrare un problema banale, ma non lo è. Dopo diverso tempo ho ripreso in mano un vecchio script che utilizza un display LCD 1602 con adattatore I2C per visualizzare alcune informazioni. Il LED della retroilluminazione si accende correttamente, ma il display non mostra alcun carattere.

Ho effettuato numerose prove, tra cui:

-Sostituzione di 3 microcontrollori (2 con USB-C e 1 con Mini-USB);
-Cambio dei cavi e riduzione delle distanze;
-Test con 5 display diversi: 2 con adattatore I2C integrato e 3 con adattatore saldato manualmente;
-Utilizzo di librerie differenti, tra cui:
#include <Wire.h> + #include <LiquidCrystal_I2C.h>
#include <hd44780.h> + #include <hd44780ioClass/hd44780_I2Cexp.h>
-Cambio dei GPIO SDA/SCL da 21/22 ad altri disponibili.

La scansione degli indirizzi I2C restituisce correttamente 0x27, quindi la comunicazione con l’adattatore è attiva. Tuttavia, utilizzando la libreria di Bill Perry (hd44780_I2Cexp), a volte ricevo il codice di errore -3, che indica una comunicazione errata.

Nonostante tutte queste prove, il risultato è sempre lo stesso: la retroilluminazione si accende, ma il display rimane vuoto. Eppure, in passato lo stesso script funzionava correttamente.

Di seguito lo sketch attualmente in uso:

  #include <LiquidCrystal_I2C.h>
#include <Wire.h>
#define I2C_SDA 12#define I2C_SCL 22
LiquidCrystal_I2C lcd(0x27, 16, 2);
void setup() {Serial.begin(115200);Wire.begin(I2C_SDA, I2C_SCL, 10000);
byte count = 0;byte address = 0;for (address = 1; address < 127; address++) {Wire.beginTransmission(address);Serial.print("0x");Serial.println(address, HEX); // Serial.println(address, BIN);
if (Wire.endTransmission() == 0) {   Serial.print("Found device at 0x");   Serial.println(address, HEX);   count++; } delay(10);
}
if (count == 0)Serial.println("No I2C devices found");elseSerial.println("Done");
lcd.init();lcd.clear();lcd.backlight();lcd.setCursor(0, 0);lcd.print("Inizio conteggio");delay(3000);
for (int ix = 1; ix <= 10; ix++) {lcd.clear();Serial.println(ix);lcd.print(ix);delay(1000);}
lcd.clear();lcd.print("Fine conteggio");}
void loop() {}

C’è modo di capire cosa sta succedendo?

grazie in anticipo

Hai usato un adattatore di tensione per passare da 3,3V a 5V?

Hai messo delle resistenze di pull-up sulle linee I2C?

Ho utilizzato l’uscita VIN e GND della scheda per alimentare il display, perché quando ho provato a collegarlo a un alimentatore esterno da 5V, l’interfaccia USB-C della scheda ha smesso di funzionare. Potrebbe essere una coincidenza, ma mi chiedo se ci sia una correlazione. Inoltre, pensavo che le resistenze di pull-up fossero già integrate nell’adattatore: è corretto?

Su un ESP32, deve tenere presente che la logica funziona a 3,3 V e che i GPIO non sono tolleranti ai 5 V. Se il Suo display alimenta le linee I²C o di controllo a 5 V, rischia di danneggiare il microcontrollore. È quindi preferibile alimentare il display a 3,3 V quando è possibile, oppure utilizzare un convertitore di livello se il display richiede i 5 V.

Per quanto riguarda le resistenze di pull-up, l’ESP32 ne possiede di interne, ma sono deboli, dell’ordine di alcune decine di kilo-ohm, quindi insufficienti per l’I²C. Deve quindi prevedere resistenze di pull-up esterne verso i 3,3 V, tipicamente da 4,7 kΩ. Molti moduli di display integrano già queste resistenze, ma occorre verificare che sia effettivamente così e soprattutto che siano collegate ai 3,3 V e non ai 5 V.

Ho collegato il display I2C all’uscita 3,3V dell’ESP32. Misurando con il multimetro tra SDA e GND, ottengo 3,3V se il display è alimentato a 3,3V, mentre ottengo 5V se lo alimento tramite il pin VIN (5V) dell’ESP32.

Collegando VCC dell’adattatore I2C al pin SDA, il multimetro rileva una resistenza di circa 2,2 kΩ, quindi presumo ci sia una resistenza di pull-up integrata.

Ho a disposizione 6 display: 2 con adattatore I2C integrato e 4 con adattatore esterno da saldare.

Non sono sicuro su come procedere per evitare problemi con i livelli logici e visualizzare il testo. Devo aggiungere altre resistenze tra sda e la scheda Esp32?

L’ESP32 deve sempre ricevere livelli logici a 3,3 V. Se alimenta i Suoi display a 5 V tramite VIN, i loro adattatori I²C portano SDA e SCL a 5 V, il che mette a rischio l’ESP32 e potrebbe essere già troppo tardi. Alcuni ESP32 tollerano certi abusi, quindi non è sicuro che la Sua scheda sia danneggiata.

Io alimento il mio schermo a 5 V ma utilizzo un convertitore di livello su SCL e SDA. In alcuni casi mi è anche capitato di dover aggiungere resistenze di pull-up per ottenere maggiore stabilità.

QUESTO va benone per il bus I2C. Lo si trova anche su Aliexpress ad 1/10 del prezzo :grin:

Guglielmo

buonasera,
vorrei chiedere un chiarimento: se utilizzo questo convertitore di livello, alimentando il display a 5V, il testo verrà visualizzato correttamente?

Mi chiedo come mai fino a un mese fa tutto funzionava senza dover aggiungere alcun componente. C'è qualcosa che potrebbe essere cambiato nel frattempo?

12 e 22?

Mio consiglio:

Butta via tutto, prendi del reference un esempio semplice e seguilo pedissequamente

Poi si vede

Questo deve essere su due righe

➜

#define I2C_SDA 12
#define I2C_SCL 22

Buongiorno,
nessun rischio nel codice, forse ho fatto un copia/incolla sbagliato dello script, ma nel microcontrollore c’è la stringa:

Wire.begin(21, 22); // SDA = 21, SCL = 22

La mi a perplessità rimane, perchè prima funzionava?

anche con un vecchio sketch:

#include <Wire.h> 
#include <LiquidCrystal_I2C.h>

#if defined(ARDUINO) && ARDUINO >= 100
#define printByte(args)  write(args);
#else#define printByte(args)  print(args,BYTE);#endif

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

int count = 0;
bool rx = true;

// ha bisogno di 5V per funzionare
// D18 (SDA) e D19 (SCL)
void setup(){
 Serial.begin(9600);
 while (!Serial);

 Serial.println ();
 Serial.println ("init LCD");

 Serial.println("Scanner I2C in corso...");

 byte error, address;
 int count = 0;

for (address = 1; address < 127; address++) {
   Wire.beginTransmission(address);
   error = Wire.endTransmission();

   if (error == 0) {
     Serial.print("Dispositivo trovato a 0x");
     if (address < 16)
        Serial.print("0");
        Serial.println(address, HEX);
        count++;
     }
  
}

 if (count == 0) Serial.println("Nessun dispositivo I2C trovato.");
 else Serial.println("Scanner completato.");

 lcd.init(); 
 lcd.backlight(); 

 lcd.setCursor(0, 0);
 lcd.print("INIT");

 lcd.home();

 Serial.println ("fine setup");

}

void loop() {
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print("Hello, world!");
  delay(500);
  // delayMicroseconds(5000);
}

su un Arduino Nano Every che accetta ingressi a 5V il risultato non cambia.
Non vedo il testo sul display, nonostante ne abbia cambiato più di uno…

@mariotto

... fosse anche per una sola riga, come richiesto al punto 7 del REGOLAMENTO, il codice va racchiuso tra i tag CODE, per cui, cortesemente edita il tuo post qui sopra (quindi NON scrivendo un nuovo post, ma utilizzando il bottone a forma di piccola matita :pencil2: che si trova in basso del tuo post), seleziona la parte di codice e premi l'icona <code/> nella barra degli strumenti per contrassegnarla come codice. Inoltre, così com'è, non è molto leggibile ... assicurati di averlo correttamente indentato nell'IDE prima di inserirlo (questo lo si fa premendo ctrlT su un PC o cmd T su un Mac, sempre all'interno del IDE).

Grazie,

Guglielmo

P.S.: Ti ricordo che, purtroppo, fino a quando non sarà sistemato il codice come indicato, nel rispetto del regolamento nessuno ti risponderà (eventuali risposte o tuoi ulteriori post, verrebbero temporaneamente nascosti), quindi ti consiglio di farlo al più presto. :wink:

ma sono visibile? perchè non ho più risposte dal post.

Si certo ...
... si vede che non è passato alcuno con possibili risposte ... :roll_eyes:

Guglielmo

Direi di no

E a ragione

(Ovvero è giusto che non ci siano risposte)

Perché ci si aspetta risposte se il programma pubblicato è ancora illeggibile?

Perché ci si aspetta risposte se l'unico suggerimento avuto è stato ignorato?

Quello potrebbe essere un problema NON completamente suo ... ci sono alcune discussioni in merito ... QUESTA è una ... :roll_eyes:

Guglielmo

Penso di aver sistemato lo sketch…

Scusami, mi sono perso qualcosa (Perché ci si aspetta risposte se l'unico suggerimento avuto è stato ignorato?)?