Bodmer TFT_eSPI Slider problem

Hi all,
I need a vertical slider in a project.
I’ve picked through the TFT_eSPI Slider widget demo and ended up with this experiment …

// Trev's Slider experiment
// https://github.com/Bodmer/TFT_eWidget
#include <Arduino.h>
#include <FS.h>
#include <SD.h>
#include <SPI.h>
#include <TFT_eSPI.h>
#include <TFT_eWidget.h>           // Widget library

// Define CS lines stuff
TFT_eSPI tft = TFT_eSPI();
#define TOUCH_CS 5      //CS pin on TFT screen
#define TFT_CS  15      //CS pin on TFT screen
#define SD_CS   22      //CS Pin on SD card reader
uint8_t TFT_Line = 20;

// This is the file name used to store the calibration data
// The SPIFFS file name must start with "/".
#define CALIBRATION_FILE "/TouchCalData2"
// Set REPEAT_CAL to true instead of false to run new calibration
#define REPEAT_CAL false

TFT_eSprite knob = TFT_eSprite(&tft); // Sprite for the slide knob

SliderWidget s1 = SliderWidget(&tft, &knob);    // Slider 1 widget

// TOUCH COORDINATES
uint16_t t_x = 0, t_y = 0;  // To store the touch coordinates

// ##CALIBRATE TOUCH SCREEN #################################
void touch_calibrate() {
  uint16_t calData[5];
  uint8_t calDataOK = 0;
  // check file system exists
  if (!SPIFFS.begin()) {
    Serial.println("formatting file system");
    SPIFFS.format();
    SPIFFS.begin(); }
  // check if calibration file exists and size is correct 
  if (SPIFFS.exists(CALIBRATION_FILE)) {
    if (REPEAT_CAL) {
      // Delete if we want to re-calibrate
      SPIFFS.remove(CALIBRATION_FILE);
    } else {
      File f = SPIFFS.open(CALIBRATION_FILE, "r");
      if (f) {
        if (f.readBytes((char *)calData, 14) == 14)
          calDataOK = 1;
        f.close();
      }
    }
  }
  //Touch screen calibration already done OK ###############
  if (calDataOK && !REPEAT_CAL) {
    //calibration data valid -------------------------------
    tft.setTouch(calData);
  } else {
    //data not valid so recalibrate ------------------------
    tft.fillScreen(TFT_BLACK);
    tft.setCursor(20, 0);
    tft.setTextFont(2);
    tft.setTextSize(2);
    tft.setTextColor(TFT_WHITE, TFT_BLACK);
    tft.println("Touch corners as indicated");
    tft.setTextFont(1);
    tft.println();
    //
    if (REPEAT_CAL) {
      tft.println("Set REPEAT_CAL to false to stop this running again!");
    }
    tft.calibrateTouch(calData, TFT_WHITE, TFT_BLACK, 15);
    tft.println("Calibration complete!");
    // store data -----------------------------------------------
    File f = SPIFFS.open(CALIBRATION_FILE, "w");
    if (f) {
      f.write((const unsigned char *)calData, 14);
      f.close();
    }
  }
}

// SETUP ##########################################################
void setup() {
  Serial.begin(115200);
  tft.begin();
  tft.setRotation(4);
  tft.fillScreen(TFT_BLACK);
  // Calibrate the touch screen and retrieve the scaling factors
  if (REPEAT_CAL) {
    touch_calibrate();
    tft.fillScreen(TFT_BLACK);
  }
  // Draw slider
  s1.createSlider(40, 200, TFT_BLUE, TFT_BLACK, V_SLIDER);
  s1.createKnob(60, 20, 5, TFT_WHITE, TFT_RED);
  s1.setSliderScale(200, 0, 2000);
  s1.drawSlider(200, 100);
  s1.setSliderPosition(0);
}

// LOOP ###########################################################
void loop() {
  static uint32_t scanTime = millis();
  t_x = 0, t_y = 0;                 // To store the touch coordinates
  // Scan for touch every 50ms
  if (millis() - scanTime >= 20) {
    // Pressed will be set true if there is a valid touch on the screen
    if( tft.getTouch(&t_x, &t_y, 0) ) { //250
      if (s1.checkTouch(t_x, t_y)) {
        Serial.print("Slider 1 = "); Serial.println(s1.getSliderPosition());
      }
    }
    scanTime = millis();
  }
}

My PIO.ini …

; PlatformIO Project Configuration File
; Please visit documentation for the other options and examples
; https://docs.platformio.org/page/projectconf.html

[env:nodemcu-32s]
platform = espressif32
board = nodemcu-32s
framework = arduino
monitor_speed = 115200
lib_deps = 
	bodmer/TFT_eSPI@^2.5.43
	bodmer/TFT_eWidget @ ^0.0.6
	SD
lib_ignore = AzureIoTHubMQTTClient //=> this one also has an SD.h file which caused trouble earlier
build_flags = 
	-D USER_SETUP_LOADED
	-D ILI9488_DRIVER
	-D TFT_WIDTH=320
	-D TFT_HEIGHT=480
	-D TFT_RST=4
	-D TFT_DC=2
;TFT
	-D TFT_SCLK=18
	-D TFT_MOSI=23
	-D TFT_MISO=19
	-D TFT_CS=15
;TOUCH
	-D TOUCH_SCLK=18
	-D TOUCH_DIN=23    ;MOSI
	-D TOUCH_DO=19     ;MISO
	-D TOUCH_CS=5
;SD
	-D SD_SCLK=18
	-D SD_MOSI=23
	-D SD_MISO=19
	-D SD_CS=22
;FONTS
	-D LOAD_GLCD=1
	-D LOAD_FONT2
	-D LOAD_FONT3
	-D LOAD_FONT4
	-D LOAD_FONT6
	-D LOAD_FONT7
	-D LOAD_FONT8
	-D LOAD_GFXFF
	-D SMOOTH_FONT
	-D SPI_FREQUENCY=40000000 

This works with tft.setRotation(3), but that’s the wrong rotation for my project.
With tft.setRotation(4), it will work just fine, if I re-calibrate the screen every time it runs (#define REPEAT_CAL true).
But if I set #define REPEAT_CAL false then I get the same VETICAL slider, but to operate it I have to slide my finger somewhere else on the screen HORIZONTALLY.
Any ideas please ?
Trevor

SOLVED !!!
I have solved this problem, so for anyone who lands here with similar problems, please see below
My code is now …

// Trev's Slider experiment
// https://github.com/Bodmer/TFT_eWidget
#include <Arduino.h>
#include <FS.h>
#include <SD.h>
#include <SPI.h>
#include <TFT_eSPI.h>
#include <TFT_eWidget.h>           // Widget library

// Define CS lines stuff
TFT_eSPI tft = TFT_eSPI();
#define TOUCH_CS 5      //CS pin on TFT screen
#define TFT_CS  15      //CS pin on TFT screen
#define SD_CS   22      //CS Pin on SD card reader
uint8_t TFT_Line = 20;

// This is the file name used to store the calibration data
// The SPIFFS file name must start with "/".
#define CALIBRATION_FILE "/TouchCalData2"
// Set REPEAT_CAL to true instead of false to run new calibration
#define REPEAT_CAL false

TFT_eSprite knob = TFT_eSprite(&tft); // Sprite for the slide knob

SliderWidget s1 = SliderWidget(&tft, &knob);    // Slider 1 widget

// TOUCH COORDINATES
uint16_t t_x = 0, t_y = 0;  // To store the touch coordinates

// #########################################################
// ############     CALIBRATE TOUCH SCREEN       ##############
// #########################################################
void touch_calibrate() {
      uint16_t calData[5];
      uint8_t calDataOK = 0;
      // check file system exists
      if (!SPIFFS.begin()) {
            Serial.println("formatting file system");
            SPIFFS.format();
            SPIFFS.begin(); }
            // check if calibration file exists and size is correct 
            if (SPIFFS.exists(CALIBRATION_FILE)) {
                  if (REPEAT_CAL) {
                  // Delete if we want to re-calibrate
                  SPIFFS.remove(CALIBRATION_FILE);
                  } else {
                        File f = SPIFFS.open(CALIBRATION_FILE, "r");
                        if (f) {
                              if (f.readBytes((char *)calData, 14) == 14)
                              calDataOK = 1;
                              f.close();
                 }
           }
      }
// ===================================================
// Touch screen calibration already done and DATA OK ?????
// ===================================================
      if (calDataOK && !REPEAT_CAL) {
            tft.setTouch(calData);   // calibration data valid ???? = EXIT ------
      } else {                       // data not valid so recalibrate ---------------
            tft.fillScreen(TFT_BLACK);
            tft.setCursor(20, 0);
            tft.setTextFont(2);
            tft.setTextSize(1);
            tft.setTextColor(TFT_WHITE, TFT_BLACK);
            tft.println("Touch corners as indicated");
            tft.setTextFont(1);
            tft.println();
            //
            if (REPEAT_CAL) {
              tft.setTextColor(TFT_RED, TFT_BLACK);
              tft.println("Set REPEAT_CAL to false to stop this running again!");
            }
            tft.calibrateTouch(calData, TFT_MAGENTA, TFT_BLACK, 15);
            tft.setTextColor(TFT_GREEN, TFT_BLACK);
            tft.println("Calibration complete!");
            // now store data -----------------------------------------------------------
            File f = SPIFFS.open(CALIBRATION_FILE, "w");
            if (f) {
              f.write((const unsigned char *)calData, 14);
              f.close();
       }
   }
}

// SETUP ##########################################################
void setup() {
      Serial.begin(115200);
      tft.begin();
      tft.setRotation(4);
      tft.fillScreen(TFT_BLACK);
      // Calibrate the touch screen and retrieve the scaling factors
      touch_calibrate();
      // Draw slider
      s1.createSlider(40, 200, TFT_BLUE, TFT_BLACK, V_SLIDER);
      s1.createKnob(60, 20, 5, TFT_WHITE, TFT_RED);
      s1.setSliderScale(200, 0, 2000);
      s1.drawSlider(200, 100);
      s1.setSliderPosition(0);
}

// LOOP ###########################################################
void loop() {
      static uint32_t scanTime = millis();
      t_x = 0, t_y = 0;                               // To store the touch coordinates
      // Scan for touch every 50ms
      if (millis() - scanTime >= 20) {
            // Pressed will be set true if there is a valid touch on the screen
            if( tft.getTouch(&t_x, &t_y, 0) ) {
                  if (s1.checkTouch(t_x, t_y)) {
                  Serial.print("Slider 1 = "); Serial.println(s1.getSliderPosition());
                 }
           }
          scanTime = millis();
    }
}

My PIO.ini is …

; PlatformIO Project Configuration File
; Please visit documentation for the other options and examples
; https://docs.platformio.org/page/projectconf.html
[env:nodemcu-32s]
platform = espressif32
board = nodemcu-32s
framework = arduino
monitor_speed = 115200
lib_deps =
bodmer/TFT_eSPI@^2.5.43
bodmer/TFT_eWidget @ ^0.0.6
SD
lib_ignore = AzureIoTHubMQTTClient //=> this one also has an SD.h file which caused trouble earlier
build_flags =
      -D USER_SETUP_LOADED
      -D ILI9488_DRIVER
      -D TFT_WIDTH=320
      -D TFT_HEIGHT=480
      -D TFT_RST=4
      -D TFT_DC=2
;TFT
      -D TFT_SCLK=18
      -D TFT_MOSI=23
      -D TFT_MISO=19
      -D TFT_CS=15
      ;TOUCH
      -D TOUCH_SCLK=18
      -D TOUCH_DIN=23 ;MOSI
      -D TOUCH_DO=19 ;MISO
      -D TOUCH_CS=5
;SD
      -D SD_SCLK=18
      -D SD_MOSI=23
      -D SD_MISO=19
      -D SD_CS=22
;FONTS
      -D LOAD_GLCD=1
      -D LOAD_FONT2
      -D LOAD_FONT3
      -D LOAD_FONT4
      -D LOAD_FONT6
      -D LOAD_FONT7
      -D LOAD_FONT8
      -D LOAD_GFXFF
      -D SMOOTH_FONT
;SPI Clock
      -D SPI_FREQUENCY=40000000

SOLUTION
The key point is that in Bodmer’s example, the void setup() call to touch_calibrate() was …

void setup()
      tft.begin();
      tft.setRotation(4);
      tft.fillScreen(TFT_BLACK);
      if (REPEAT_CAL) {
        touch_calibrate();
        tft.fillScreen(TFT_BLACK);
      }

So, if REPEAT_CAL is false (= don’t calibrate again), then touch_calibrate() is never ever called, and so the previous calibration data is NEVER retrieved.

My new setup …

void setup()
      tft.begin();
      tft.setRotation(4);
      tft.fillScreen(TFT_BLACK);
      // Calibrate the touch screen and retrieve the scaling factors
      touch_calibrate();

Call tft.setRotation(4) FIRST, before any calibration.
Then touch_calibrate() is called regardless of the state of REPEAT_CAL.
Then in touch_calibrate(), if the REPEAT_CAL is false, it skips a new calibration, to just retrieve the old calibration data.
Trevor

1 Like