Problema Display Nextion e Arduino

Buonasera a tutti, premetto che non sono molto pratico, ho scritto questo codice per comandare due relè mediante due pulsanti tramite display Nextion.
Il tutto funziona, al tocco di un tasto sul display il relè corrispondente si eccita, ed al rilascio si spegne.
A volte però (non sempre) succede che pur togliendo il dito dal Touch del display il relè resta eccitato e non ritorna allo stato di riposo, oppure al contrario, con il dito sul display il relè non si eccita............ Mi lascia pensare che quando i pulsanti non rispondono ai comandi, probabilmente Arduino è impegnato in un altra funzione e quindi non avverte il comando da me impartito in quel momento. Ho commesso sicuramente qualche errore nello sketch ma dove non ho idea.....

#include <Nextion.h>
int swichiusa=0;
int swiaperta=0;
NexButton apre = NexButton(2, 6, "apre");
NexButton chiude = NexButton(2, 4, "chiude");
NexText lbFinecorsa = NexText(2, 5, "t1");
NexText lbFinecorsa2 = NexText(2, 5, "t1");
char buffer[10] = {0};
NexTouch *nex_listen_list[] = {
&chiude, &apre, NULL
};
void setup() {
  Serial.begin(9600);
  pinMode(2, INPUT);
  pinMode(3, INPUT);
  pinMode(11, OUTPUT);
  pinMode(12, OUTPUT);  
  chiude.attachPush(bton, &chiude);
  chiude.attachPop(btoff, &chiude);
  apre.attachPush(bta, &apre);
  apre.attachPop(bts, &apre);
  digitalWrite(11, LOW);
  digitalWrite(12, LOW);
  nexInit();
  
}

unsigned long t1, dt;
void loop() {
  nexLoop(nex_listen_list);
swichiusa=analogRead (2);
swiaperta=analogRead (3);
  dt = millis() - t1;
  if (dt > 800) {
    updateNextion();
    t1 = millis();  
  }
}
void bton(void *ptr) {
  digitalWrite(11, HIGH);   
}
void btoff(void *ptr) {
  digitalWrite(11, LOW);   
}
void bta(void *ptr) {
  digitalWrite(12, HIGH);   
}
void bts(void *ptr) {
  digitalWrite(12, LOW);   
}
void updateNextion() {
  if (digitalRead(2))
    {
    lbFinecorsa.setText("CLOSED");   
  } else { 
    lbFinecorsa.setText("OPEN"); 
  }
  if (digitalRead(3)) {
   lbFinecorsa2.setText("APERTA");
  
  }
     
  }

Nel frattempo cerco di fare altre prove smanettando nel codice:)

Premetto che non uso la libreria per gestire i Nextion ma leggo e scrivo direttamente sulla seriale dedicata, il codice non presenta errori in base a quello che dichiari che deve fare.
Credo che la gestione dei pulsanti lato Nextion/libreria nella modalità in cui li usi tu possa soffrire di qualche problema che scatena il comportamento non desiderato.
Come suggerimento posso solo dirti di provare a cambiare modo di operare, se proprio devi mantenere la funzionalità così com'è ovvero finché premo fai qualcosa allora posso suggerirti di lavorare lato Nextion per gestire direttamente li gli eventi premuto e rilasciato, nel codice Nextion ai due eventi ti setti una variabile che da Arduino leggi continuamente in modo da intercettare i vari cambi stato

Buongiorno Fab, innanzitutto grazie.
Ad essere sincero, non so come procedere al tuo suggerimento in quanto non essendo programmatore ho difficoltà (tipo, settare variabile in Nextion e farla leggere da Arduino, oppure la procedura per far leggere e scrivere dalla seriale). Ad ogni modo, se può essere un indizio, ieri ho provato ad aumentare il valore nella riga: if (dt > 800) portandolo a 1500 e il difetto si presenta sporadicamente rispetto a prima.
Male che và mi accontento cosi, in quanto questo genere di progetto mi serve per fine mese ed è importante per risolvere un problema abbastanza delicato.
Grazie

Se il problema è delicato avere software che "a volte" da problemi a me non farebbe dormire sonni tranquilli.
Se il problema è circoscritto all'aggiornamento del testo sul Nextion, come pare di capire visto che se lo fai meno spesso perdi meno tocchi, allora ti propongo di cambiare metodologia e anche qui invece di aggiornare ogni N millisecondi, aggiorna il display solo quando serve.
Ti memorizzi lo stato dei due ingressi in modo da aggiornare il display solo se questi cambiano, una cosa del tipo:

int vecchioStato = -1;
...
void loop(){
  bool statoAttuale=digitalRead(2);
  if (statoAttuale){
    if(statoAttuale!=vecchioStato){
      lbFinecorsa.setText("CLOSED");
      vecchioStato=statoAttuale;
    }
  }
  else{
     if(statoAttuale!=vecchioStato){
      lbFinecorsa.setText("OPEN");
      vecchioStato=statoAttuale;
    }
  }
}

Togliendo quindi

if (dt > 800) {
    updateNextion();
    t1 = millis();  
  }

Per pulizia di codice puoi anche pensare di fare i controlli dentro la tua funzione che richiami sempre dal loop:

void loop(){
  ...
  updateNextion();
}

void updateNextion(){
  bool statoAttuale=digitalRead(2);
  if (statoAttuale){
    if(statoAttuale!=vecchioStato){
      lbFinecorsa.setText("CLOSED");
      vecchioStato=statoAttuale;
    }
  }
  else{
     if(statoAttuale!=vecchioStato){
      lbFinecorsa.setText("OPEN");
      vecchioStato=statoAttuale;
    }
  }
}

Il codice che ho scritto potrebbe essere ottimizzato, ma ho preferito scriverlo così visto che dici di non essere esperto in modo che sia meno ottimizzato ma più facilmente leggibile

Ok Fab, stasera appena rientro faccio un po di prove e ti aggiorno, sei stato molto prezioso.
Grazie

Buonasera Fab, fatto le prove, i pulsanti funzionano bene, nessun fallimento, perfetto.
Ho dovuto aggiungere il secondo finecorsa che mancava nella parte di codice, e fin qui tutto ok.
Quindi diciamo che funziona tutto tranne che quando alimento il circuito, non legge lo stato dei finecorsa.
Per conoscere lo stato devo chiudere i contatti di un finecorsa qualsiasi, e da quel momento legge ogni variazione di stato dei finecorsa....`

#include <Nextion.h>
int swichiusa = 0;
int swiaperta = 0;
int vecchioStato = -1;
int secondoStato = -1;
NexButton apre = NexButton(2, 5, "apre");
NexButton chiude = NexButton(2, 3, "chiude");
NexText lbFinecorsa = NexText(2, 4, "t1");
NexText lbFinecorsa2 = NexText(2, 4, "t1");
char buffer[10] = { 0 };
NexTouch *nex_listen_list[] = {
  &chiude, &apre, NULL
};
void setup() {
  Serial.begin(9600);
  pinMode(2, INPUT);
  pinMode(3, INPUT);
  pinMode(11, OUTPUT);
  pinMode(12, OUTPUT);
  chiude.attachPush(bton, &chiude);
  chiude.attachPop(btoff, &chiude);
  apre.attachPush(bta, &apre);
  apre.attachPop(bts, &apre);
  digitalWrite(11, HIGH);
  digitalWrite(12, HIGH);
  nexInit();
}

unsigned long t1, dt;
void loop() {
  nexLoop(nex_listen_list);
  swichiusa = analogRead(2);
  swiaperta = analogRead(3);
  dt = millis() - t1;
  //if (dt > 3000) {
  updateNextion();
  //t1 = millis();
 // }
}
void bton(void *ptr) {
  digitalWrite(11, LOW);
}
void btoff(void *ptr) {
  digitalWrite(11, HIGH);
}
void bta(void *ptr) {
  digitalWrite(12, LOW);
}
void bts(void *ptr) {
  digitalWrite(12, HIGH);
}

void updateNextion(){
  bool statoAttuale=digitalRead(2);
  bool statoFinale=digitalRead(3);
  if (statoAttuale){
    if(statoAttuale!=vecchioStato){
      lbFinecorsa.setText("CLOSED");
      vecchioStato=statoAttuale;
    }
  }
  else{
     if(statoAttuale!=vecchioStato){
      lbFinecorsa.setText("OPEN");
      vecchioStato=statoAttuale;
    }
    
    if(statoFinale!=secondoStato){
      lbFinecorsa2.setText("APERTA");
      secondoStato=statoFinale;
    }  
  }
}



`

Non mi è chiaro cosa intendi con "non legge lo stato del fine corsa" se intendi che la digitalRead fallisce mi sembra veramente strano e ti direi che ci sono problemi di software da debuggare per essere capiti.
Se invece intendi che lo stato del display non corrisponde allo stato dei fine corsa allora non ti resta che implementare un "allineamento" del display nel setup dopo l'inizializzazione del Nextion leggendo gli stati e "informando" il display della reale situazione di partenza

Si, è la seconda ipotesi.
Mi spiego meglio:

  • alimento la scheda con i contatti del fine corsa chiusi e sul display non appare la scritta "CLOSE"
    A questo punto mi basta aprire i contatti di uno dei finecorsa, e immediatamente inizia ad apparire lo stato sul display (OPEN, CLOSE ecc ecc.).
    Quindi penso che bisogna implementare un allineamento del display all'avvio........

Ciao Fab, dopo 8 ore ho risolto:)
Dunque il problema era nell'IDE Nextion.
Per evitare che cambiando pagina perdi lo stato dello switch, è necessario attivare la casella "Global" nella lista degli attributi della casella di testo alla voce "VSCOPE", e non "LOCAL" come avevo fatto precedentemente.
In questo modo anche se cambi pagina, quando ritorni alla pagina dove è presente la casella di testo che indica lo stato dello switch quest'ultima resta invariata indicando lo stato reale del finecorsa.
Ad ogni modo ti ringrazio moltissimo per la pazienza e la comprensione.
Buon wend

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