Search code examples
arduinoesp8266touchscreenarduino-esp8266

Basic On / Off Button with ESP8266 + ILI9341 Touch Panel


I am trying to create a simple on / off touch screen butting using a HiLetgo ESP8266 12-E and an ILI9341 LCD touch screen.

I have wired the board as follows:

ILI9341 <--> ESP8266

  • SDD/MISO <--> D6
  • LED <--> 3.3V
  • SCK <--> D5
  • SDI/MOSI <--> D7
  • T_CS <--> D8 touch chip select?
  • DC/RS <--> D1
  • RESET <--> 3.3V
  • CS <--> D2
  • GND <--> GND
  • VCC <--> 3.3V

I am using the Adafruit library and the example Adafruit ONOFFBUTTON example using the Arduino IDE. My code looks like this:

//This example implements a simple sliding On/Off button. The example
// demonstrates drawing and touch operations.
//
//Thanks to Adafruit forums member Asteroid for the original sketch!
//
#include <Adafruit_GFX.h>
#include <SPI.h>
#include <Wire.h>
#include <Adafruit_ILI9341.h>
#include <Adafruit_STMPE610.h>

// This is calibration data for the raw touch data to the screen coordinates
#define TS_MINX 150
#define TS_MINY 130
#define TS_MAXX 3800
#define TS_MAXY 4000

#define STMPE_CS D8
Adafruit_STMPE610 ts = Adafruit_STMPE610(STMPE_CS);
#define TFT_CS D2
#define TFT_DC D1
Adafruit_ILI9341 tft = Adafruit_ILI9341(TFT_CS, TFT_DC);

boolean RecordOn = false;

#define FRAME_X 210
#define FRAME_Y 180
#define FRAME_W 100
#define FRAME_H 50

#define REDBUTTON_X FRAME_X
#define REDBUTTON_Y FRAME_Y
#define REDBUTTON_W (FRAME_W/2)
#define REDBUTTON_H FRAME_H

#define GREENBUTTON_X (REDBUTTON_X + REDBUTTON_W)
#define GREENBUTTON_Y FRAME_Y
#define GREENBUTTON_W (FRAME_W/2)
#define GREENBUTTON_H FRAME_H

void drawFrame()
{
  tft.drawRect(FRAME_X, FRAME_Y, FRAME_W, FRAME_H, ILI9341_BLACK);
}

void redBtn()
{ 
  tft.fillRect(REDBUTTON_X, REDBUTTON_Y, REDBUTTON_W, REDBUTTON_H, ILI9341_RED);
  tft.fillRect(GREENBUTTON_X, GREENBUTTON_Y, GREENBUTTON_W, GREENBUTTON_H, ILI9341_BLUE);
  drawFrame();
  tft.setCursor(GREENBUTTON_X + 6 , GREENBUTTON_Y + (GREENBUTTON_H/2));
  tft.setTextColor(ILI9341_WHITE);
  tft.setTextSize(2);
  tft.println("ON");
  RecordOn = false;
}

void greenBtn()
{
  tft.fillRect(GREENBUTTON_X, GREENBUTTON_Y, GREENBUTTON_W, GREENBUTTON_H, ILI9341_GREEN);
  tft.fillRect(REDBUTTON_X, REDBUTTON_Y, REDBUTTON_W, REDBUTTON_H, ILI9341_BLUE);
  drawFrame();
  tft.setCursor(REDBUTTON_X + 6 , REDBUTTON_Y + (REDBUTTON_H/2));
  tft.setTextColor(ILI9341_WHITE);
  tft.setTextSize(2);
  tft.println("OFF");
  RecordOn = true;
}

void setup(void)
{
  SPI.setMOSI(7);
  SPI.setSCK(14);

  Serial.begin(74880);
  tft.begin();
  if (!ts.begin()) { 
    Serial.println("Unable to start touchscreen.");
  } 
  else { 
    Serial.println("Touchscreen started."); 
  }

  tft.fillScreen(ILI9341_BLUE);
  // origin = left,top landscape (USB left upper)
  tft.setRotation(1); 
  redBtn();
}

void loop()
{
  // See if there's any  touch data for us
  if (!ts.bufferEmpty())
  {   
    // Retrieve a point  
    TS_Point p = ts.getPoint(); 
    // Scale using the calibration #'s
    // and rotate coordinate system
    p.x = map(p.x, TS_MINY, TS_MAXY, 0, tft.height());
    p.y = map(p.y, TS_MINX, TS_MAXX, 0, tft.width());
    int y = tft.height() - p.x;
    int x = p.y;

    if (RecordOn)
    {
      if((x > REDBUTTON_X) && (x < (REDBUTTON_X + REDBUTTON_W))) {
        if ((y > REDBUTTON_Y) && (y <= (REDBUTTON_Y + REDBUTTON_H))) {
          Serial.println("Red btn hit"); 
          redBtn();
        }
      }
    }
    else //Record is off (RecordOn == false)
    {
      if((x > GREENBUTTON_X) && (x < (GREENBUTTON_X + GREENBUTTON_W))) {
        if ((y > GREENBUTTON_Y) && (y <= (GREENBUTTON_Y + GREENBUTTON_H))) {
          Serial.println("Green btn hit"); 
          greenBtn();
        }
      }
    }

    Serial.println(RecordOn);
  }  
}

I can't find many examples or documentation online for utilizing touch screens with the ESP8266 and the ILI9341. I am looking to

  1. Verify that I have correctly wired the darn thing
  2. Modify the code as necessary to reflect pins used, and make the touch buttons work correctly

Thank you very much for your time reading this. Your help is very appreciated!


Solution

  • I am trying to create a simple on / off touch screen butting using a HiLetgo ESP8266 12-E and an ILI9341 LCD touch screen.

    EDIT - I found a solution
    Based on the info taken from nailbuster's blog.

    Wire the board as follows:

    ILI9341 <--> ESP8266
    T_IRQ <--> GPIO16
    T_DO, SODI (MISO) <---> GPIO12
    T_DIN, SDI (MOSI) <---> GPIO13
    T_CS <--> GPIO4
    T_CLK, SCK <--> GPIO14
    LED, RESET, VCC <--> 3.3V
    D/C <--> GPI02
    CS <--> GPIO15
    GND <--> GND

    Some wires are on the same channel.

    Here is working example code, modified version of Nailbuster's XPTPaint

    #include <Arduino.h>
    #include <SPI.h>
    
    #include <Adafruit_ILI9341esp.h>
    #include <Adafruit_GFX.h>
    #include <XPT2046.h>
    
    // Modify the following two lines to match your hardware
    // Also, update calibration parameters below, as necessary
    // For the esp shield, these are the default.
    #define TFT_DC 2
    #define TFT_CS 15
    
    Adafruit_ILI9341 tft = Adafruit_ILI9341(TFT_CS, TFT_DC);
    XPT2046 touch(/*cs=*/ 4, /*irq=*/ 5);
    
    Adafruit_GFX_Button button;
    
    void setup() {
      delay(1000);
    
      Serial.begin(115200);
      SPI.setFrequency(ESP_SPI_FREQ);
    
      tft.begin();
      touch.begin(tft.width(), tft.height());  // Must be done before setting rotation
      Serial.print("tftx ="); Serial.print(tft.width()); Serial.print(" tfty ="); Serial.println(tft.height());
      tft.fillScreen(ILI9341_BLACK);
    
      // Replace these for your screen module
      touch.setCalibration(209, 1759, 1775, 273);
      button.initButton(&tft, 0, 0, 70, 40, ILI9341_DARKCYAN, ILI9341_BLUE, ILI9341_GREENYELLOW, "BUTTON", 2);
      button.drawButton();
    
    }
    
    static uint16_t prev_x = 0xffff, prev_y = 0xffff;
    
    void loop() {
        uint16_t x, y;
      if (touch.isTouching()) {
        touch.getPosition(x, y);
    //  Serial.print("x ="); Serial.print(x); Serial.print(" y ="); Serial.println(y);
    
        prev_x = x;
        prev_y = y;
      } else {
        prev_x = prev_y = 0xffff;
      }
    
    
      button.press(button.contains(x, y)); // tell the button it is pressed
    
    
    // now we can ask the buttons if their state has changed
        if (button.justReleased()) {
            button.drawButton(); // draw normal
       // do work here
        }
    
        if (button.justPressed()) {
            button.drawButton(true); // draw invert!
        }
    
      delay(20);
    }
    

    I hope this can serve as a helpful reference to anyone in the future with this problem