LCD, visualizzare pagine in modo ciclico

Obiettivo:
un display 16x2 che visualizza in successione 3 pagine con dati ambientali.
Al superamento di una soglia visualizza la pagina LCD fuori soglia.

Per il momento sono fermo alla sola successione ciclica delle pagine.

Questo funziona, ma è poco efficiente: (le pagine LCD sono sostituite dal Serial.print)

Serial.println("pagina uno");
delay(2000);

Serial.println("pagina due");
delay(2000);

Serial.println("pagina tre");
delay(2000);

Questa la versione senza delay() che non funziona (ripete solo "pagina uno")

//----------------------------------------------
unsigned long timer;
unsigned long ciclo = 2000;
byte page = 0;

void setup()
{
timer = millis(); 
}


void loop()
{

  if (millis() - timer > ciclo) {
     page ++;  
     if (page>3) page = 1;
    }

switch(page) {
   case 1: {       
   Serial.println("pagina uno");
   timer = millis();
   break;
    }

case 2: {       
   pagina2LCD ();
   Serial.println("pagina due");
   timer=millis();    
   break;
    }

case 3: {       
   Serial.println("pagina tre");
   timer = millis();
   break;
    }
 } 
}
//------------------------------------

E' sbagliato il codice, oppure ho scelto la strada sbagliata?

Ciao dinopaolo in conformità al regolamento, punto 7, devi editare il tuo primo post (quindi NON scrivendo un nuovo post, ma utilizzando il bottone More -> Modify che si trova in basso a destra del tuo post) e racchiudere il codice all'interno dei tag CODE (... sono quelli che in edit inserisce il bottone con icona fatta così: </>, tutto a sinistra).

In pratica, tutto il tuo codice dovrà trovarsi racchiuso tra due tag:

[code] _il _tuo_ codice_ [/code]

così da non venire interpretato e non dare adito alla formazione di caratteri indesiderati. Grazie.

La strada che hai percorso è corretta, vedi sempre e solo pagina1 perché la MCU è molto molto veloce e non avendo mai riassegnato a timer il nuovo valore di millis() ad ogni ciclo entri nell'if e ti sembra di visualizzare solo una pagina mente le scorri tutte troppo velocemente per essere viste.
Più sintetico: dopo che sono trascorsi i primi 2000 mS incrementi sempre la pagina ad ogni ciclo di loop

come impostato nel codice

*case 1: { *

  • Serial.println("pagina uno");*
  • timer = millis();*
  • break;*

il timer è aggiornato nella condizione soddisfatta, ma è come se non venisse letta.

Nota che le pagine le "vedo" nel print del monitor seriale dove non ho il problema della latenza visivo

Non ne sono sicuro ma credo possa essere la sintassi del case prova a fare così:

case 1:
  Serial.println(...
  break;

Togliendo quindi le graffe

Corretto, ho riletto la definizione di "switch" e le graffe non sono necessarie nel singolo "case"

modificato lo sketch ma non cambia niente, continua a stampare solo "pagina uno"

Non ho capito una cosa, vedi pagina 1 a raffica o solo una volta?Prova a fre una cosa elimina tutto ciò che è riferito all'LCD e ad usare solo il serial monitor, cambia qualcosa?

Manca
timer = millis();
quando scatta il tempo nel pezzo a inizio loop

void loop()
{
  if (millis() - timer > ciclo) 
  { timer = millis();         // mancava
    page ++;  
    if (page>3) page = 1;
  }...

Sto usando lo sketch semplificato del mio post iniziale ( no LCD, solo Serial.print)

ho visto che nello sketch c'è refuso dimenticato dal display LCD, mi scuso.

il risultato è una stampa continua e veloce del testo "pagina uno"

nid69ita:
Manca
timer = millis();
quando scatta il tempo nel pezzo a inizio loop

void loop()

{
 if (millis() - timer > ciclo)
 { timer = millis();         // mancava
   page ++;  
   if (page>3) page = 1;
 }...

Ci sono cascato anch'io l'ha messo nel case, anch'io lo aspettavo li anziché nel case ma non dovrebbe fare differenza

dinopaolo:
Sto usando lo sketch semplificato del mio post iniziale ( no LCD, solo Serial.print)

ho visto che nello sketch c'è refuso dimenticato dal display LCD, mi scuso.

il risultato è una stampa continua e veloce del testo "pagina uno"

Metti per favore il codice completo che stai usando, perché dovrebbe funzionare correttamente e invece dal tuo test dici che non funzioona, deve esserci qualcos'altro che non è riportato nel primo post che ti sta facendo non funzionare il tutto

Ecco lo sketch semplificato che sto provando.

Anche spostando "timer=millis()" nella condizione dello switch non modifica il risultato.

Risultato, una stampa molto veloce della sola "pagina uno"

//-------------------------
unsigned long timer;
unsigned long ciclo = 1000;
byte page = 0;
//-------------------------
void setup()
{

  Serial.begin(9600);
  Serial.println("Prova - Cambio Pagina");

  delay(1000);

timer = millis();        // valore iniziale

}

//-------------------------
void loop()
{
  if (millis() - timer > ciclo) {
     page ++;  
     if (page>2) page = 1;
     timer = millis();
    }

switch(page) {
   case 1: {      
   Serial.println("pagina uno");
//   timer = millis();
   break;
    }

case 2: {      
    Serial.println("pagina due");
//   timer=millis();    
   break;
    }
 }
}

L'unica cosa che mi viene in mente è questa:

page ++;

Cambialo in

page++;

o meglio ancora

if (millis() - timer > ciclo)
{
   page++;
   Serial.print("Timer - nuova pagina");
   Serial.println(page);
   if (page>2)
   {
      page = 1;
      Serial.print("Timer - torno a pagina 1");
   }
   timer = millis();
}

Proverei anche

  1. a togliere le graffe nei case (non servono)
  2. cambia anche page e timer con nomi diversi, non si sa mai siano parole riservate (magari segnalate in warning ma solo se metti il verbose alla compilazione)

Questa la versione funzionante

unsigned long timer;
unsigned long ciclo = 1400;
byte page = 1;


//================================================
// SETUP
//================================================
void setup() {
  
  Serial.begin(9600);
  Serial.println("Prova - Cambio Pagina");

  delay(1000);

  timer = millis();
}

//================================================
// MAIN LOOP
//================================================
void loop() {

  if (millis() - timer > ciclo)
   {
   Serial.print("nuova pagina - ");
   Serial.println(page);
   timer = millis();
   page++;
      if (page>3) page = 1;
   }
}

con questo risultato:
Prova - Cambio Pagina
nuova pagina - 1
nuova pagina - 2
nuova pagina - 3
nuova pagina - 1
nuova pagina - 2
nuova pagina - 3
etc...con intervallo come dal valore di "ciclo"

adesso vedo di trasferire il tutto nello sketch del display LCD

Cosa hai cambiato ? Parrebbe aver risolto il page++ senza lo spazio ? :o

no, ha messo timer=millis() nel primo if come è giusto che sia :smiley:

ho verificato .... page funziona con o senza spazi e lo switch case funziona anche con le graffe nei case, potenza del compilatore che aggiusta tutto lui :wink:

Bene, grazie a tutti.

Abbiamo risolto il problema del ritardo ciclico della stampa.

Adesso devo sostituire ogni pagina di stampa con paginaLCD1, paginaLCD2

paginaLCD1() e paginaLCD2(), sono due funzioni che al loro interno contengono la formattazione del testo e le variabili da visualizzare.

Ho pensato di memorizzare il nome delle funzioni in un'array e richiamarle in sequenza, ma ho dei dubbi.

Attendo suggerimenti.....

Puoi farlo ma mi pare eccessivo. Quante pagine sono ?

Sono 3 pagine,

Le pagine sono già strutturate, ognuna una funzione.

Il mio problema è come richiamarle dal ciclo di ritardo (vedi post iniziale per descrizione)