Bike Computer - help with touchscreen

This is the sequel to Bike Computer help- using smooth arc.

I didn't even know where to get started. All of my web searches on the matter were fruitless. My hardware is an ESP32-S3 with an integral 240 x 240 round LCD and touchscreen. You can see it here:

I honestly didn't even know how to start until I found this webpage:
https://www.bitsanddroids.com/post/how-to-program-a-touchscreen-on-an-esp32

I entered the code from there on lines 31, 34-44 and 66 of my previous sketch. It's a work in progress so there are some commented lines that will be deleted at some point.

Anyway, on that site, the author implied that tft.getTouch was enough to register a touch on the screen. In my case, that's all I want to do. Ideally, I would like to swipe the screen right to go right and left to go left, but the bottom of the screen would just circle around. I haven't seen ANYTHING on swiping, so a touch on the screen would be fine. I don't need a button. The whole screen can be used. I was happy that it did compile and load without puking, but it also didn't work. Thought I would turn the whole screen red just to let me know it worked.

I could use some help understanding the touchscreen. Let me know if you have any questions. Here's what the screen looks like and the area where it says TOTAL MILES should switch between the various modes (TRIP MILES, AVG. SPEED, etc.).

// 11-29-24 Bike computer interface with smooth arc instead of sprite with no erase.
#include "outer_ring_test_gradiant_pink_blue_glow3.h"
#include <TFT_eSPI.h>
//#include <Adafruit_GFX.h>
#include <lvgl.h>
//#include <Fonts/FreeSansBold9pt7b.h>

//lv_disp_t * display1 = lv_disp_create(240, 240)

uint16_t x = 120;                           // Position of centre of arc, round screen is 240 x 240 with corners chopped off.
uint16_t y = 120;

uint16_t fg_color = TFT_CYAN;               // Foreground and background colour used for smoothing (anti-aliasing)
uint16_t bg_color = TFT_BLACK;

uint8_t radius = 100;                       // Outer arc radius
uint8_t thickness = 15;                     // Thickness or arc
uint8_t inner_radius = radius - thickness;  // Calculate inner radius (can be 0 for circle segment)

const unsigned long refresh_rate = 1000;    //interval to update speed/screen (millis)
unsigned long previousTime = 0;             //longs are needed because millis can get big fast
float speed;
static int16_t old_end_angle = 60;          //start old_end_angle for program.

TFT_eSPI tft = TFT_eSPI();                  // Create object "tft"
#include "NotoSansBold72.h"
#include "Dune_Rise_24.h"
#define AA_FONT_LARGE NotoSansBold72
#define AA_FONT_SMALL Dune_Rise_24

uint16_t t_x = 0, t_y = 0;

long a;
void checkTouched()                         //Copied this function from somewhere to try out.  Needs the t_x and t_y defined
                                            //and then call the checkTouched() function in the loop.
{
	//Remember this function returns false if the touch is invalid
	//C++ asserts something as true if it's not 0. So with a valid press
  //This statement will assert to true
	if(tft.getTouch(&t_x, &t_y))
  {
    tft.fillScreen(TFT_RED);
  }
}

//SETUP *********************************************************************************************************
void setup(void) 
{
  Serial.begin(115200);
  tft.init();
  tft.setRotation(0);  //Rotate display to appropriate angle. 0 degrees is at 6 o'clock position
  tft.fillScreen(TFT_BLACK);
  tft.pushImage(0, 0, 240, 240, outer_ring_test_gradiant_pink_blue_glow3);
  tft.setTextDatum(MC_DATUM);
  tft.drawString("MPH", x, y + 35, 2);
  tft.drawString("TOTAL MILES", x, y + 90, 2);

  // Create a sprite for the mileage display
#define MILE_TEXT_WIDTH   240
#define MILE_TEXT_HEIGHT  50
 
}
//MAIN LOOP********************************************************************************************************
void loop() 
{
  checkTouched();
  unsigned long currentTime = millis();
  if (currentTime - previousTime >= refresh_rate) 
  {
    a = random(60, 301);

    speed = 27.7;
    uint16_t start_angle = 60;  // Start angle must be in range 0 to 360. Arcs are drawn clockwise from start_angle to end_angle
    uint16_t end_angle = a;     // End angle must be in range 0 to 360
    while (end_angle != old_end_angle) 
    {
      tft.drawArc(x, y, radius, inner_radius, start_angle, end_angle, fg_color, bg_color);

      if (end_angle < old_end_angle) 
      {
        tft.drawArc(x, y, radius, inner_radius, end_angle, old_end_angle, TFT_BLACK, bg_color);
      }
      float distance = 1000.3;
      tft.setTextColor(TFT_WHITE);
      tft.loadFont(AA_FONT_LARGE);
      tft.drawFloat(speed, 1, x, y);  //x and y are the upper left corner of the speed text, apparently
      tft.loadFont(AA_FONT_SMALL);
      //tft.setTextColor(TFT_WHITE);
      tft.drawFloat(distance, 1, MILE_TEXT_WIDTH / 2, y + 90 - MILE_TEXT_HEIGHT / 2);
      //delay(250);
      //tft.setTextColor(TFT_BLACK);
      //tft.drawFloat(distance, 1, MILE_TEXT_WIDTH / 2, y + 90 - MILE_TEXT_HEIGHT / 2);
      old_end_angle = end_angle;
    }

    previousTime = currentTime;
  }
}

When I run the Test_Touch_Controller.ino, it fails. I've tried several different pins for the touch and none of them have worked.

What I don't understand is the documentation says the touch screen shares an I2C connection, which is two lines, but these sketches seem to imply that the touch screen will come over only one GPIO pin. Comments?

Ok here's a new interesting problem. When I turn on the Serial Monitor, it causes the display (round project display) to go blank. WTF?

Hi,

The touch driver of your display is "CST8165S".

So I think you can use this library.

You can download it from Library Manager.

https://docs.arduino.cc/libraries/cst816s/

1 Like

Thank you for that. I tried the touch_test.ino with a whole bunch of different values based on the documentation for the following command, but none of them worked.

CST816S touch(6, 7, 13, 5); // sda, scl, rst, irq

Pin assignment looks good.

Then please check the I2C address. The library assumes it is 0x15 in CST816S.h.

#define CST816S_ADDRESS     0x15

You can get the I2C address of your device using i2c_scanner:

https://playground.arduino.cc/Main/I2cScanner/

1 Like

I ran the scan, but all I got was gibberish even though I matched the 9600 baud rate. The instructions DO say this, though.

This sketch tests the standard 7-bit addresses
// Devices with higher bit address might not be seen properly.

Hum...

Here is the datasheet from waveshare.com:
https://www.waveshare.com/w/upload/5/51/CST816S_Datasheet_EN.pdf

It says:

So 0x15 might be OK.

This message typically appears when I2C communication fails.

Maybe try asking the seller for support?

By the way, you can refer your pin assignments in here:

This header file will be loaded automatically by Arduino IDE. So you can:

CST816S touch(SDA, SCL, TP_RST, TP_INT); // sda, scl, rst, irq
1 Like

I used a second scanner from Nick Gammon and it didn't see anything either. I do know the touchscreen works because the sketch it came pre-loaded with worked.

The document shows the I2C on GPIO 6 and 7. Is the hex address just either 6 or 7 in hex?

Yes. Using SDA, SCL is better.

1 Like

Can you get that sketch?

Thank you again. This information appears to be the same as that in the documentation from Waveshare.

No. There is another demo it came with, but when I verify it, it has errors. Guess where?

Here's the error but I'm not sure how to decifer it:

In file included from M:\Downloads\Win10 downloads\Arduino\Esp32_s3_touch_lcd_1.28_code\Esp32_s3_touch_lcd_1.28_code\Arduino\esp32-s3-touch-lcd-1.28-demo\DEV_Config.h:36,
from M:\Downloads\Win10 downloads\Arduino\Esp32_s3_touch_lcd_1.28_code\Esp32_s3_touch_lcd_1.28_code\Arduino\esp32-s3-touch-lcd-1.28-demo\DEV_Config.cpp:29:
C:\Users\ozone\AppData\Local\Arduino15\packages\esp32\hardware\esp32\2.0.12\libraries\Wire\src/Wire.h: In function 'void DEV_I2C_Read_Register(uint8_t, uint8_t, uint16_t*)':
C:\Users\ozone\AppData\Local\Arduino15\packages\esp32\hardware\esp32\2.0.12\libraries\Wire\src/Wire.h:127:13: note: candidate 1: 'uint8_t TwoWire::requestFrom(int, int)'
uint8_t requestFrom(int address, int size);
^~~~~~~~~~~
C:\Users\ozone\AppData\Local\Arduino15\packages\esp32\hardware\esp32\2.0.12\libraries\Wire\src/Wire.h:125:13: note: candidate 2: 'uint8_t TwoWire::requestFrom(uint8_t, uint8_t)'
uint8_t requestFrom(uint8_t address, uint8_t size);

It look like it's having trouble finding uint8_t TwoWire in the Wire.h library. But I don't see that .h file called out in the program. But I also don't see it in my library. Sooo. . . I'll go get it and see what happens.

Man, I swear, everything is like pulling teeth. The CST816S.cpp file DOES call Wire.h, so I go to the libraries and it doesn't come up. I do a search online and an answer in a forum tells me where to find it, except that location doesn't seem to exist on my computer and/or I can't seem to find that location. I performed a search on my computer and nothing. I went to github and found it there. I created a new tab, called it Wire.h and pasted it in. Now it errors on TwoWire, but in Wire.h it seems to call out a TwoWire_h not a TwoWire.h. What do I do with that?

Did you read "Install Arduino-ESP32" section in WaveShare's wiki ?

I think your version of esp32 board package might be 3.0.7, the latest. So try to downgrade it to 2.0.12.

This may be the reason why i2c_scanner failed and why you experienced such compile errors.

Edit: You can downgrade it from "Board Manager".

1 Like

Yeah, I read it. It's 2.0.12. The board literally won't work with newer versions.

Oh, I'm sorry. There's "2.0.12" in error message you posted.

Hum...

1 Like

I think the best place to request support is via the "Support" link at the top of the Wiki page.

1 Like

I'll look into it. Gonna go work on my car today. At least I understand that. Here's the new error:
In file included from M:\Downloads\Win10 downloads\Arduino\Esp32_s3_touch_lcd_1.28_code\Esp32_s3_touch_lcd_1.28_code\Arduino\esp32-s3-touch-lcd-1.28-demo\DEV_Config.h:36,
from M:\Downloads\Win10 downloads\Arduino\Esp32_s3_touch_lcd_1.28_code\Esp32_s3_touch_lcd_1.28_code\Arduino\esp32-s3-touch-lcd-1.28-demo\DEV_Config.cpp:29:
C:\Users\ozone\AppData\Local\Arduino15\packages\esp32\hardware\esp32\2.0.12\libraries\Wire\src/Wire.h: In function 'void DEV_I2C_Read_Register(uint8_t, uint8_t, uint16_t*)':
C:\Users\ozone\AppData\Local\Arduino15\packages\esp32\hardware\esp32\2.0.12\libraries\Wire\src/Wire.h:127:13: note: candidate 1: 'uint8_t TwoWire::requestFrom(int, int)'
uint8_t requestFrom(int address, int size);
^~~~~~~~~~~
C:\Users\ozone\AppData\Local\Arduino15\packages\esp32\hardware\esp32\2.0.12\libraries\Wire\src/Wire.h:125:13: note: candidate 2: 'uint8_t TwoWire::requestFrom(uint8_t, uint8_t)'
uint8_t requestFrom(uint8_t address, uint8_t size);
^~~~~~~~~~~