ArduiTouch 3 - Zeichnen am Touch Screen


In diesem Beitrag möchte ich die Möglichkeiten meiner TouchEvent Library zeigen. Sie ermöglicht es sehr einfach auf Ereignisse am Touch-Screen zu reagieren. Die Library könnt ihr ganz einfach von GitHub herunterladen und in das Arduino libraries Verzeichnis kopieren. Es gibt in den Beispielen ein Demo-Programm, das die Anwendung zeigt. Anhand dieses Demo-Programms werde ich in diesem Beitrag die einzelnen Funktionen der Bibliothejk erläutern.

Als Hardware benötigen wir einen ArduiTouch mit ESP32-Prozessor.

Code:

 

 

/* this example demonstrates the usage of the TouchEvent library
 *  it uses a 2.4 inch TFT display with resistive touch screen
 *  the display uses an ILI9341 controller
 *  and the touch screen a XPT2046
 *  the module is used together with an ESP32 but any other
 *  arduino compatible processor should work
 *  For the used pins see definitions in the code
 */

//required libraries
#include <SPI.h>
#include "Adafruit_GFX.h"
#include "Adafruit_ILI9341.h"
#include <XPT2046_Touchscreen.h>
#include <Fonts/FreeSans9pt7b.h> //used font5

#include "TouchEvent.h"

//used pins
#define TFT_CS   5      //diplay chip select
#define TFT_DC   4      //display d/c
#define TFT_MOSI 23     //diplay MOSI
#define TFT_CLK  18     //display clock
#define TFT_RST  22     //display reset
#define TFT_MISO 19     //display MISO
#define TFT_LED  15     //display background LED


#define TOUCH_CS 14     //touch screen chip select
#define TOUCH_IRQ 2     //touch screen interrupt


//prepare driver for display and touch screen
Adafruit_ILI9341 tft = Adafruit_ILI9341(TFT_CS, TFT_DC, TFT_RST);
XPT2046_Touchscreen touch(TOUCH_CS, TOUCH_IRQ);

//init TouchEvent with pointer to the touch screen driver
TouchEvent tevent(touch);

// some global variables
int scr = 0;
uint16_t bg[4] = {ILI9341_WHITE,ILI9341_RED,ILI9341_GREEN,ILI9341_YELLOW};
TS_Point last;
boolean draw;

//swipe event
void onSwipe(uint8_t dir) {
  switch(dir) {
    case 0: if (scr <3) { //right to left switch to next screen
        scr++;
        draw_screen(scr);
      }
      break;
    case 1: if (scr > 0) { //left to right switch to previous screen
        scr--;
        draw_screen(scr);
      }
      break;
  }
  tevent.setDrawMode(scr==0);
}

void onClick(TS_Point p) {
  if (scr > 0) { //on any screen except 0 show the click position
    tft.setFont(&FreeSans9pt7b);
    tft.fillRect(0,40,240,70,ILI9341_WHITE);
    tft.setTextColor(ILI9341_BLACK,ILI9341_WHITE);
    tft.setCursor(10,60);
    tft.println("Clicked");
    tft.println(p.x);
    tft.println(p.y);
  }
}

void onDblClick(TS_Point p) {
  if (scr > 0) { //on any screen except 0 show double click position
    tft.fillRect(0,40,240,70,ILI9341_WHITE);
    tft.setFont(&FreeSans9pt7b);
    tft.setTextColor(ILI9341_BLACK,ILI9341_WHITE);
    tft.setCursor(10,60);
    tft.println("Doubleclick");
    tft.println(p.x);
    tft.println(p.y);
  } else {
    tevent.setDrawMode(false);
  }
}

void onDraw(TS_Point p) {
  //draw a line from the last position to the current position
  if (draw) tft.drawLine(last.x,last.y,p.x,p.y,ILI9341_BLACK);
  last = p;
}

void onTouch(TS_Point p) {
  last = p;
  draw = true;
}

void onUntouch(TS_Point p) {
  draw = false;
}

void onLongClick(TS_Point p) {
  if (scr > 0) { //on any screen except 0 show double click position
    tft.setFont(&FreeSans9pt7b);
    tft.fillRect(0,40,240,70,ILI9341_WHITE);
    tft.setTextColor(ILI9341_BLACK,ILI9341_WHITE);
    tft.setCursor(10,60);
    tft.println("Long Click");
    tft.println(p.x);
    tft.println(p.y);
  }
}

void setup() {
  Serial.begin(115200);
  pinMode(TFT_LED, OUTPUT);
  digitalWrite(TFT_LED, HIGH);    // switch display on
  //start drivers
  tft.begin();
  touch.begin();
  //show the displays resolution
  Serial.print("tftx ="); Serial.print(tft.width()); Serial.print(" tfty ="); Serial.println(tft.height());
  //init TouchEvent instance
  tevent.setResolution(tft.width(),tft.height());
  tevent.setDblClick(300);
  tevent.registerOnTouchSwipe(onSwipe);
  tevent.registerOnTouchClick(onClick);
  tevent.registerOnTouchDblClick(onDblClick);
  tevent.registerOnTouchLong(onLongClick);
  tevent.registerOnTouchDraw(onDraw);
  tevent.registerOnTouchDown(onTouch);
  tevent.registerOnTouchUp(onUntouch);
  //display
 draw_screen(scr);
}

//fill screen with different colors for different screen numbers
void draw_screen(uint8_t nr) {
  tft.fillScreen(bg[nr]);
  tft.setFont(&FreeSans9pt7b);
  tft.setTextColor(ILI9341_BLACK,ILI9341_WHITE);
  tft.setCursor(10,20);
  tft.print("Screen Nr. ");
  tft.print(nr);
  
}

void loop() {
  //poll for touch events
  tevent.pollTouchScreen();
}

Die TouchEvent Klasse holt in ihrer Hauptfunktion pollTouchScreen() die aktuellen Werte vom Touch-Screen und versucht Ereignisse zu erkennen. Wurde ein Ereignis erkannt und eine Callback-Funktion für dieses Ereignis registriert, so wird diese Funktion mit der aktuellen Position in Bildschirm-Koordinaten aufgerufen. Eine Ausnahme ist die Callback-Funktion für das Swipe-Ereignis, in diesem Fall wird die Richtung der Wischbewegung als Parameter übergeben.

Für folgende Ereignisse kann eine Callback-Funktion registriert werden.

 

  • onTouchDown(TS_Point p) diese Funktion wird immer dann aufgerufen, wenn der Schirm berührt wird.
  • onTouchUp(void (TS_Point p) diese Funktion wird immer dann aufgerufen wenn die Schirmberührung endet.
  • onTouchClick(void (TS_Point p) diese Funktion wird dann aufgerufen, wenn der Schirm kurz berührt wurde. Die Berührung darf nicht länger sein als die Zeit, die für den langen Klick eingestellt wurde. (Default 1 Sekunde)
  • onTouchDblClick(TS_Point p) diese Funktion wird aufgerufen wenn der Schirm innerhals beiner einstellbaren Zeit (Default 500 ms) zweimal kurz berührt wurde. Jedes Doppelklick Ereignis löst beim ersten Klick auch ein Klick-Ereignis aus.
  • onTouchLong(TS_Point p) diese Funktion wird dann aufgerufen wenn der Schirm mindestens eine einstellbare Zeit (Default 1 s) berührt wurde. In diesem Fall wird kein Klick-Ereignis ausgelöst.
  • onTouchDraw(TS_Point p) diese Funktion wird aufgerufen wenn der Berührungspunkt während der Berührung verändert wird. Über den einstellbaren Wert moveThreshold (Default = 10) kann die Empfindlichkeit variiert werden. Das Ereignis wird nur aufgerufen wenn der Draw-Mode aktiv ist.
  • onTouchSwipe(uint8_t direction) diese Funktion wird aufgerufen, wenn über den Bildschirm gewischt wird. Die mindest Wischlänge kann für x (default = 500) und y (default = 700) eingestellt werden. Der Funktion wird als parameter die Richtung migegeben. 0 = von rechts nach links, 1=vonlinks nach rechts, 2 = von oben nach unten und 3=von unten nach oben. Dieses Ereignis wird nicht ausgelöst, wenn der Draw-Mode nicht aktiv ist.

Als Zusammenfassung hier noch einmal alle Funktionen der Klasse:

  • pollTouchScreen();
    die aktuelle Position des Touch-Screen wird abgefragt und je nach erkannten Ereignissen werden registrierte Callback-Funktionen aufgerufen
  • void setResolution(int16_t xResolution, int16_t yResolution);
    die Auflösung des Bildschirms in Pixel kann eingestellt werden (default 240 und 320)
  • void setDrawMode(boolean drawMode);
    schaltet den Zeichen-Modus ein oder aus (default = aus).
  • void calibrate(uint16_t xMin, uint16_t yMin, uint16_t xMax, uint16_t yMax);
    dient zur Kalibrierung des Touch-Screens. Die Werte geben die linke obere und die rechte untere Ecke in Touch-Screen Koordinaten an (default = 230, 350, 3700 und 3900).
  • void setMoveTreshold(uint16_t threshold);
    setzt die Änderung in Touch-Screen Koordinaten die auftreten muß, damit ein onDraw Ereignis erkannt wird (default = 10).
  • void setSwipe(uint16_t swipeX, uint16_t swipeY);
    setzt die Länge für den Wischvorgang in Touch-Screen Koordinaten damit ein Wisch-Ereignis erkannt wird (defaul = 500,700).
  • void setLongClick(uint16_t clickLong);
    setzt die Zeit in ms wie lange eine Berührung dauern muss damit ein langer Klick erkannt wird (default = 1000ms).
  • void setDblClick(uint16_t dblclick);
    setzt die maximale Zeit zwischen 2 Klicks in ms damit ein Doppelklick erkannt wird (default = 500ms).
  • void registerOnTouchDown(void (*callback)(TS_Point p));
    registriert eine Callback-Funktion für das onTouchDown Ereignis.
  • void registerOnTouchUp(void (*callback)(TS_Point p));
    registriert eine Callback-Funktion für das onTouchUp Ereignis.
  • void registerOnTouchClick(void (*callback)(TS_Point p));
    registriert eine Callback-Funktion für das onTouchClick Ereignis.
  • void registerOnTouchDblClick(void (*callback)(TS_Point p));
    registriert eine Callback-Funktion für das onTouchDblClick Ereignis.
  • void registerOnTouchLong(void (*callback)(TS_Point p));
    registriert eine Callback-Funktion für das onTouchLong Ereignis.
  • void registerOnTouchDraw(void (*callback)(TS_Point p));
    registriert eine Callback-Funktion für das onTouchDraw Ereignis.
  • void registerOnTouchSwipe(void (*callback)(uint8_t direction));
    registriert eine Callback-Funktion für das onSwipeDown Ereignis.
  • boolean isInArea(TS_Point p, int16_t x1, int16_t y1, int16_t x2, int16_t y2);
    Hilfsfuntion gibt whar zurück wenn der Punkte p innerhalb des Rechtecks x1, y1 und x2, y2 liegt.

 

Nachdem das Demo-Programm gestartet wurde wird die erste Seite "Screen Nr. 0" mit weißem Hintergrund angezeigt. Auf dieser Seite ist der Zeichen-Modus aktiv und man kann mit dem Finger oder besser mit einem weichen stumpfen Bleistift zeichnen.

Mit einem Doppelklick wird der Zeichen-Modus beendet. Nun kann man durch Wischen zwischen den Seiten hin und her schalten. Seite 1 mit rotem Hintergrund, Seite 2 gelb und Seite 3 grün. Auf allen Seiten außer Seite 0 werden Klick, Doppelklickk und langer Klick mit Position angezeigt. Beim Wechsel auf Seite 0 wird automatisch wieder der Zeichen-Modus aktiviert.

Viel Spass beim Klicken und Wischen ;)

 

Letzter Artikel Smarthome Zentrale mit ArduiTouch Teil 6 - WLAN Verbindung, Echtzeituhr und Webserver

Hinterlasse einen Kommentar

Kommentare müssen vor der Veröffentlichung überprüft werden

Erforderliche Angabe