From 7e3623348951f3e06e64e7bed5b592e6ceb0a362 Mon Sep 17 00:00:00 2001 From: wesleygas Date: Sat, 18 Sep 2021 20:05:30 -0300 Subject: [PATCH] ILI9341 unoshield with analog touch implementation --- platformio_override-template.ini | 5 + src/drv/old/hasp_drv_analogTouch.h | 149 ++++++++++++++++++ src/drv/touch/touch_driver.h | 3 + src/drv/touch/touch_driver_analog.h | 69 ++++++++ .../esp32/esp32-ili9341-unoshield-analog.ini | 57 +++++++ 5 files changed, 283 insertions(+) create mode 100644 src/drv/old/hasp_drv_analogTouch.h create mode 100644 src/drv/touch/touch_driver_analog.h create mode 100644 user_setups/esp32/esp32-ili9341-unoshield-analog.ini diff --git a/platformio_override-template.ini b/platformio_override-template.ini index 571d4c2d..0d4cdc6c 100644 --- a/platformio_override-template.ini +++ b/platformio_override-template.ini @@ -26,6 +26,7 @@ extra_default_envs = ; d1-mini-esp32_ili9341 ; d1-mini-esp8266_ili9341 ; d1-r32-unoshield + ; esp32-9341-unoshield-analog ; esp12e-st7735 ; esp32dev-mrb3511 ; esp32dev-ili9488 @@ -58,6 +59,10 @@ upload_port = 192.168.4.4 ; IP of the ESP upload_protocol = espota ; Use ArduinoOTA after flashing over serial upload_flags = --port=3232 ; --auth=haspadmin ; OTA password +[env:esp32-9341-unoshield-analog] +monitor_port = COM7 ; Leave commented to autodescover +; upload_port = ${$env:esp32-9341-unoshield-analog.monitor_port} + [env:ttgo_esp32_poe-ili9341] monitor_port = COM9 ; Change to the correct port ;upload_port = ${env:ttgo_esp32_poe-ili9341.monitor_port} diff --git a/src/drv/old/hasp_drv_analogTouch.h b/src/drv/old/hasp_drv_analogTouch.h new file mode 100644 index 00000000..5ca176b4 --- /dev/null +++ b/src/drv/old/hasp_drv_analogTouch.h @@ -0,0 +1,149 @@ +// Touch screen library with X Y and Z (pressure) readings as well +// as oversampling to avoid 'bouncing' +// (c) ladyada / adafruit +// Code under MIT License +// Code under MIT License + +#ifndef _ADAFRUIT_TOUCHSCREEN_H_ +#define _ADAFRUIT_TOUCHSCREEN_H_ + +#include + +#ifdef ARDUINO +#include "Arduino.h" + +#define ADC_MAX 4095 // maximum value for ESP32 ADC (default 11db, 12 bits) +#define aXM TOUCH_anDC // analog input pin connected to LCD_RS +#define aYP TOUCH_anWR // analog input pin connected to LCD_WR + +#define NOISE_LEVEL 4 // Allow small amount of measurement noise + +typedef volatile uint32_t RwReg; + +class TSPoint { + public: + TSPoint(void); + TSPoint(int16_t x, int16_t y, int16_t z); + + bool operator==(TSPoint); + bool operator!=(TSPoint); + + int16_t x, y, z; +}; + +class TouchScreen { + public: + TouchScreen(uint8_t xp, uint8_t yp, uint8_t xm, uint8_t ym, uint16_t rx); + + TSPoint getPoint(); + + private: + uint8_t _yp, _ym, _xm, _xp; + uint16_t _rxplate; + + volatile RwReg *xp_port, *yp_port, *xm_port, *ym_port; + RwReg xp_pin, xm_pin, yp_pin, ym_pin; +}; + +// increase or decrease the touchscreen oversampling. This is a little different than you make think: +// 1 is no oversampling, whatever data we get is immediately returned +// 2 is double-sampling and we only return valid data if both points are the same +// 3+ uses insert sort to get the median value. +// We found 2 is precise yet not too slow so we suggest sticking with it! + +#define NUMSAMPLES 2 + +TSPoint::TSPoint(void) +{ + x = y = 0; +} + +TSPoint::TSPoint(int16_t x0, int16_t y0, int16_t z0) +{ + x = x0; + y = y0; + z = z0; +} + +bool TSPoint::operator==(TSPoint p1) +{ + return ((p1.x == x) && (p1.y == y) && (p1.z == z)); +} + +bool TSPoint::operator!=(TSPoint p1) +{ + return ((p1.x != x) || (p1.y != y) || (p1.z != z)); +} + +TSPoint TouchScreen::getPoint(void) +{ + int x, y, z; + int samples[NUMSAMPLES]; + uint8_t i; + + valid = 1; + + pinMode(_yp, INPUT); + pinMode(_ym, INPUT); + pinMode(_xp, OUTPUT); + pinMode(_xm, OUTPUT); + + digitalWrite(_xp, HIGH); + digitalWrite(_xm, LOW); + + for(i = 0; i < NUMSAMPLES; i++) { + samples[i] = analogRead(aYP); + } + + samples[1] = (samples[0] + samples[1]) >> 1; // average 2 samples + x = (ADC_MAX - samples[NUMSAMPLES / 2]); + + pinMode(_xp, INPUT); + pinMode(_xm, INPUT); + pinMode(_yp, OUTPUT); + pinMode(_ym, OUTPUT); + + digitalWrite(_ym, LOW); + digitalWrite(_yp, HIGH); + + for(i = 0; i < NUMSAMPLES; i++) { + + samples[i] = analogRead(aXM); + } + + samples[1] = (samples[0] + samples[1]) >> 1; // average 2 samples + + y = (ADC_MAX - samples[NUMSAMPLES / 2]); + + // Set X+ to ground + // Set Y- to VCC + // Hi-Z X- and Y+ + pinMode(_xp, OUTPUT); + pinMode(_yp, INPUT); + + digitalWrite(_xp, LOW); + digitalWrite(_ym, HIGH); + + int z1 = analogRead(aXM); + int z2 = analogRead(aYP); + + z = (ADC_MAX - (z2 - z1)); + + // Restore pin states + pinMode(_xm, OUTPUT); + pinMode(_yp, OUTPUT); + return TSPoint(x, y, z); +} + +TouchScreen::TouchScreen(uint8_t xp, uint8_t yp, uint8_t xm, uint8_t ym, uint16_t rxplate = 0) +{ + _yp = yp; + _xm = xm; + _ym = ym; + _xp = xp; + _rxplate = rxplate; + +} + +#endif // ARDUINO +#endif // _ADAFRUIT_TOUCHSCREEN_H_ \ No newline at end of file diff --git a/src/drv/touch/touch_driver.h b/src/drv/touch/touch_driver.h index dfd3ae31..2da354f0 100644 --- a/src/drv/touch/touch_driver.h +++ b/src/drv/touch/touch_driver.h @@ -63,6 +63,9 @@ class BaseTouch { #elif TOUCH_DRIVER == 911 #warning Building for GT911 #include "touch_driver_gt911.h" +#elif TOUCH_DRIVER == 404 +#warning Building for analog touch +#include "touch_driver_analog.h" #else #warning Building for Generic Touch using dev::BaseTouch; diff --git a/src/drv/touch/touch_driver_analog.h b/src/drv/touch/touch_driver_analog.h new file mode 100644 index 00000000..27361c21 --- /dev/null +++ b/src/drv/touch/touch_driver_analog.h @@ -0,0 +1,69 @@ +/* MIT License - Copyright (c) 2019-2021 Francis Van Roie + For full license information read the LICENSE file in the project folder */ + +#ifndef HASP_ANALOG_TOUCH_DRIVER_H +#define HASP_ANALOG_TOUCH_DRIVER_H + +#ifdef ARDUINO +#include "hasp_conf.h" + +#include "Arduino.h" +#include "../old/hasp_drv_analogTouch.h" +#include "ArduinoLog.h" + +#include "touch_driver.h" // base class + +#include "../../hasp/hasp.h" // for hasp_sleep_state +extern uint8_t hasp_sleep_state; +#define MINPRESSURE 200 +#define MAXPRESSURE 2400 + +const int XP=TFT_D6,XM=TFT_DC,YP=TFT_WR,YM=TFT_D7; //ID=0x9341 +const int TS_LEFT=560,TS_RT=3670,TS_TOP=3850,TS_BOT=580; +int max_x = 4095,max_y=4095; + +static TouchScreen ts = TouchScreen(XP, YP, XM, YM, 300); + +IRAM_ATTR bool touch_read(lv_indev_drv_t* indev_driver, lv_indev_data_t* data) +{ + static TSPoint tp; + tp = ts.getPoint(); + if (tp.z < MINPRESSURE){ + data->state = LV_INDEV_STATE_REL; + }else{ + data->point.x = map(tp.x,TS_LEFT,TS_RT,0,max_x); + data->point.y = map(tp.y,TS_BOT,TS_TOP,max_y,0); + data->state = LV_INDEV_STATE_PR; + } + + return false; + + /*Return `false` because we are not buffering and no more data to read*/ + // return false; +} + +namespace dev { + +class AnalogTouch : public BaseTouch { + + public: + void init(int w, int h) + { + max_x = w; + max_y = h; + } + + IRAM_ATTR bool read(lv_indev_drv_t* indev_driver, lv_indev_data_t* data) + { + return touch_read(indev_driver, data); + } +}; + +} // namespace dev + +using dev::AnalogTouch; +extern dev::AnalogTouch haspTouch; + +#endif // ARDUINO + +#endif // HASP_ANALOG_TOUCH_DRIVER_H diff --git a/user_setups/esp32/esp32-ili9341-unoshield-analog.ini b/user_setups/esp32/esp32-ili9341-unoshield-analog.ini new file mode 100644 index 00000000..66def78e --- /dev/null +++ b/user_setups/esp32/esp32-ili9341-unoshield-analog.ini @@ -0,0 +1,57 @@ +;***************************************************; +; GenericESP32 build with ; +; - Arduino UNO ILI9341 2.4" TFT shield ; +;***************************************************; + +[env:esp32-9341-unoshield-analog] +extends = esp32 +board = esp32dev + +build_flags = + ${env.build_flags} + ${esp32.build_flags} + +;region -- TFT_eSPI build options ------------------------ + -D USER_SETUP_LOADED=1 + -D ILI9341_DRIVER=1 + -D TFT_WIDTH=240 + -D TFT_HEIGHT=320 + -D ESP32_PARALLEL=1 + -D TFT_BACKLIGHT_ON=0 ; At what level is the backlight on + -D TFT_ROTATION=0 ; Use default, see TFT_ROTATION values + ${esp32.vspi} ; Use VSPI hardware SPI bus + -D TFT_BCKL=-1 ;None, configurable via web UI (e.g. 2 for D4) + -D TFT_CS=33 ; Chip select control pin + -D TFT_DC=15 ; Data Command control pin - must use a pin in the range 0-31 + -D TFT_RST=32 ; Reset pin + -D TFT_WR=4 ; Write strobe control pin - must use a pin in the range 0-31 + -D TFT_RD=2 + -D TFT_D0=12 ; Must use pins in the range 0-31 for the data bus + -D TFT_D1=13 ; so a single register write sets/clears all bits + -D TFT_D2=26 + -D TFT_D3=25 + -D TFT_D4=17 + -D TFT_D5=16 + -D TFT_D6=27 + -D TFT_D7=14 + -D SD_CS=5 + -D SPI_FREQUENCY=40000000 + -D TOUCH_DRIVER=404 ; No touch driver found? No problem + -D TOUCH_anDC=35 ; Analog pin to be connected to TFT_DC + -D TOUCH_anWR=34 ; Analog pin to be connected to TFT_WR +;endregion + +; -- Debugging options ----------------------------- +; -D CORE_DEBUG_LEVEL=ARDUHAL_LOG_LEVEL_DEBUG + +;region -- Library options ------------------------------- +lib_deps = + ${env.lib_deps} + ${esp32.lib_deps} + ;git+https://github.com/s60sc/Adafruit_TouchScreen + adafruit/Adafruit TouchScreen @ ~1.1.2 + +lib_ignore = + ${env.lib_ignore} + ${esp32.lib_ignore} +;endregion