FUNZIONE IF RIPETUTO E SCRITTURA DISPLAY

Ciao a tutti :) volevo chiedere un consiglio per un mio primo programma, devo leggere lo stato di sensori per un antifurto, ho fatto ripetuti IF, che poi vanno a scrivere il sensore su un display; vi chiedo se c'è un modo semplice per non far scrivere ciclicamente sul display, ma fargli scrivere una sola volta al cambio di stato del sensore (tutto ciò per alleggerire il programma penso). A me l'unica idea venuta è quella di settare dei bit una volta scritto e andarli ad azzerare al cambio di stato del sensore, ripetuto per i 2 stati del sensore e per tutti i sensori... spero in qualcosa di più semplice :) Vi allego solo quella parte di programma. Grazie a tutti

void loop() 
{
  bacaest = digitalRead(BAR_CANC_EST);    //leggo gli ingressi digitali e li memorizzo
  bacaint = digitalRead(BAR_CANC_INT);    //nelle rispettive variabili booleane
  bacap = digitalRead(BAR_CAPANN);
  sencor = digitalRead(SENS_CORT);
  cancap = digitalRead(CANC_APERTO);
  portaap = digitalRead(PORTA_APERTA);
  capap = digitalRead(CAPANN_APERTO);
  
  myGLCD.setBackColor(0, 140, 0);          //colore sfondo scritta verdino
  myGLCD.setColor(255,255,255);            //colore scritta
  
  if(bacaest==0) myGLCD.print("BARRIERA CANCELLO, ESTERNA", CENTER, 40); //controllo l'ingresso e lo
  else myGLCD.print("                          ", CENTER, 40);           //scrivo nel display

  if(bacaint==0) myGLCD.print("BARRIERA CANCELLO, INTERNA", CENTER, 60);
  else myGLCD.print("                          ", CENTER, 60);
  
  if(bacap==0) myGLCD.print("BARRIERA CAPANNONE", CENTER, 80);
  else myGLCD.print("                  ", CENTER, 80);
  
  if(sencor==0) myGLCD.print("SENSORE CORTILE", CENTER, 100);
  else myGLCD.print("               ", CENTER, 100);
  
  if(cancap==0) myGLCD.print("CANCELLO APERTO", CENTER, 120);
  else myGLCD.print("               ", CENTER, 120);
  
  if(portaap==0) myGLCD.print("PORTA APERTA", CENTER, 140);
  else myGLCD.print("            ", CENTER, 140);
  
  if(capap==0) myGLCD.print("PORTONE CAPANNONE APERTO", CENTER, 160);
  else myGLCD.print("                        ", CENTER, 160);

A me l'unica idea venuta è quella di settare dei bit una volta scritto e andarli ad azzerare al cambio di stato del sensore, ripetuto per i 2 stati del sensore e per tutti i sensori... spero in qualcosa di più semplice

No, non c'é niente di piú semplice. Ciao Uwe

uwefed: No, non c'é niente di piú semplice. Ciao Uwe

Capisco, allora mi metto all'opera Grazie

Forse così è più chiaro:

  if (bacaest == 0) myGLCD.print("BARRIERA CANCELLO, ESTERNA", CENTER, 40); //controllo l'ingresso e lo
  else if (bacaint == 0) myGLCD.print("BARRIERA CANCELLO, INTERNA", CENTER, 60);
  else if (bacap == 0) myGLCD.print("BARRIERA CAPANNONE", CENTER, 80);
  else if (sencor == 0) myGLCD.print("SENSORE CORTILE", CENTER, 100);
  else if (cancap == 0) myGLCD.print("CANCELLO APERTO", CENTER, 120);
  else if (portaap == 0) myGLCD.print("PORTA APERTA", CENTER, 140);
  else if (capap == 0) myGLCD.print("PORTONE CAPANNONE APERTO", CENTER, 160);
  else myGLCD.print("                          ", CENTER, 160);

Puoi collezionare i 7 boolean in una variabile di tipo byte, poi crei altra variabile di tipo byte e fai in modo che una contenga l’ultimo valore e l’altra il valore precedente computato, in questo modo con if (lastValue != oldValue) puoi aggiornare il display solo quando necessario.

I bit li puoi spingere così:

byte dataBitSensor = 0;
byte oldDataBitSensor = 255; // deve avere un valore univoco non replicabile dal codice seguente 

dataBitSensor = digitalRead(BAR_CANC_EST) ?  dataBitSensor | _BV(0) : dataBitSensor & ~_BV(0);
dataBitSensor = digitalRead(BAR_CANC_INT) ? dataBitSensor | _BV(1) : dataBitSensor & ~_BV(1);
dataBitSensor = digitalRead(BAR_CAPANN) ? dataBitSensor | _BV(2) : dataBitSensor & ~_BV(2);


// nella routine di gestione stampa
if (dataBitSensor != oldDataBitSensor) {
   
   // stampa tutto
   oldDataBitSensor = dataBitSensor;   // entrambe le variabili hanno lo stesso valore
}

Ciao.

cyberhs: Forse così è più chiaro:

  if (bacaest == 0) myGLCD.print("BARRIERA CANCELLO, ESTERNA", CENTER, 40); //controllo l'ingresso e lo
  else if (bacaint == 0) myGLCD.print("BARRIERA CANCELLO, INTERNA", CENTER, 60);
  else if (bacap == 0) myGLCD.print("BARRIERA CAPANNONE", CENTER, 80);
  else if (sencor == 0) myGLCD.print("SENSORE CORTILE", CENTER, 100);
  else if (cancap == 0) myGLCD.print("CANCELLO APERTO", CENTER, 120);
  else if (portaap == 0) myGLCD.print("PORTA APERTA", CENTER, 140);
  else if (capap == 0) myGLCD.print("PORTONE CAPANNONE APERTO", CENTER, 160);
  else myGLCD.print("                          ", CENTER, 160);

Ciao, allora, o io non ho capito, o mi pare errato così: l'ultima istruzione che cancella una riga, (a parte dovrebbe cancellarle tutte e non una) ma nel caso, va a cancellare solo se il portone capannone è chiuso, io ho necessità di vedere anche tutti i sensori, ma se uno si ripristina deve cancellarsi solo quello. Quindi o ogni ciclo cancello il display e lo riscrivo se necessario, oppure così mi pare non possa andare. Correggimi se non ho capito. Grazie

MauroTec: Puoi collezionare i 7 boolean in una variabile di tipo byte, poi crei altra variabile di tipo byte e fai in modo che una contenga l'ultimo valore e l'altra il valore precedente computato, in questo modo con if (lastValue != oldValue) puoi aggiornare il display solo quando necessario.

I bit li puoi spingere così:

byte dataBitSensor = 0;
byte oldDataBitSensor = 255; // deve avere un valore univoco non replicabile dal codice seguente 

dataBitSensor = digitalRead(BAR_CANC_EST) ?  dataBitSensor | _BV(0) : dataBitSensor & ~_BV(0); dataBitSensor = digitalRead(BAR_CANC_INT) ? dataBitSensor | _BV(1) : dataBitSensor & ~_BV(1); dataBitSensor = digitalRead(BAR_CAPANN) ? dataBitSensor | _BV(2) : dataBitSensor & ~_BV(2);

// nella routine di gestione stampa if (dataBitSensor != oldDataBitSensor) {  
  // stampa tutto   oldDataBitSensor = dataBitSensor;  // entrambe le variabili hanno lo stesso valore }




Ciao.

Ciao Mauro, questo per me è molto complicato, non ci ho capito nulla :o vedrò con calma di studiarmelo, per capire cosa dici di fare :) Grazie mille

Hai ragione, non mi ero accorto che scrivi su righe diverse.

Ciao Mauro,
questo per me è molto complicato, non ci ho capito nulla :o vedrò con calma di studiarmelo, per capire cosa dici di fare :slight_smile:
Grazie mille

Purtroppo ho frainteso, io pensavo volessi aggiornare il display solo quando “necessario”.
“necessario” significa che stampa solo quando i dati da stampare sono diversi da quelli già stampati.

Ora vedendo il codice ti posso dire che se tutti gli ingressi valgono 1 il tuo codice pulisce il display ripetutamente, anche se il display è già pulito.

Prova un po questo codice:

byte dataBitSensor = 0;
byte oldDataBitSensor = 255; // deve avere un valore univoco non replicabile dal codice seguente 

void updateDisplay() {
  myGLCD.setBackColor(0, 140, 0);          //colore sfondo scritta verdino
  myGLCD.setColor(255,255,255);            //colore scritta
 
  if(bacaest==0) myGLCD.print("BARRIERA CANCELLO, ESTERNA", CENTER, 40); //controllo l'ingresso e lo
  else myGLCD.print("                          ", CENTER, 40);           //scrivo nel display

  if(bacaint==0) myGLCD.print("BARRIERA CANCELLO, INTERNA", CENTER, 60);
  else myGLCD.print("                          ", CENTER, 60);
 
  if(bacap==0) myGLCD.print("BARRIERA CAPANNONE", CENTER, 80);
  else myGLCD.print("                  ", CENTER, 80);
 
  if(sencor==0) myGLCD.print("SENSORE CORTILE", CENTER, 100);
  else myGLCD.print("               ", CENTER, 100);
 
  if(cancap==0) myGLCD.print("CANCELLO APERTO", CENTER, 120);
  else myGLCD.print("               ", CENTER, 120);
 
  if(portaap==0) myGLCD.print("PORTA APERTA", CENTER, 140);
  else myGLCD.print("            ", CENTER, 140);
 
  if(capap==0) myGLCD.print("PORTONE CAPANNONE APERTO", CENTER, 160);
  else myGLCD.print("                        ", CENTER, 160);

}

void loop()
{
  bacaest = digitalRead(BAR_CANC_EST);    //leggo gli ingressi digitali e li memorizzo
  bacaint = digitalRead(BAR_CANC_INT);    //nelle rispettive variabili booleane
  bacap = digitalRead(BAR_CAPANN);
  sencor = digitalRead(SENS_CORT);
  cancap = digitalRead(CANC_APERTO);
  portaap = digitalRead(PORTA_APERTA);
  capap = digitalRead(CAPANN_APERTO);
 
  dataBitSensor = bacaest ?  dataBitSensor | _BV(0) : dataBitSensor & ~_BV(0); //  bit 0
  dataBitSensor = bacaint ? dataBitSensor | _BV(1) : dataBitSensor & ~_BV(1);  //   bit 1 
  dataBitSensor = bacap ? dataBitSensor | _BV(2) : dataBitSensor & ~_BV(2);    //   bit 2
  dataBitSensor = sencor ? dataBitSensor | _BV(3) : dataBitSensor & ~_BV(3);   //   bit 3
  dataBitSensor = cancap ? dataBitSensor | _BV(4) : dataBitSensor & ~_BV(4);  //   bit 4 
  dataBitSensor = portaap ? dataBitSensor | _BV(5) : dataBitSensor & ~_BV(5);  //  bit 5
  dataBitSensor = capap ? dataBitSensor | _BV(6) : dataBitSensor & ~_BV(6);    //   bit 6

  // nella routine di gestione stampa
  if (dataBitSensor != oldDataBitSensor) {
     updateDisplay(); // chiama la funzione updateDisplay() perché dataBitSensor è diverso rispetto alla vecchia versione
                               // contenuta in oldDataBitSensor
     dataBitSensor = oldDataBitSensor; // dopo avere stampato vecchio e nuovo hanno lo stesso valore   
  } 
} // end loop()

Se non ho dimenticato quale << ; { ( ecc >> dovrebbe compilare e chiamare displayUpdate() solo quando serve.

Ciao.

MauroTec:
Purtroppo ho frainteso, io pensavo volessi aggiornare il display solo quando “necessario”.
“necessario” significa che stampa solo quando i dati da stampare sono diversi da quelli già stampati.

Ora vedendo il codice ti posso dire che se tutti gli ingressi valgono 1 il tuo codice pulisce il display ripetutamente, anche se il display è già pulito.

Prova un po questo codice:

byte dataBitSensor = 0;

byte oldDataBitSensor = 255; // deve avere un valore univoco non replicabile dal codice seguente

void updateDisplay() {
  myGLCD.setBackColor(0, 140, 0);          //colore sfondo scritta verdino
  myGLCD.setColor(255,255,255);            //colore scritta

if(bacaest==0) myGLCD.print(“BARRIERA CANCELLO, ESTERNA”, CENTER, 40); //controllo l’ingresso e lo
  else myGLCD.print("                          ", CENTER, 40);          //scrivo nel display

if(bacaint==0) myGLCD.print(“BARRIERA CANCELLO, INTERNA”, CENTER, 60);
  else myGLCD.print("                          ", CENTER, 60);

if(bacap==0) myGLCD.print(“BARRIERA CAPANNONE”, CENTER, 80);
  else myGLCD.print("                  ", CENTER, 80);

if(sencor==0) myGLCD.print(“SENSORE CORTILE”, CENTER, 100);
  else myGLCD.print("              ", CENTER, 100);

if(cancap==0) myGLCD.print(“CANCELLO APERTO”, CENTER, 120);
  else myGLCD.print("              ", CENTER, 120);

if(portaap==0) myGLCD.print(“PORTA APERTA”, CENTER, 140);
  else myGLCD.print("            ", CENTER, 140);

if(capap==0) myGLCD.print(“PORTONE CAPANNONE APERTO”, CENTER, 160);
  else myGLCD.print("                        ", CENTER, 160);

}

void loop()
{
  bacaest = digitalRead(BAR_CANC_EST);    //leggo gli ingressi digitali e li memorizzo
  bacaint = digitalRead(BAR_CANC_INT);    //nelle rispettive variabili booleane
  bacap = digitalRead(BAR_CAPANN);
  sencor = digitalRead(SENS_CORT);
  cancap = digitalRead(CANC_APERTO);
  portaap = digitalRead(PORTA_APERTA);
  capap = digitalRead(CAPANN_APERTO);

dataBitSensor = bacaest ?  dataBitSensor | _BV(0) : dataBitSensor & ~_BV(0); //  bit 0
  dataBitSensor = bacaint ? dataBitSensor | _BV(1) : dataBitSensor & ~_BV(1);  //  bit 1
  dataBitSensor = bacap ? dataBitSensor | _BV(2) : dataBitSensor & ~_BV(2);    //  bit 2
  dataBitSensor = sencor ? dataBitSensor | _BV(3) : dataBitSensor & ~_BV(3);  //  bit 3
  dataBitSensor = cancap ? dataBitSensor | _BV(4) : dataBitSensor & ~_BV(4);  //  bit 4
  dataBitSensor = portaap ? dataBitSensor | _BV(5) : dataBitSensor & ~_BV(5);  //  bit 5
  dataBitSensor = capap ? dataBitSensor | _BV(6) : dataBitSensor & ~_BV(6);    //  bit 6

// nella routine di gestione stampa
  if (dataBitSensor != oldDataBitSensor) {
    updateDisplay(); // chiama la funzione updateDisplay() perché dataBitSensor è diverso rispetto alla vecchia versione
                              // contenuta in oldDataBitSensor
    dataBitSensor = oldDataBitSensor; // dopo avere stampato vecchio e nuovo hanno lo stesso valore 
  }
} // end loop()




Se non ho dimenticato quale << ; { ( ecc >> dovrebbe compilare e chiamare displayUpdate() solo quando serve.

Ciao.

Ciao, forse ho capito cosa dici di fare, si, è quello che volevo, aggiornare il display solo se cambia uno stato…
Mi metto con calma a provarlo appena posso e ti faccio sapere :wink: mille grazie
ciao ciao