Problema bitmap su ssd1306

Salve sono un principiante! sto facendo delle prove con un oled ssd1306 e un sensore ti temperatura BMP180.
Vorrei che quando la temperatura supera una certa T mi compaia una bitmap di un termometro, per intenderci la bitmap compare ma purtroppo ogni volta che la temperatura cambia di un decimo (anche sopra la soglia fissata) la bitmap scompare :sweat_smile: e poi riappare... dov'è che sbaglio??

grazie per la disponibilità!

#include <Adafruit_BMP085.h>
//configuro sensore di temperatura
Adafruit_BMP085 Sens_Temp;


#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
//definisco la tipologia di display
#define OLED_RESET  0x3C
Adafruit_SSD1306 display(128,64, &Wire,4);


const unsigned char PROGMEM Hot [] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x80, 0x00, 0x00, 0x00, 0x00, 0x03, 0xC0, 0x00, 0x00,
0x00, 0x00, 0x06, 0x60, 0x00, 0x00, 0x00, 0x00, 0x06, 0x60, 0x00, 0x00, 0x00, 0x00, 0x07, 0xF0,
0x00, 0x00, 0x00, 0x00, 0x07, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x07, 0xE0, 0x00, 0x00, 0x00, 0x00,
0x07, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x07, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x07, 0xF0, 0x00, 0x00,
0x00, 0x00, 0x07, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x07, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xF0,
0x00, 0x00, 0x00, 0x00, 0x0F, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xF0, 0x00, 0x00, 0x00, 0x00,
0x0F, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xF0, 0x00, 0x00,
0x00, 0x00, 0x07, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
};



void setup() {
  //inizializzo il display
  if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)){
  while(true);
  }
  delay(1000);
  display.clearDisplay();
//inizializzo sensore T
if (!Sens_Temp.begin()) {
      display.setCursor(0,0);
      display.print("BMP180");
      display.setCursor(0,40);
      display.print("ERRORE");
      display.display();
      while (1) {}
  }
  
}

void loop() {

//imposto font sul display
  display.clearDisplay();  
  display.setTextSize(1);
  display.setTextColor(WHITE);
  display.cp437(true);
//scrivo su display
  display.setCursor(0,0);
  display.print("T=");
  display.setCursor(30,0);
  display.print(Sens_Temp.readTemperature());
  display.setCursor(93,0);
  display.print("C");
  display.display();
//condizione per bitmap
 if(Sens_Temp.readTemperature()>=23)  { 
   display.drawBitmap(40, 20,  Hot, 48, 34, 1);
   display.display(); 
  
  } 
}

Ancorarlo fino a quando la temperatura non scende e non può fare il clearDisplay.

//condizione per bitmap
 if(Sens_Temp.readTemperature()>=23)  { 
   display.drawBitmap(40, 20,  Hot, 48, 34, 1);
   display.display(); 
   while (Sens_Temp.readTemperature()>=23);
  } 

Era quello?. Non so se ti ho capito bene.

Ciao! grazie per avermi dato una risposta :smiley:, proverò a modificare quando torno da lavoro... dato che voglio capire bene quel ciclo while dentro all'if come si traduce in parole semplici??

Il metodo readTemperature() restituisce un valore in virgola mobile (float).

// dalla documentazione online
float readTemperature(void);

Quindi ad esempio 23.01 è maggiore di 23 che è un intero. Tra una lettura e la successiva potresti avere una successione di valori che oscillano, ad esempio: 23.01, 23.00, 22.99, 23.02. Questo è un primo problema che facciamo finta che non ci sia.

L'altro problema invece è quello che una volta stampato il simbolo non ha senso stamparlo continuamente in loop, cioè basta stamparlo una sola volta.

Propongo le due funzioni seguenti:

bool termometroIsShow;   // variabile globale, se vale "true" il simbolo è mostrato, se false il simbolo è cancellato.

void drawTermometro() {
    if (!termometroIsShow) {
        display.drawBitmap(40, 20,  Hot, 48, 34, 1);
        display.display(); 
        termometroIsShow = true;
    }
}

void clearTermometro() {
    if (termometroIsShow) {
        display.drawBitmap(40, 20,  Hot, 48, 34, 0);
        display.display(); 
        termometroIsShow = false;
    }
}

Funzioni da usare nel loop() così:

if (Sens_Temp.readTemperature() >= 23)  { 
    drawTermometro();
} else if (Sens_Temp.readTemperature() <= (23 - 1)) {
    clearTermometro();
}

In questo modo il simbolo compare per temperatura >= 23 °C e scompare
per temperature <= 22.

Cioè c'è 1 grado di isteresi.

Ciao.

L'istruzione while termina quando la condizione non è soddisfatta, ovvero quando il risultato della valutazione è zero o false. Ad esempio l'istruzione:

while (1);

Fermerà il tuo codice su quella riga a tempo indeterminato.
Nella soluzione proposta, l'istruzione while ferma il proprio codice su quella riga, leggendo continuamente il sensore, finché la temperatura non scende sotto i 23, evitando di uscire dall'"if". In questo modo il loop non viene riavviato e lo schermo non viene cancellato.

Ciao @Maurotec e @gonpezzi , ho risolto togliendo l'if e mettendo un while in questo modo:

 while(Sens_Temp.readTemperature()>=23){ 
     display.clearDisplay();
     display.drawBitmap(40, 20,  Hot, 48, 34, 1);
     display.setCursor(0,0);
     display.print("T=");
     display.setCursor(30,0);
     display.print(Sens_Temp.readTemperature());
     display.setCursor(93,0);
     display.print("C");     
     display.display();       
  }

credo non sia molto corretto dal punto di vista del codice ma adesso quando la T supera i gradi prefissati appare la bitmap costantemente quando torna sotto la soglia scompare !! :smile:

Ha poco senso cancellare e riscrive le stesse cose sul display. Inoltre così il programma non può fare altre operazioni durante il while. Ma se sta bene a te sta bene pure a me. :smiley:

Ciao.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.