Go Down

Topic: Problema con TouchScreen (Read 162 times) previous topic - next topic

filomeni

Mar 17, 2019, 09:50 pm Last Edit: Mar 17, 2019, 10:00 pm by filomeni
Salve,
ho creato un menu con diverse pagine il touch funziona bene, ma ora ho implementato una pagina con temperatura e umidità.
Ho notato che in questa pagina il touch funziona molto male essendo aperta al loop continuo, scrivo un pò di codice di esempio per spiegare meglio:
Code: [Select]

if (currentpage == 2 && daDisegnare) {
    drawTemperatura();//mi disegna gli elementi della pagina termometro umidità
    daDisegnare = false;

if (p.x > 39 && p.x < 65 && p.y > 155 && p.y < 270) {//il tocco che mi porta alla pagina 3

currentpage = 3;
daDisegnare = true;
      }
  }

In questo caso, il termometro si blocca con il rilevare la temperatura nell'istante dell'accesso alla pagina ed il tocco per andare sulla pagina 3 (currentpage = 3) funziona regolarmente.
Il problema è che se lascio "aperto" l'if, per avere lettura continua della temperatura/umidità nel modo seguente
Code: [Select]

if (currentpage == 2) {

    drawTemperatura();//mi disegna gli elementi della pagina termometro umidità
    

if (p.x > 39 && p.x < 65 && p.y > 155 && p.y < 270) {//il tocco che mi porta alla pagina 3

currentpage = 3;
daDisegnare = true;
      }
  }

in questa maniera il loop mi enta continuamente nell'if e la lettura è in tempo reale, ma questo va a dar fastidio al tocco, prima che agisca, devo ripeterlo molte volte intercettando il il tempo giusto che il loop non dia interferenza...
Spero di esser stato chiaro.
Grazie
Maurizio Filomeni
Siamo qui per spiegare a chi sa meno e iparare da sa di più...

fabpolli

Nel primo esempio che hai fatto entri nell'if se sei nella pagina due e se la variabile daDisegnare ha il valore true, immediatamente dopo il ridisegno la metti a false e poi testi il touch, cosa che non farai mai più finché la variabile daDisegnare non verrà reimpostata a true (da chi??? non hai messo il codcie compelto quindi impossibile saperlo).
Nel secondo codice il touch ti funziona male perché avendo rimosso la variabile daDisegnare entri sempre nell'if se sei in pagina due ma ridisegnando ogni volta il display non risponde come vorresti tu.
Detto che non si sa chi setta daDisegnare puoi cercare di implementare la cosa in un modo come questo:
Code: [Select]

Se ( sono in pagina due )
   se ( devo disegnare )
       disegno
   se ( utente ha toccato nelle coordinate desiderate)
      vado in pagina 3
      ecc.

filomeni

Grazie per la risposta. Il da disegnare è inizializzato con
Code: [Select]

int currentpage = 0;
bool daDisegnare = true;


appena accendo quindi va sulla pagina ZERO e la disegna...
poi ad ognitocco la variabile torna a TRUE...
Ma abbiamo decentrato il problema...
posto questo blocco per spiegarmi meglio:

Code: [Select]

if (currentpage == 3) {

    //timer utilizzo device
    cli();  // disabilito l'interrupts
    current_millis_value = millis();
    sei();  // abilito l'interrupts

    // overflow millis()
    if (current_millis_value < previous_millis_value)
      m += MAX_MILLIS_VALUE - previous_millis_value + current_millis_value;
    else m += current_millis_value - previous_millis_value;

    seconds += m / 1000;
    m = m % 1000;
    minutes += seconds / 60;
    seconds = seconds % 60;
    hours += minutes / 60;
    minutes = minutes % 60;
    hours = hours % 24;
    previous_millis_value = current_millis_value;
    tft.setTextSize(2);
    tft.setTextColor(NERO);
    tft.setCursor(80, 60);
    tft.fillRect(30, 58, 170, 20, WHITE);
    tft.print(hours);
    tft.print(":");
    tft.print(minutes);
    tft.print(":");
    tft.print(seconds);
    delay(1000);
    //fine timer
  }

Tutto questo papocchio è semplicemente un timer che conta il tempo di utilizzo del devices.
Il codice è racchiuso in "currentpage=3" e funziona correttamente, il probelma è che se all'interno inserisco un "tocco" per andare altrove, non funziona bene, o meglio devo picchiare più volte per prendere il tocco... il codice:

Code: [Select]

if (currentpage == 3) {

if (p.x > 39 && p.x < 65 && p.y > 155 && p.y < 270) {//questo tocco fa fatica a funzionare...
       currentpage=2;
daDisegnare=true;
      }

    //timer utilizzo device
    cli();  // disabilito l'interrupts
    current_millis_value = millis();
    sei();  // abilito l'interrupts

    // overflow millis()
    if (current_millis_value < previous_millis_value)
      m += MAX_MILLIS_VALUE - previous_millis_value + current_millis_value;
    else m += current_millis_value - previous_millis_value;

    seconds += m / 1000;
    m = m % 1000;
    minutes += seconds / 60;
    seconds = seconds % 60;
    hours += minutes / 60;
    minutes = minutes % 60;
    hours = hours % 24;
    previous_millis_value = current_millis_value;
    tft.setTextSize(2);
    tft.setTextColor(NERO);
    tft.setCursor(80, 60);
    tft.fillRect(30, 58, 170, 20, WHITE);
    tft.print(hours);
    tft.print(":");
    tft.print(minutes);
    tft.print(":");
    tft.print(seconds);
    delay(1000);
    //fine timer
  }


Grazie
Maurizio Filomeni
Siamo qui per spiegare a chi sa meno e iparare da sa di più...

fabpolli

Guarda vado un po' ad intuito ma credo che l'origine dei tuoi mali sia qui:
Code: [Select]

delay(1000);

Capisco che l'hai messo per non ridisegnare continuamente ma se metti il delay e tocchi metre sei nel delay ti perdi i tocchi con buone probabilità.
Dovresti provare a eliminare il delay ed andare ad aggiornare il display ogni secondo ma mediante l'uso di millis, il dellay è bloccante e va usato solo quando il programma deve attendere e non far null'altro per il tempo prestablito e per null'altro intento nulla nulla, mentre tu vuoi che il tuo programma reagisca all'interazione dell'utente.
Non so da dove tu abbia preso il codice (intendo dire che è la prima volta che mi imbatto in un codice simile, non che sia errato) ma anche la disabilitazione e riabilitazione degli interrupt per la rilevazione del millis() attuale per me è aberrante ed innutile, ma magari ha un senso ed un utilità che io non conosco.
Ultima cosa se il codcie è troppo lungo per metterlo racchiuso tra i tag code allegalo, è di immenso aiuto avere tutto il codice per cercare di fornire risposte adeguate. Per farlo non puoi usare l'area quick Reply ma devi per forza fare click sul pulsante Reply, li hai l'edito compelto che permette di allegare file

filomeni

Sempre grazie per la risposta...
Il delay era commentato... ho sbagliato a decommentarlo.
Comunque anche senza delay il mal funzionamento rimane. La cosa del millis non l'ho provata, quindi ritardare la funzione con millis a un secondo.
Ci provo e vediamo... Ora mi vado a ficcare ;-)
Ciao
Siamo qui per spiegare a chi sa meno e iparare da sa di più...

filomeni

#5
Mar 24, 2019, 03:40 pm Last Edit: Mar 24, 2019, 03:43 pm by filomeni
Dopo svariate prove, sono arrivato alle mie conclusioni.
Se nella pagina c'è un programma che necessita di aggiornamento continuo, ad esempio un "conta secondi" e nella stessa abbiamo degli ogetti sensibili al tocco (menu, pulsanti ecc.), in questo caso il tocco non funziona in maniera adeguata, ad ogni ciclo di loop si interrompe il tocco.
Quindi se devono coesistere il programma (contatore) e il l'oggetto sensibile al tocco, l'unica cosa è ricorrere a un compromesso, temporizzare l'accesso del loop per dar modo che il funzionamento del touch sia non perfetto ma accettabile... posto codice di esempio:
Code: [Select]
if (currentpage == 0) {
    
    Salt++;
  
    if (Salt == 3000) {
      Salt = 0;

//qui ci andrà il codice del conta secondi e segue il touch

if (p.x > 0 && p.x < 245 && p.y > 26 && p.y < 280) {
          currentpage = 1;
          daDisegnare = true;
        }

}
}

Quando la variabile "Salt" raggiunge il valore 3000 il conta secondi si aggiorna ma in questo istante il touch non funziona. Poi resetto la variabile Salt per ricominciare il conteggio e finchè Salt non arriva a 3000 il touch funzionerà in maniera corretta...
Immagino ci siano strade più eleganti, tramite millis() o altro, ma il mio ingegno mi ha portato a questo risultato.
Siamo qui per spiegare a chi sa meno e iparare da sa di più...

Go Up