Schermo OLED SSD: strano sfarfallio

Salve a tutti, da una sera sbatto contro uno strano problema per il quale dopo un numero irragionevoli di prove ho forse capito il perchè ma non il come risolverlo(colpa la mia ancora scarsa conoscenza di arduino?!)

Dunque, ho implementato tramite un pulsante delle schermate(per l'esattezza erano 3)
Fintanto che erano 2 tutto filava liscio, appena arrivata la terza è iniziato uno strano "sfarfallio", come se ci fossero tanti caratteri in continua sovrapposizione nell'angolo in basso a destra

Vi mostro la funzione che viene richiamata dal ciclo loop "incondizionatamente"(ho tolto la terza schermata per adesso perchè ho trovato un sistema diverso, ma vorrei capire se e come risolvere)

void stampaSchermo()
{
  display.clearDisplay();
  if (schermata==0) {
    display.drawBitmap(92, 5, fanBmp, 32, 32, WHITE);
      display.setTextSize(1);   
      display.setCursor(0, 0);        
      display.println(F("Ambiente")); 
      display.setCursor(0, 40);
      display.println(F("SET")); 
      display.drawFastHLine(0, 32, 87, WHITE);
      display.drawFastVLine(87, 0, 64, WHITE);
      display.setTextSize(2);
      display.setTextColor(WHITE);
      display.setCursor(25, 15);
      display.print(h);
      display.println("%");
      display.setCursor(25, 48);
      display.print(setVal);
      display.println("%");
      display.setCursor(92, 48); 
      if(manuale==0){ 
      display.println((relayState ? "OFF" : "ON")); }
      else{display.println("MAN");}
      }
if (schermata==1){
      display.setTextSize(1);   
      display.setCursor(30, 15);        
      display.println("Temperatura"); 
      display.drawFastHLine(0, 32, 128, WHITE);
      display.setTextSize(2);   
      display.setCursor(35, 40);        
      display.print(t); 
      display.print((char)247); display.print("C");
}

SE aggiungo una terza schermata, il problema si presenta, almeno che io non tolga elementi dalle precedenti. E' come se arduino prendesse le tre schermate, ne crea una copia in memoria, ma non riuscendo a gestire tutti quei dati si incasina.

Ho pensato bene o no? Penso proprio che per il piccolino(ed economico) serva un codice più ottimizzato, ma come?

Grazie mille per l'eventuale aiuto e buon lavoro

Salvo De Cervo

Dovresti postare il codice completo, così si capisce dove e quanto richiami la funzione stampaSchermo(). Quante volte cambi la schermata? Quasi sicuramente comunque il colpevole dello sfarfallio è il clearDisplay() ad inizio funzione, potresti intanto evitarlo se la schermata non è cambiata. Inoltre ti consiglierei di usare 2 funzioni diverse, una che stampa gli elementi fissi della schermata (bitmap, linee,etc) ed una in cui aggiorni solo i valori che cambiano.

Ciao, Ale.

Quando premi il pulsante devi cancellare tutto e poi visualizzare una sola volta la maschera A o la maschera B con le scritte fisse; poi, periodicamente, cancelli e riscrivi i valori aggiornati. Per fare questo hai due possibilità:

  1. un rettangolo nero che copre i valori da cancellare;
  2. conservi i valori vecchi in una o più variabili e, quando devi cancellarli, li riscrivi identici in nero.

Ciao Ale,

Il codice lo richiamo sempre nel loop. In effetti anche a me sembrava una soluzione poco ortodossa, ma ovviamente non riscontrando alcun problema non mi ero posto alternative.

A questo punto mi vado a creare un codice che piglia sia i tuoi consigli che quelli di @Datman .

Appena faccio il tutto posto il codice completo, magari mi date qualche dritta. Intanto sono soddisfatto già del risultato, sempre migliorabile, che ho ottenuto.

Grazie a tutti

Saluti
Salvo

Con che frequenza possono cambiare i valori che visualizzi?
Le soluzioni proposte da @ilguargua e @Datman sono le più ortodosse, ma in alcuni casi può bastare richiamare la funzione con meno frequenza, tipo una o 2 volte al secondo...

Per farlo male, sì...

mmm ... se non aggiorni solo la regione interessata (come suggerisce Datman), ma fai la pulizia dello schermo e riscrivi, lo "sfarfallamento" è assicurato e ... 1 o 2 volte al secondo è comunque fastidioso :wink:

Guglielmo

Stasera lavorerò alla cosa anche se avendo ridotto i dati da stampare lo sfarfallio non ci sta più ma... farò in modo di reinserirlo aumentando di nuovo le scritte e mantenendo il codice attuale.
Poi lavorerò su una nuova versione del codice per efficientare il tutti.
Innanzitutto divido il codice per la scrittura a schermi in 2: una funzione che si occupa dei layout delle varie pagine che per adesso sono solo 2, ed una che si occupa della gestione dei contenuti variabili.
Di base le pagine cambiano alla pressione di un tasto(SET) che lavora con una variabile( valori attuali 0 e 1)
Da questo bottone richiamo la funzione di stampa layout che stampa il layout di tutto lo schermo dopo un clearscreen.
Nel loop invece avvio la funzione per la scrittura dei valori, individuati per pagina. Mi faccio una mappatura delle aree interessate, ricopro con un fillrect nero e riscrivo.
Ovviamente anche al setup entrambe le funzioni vengono richiamate.
Penso che sia la migliore soluzione basandomi sui vostri consigli.

Grazie mille

Saluti

Salvo

1 Like

Il layout, cioè la disposizione, di tutto lo schermo?...

Ciao @Datman , e ciao a tutti coloro che hanno dato un contributo a questo argomento!

Intanto rispondo alla tua domanda. Per layout delle 2 pagine intendo le parti fisse.

Nella prima pagina c'è una piccola bitmap, 2 linee(orizzontale e verticale) e 2 scritte fisse
Le scritte variabili sono l'umidità rilevata, la soglia impostata e lo stato della ventola(ON,OFF,MAN)
Nella seconda pagina ho una scritta fissa(temperatura) ed una linea fissa orizzontale e poi la temperatura costantemente aggiornata.

Ho provato ad applicare tutti i vostri consigli ma...il risultato è peggiorato di tanto.

Il codice, molto semplice funziona così:
in prima pagina attraverso due bottoni posso aumentare o diminuire la soglia
In seconda visualizzo la temperatura
Passo dalla prima allla seconda attraverso un terzo pulsante(SET)
Se premo a lungo SET invece la ventola si accende fissa, se ripremo a lungo si spegne.

Il tutto è composto da 1 Nano, DHT11,Mod relay 2 posizioni, Schermo SSD1306, 3 bottoni.

Posto di seguito i 2 listati(prima delle modifiche e dopo) ma il problema è legato a 2 motivi secondo me:
inserisce delle spurie in basso a destra perchè ,forse, ha troppo da gestire. Infatti se nel codice faccio stampare solo la scritta "Temperatura" il problema sparisce. Se modifico in "Temperatura attuale" o comunque aumento i caratteri inizia il problema.
Così come se allungo ancora di più i contenuti(tipo scrivo temperatura attuale registrata o comunque allungo qualsiasi altra scritta o ne aggiungo) le spurie aumentano.
Inoltre le spurie "sfarfallano" per via del costante aggiornamento dello schermo(nel primo codice)

Per rendere meglio l'l'idea gho caricato su youtube il video dei 2 risultati

CODICE VECCHIO

CODICE NUOVO

Da notare che nel secondo listato ho spostato quante più scritte possibili nella flash, senza avere miglioramenti.

Ecco i Listati, vi prego di essere pacati con le critiche...sono alle prime armi con arduino :grimacing:
Però consigli, commenti o altro possa essere costruttivo sono per me una manna!

LISTATO VECCHIO

//Gestione dipendenze-------------------------------------------------
#include <Wire.h>
#include <DHT.h>
#include <OneButton.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
// Dichiarazione dei PIN-----------------------------------------------
#define downBtnPin 2
#define upBtnPin 3
#define setBtnPin 4
#define DHTPin 5
#define relayPin 6
//Settaggi schermo OLED SSM1306----------------------------------------
#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);
//SDA su A4
//SCL su A5
//Icona ventola
const unsigned char fanBmp[] PROGMEM = {
  0x00, 0x0f, 0xc0, 0x00, 0x00, 0x3f, 0xf8, 0x00, 0x00, 0x7f, 0xfc, 0x00, 0x00, 0xff, 0xfe, 0x00, 
  0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x01, 0xff, 0xff, 0x00, 0x01, 0xff, 0xff, 0x00, 
  0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xfe, 0x00, 0x00, 0x7f, 0xf8, 0x00, 
  0x00, 0x7f, 0xf0, 0x00, 0x00, 0x3f, 0xc3, 0xc0, 0x1f, 0x0f, 0xcf, 0xf0, 0x3f, 0xc5, 0xbf, 0xfc, 
  0x7f, 0xf3, 0xbf, 0xfe, 0xff, 0xfb, 0xbf, 0xfe, 0xff, 0xfc, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 
  0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0x3f, 0xff, 0xff, 0xff, 0x3f, 0xff, 0x7f, 0xff, 0x3f, 0xfe, 
  0x7f, 0xfe, 0x3f, 0xfe, 0x7f, 0xfe, 0x3f, 0xfc, 0x3f, 0xfc, 0x3f, 0xf8, 0x1f, 0xfc, 0x3f, 0xf0, 
  0x0f, 0xf0, 0x1f, 0xe0, 0x07, 0xe0, 0x0f, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
//Settaggi sensore DHT11
#define DHTTYPE DHT11
DHT dht(DHTPin,DHTTYPE);
//Variabili di stato e conservazione valori
int setVal =60;//valore di base per l'umidità in partenza
int varVal = 5;//sottratto al valore settato è il valore di spegnimento della ventola
int h;//Umidità
int t;//Temperatura
bool relayState=1;//Memorizza lo stato del Relè. A 1 la ventola è spenta
//Variabili per la gestione delle schermate
int schermata=0;//Provo a gestire diverse schermate...
int maxSchermata =1;//Numero massimo schermate, se è 1 ho la 0 e la 1, ecc
//Gestione manuale, quando è attiva la ventola sta sempre accesa
bool manuale =0;
//Creazione dei bottoni per la gestione con ONE BUTTON
OneButton btnUp;
OneButton btnDown;
OneButton btnSet;

void setup() {
 Serial.begin(9600);
dht.begin();
display.begin(SSD1306_SWITCHCAPVCC, 0x3C);
//Inizializzazione dei bottoni---------------------------------------------------
btnUp.setup(upBtnPin,INPUT_PULLUP,true);
btnDown.setup(downBtnPin,INPUT_PULLUP,true);
btnSet.setup(setBtnPin,INPUT_PULLUP,true);
btnUp.attachClick(btnUpClick);
btnDown.attachClick(btnDownClick);
btnSet.attachClick(btnSetClick);
btnSet.attachLongPressStart(btnSetLongClick);
//SPLASH SCREEN
display.clearDisplay();
display.setTextSize(1);
display.setTextColor(WHITE);
display.setCursor(30, 20);
display.println("Umidostato");
display.setCursor(45, 40);
display.println("V 1.1");
display.display(); 
pinMode(relayPin,OUTPUT);
digitalWrite(relayPin,relayState);
delay(3000);

}

void loop() {

btnUp.tick();
btnDown.tick();
btnSet.tick();
h = int(dht.readHumidity());
t=int(dht.readTemperature());

//Gestione automatica
if(manuale==0){
if (h>setVal){relayState=0;}//accendo
if (h<=setVal-varVal){relayState=1;}//spengo
digitalWrite(relayPin,relayState);
}
if(manuale==1){digitalWrite(relayPin,LOW);}

Serial.print(manuale);
stampaSchermo();
}
void btnUpClick()
{
   //l'implementazione è solo nella prima schermata
  if (schermata !=0){return;}
  setVal++;
     if (setVal>99){setVal=1;}
  }
 void btnDownClick()
{
  //l'implementazione è solo nella prima schermata
  if (schermata !=0){return;}
  setVal--;
     if (setVal<1){setVal=99;}
  }

void btnSetClick()
{
  schermata++;
     if (schermata>maxSchermata){schermata=0;}
     Serial.println(schermata);
     }

void btnSetLongClick()
{
   manuale=!manuale;
  }

void stampaSchermo()
{
  display.clearDisplay();
  if (schermata==0) {
    display.drawBitmap(92, 5, fanBmp, 32, 32, WHITE);
      display.setTextSize(1);   
      display.setCursor(0, 0);        
      display.println(F("Ambiente")); 
      display.setCursor(0, 40);
      display.println(F("SET")); 
      display.drawFastHLine(0, 32, 87, WHITE);
      display.drawFastVLine(87, 0, 64, WHITE);
      display.setTextSize(2);
      display.setTextColor(WHITE);
      display.setCursor(25, 15);
      display.print(h);
      display.println("%");
      display.setCursor(25, 48);
      display.print(setVal);
      display.println("%");
      display.setCursor(92, 48); 
      if(manuale==0){ 
      display.println((relayState ? "OFF" : "ON")); }
      else{display.println("MAN");}
      }
if (schermata==1){
      display.setTextSize(1);   
      display.setCursor(30, 15);        
      display.println("Temperatura Attuale registrata"); 
      display.drawFastHLine(0, 32, 128, WHITE);
      display.setTextSize(2);   
      display.setCursor(35, 40);        
      display.print(t); 
      display.print((char)247); display.print("C");
}


display.display();
}

LISTATO NUOVO

//Gestione dipendenze-------------------------------------------------
#include <Wire.h>
#include <DHT.h>
#include <OneButton.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
// Dichiarazione dei PIN-----------------------------------------------
#define downBtnPin 2
#define upBtnPin 3
#define setBtnPin 4
#define DHTPin 5
#define relayPin 6
//Settaggi schermo OLED SSM1306----------------------------------------
#define SCREEN_WIDTH 128 
#define SCREEN_HEIGHT 64 
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);
//Per Arduino Nano
//SDA su A4
//SCL su A5
//Icona ventola
const unsigned char fanBmp[] PROGMEM = {
  0x00, 0x0f, 0xc0, 0x00, 0x00, 0x3f, 0xf8, 0x00, 0x00, 0x7f, 0xfc, 0x00, 0x00, 0xff, 0xfe, 0x00, 
  0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x01, 0xff, 0xff, 0x00, 0x01, 0xff, 0xff, 0x00, 
  0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xfe, 0x00, 0x00, 0x7f, 0xf8, 0x00, 
  0x00, 0x7f, 0xf0, 0x00, 0x00, 0x3f, 0xc3, 0xc0, 0x1f, 0x0f, 0xcf, 0xf0, 0x3f, 0xc5, 0xbf, 0xfc, 
  0x7f, 0xf3, 0xbf, 0xfe, 0xff, 0xfb, 0xbf, 0xfe, 0xff, 0xfc, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 
  0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0x3f, 0xff, 0xff, 0xff, 0x3f, 0xff, 0x7f, 0xff, 0x3f, 0xfe, 
  0x7f, 0xfe, 0x3f, 0xfe, 0x7f, 0xfe, 0x3f, 0xfc, 0x3f, 0xfc, 0x3f, 0xf8, 0x1f, 0xfc, 0x3f, 0xf0, 
  0x0f, 0xf0, 0x1f, 0xe0, 0x07, 0xe0, 0x0f, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
//Settaggi sensore DHT11
#define DHTTYPE DHT11
DHT dht(DHTPin,DHTTYPE);
//Variabili di stato e conservazione valori
int setVal =60;//valore di base per l'umidità in partenza
int varVal = 5;//sottratto al valore settato è il valore di spegnimento della ventola
int h;//Umidità
int t;//Temperatura
bool relayState=1;//Memorizza lo stato del Relè. A 1 la ventola è spenta
//Variabili per la gestione delle schermate
int schermata=0;//Provo a gestire diverse schermate...
int maxSchermata =1;//Numero massimo schermate, se è 1 ho la 0 e la 1, ecc
//Gestione manuale, quando è attiva la ventola sta sempre accesa
bool manuale =0;
//Creazione dei bottoni per la gestione con ONE BUTTON
OneButton btnUp;
OneButton btnDown;
OneButton btnSet;

void setup() {

      dht.begin();
      display.begin(SSD1306_SWITCHCAPVCC, 0x3C);
      //Inizializzazione dei bottoni---------------------------------------------------
      btnUp.setup(upBtnPin,INPUT_PULLUP,true);
      btnDown.setup(downBtnPin,INPUT_PULLUP,true);
      btnSet.setup(setBtnPin,INPUT_PULLUP,true);
      btnUp.attachClick(btnUpClick);
      btnDown.attachClick(btnDownClick);
      btnSet.attachClick(btnSetClick);
      btnSet.attachLongPressStart(btnSetLongClick);
      //SPLASH SCREEN
      display.clearDisplay();
      display.setTextSize(1);
      display.setTextColor(WHITE);
      display.setCursor(30, 20);
      display.println("Umidostato");
      display.setCursor(45, 40);
      display.println("V 1.1");
      display.display(); 
      pinMode(relayPin,OUTPUT);
      digitalWrite(relayPin,relayState);
      delay(3000);
      stampaLayout();
      stampaValori();
}

void loop() {

      btnUp.tick();
      btnDown.tick();
      btnSet.tick();
      h = int(dht.readHumidity());
      t=int(dht.readTemperature());
      //Gestione automatica
      if(manuale==0){
            if (h>setVal){relayState=0;}//accendo
            if (h<=setVal-varVal){relayState=1;}//spengo
            digitalWrite(relayPin,relayState);
      }
      //Gestione Manuale
      if(manuale==1){digitalWrite(relayPin,LOW);}
      stampaValori();
}
void btnUpClick()
{
       //l'implementazione è solo nella prima schermata
      if (schermata !=0){return;}
      setVal++;
         if (setVal>99){setVal=1;}
  }
 void btnDownClick()
{
  //l'implementazione è solo nella prima schermata
      if (schermata !=0){return;}
      setVal--;
      if (setVal<1){setVal=99;}
}

void btnSetClick()
{
      schermata++;
      if (schermata>maxSchermata){schermata=0;}
      stampaLayout();
}

void btnSetLongClick()
{
   manuale=!manuale;
}

void stampaLayout()
{
      display.clearDisplay();
      if (schermata==0) {
            display.drawBitmap(92, 5, fanBmp, 32, 32, WHITE);
            display.setTextSize(1);   
            display.setCursor(0, 0);        
            display.println(F("Ambiente")); 
            display.setCursor(0, 40);
            display.println(F("SET")); 
            display.drawFastHLine(0, 32, 87, WHITE);
            display.drawFastVLine(87, 0, 64, WHITE);
      }
      if (schermata==1){
            display.setTextSize(1);   
            display.setCursor(30, 15);        
            display.println(F("Temperatura")); 
            display.drawFastHLine(0, 32, 128, WHITE);
      }
      display.display();
}
void stampaValori()

{
      if(schermata==0){
            //Ripulisco lo spazio delle variabili
            display.fillRect(25,48,35,15,BLACK);
            display.fillRect(25,15,35,15,BLACK);
            display.fillRect(92,48,35,20,BLACK);
            display.setTextSize(2);
            display.setTextColor(WHITE);
            display.setCursor(25, 15);
            display.print(h);
            display.println("%");
            display.setCursor(25, 48);
            display.print(setVal);
            display.println(F("%"));
            display.setCursor(92, 48); 
            if(manuale==0){ 
                    display.println((relayState ? "OFF" : "ON")); }
            else{
                    display.println("MAN");}
       }
      if (schermata==1){
            //Ripulisco lo spazio delle variabili
            display.fillRect(35,40,47,15,BLACK);
            display.setTextSize(2);   
            display.setCursor(35, 40);        
            display.print(t); 
            display.print((char)247); display.print("C");
  }

display.display();
}

In sostanza solo se il nuovo dato è diverso da quello vecchio già visualizzato, dovrai
visualizzare il nuovo, ma prima scrivi il vecchio in nero.
Inoltre con che frequenza possono variare questi dati? in genere temperatura e umidità variano lentamente per cui potresti aggiornare il display ogni 1 secondi, eviti così i valori ballerini.

Le variabili prevH e prevT devi dichiarale come h e t, ma a prevH e prevT ci assegni dei valori che h e t non possono assumere nel normale funzionamento. in questo modo è certo che prevH sarà diverso da H per cui stamperà almeno la prima volta, poi dipende se h cambia rispetto a prevH, se non è cambiato non ha senso stampare nuovamente il dato che è già sul display.

PS: sono le 03:27 e non sono molto lucido.

Ciao.

Ciao.

Salve @Maurotec ,

mi sono perso un attimo per via di impegni di maggior importanza. Alla fine questa è diventata più una sfida che una necessità.

Ho fatto quello che mi hai detto tu e pure oltre, mettendo una condizione per ogni cosa, facendo in modo che ogni aggiornamento dipendesse da un cambiamento reale, ma niente. Ho pure aggiunto un rozzo delay(2000) ma niente lo stesso.
A questo punto penso che non è ammissibile che per visualizzare 2 dati a schermo servano così tante accortezze e sono sempre più convinto che se questo codice lo carico su un arduino Uno non mi da lo stesso problema per via della maggior memoria.

Infatti i problemi sono nati via via che i contenuti sono aumentati.

Non so che dire, probabilmente nei prossimi giorni non avrò tempo da dedicargli, ma non è una partita chiusa, semmai una battaglia sospesa.

Grazie mille ancora

Saluti

Salvo

No il delay è pure peggio anche per altri motivi.
La libreria che usi viene con una demo, hai provato questa demo per verificare il corretto funzionamento del display?
Viene naturale pensare ad un difetto del display.

Certo può anche dipendere da un consumo di ram eccessivo, ma non mi sembra il tuo caso. Quel difetto nei video che hai linkato non è mai stato segnalato sul forum, in genere come sfarfallio si intende la pulsazione dovuta al fatto che quando cancelli il display in realtà cancelli il contenuto del buffer che si trova in ram e poi display.display() invia il buffer via I2c. A proposito la MCU atmega328p di default usa per la Wire la velocità di 100K, che con Wire.setClock(400000); si può aumentare al massimo a 400K.

Ma prima proverei la demo della GFX.

Ciao.

Premetto che io ho usato la libreria SSD1306Ascii.h (consigliatami a suo tempo da Guglielmo, leggera e funzionante sia sui display con SSD1306 che su quelli con SH1106), che stampa solo caratteri e niente grafica, per cui serve che provi sulla tua, ma per eliminare lo sfarfallio ho semplicemente stampato delle stringhe complete di spazi piu lunghe del numero massimo di caratteri che ci stavano su una riga, e dato che quei display, facendo cosi, sovrascrivono direttamente tutto quello che c'e' sulla riga (almeno lo fanno con quella libreria), non c'e' stato alcun bisogno di fare dei clear o ristampare rettangoli vuoti.

Ma a te' serve per forza di visualizzare grafica, o ti basta il solo testo ?

Convinzione errata, il nano e l'uno usano la stessa MCU, con stesse caratteristiche, solo il contenitore cambia.

Ciao, Ale.

Forse dipende dalla libreria che si usa, ma mi sembra proprio che la u8g2 sovrapponga i caratteri, cioè aggiunga solo i pixel del nuovo carattere.

... sempre detto che è una schifezza di libreria :smiling_imp:

Guglielmo

Avevo cercato di usare pure quella, ma mi mangiava un sacco di spazio in flash ... sostituendola con la SSD1306Ascii, solo quello mi ha dimezato l'occupazione di memoria del programma, e dato che a me' servivano solo lettere e numeri, altre librerie con piu funzioni mi erano inutili.

Per la u8g2 non lo so proprio, ma l'altra quando scrivi una nuova riga, sovrascrive cancellando totalmente la vecchia, quindi era bastato usare sprintf per creare delle variabili completando con uno spazio in piu di quello che occupava quel font per riempire una riga e scriverle senza cancellare nulla, per eliminare totalmente lo sfarfallio.

esempio:

  sprintf(linea, "LETT %u       ", lettura);
  oled.setCursor(0, 0);
  oled.print(linea);

"linea" era un carattere piu lungo dello spazio massimo, ogni cosa che lo supera viene automaticamente "persa" dal chip, quindi ogni scrittura sovrascriveva la precedente senza bisogno di cancellare prima i vecchi caratteri ... se la u8g2 non lo fa, probabilmente si potrebbe ottenere la stessa cosa scrivendo prima la linea precedente con il colore dello sfondo e poi la nuova linea subito dopo, ma serve ovviamente memorizzare la nuova linea per poterla usare la volta dopo per cancellarla, non so se questo possa eliminare totalmente lo sfarfallio, ma credo che diventerebbe comunque molto minore che usando un clear :roll_eyes:

ERRORE grosso quanto una casa :grimacing:

Rileggendo il codice salta fuori che usi i pin riservati per i2c, in particolare quello del DHT. Quasi certo che il problema è dovuto a questo errore.

Ora mi chiedo come è possibile che l'errore sia sfuggito a tutti?

Ciao.

Mica sono sicuro, quelli sono i pin digitali 4 e 5, il bus I2C è su A4 ed A5 che sono tutt'altri pin (18 e 19) :roll_eyes:

Guglielmo