Forum: Mikrocontroller und Digitale Elektronik Interrupt mit Touch Controller


von Thomas K. (thomaskron)


Lesenswert?

Hallo Forum

ich habe ein kleines Problem  stehe aber im Moment auf dem Schlauch und 
habe keine Vernünftige Idee das zu lösen.

Ich habe ein Arduino Due mit einem 5Zoll TFT (ER-TFTM050-5 von 
Buydisplay) mit integriertem Touch Controller GSL1680. Zwischen DUE und 
Display ist ein Shield mit LevelShifter (5V / 3.3V). Läuft soweit alles 
ok mit der UTFT libary. In der BEschreibung zum Touch Controller steht 
dass er ein Interrupt verwendet wenn ein Ereignis (drücken auf den 
Touchscreen).

Doch leider sieht die "Realität anders aus. Der Touch Controller sendet 
den Interrupt aber anders. Je nach Zeitdauer des drückens produziert der 
GSL1680 ehtliche Interrupts. Die Interrupst sind 1ms lang und haben eine 
Pause von 20ms. Also wird die Digitale Leitung nicht nur einmal sondern 
wechselt zigmal von High to Low.  Da wird die Auswertung mittels 
Interrupt Routine zum Nervenspiel....


Den Interrupt habe ich so eingerichtet:
- attachInterrupt(digitalPinToInterrupt(48), isr_touch, FALLING);

Die ISR:

void isr_touch(){
  touch_flag = true;
  Serial.println("touch   "); //nur zur Veranschaulichung
 }

Die Abfrage des GSL1680:
void read_touch(){
 if (touch_flag == true){
   noInterrupts();
   Serial.print("read touch");
   int n= read_data();
        for(int i=0; i<n; i++){
            Serial.print(ts_event.coords[i].finger);
            Serial.print(" "),Serial.print(ts_event.coords[i].x);
            Serial.print(" "), Serial.print(ts_event.coords[i].y);
            Serial.println("");
           }
           touch_flag = false;
           menu_flag = true;
     interrupts();
    }
}


hat vielleicht jemand eine Idee wie ich das Lösen kann ?

Gruss Thomas

von Conny G. (conny_g)


Lesenswert?

Du möchtest ja auch mitbekommen, wenn der Benutzer seinen Finger über 
das Display bewegt, deshalb schickt der Controller ständig die neuen 
Koordinaten per Interrupt.
Du müsstest in der Interrupt-Routine oder ausgelöst durch die 
Interruptroutine in der Hauptschleife die Koordinaten abholen und 
hinterlegen.
Dann musst Du entscheiden wann Du auf den Touch reagieren willst.
Entweder beim ersten Impuls ("Key down") und die ignorierst die 
weiteren, die im Abstand von 20ms kommen.
Oder Du wartest bis keine Updates mehr kommen ("Key up") und ignorierst 
alle vorher.
D.h. in beiden Fällen musst Du einen Timeout definieren -> z.B. ab 40ms 
kein Update hast Du das "Key Up" Event.

Auf Code-Seite setzt Du jedesmal ein Timestamp, wenn ein Int kommt:
1
lastTouch = getMillis()

Und in der Hauptschleife:
1
if (getMillis() - lastTouch > 40) {
2
  // koordinaten auswerten, button ermitteln, aktion starten
3
}

: Bearbeitet durch User
von Thomas K. (thomaskron)


Lesenswert?

Hallo Conny

Danke für deinen Input. Funktioniert aber nicht wirklich
Ich habe Tasten auf dem Display, so dass es eher eine statische Abfrage 
ist
nichts zum wischen oder so :-). Aber deine Erklärung macht Sinn.


Die if Anweisung in der loop ist immer wahr, weil millis() ja immer hoch
zählt nach dem Start und die lastTouch ja nur beim eintreffen des 
Interrupts.

Oder sehe ich das falsch ?

gruss Thomas

von Conny G. (conny_g)


Lesenswert?

Hi Thomas,

im Prinzip ist das if immer wahr wenn kein Button (mehr) gedrückt ist.
Um es zu einem Key Up Event zu machen muss man es noch ein bisschen 
ausbauen, das stimmt.

Irgendwie so:
1
if (getMillis() - lastTouch > 40 && buttonDown) {
2
  buttonDown = false;
3
  // jetzt auswerten welcher Button es war etc.
4
}

Und im Interrupt buttonDown auf true setzen.

Das ist jetzt nicht komplett ausformuliert, aber ich hoffe die Idee 
kommt rüber.

von Thomas K. (thomaskron)


Lesenswert?

Hallo Conny

Ja "jetzt" habe ich deine Idee langsam verstanden :-)
Ich versuche das mal umzusetzen.
Gruss Thomas

von Julian (Gast)


Lesenswert?

Hallo Thomas,

Ich stehe gerade vor dem gleichen Problem. Ich versuche den GSL1680 mit 
meinem F4-Discovery zum Laufen zu bringen.
Die I2C-Kommunikation funktioniert tadellos.
Der IRQ-Pin wird von mir testweise in einer while(1)-Schleife 
eingelesen. Der IRQ-Pin toggelt wie verrückt, selbst wenn ich den 
Touchscreen NICHT berühre! Drücke ich ein paar mal auf dem Screen herum, 
bekomme ich ab und zu plausible Werte für die X- und Y-Position, jedoch 
sehr unzuverlässig.

Bist du diesbezüglich schon weitergekommen?

Ich frage mich, ob das mit der Firmware zusammenhängt, die man bei der 
Initialisierung per I2C aufspielt.

Viele Grüße

Julian

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.