Go Down

Topic: Problema schermo i2c (Read 620 times) previous topic - next topic

gpb01

Allora per semplificare ti direi di provare semplicemente con un convertitore di livello  ...
... mmm, molto meglio quello di Adafruit appositamente fatto per il bus I2C e che contiene già le pull-up su entrambi i lati.  Io lo uso ormai dovunque :D

Guglielmo

P.S.: Su AliExpress si trova a meno di un decimo del prezzo  :smiley-mr-green:
Search is Your friend ... or I am Your enemy !

Mullen26

Allora ragazzi

Comincio nel ringraziare tutti per le risposte che mi avete fornito fino ad ora e vi aggiorno sulla situazione attuale

Stasera ho dedicato ancora qualche ora al mio schermo nel tentativo di capirci qualcosa.
Praticamento ho resettato tutto quanto, reinstallato tutte le librerie e rifatto upload dello sketch sul mkr1010....praticamente ho visto i caratteri per circa un sec e poi sparito tutto.
quindi ho ripreso il 20x4 al posto del 16x2  riprovato e questo funziona  :-X

Riprovato anche con arduino 2 e funziona correttamente solo il 20x 4

Presenta solo un picco problema di instabilita sulla seconda riga(tende a lampeggiare in corrispondeza del refesh)
Mi chiedo se  a questo punto converrebbe installare il famoso convertitore di livello di cui mi parlavate prima per tentare di eliminare eventuali disturbi. potrebbe aiutare?

docdoc

Domanda forse sciocca: ma tu i display li alimenti a 5V, vero?....
Alex "docdoc"
- "Qualsiasi cosa, prima di rompersi, funzionava"

Mullen26

#18
Sep 11, 2020, 12:06 pm Last Edit: Sep 11, 2020, 01:21 pm by Mullen26
Si corretto per ora alimentato dal 5v del mkr
poi quando sarà installato  verrà alimentato dal lm7805.

gpb01

... alimenta anche il convertitore I2C a 5V ed usa i "level shifter" sui due pin I2C.

Guglielmo
Search is Your friend ... or I am Your enemy !

Mullen26

Ok ragazzi ho appena acquistato un lever shifter.
Appena mi arriva lo provo e vi faccio sapere.

Mullen26

Ragazzi rieccomi.
Ho acquistato questi 2 tipi di level shifter http://https://www.adafruit.com/product/1875  http://https://www.adafruit.com/product/757
Nel primo caso il mio schermo non dava solo quadrati neri (ho provato a modificare il potenziometro ma nulla)
Nel secondo caso lo schermo funziona correttamente ma da ancora i problemi presenti prima ( lampeggio dalla prima riga in giu e caratteri strani che compaiono ogni tanto)
Il collegamento dei jumper l'ho eseguito collegando dalla parte low voltage il 3.3 volt fornito da un UA78M33CKCS
Dalla parte high voltage il 5 volt fornito da un UA7805CKCT
Quello che ho notato è che il lampeggio è sempre presente fin dall'accensione, mentre i caratteri strani compaiono soprattutto quando il modulo relè che ho installato inizia a spegnerli(ne utilizzo max 4 insieme).





cotestatnt

Il PCF8574 funziona nel range 2.5/6V quindi il convertitore di livello non è necessario.
Per quanto riguarda l'LCD bisognerebbe vedere esattamente che modello è, 
ma di solito anche quelli non hanno problemi a lavorare con 3.3V


Se metti il codice completo che ti da errori forse è meglio.

steve-cr

#23
Oct 26, 2020, 04:37 pm Last Edit: Oct 26, 2020, 04:39 pm by steve-cr
I display che uso da sempre, i 20x04 I2C con HD44780, funzionano anche a 3,3 volt.
Il data sheet consiglia solo di sostituire la resistenza Rf da 91Kohm e portarla a 75Kohm per adattarne la velocità di risposta, altrimenti diventa lento.

Per quanto riguarda i "caratteri strani" è UN ALTRO PROBLEMA, non collegato al tuo programma oppure alla alimentazione, tanto è vero che tu stesso confermi che succede solo quando utilizzi i relé.

Ci sono diverse soluzioni sul forum per schermare il contatto relè con un filtro R+C

E una sola soluzione per rendere il display meno "schizzinoso" e far apparire meno caratteri strani, usando un condensatore da 0,1 tra VSS e E ed una resistenza da 3k3 tra VDD e E.

Facci sapere.
Samantha Cristoforetti: "Mi fai fare un giro sul tuo ultraleggero?". "Certamente, però piloto io !"

Mullen26

Ho appena fatto un test.
Effettivamente lo schermo togliendo il level-shifter e alimentandolo direttamente a 3.3v funziona correttamente, in questo momento non ho a disposizione una resistenza smd da sostituire a quella da 91kohm, domani provo con una classica.
Lo schermo tuttavia presenta sempre il problema del lampeggio( in questo momento il refresh viene eseguito ogni sec)
Per quanto riguarda il fitro grazie del consiglio ora provo a spulciare un po il forum

cotestatnt

Il problema del lampeggio è con tutta probabilità dovuto al fatto che esegui un clear() prima di aggiornare il testo visualizzato.

Con i display LCD, per evitare questo fastidioso inconveniente evita il clear() o usalo solo in determinato momenti.
Quando devi aggiornare le righe, formatti un char array sempre al numero dei caratteri max usando l'istruzione snprintf e stampi la riga completa in un colpo solo.
Code: [Select]
#define COLS 20
#define ROWS 4

char lcdBuf[COLS];
....
void loop(){
    snprintf(lcdBuf, COLS, "%-20s", "Hello World!");  // stringa giustificata a sinistra
    lcd.setCursor(0,0);
    lcd.print(lcdBuf);
    snprintf(lcdBuf, COLS, "Il tempo scorre %03lu", millis()/1000);
    lcd.setCursor(0, 1);
    lcd.print(lcdBuf);

}



Mullen26

Ho fatto qualche prova stasera, effettivamnete contestatnt hai ragione ho provato ad inserire il tuo codice e nessuna traccia di lampeggio  ;)
Tuttavia vi chiedo ancora una mano visto che ho provato ad inserire il codice che utilizzavo prima con questo metodo ma purtroppo ottengo un risultato solo parziale.
Code: [Select]
//lcd

unsigned long currentMillislcd = millis();

 if (currentMillislcd - previousMillislcd >= intervallcd) {
    previousMillislcd = currentMillislcd;
lcd.clear();   
lcd.setCursor(0,0);
lcd.print("andat:");
lcd.print(sen_number);
lcd.setCursor(8,0);
lcd.print("Temp:");
lcd.print(sensors.getTempC(T1)); lcd.write((char)223); lcd.print("C");
lcd.setCursor(0,1);
lcd.print("ritor:");
lcd.print(sen_number+1);
lcd.setCursor(8,1);
lcd.print("Temp:");
lcd.print(sensors.getTempC(T2)); lcd.write((char)223); lcd.print("C");
Serial.print("Sensor Number="); Serial.println(sen_number);
 }

 questo era il precedente.
il problema è che non riesco a far scrivere la temperatura letta dalla sonda sul lcd.
Code: [Select]

unsigned long currentMillislcd = millis();
char lcdandata = sensors.getTempC(T1);
char lcdritorno = sensors.getTempC(T2);

 if (currentMillislcd - previousMillislcd >= intervallcd) {
    previousMillislcd = currentMillislcd;
   
snprintf(lcdBuf, COLS, "andat:","Temp:",lcdandata, "C");  // stringa giustificata a sinistra 
lcd.setCursor(0,0);
lcd.print(lcdBuf);
snprintf(lcdBuf, COLS, "ritor:","Temp:",lcdritorno, "C"); // stringa giustificata a sinistra
lcd.setCursor(0, 1);
lcd.print(lcdBuf);
Serial.print("Sensor Number="); Serial.println(sen_number);

questo è quello che ho provato a scrivere

cotestatnt

Non puoi scrivere istruzioni a caso!
L'istruzione snprintf si usa passando nell'ordine: 
- il buffer che deve riempire
- la dimensione del buffer (questo assicura che non si vanno a scrivere porzioni di memoria sbagliata)
- la stringa di formattazione
- N parametri in funzione dei "format specifier" indicati nella stringa di formattazione per i quali ti rimando qui

Rispetto al link, c'è qualche eccezione nel mondo "Arduino". Ad esempio non sono supportati i float/double come probabilmente è il valore restituito da sensors.getTempC(T1)   { quel "char lcdritorno = sensors.getTempC(T2)" non si può vedere  :'( :smiley-wink:}

Io uso sempre questo "work-around" per ovviare al problema
Code: [Select]
float temp1 = sensors.getTempC(T1);
snprintf(row, COLS, "Temp. 1: %d.%d %dC", (int)temp1, (int) (temp1*10) %10, (char) 223);    // 1 cifra dopo la virgola

oppure
snprintf(row, COLS, "Temp. 1: %d.%d %dC", (int)temp1, (int) (temp1*100) %100, (char)223);    // 2 cifre dopo la virgola

oppure
snprintf(row, COLS, "Temp. 1: %03d.%d %dC", (int)temp1, (int) (temp1*10) %10, (char) 223);
// il numero sarà sempre nel formato xxx.yy (002.2, 023.5, 123.8 etc etc), al posto dello 0 puoi usare uno spazio.


La stringa di formattazione usata prevede che seguiranno 3 format specifier di tipo %d ovvero interi decimali con segno,
ma le possibilità sono molteplici come puoi vedere nel link che ti ho messo.

Mullen26

#28
Oct 28, 2020, 08:37 pm Last Edit: Oct 28, 2020, 08:37 pm by Mullen26
Perdona la mia enorme ignoranza ma sono veramente ai primi passi sull'elettronica :smiley-confuse: ;) .
Quindi vediamo se ho capito bene la funzione snprintf stampa l'intera riga di caratteri in un colpo solo, evitando che il normale lcd.print dia problemi "diciamo così".
Di conseguenza il clear potrei usarlo solo in rarissimi casi all'interno dello sketch.
l'unico problema rimanete è questo errore che mi appare quando verifico


error: 'row' was not declared in this scope




cotestatnt

error: 'row' was not declared in this scope
Allora non hai studiato bene la funzione  ;)
Ti metto il trabocchetto e ci caschi?


Scherzi a parte snprintf  comunque non stampa nulla, ma "popola" il char array con i dati che gli passi come parametri ed in questo secondo esempio l'array si chiama row mentre la prima volta lo avevo dichiarato come lcdBuf
(ho fatto un copia incolla da un progetto che avevo sotto mano e l'avevo dichiarato cosi)



Go Up