Nextion display disabilitare un button da codice

Perdonatemi.
Esiste un modo per disabilitare/abilitare un bottone creato su un display NEXTION via software dallo sketch di arduino?
Cioe vorrei inibire un bottone quando questo non deve essere premuto.
Ho letto in rete (documentazione neotion)che si puo con tsw, ma penso si possa utilizzare nel codice del display..............
Grazie

Da libreria non puoi, ma essendo che il nextion accetta i comandi da seriale puoi fare una cosa del tipo:

char cmdToSend[8] = "tsw 5,0";
displaySerial.print(cmdToSend);
displaySerial.write(0xFF);
displaySerial.write(0xFF);
displaySerial.write(0xFF);

Dove displaySerial lo devi sostituire non la seriale dove hai collegato il Nextion (Serial1, SoftwareSerial, ecc.) e il primo parametro di tsw (5 nell'esempio) con l'id dell'oggetto da disattivare

Funziona!
ho imparato un'altra cosa veramente utile!!
Grazie infinite!!

Avrei bisogno di un consiglio.
Vorrei interrompere un ciclo Do-While attivato da un pulsante su display neotion, alla pressione successiva dello stesso pulsante. in pratica attiva un countdown, e lo vorrei interrompere con lo stesso pulsante. pensereri di farlo con un ciclo IF, ma non capisco come intercettare l'eventi di pressione successiva........Grazie in anticipo. Posto il codice della VOID di chiamata.

void b4PopCallback(void *ptr)
{
countDown=60;
digitalWrite (pintimeoutcasa, HIGH);

do {
      countDown--;
int mins = countDown / 60;
int secs = countDown % 60;
char bufferx [4];
char buffery [4];
sprintf(bufferx, "%00d%02d", mins, secs);
g_numberToDisplay4 = (atoi(bufferx));
sprintf(buffery, "%00d:%02d", mins, secs);
b4.setText(buffery);
      TO();
      delay(interval);

      }
      while (0<countDown);
char cmdToSend[8] = "tsw 5,0";
Serial2.print(cmdToSend);
Serial2.write(0xFF);
Serial2.write(0xFF);
Serial2.write(0xFF);
     countDown=421;  
     TO();
     b4.setText("-");  
    
}

In conformità al regolamento, punto 7, devi editare il tuo 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).

nel frattempo penso alla risposta :slight_smile:

Qualche idea??
Ne sto uscendo pazzo...

Ti consiglio di cambiare proprio approccio alla cosa, ovvero le callback degli elementi del display le devi vedere come una funzione che viene richiamata allo scatenarsi di un evento generato da un utente (click sul pulsante ad esempio), dentro questa non prevedere cicli o funzionalità che quasi sicuramente ti daranno fastidio (come in questo caso) perché mente sei bloccato dentro il ciclo non hai modo di fare altro, in questo caso specifico non fai più il polling degli eventi del display (ma anche altro).
Per quanto possibile le cose ripetitive falle nel loop (o in funzioni richiamate dentro di esso) in modo tale che non siano bloccanti (a meno che non lo debbano essere in modo specifico) ovvero sfruttando la funzione millis() e non il delay e delle variabili di controllo che dicano al programma se deve o meno eseguire qualcosa.
Chiarisco meglio con un esempio in pseudo codice:

void b4PopCallback(void *ptr)
{
  if(bCountDownAvviato)
  {
    bCountDownAvviato = false;
	ripristina_condizioni_varie
	spegni_led;
	ecc.
	ecc.
  }
  else
  {
    countDown=60;
    digitalWrite (pintimeoutcasa, HIGH);
    bCountDownAvviato = true;
    tempo_trascorso = millis() - intervallo_aggiornamento;
  }
	
}

void loop()
{
  if(bCountDownAvviato e tempo_trascorso>intervallo_aggiornamento)
  {
     scrivi sul display
	 aggiorna_tempo_ultima_esecuzione
	 accendi_led
	 ecc.
	 ecc.
	 if(countDownArrivatoAllaFine)
	 {
	   bCountDownAvviato = false;
	   scoppia_bomba
	   spegni_led
	   ecc.
	   ecc.
	 }
  }
  fai_altro
  altro_ancora
  leggi_display();
}

in questo modo non blocchi nulla, continui a sentire gli eventi del display e sei libero di fare altre cose mentre il countdown sta andando.
Se non hai mai usato millis per capire le basi con cui si usa millis() consiglio prima la lettura di QUESTO post esplicativo, dopo di che lo studio di come si usa la funzione millis(), prima QUI, poi QUI e QUI e QUI e tutti gli articoli che sono in QUESTA pagina ... alla fine il tutto dovrebbe essere più chiaro :slight_smile:

Chiaro Grazie.

ciao FABPOLLI perdonami
ho scritto questa cosa come da te suggerito

char cmdToSend[8] = "tsw 6,0";
 Serial2.print(cmdToSend);
 Serial2.write(0xFF);
 Serial2.write(0xFF);
 Serial2.write(0xFF);

Ma mi funziona solo se la inserisco in un void di evento di un button.
In altri void richiamati non funziona e si resetta arduino............

Dove sbaglio?

Dove sbagli è difficile dirlo senza il programma in quanto le istruzioni che usi si limitano a sparare una manciata di caratteri sulla serial2 quindi non dovrebbero portare al blocco di Arduino, soprattutto se non hai impostato il watchdog.
Posta tutto e dettaglia qual'è la parte che funziona e quale no.
Una piccola richiesta non chiamarle void si chiamano funzioni o metodi se fosse un oggetto (se fossimo in programmazione ad oggetti) void è il tipo restituito della funzione che in questo caso è void cioè niente/nessun valore restituito

ok provo a postare il codice.

Quando premo il button b4 o b5 che ad ogni pressione cambiano di stato, dopo essere passato alla funzione azzeratimeoutospiti() o azzeratimeoutcasa() si resetta tutto e tutto riparte da capo.

vorrei che quei pulsanti facessero partire un conto alla rovescia, ma alla stessa nuova pressione azzerassero il conteggio, e quando viene premuto uno dei due, l'altro si disabilitasse al touch, perché non devono partire nello stesso momento.

Un po contorto lo so!
Grazie comunque della vostra pazienza.

Segnapunti_shiftregister_millis_2.ino (12 KB)

Analizziamo solo il 5 tanto il 4 è uguale
Se inverti statebutton5 ad ogni pressione al primo giro disabiliti l'altro pulante e metti countdoen a 5 se lo ripremi lo azzeri, tutto ok sembra ma chi reimposta la possibilità di premere l'altro pulsante? non ne ho trovato traccia.
Per il fatto che Arduino si resetta i comandi così come sono messi non dovrebbero centrare nulla, credo che i tuoi problemi siano insiti nella funzione TO() e/o sendSerialData4 et simila.
L'unica cosa che ti posso consigliare di fare è quella di mettere un bel po di output su seriale a scopo di debug per identificare in che punto la procedura resetta Arduino perché credo che giocando su gli array con i puntatori tu possa andare a scrivere in aree di memoria fuori dai limiti degli array e causare il reset.
Nel setup richiami la dbSerialPrintln a che pro?
Per definire le sezioni di debug ti consiglio di fare una cosa del tipo

#include "Nextion.h"
#define DEBUG_MODE

e poi nelle parti dove ti serve

#ifdef DEBUG_MODE
  Serial.println(F("IL_TUO_MESSAGGIO_DI_DEBUG"));
#endif

in questo modo terminato il debug commentando la define tutto il codice di debug sparisce alleggerendo il codice

infatti.
vorrei reimpostare il button al touch in questa funzione scrivendo cosi:

void azzeratimeoutospiti(){
       countDown=0;
       TO();
       b5.setText("-");
  char cmdToSend[8] = "tsw 5,1";
  Serial2.print(cmdToSend);
  Serial2.write(0xFF);
  Serial2.write(0xFF);
  Serial2.write(0xFF);

ma non funziona cioe rimane disabilitato.
Il TO() e i vari sendSerialData servono per scrivere su dei display 7 segmenti di grandi dimensioni, ma da quel punto di vista tutto funziona.

Dovrebbe andare, nel Nextion non è che cambi pagina? Se non cambi pagina prova a sostituire il comando tsw con il comando vis, funziona uguale solo che invece di disabilitarlo lo nasconde

in realtà ho due pagine.
una mi serve come presentazione. dopo il primo touch su questa pagina, va direttamente alla seconda dove ci sono i button.
Adesso provo anche con vis

niente anche con vis non funziona.
o meglio, i button spariscono, ma poi alla fine del conteggio, quando richiamo la funzione di azzeramento, non riappaiono.
puo darsi problemi di comunicazione con la Serial2?
Va impostata in qualche maniera che non conosco?

Direi di no, a questo punto credo sia un bug di Nextion, hai due strade per come la vedo.
La prima è che invece di usare i comandi tal quali aggiungi al nextion un timer ed una variabile per ciascun pulsante, disabilitato con timer impostato al minimo possibile (50ms credo). Quando ti serve invece di fare vis 5,0 invii il comando timer1.en=1 e all'interno del Nextion nel codice legato al timer (in base al valore della variabile) fai li il comando tws (o vis), provo a dettagliare il codice del timer:

timer1.en=0;
tws 5,var1.val
if(var1.val==0)
{
  var1.val=1;
}
else
{
  var1.val=0;
}

Con la prima istruzione disabiliti il timer in modo che scarri solo una volta e poi con il resto abiliti/disabiliti il pulsante.
La seconda possibilità è chiedere sul forum di Nextion spieganto la faccenda, magari basta un comando di refresh o simile che non conoco per sbloccare la situazione

avevo pensato anche io di andare a lavorare sul codice nextion dirattamente sul display, ma non sono ferratissimo, pero provo ad imparare.
visto pero che la variabile tempo del timer la devo rappresentare anche su dei display 7 segmenti, come ti accennavo precedentemente, come posso intercettare questa variabile da utilizzare sul codice di arduino?
penso esista un modo.........se penso agli slider che impostano un valore che poi arduino gestisce.......
si puo fare secondo te?
Gentilissimo.

Se per timer intendi il countdown io lo gestirei com'è adesso ovvero arduino fa i conti e invia al display i vari valori, è più sepmlice perché se gestisci il countdown dal Nextion da Arduino ogni 172 secondo devi andare ad interrogare il display per sapere il valore della variabile e sarebbe poco efficente