Visualizzazione orario senza secondi e problema con scritta che "lampeggia"

Ciao a tutti, eccomi ad esporvi la mia situazione e relativi problemi (sono due e mezzo).

Con un Nano, un DS1302 ed un Oled I2c 2,3" 128x64, vorrei poter visualizzare l'orario e la temperatura di un termistore; utilizzo le librerie Adafruit per il display e la DS1302 per il relativo RTC.
Tramite il sito image2cpp ho inserito due icone nella visualizzazione, ho poi importato l'orario e la lettura del termistore (per ora per comodità è un semplice potenziometro) e fin qui tutto bene, o quasi.

Cominciamo dal "mezzo" problema: ho costruito un rettangolo nero per pulire l'area dove viene visualizzato il potenziometro; ho fatto ciò per far sì che i caratteri sul display si puliscano e non si sovrascrivano lasciando accesi tutti i pixel. Ho fatto in modo corretto oppure c'è un metodo più veloce e semplice?

Passiamo al primo problema quindi. Il valore letto del potenziometro, lampeggia. Perchè?
Ho inserito un "if - else" su due soglie per far apparire un relativo messaggio quando vengono attivate ed in questa situazione accade che il messaggio (molto banalmente "LOW" e "WARNING") si alterna al valore. Questa ultima cosa mi va bene, anzi, è proprio come lo volevo, ma quando il valore è compreso tra if ed else vorrei visualizzare il valore senza che questo lampeggi.

Secondo problema: è possibile in qualche modo visualizzare l'orario senza i secondi, quindi solo con ore e minuti? Ho provato a modificare la libreria, ma ovviamente quando vado poi a compilare mi si presentano mille errori. Specifico che io richiamo solo l'orario, lasciando stare data e giorno della settimana.

Di seguito allego il codice:

#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <DS1302.h>

// definizioni per display

#define SSD1306_128_64
#define OLED_RESET 4
DS1302 rtc(7, 6, 5);      //inizializza il DS1302 e definisce (in ordine) pin di RST, DAT, CLK

Adafruit_SSD1306 display(OLED_RESET);

//PIN A4 = SDA
//PIN A5 = SCL

#if (SSD1306_LCDHEIGHT != 64)
#endif

// 'IconaOrologio_30_BMP', 30x30px
const unsigned char epd_bitmap_IconaOrologio_30_BMP [] PROGMEM = {
  0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x03, 0x00, 0x00, 0x3e, 0x1f, 0x00, 0x80, 0x03, 0x70, 0x00, 
  0xc0, 0x00, 0xc0, 0x00, 0x60, 0xc0, 0x80, 0x01, 0x30, 0xc0, 0x00, 0x03, 0x18, 0xc0, 0x00, 0x06, 
  0x08, 0xc0, 0x00, 0x04, 0x0c, 0xc0, 0x00, 0x0c, 0x04, 0xc0, 0x00, 0x08, 0x04, 0xc0, 0x00, 0x08, 
  0x06, 0xc0, 0x00, 0x18, 0x06, 0xc0, 0x00, 0x18, 0x02, 0xe0, 0x01, 0x10, 0x02, 0xe0, 0x01, 0x10, 
  0x06, 0xe0, 0x00, 0x18, 0x06, 0x10, 0x00, 0x18, 0x04, 0x08, 0x00, 0x08, 0x04, 0x04, 0x00, 0x08, 
  0x0c, 0x00, 0x00, 0x0c, 0x08, 0x00, 0x00, 0x04, 0x18, 0x00, 0x00, 0x06, 0x30, 0x00, 0x00, 0x03, 
  0x60, 0x00, 0x80, 0x01, 0xc0, 0x00, 0xc0, 0x00, 0x80, 0x03, 0x70, 0x00, 0x00, 0x3e, 0x1f, 0x00, 
  0x00, 0xf0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00
};

// 'icons8-liquido-di-raffreddamento-motore-30_BMP', 30x30px
const unsigned char epd_bitmap_icons8_liquido_di_raffreddamento_motore_30_BMP [] PROGMEM = {
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 
  0x00, 0xc0, 0x00, 0x00, 0x00, 0xc0, 0x07, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 
  0x00, 0xc0, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, 0xc0, 0x07, 0x00, 0x00, 0xc0, 0x00, 0x00, 
  0x00, 0xc0, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, 0xc0, 0x07, 0x00, 0x00, 0xc0, 0x07, 0x00, 
  0x00, 0xc0, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, 0xe0, 0x01, 0x00, 0x00, 0x30, 0x03, 0x00, 
  0x00, 0x10, 0x02, 0x00, 0xee, 0x19, 0xe6, 0x1d, 0x38, 0x11, 0x22, 0x07, 0x00, 0x30, 0x03, 0x00, 
  0x00, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x3e, 0xbf, 0x03, 
  0xc0, 0xe3, 0xf1, 0x00, 0x00, 0x00, 0x00, 0x00
};

// definizioni per temperatura

int SensoreT;
float TempOlio;

void setup()   {       

  display.begin(SSD1306_SWITCHCAPVCC, 0x3C);  //Inizializza il display e imposta l'indirizzo I2c

     //RTC
     
  Serial.begin(9600);                         // attiva la seriale
  rtc.halt(false);                            // avvia l'orologio
  rtc.writeProtect(false);                    // Disabilita la protezione alla scrittura
  rtc.setTime(15, 45, 0);                     // set orario (24H)
    
  
     //visualizza icone

  display.clearDisplay();                                                                                  //Pulisce il display
  display.drawXBitmap(10, 0,  epd_bitmap_IconaOrologio_30_BMP, 30, 30, WHITE);                             // Display icona orologio
  display.drawXBitmap(10, 32, epd_bitmap_icons8_liquido_di_raffreddamento_motore_30_BMP, 30, 30, WHITE);   //display icona temperatura liquido 

}


void loop() {                         
  
  Serial.println(rtc.getTimeStr());             //invia orario
  display.fillRect(65, 10, 128, 64, BLACK);    //creo rettangolo per "pulire" area scrittura orario
  display.setTextSize(2);                       //Imposto la grandezza del testo
  display.setTextColor(WHITE);                  //Imposto il colore del testo
  display.setCursor(65, 10);                    //Imposto la posizione della scritta
  display.println(rtc.getTimeStr());            //Visualizza orario
  display.display();                            //Invia al display

  int SensoreT = analogRead(A7);                //leggo il valore dal sensore

   float TempOlio = SensoreT * (5.0 / 1023.0);  // Converte l'AI letto (da 0 - a 1023bit) in volt (0 - 5V)
   display.fillRect(60, 32, 128, 64, BLACK);    //creo rettangolo per "pulire" area scrittura T olio
   display.setTextSize(2);                      //Imposto la grandezza del testo
   display.setTextColor(WHITE);                 //Imposto il colore del testo
   display.setCursor(65, 40);                   //Imposto la posizione del cursore
   display.println(TempOlio);                   //visualizza T olio
   display.display();                           //Invia T olio al display
   
  if (TempOlio < 1.0) {                            //SE T olio minore di 1 fai comparire scritta LOW
    display.fillRect(60, 32, 128, 64, BLACK);   //creo rettangolo per "pulire" area scrittura T olio
    display.setTextSize(2);                     //Imposto la grandezza del testo
    display.setTextColor(WHITE);                //Imposto il colore del testo
    display.setCursor(70, 40);                  //Imposto la posizione del cursore
    display.println("LOW");                     //visualizza messaggio
    display.display();                          //Invia il messaggio al display
    
  } else if (TempOlio >= 4.0) {                    //SE T olio uguale/maggiore di 4 fai comparire scritta WARNING
    display.fillRect(60, 32, 128, 64, BLACK);   //creo rettangolo per "pulire" area scrittura T olio
    display.setTextSize(1);                     //Imposto la grandezza del testo
    display.setTextColor(WHITE);                //Imposto il colore del testo
    display.setCursor(70, 45);                  //Imposto la posizione del cursore
    display.println("WARNING");                 //visualizza messaggio
    display.display();                          //Invia il messaggio al display
  }
}

Spero di aver scritto tutto e scusate la lungaggine.
Resto in attesa, fiducioso e abbiate pietà se ho scritto delle cavolate

Non bisogna cancellare e riscrivere ad ogni ciclo di loop, ma solo quando il valore da visualizzare cambia.

La cancellazione con fillrect va bene, se si deve aggiornare solo una parte credo non ci sia altra scelta.

Quindi dovrei togliere la lettura del potenziometro, dal loop?

E per togliere i secondi dall'orario, suggerimenti?

Per il lampeggio ho risolto così:

Serial.println(rtc.getTimeStr());             //invia orario
  display.fillRect(65, 10, 128, 64, BLACK);    //creo rettangolo per "pulire" area scrittura orario
  display.setTextSize(2);                       //Imposto la grandezza del testo
  display.setTextColor(WHITE);                  //Imposto il colore del testo
  display.setCursor(65, 10);                    //Imposto la posizione della scritta
  display.println(rtc.getTimeStr());            //Visualizza orario
  //display.display();                            //Invia al display

sostanzialmente non invio al display l'orario, lo stampo e basta.

Rimane il problema di eliminare i secondi.
Nessuna idea o suggerimento?

Come detto avevo provato a modificare la libreira DS1302.h , ma senza risultato.

Scusa QUALE libreria DS1302 stai usando (metti un link)? Perché ne esistono parecchie, ciascuna con i suoi metodi ... :roll_eyes:

Guglielmo

Il link da dove ho scaricato la libreria è questo:

http://www.rinkydinkelectronics.com/library.php?id=5

Le librerie di Rinky-Dink Electronics sono sempre fatte molto bene e ben documentate ...
... ti sei studiato i sorgenti e/o la documentazione della libreria?

Perché, se lo avessi fatto, avresti già trovato la soluzione da tempo :roll_eyes: ... la funzione che usi è così definita:

char *getTimeStr(uint8_t format=FORMAT_LONG);

... non ti è venuto il dubbio e/o la curiosità di capire cosa è quel parametro 'format' che la funzione accetta ed il cui valore di default è FORMAT_LONG ?

Vediamo se trovi da solo la soluzione ...

Guglielmo

1 Like

Ammetto di non aver letto la guida, ma di essermi incaponito cercando la soluzione nella libreria e non avendo dimestichezza, mi son perso letteralmente in un bicchier d'acqua.

Leggendo la guida si capisce molto facilmente che basta modificare la libreria e cambiare così la riga dedicata all'orario:

char	*getTimeStr(uint8_t format=FORMAT_SHORT);

Grazie!

Ora sto smanettando un po' per ampliare questo mio progetto, voglio provare a fare "di testa mia" e prossimamente ritornerò qui (con una nuova discussione) per chiedere pareri su COME ho scritto il codice, sperando funzioni tutto.

Non serve modificare la libreria, ma basta chiamare la funzione così:

display.println(rtc.getTimeStr(FORMAT_SHORT)); 

Ciao.

Per cancellare le scritte precedenti, basta tenerle da parte e riscriverle in nero un attimo prima di quelle nuove.

L'ho fatto qui:

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