Hello! I’ve been working on a project with a xiao ESP32c3 and a round display. I’ve got a lot working, but when I enable wifi I seem to have problems with the touch screen. Is it supported to use WiFi and touch screen at the same time?
… i would not know of any reason why the wifi would not work with the round display… the only think i could think is that the Wifi subsystem uses a dedicated core, so that it can do its wifi stuff continuiously without interuption… the touch process probably also probably likes to run uninterupted. Therefore if the touch is trying to run in the same core as the wifi… this would probably cause a problem… I dont know if you understand the programming well enough to tell what core it is running on… i also dont understand that well… but that is probably the problem… I know the whole touch process is funny acting to begin with…
I think the esp32c3 is just single core, so that might be the problem? I found this which seems to indicate that GPIO is a problem. Could this be affecting the touch screen function?
… it may be technically single core… but the wifi and bluetooth subsystems run in a dedicated processing area… the wifi should not require any gpio to function… but if the gpio is not properly configured it would not work… i am assumung you have a non wifi code that runs correctly?
HI there,
SoCan you post up the code you are using?, Use the code tags above “</>” and paste it in there.
I don’t think that LIB is current BTW, So I would retest using the more Current Seeed Specific for round display(other threads) and try that.
Which Touch driver and Pin are you using?
HTH
GL PJ
Afaik , there isn’t an issue and it does work.
Sorry my code isn’t the best, its an amalgamation of a bunch of other peoples projects, so maybe there is another bug in here. Best I can tell the problem only occurs when the “high power” task is set to high power mode (wifi turns on). It also happens if I inline the tasks so that wifi and display are happening in the same task.
Hi there,
No worries , ALL code is Garbage LOL, what my old instructor used to say.
I’ll try a compile on it see what I get ,
In the mean Time I loaded up a C3 on my Round display and Rolled back to BSP 2.0.17
I ran the Hardware test under the “Seeed Round Display Examples” the touch screen works good, so I went and Added the WIfi to it and made it display the Wifi name and Ip address it gets.
Try that see if it works for you?
Should look like this…
Slider touch still works fine…
#include <lvgl.h>
// uncomment a library for display driver
//#define USE_TFT_ESPI_LIBRARY
#define USE_ARDUINO_GFX_LIBRARY
#include "lv_xiao_round_screen.h"
#include "lv_hardware_test.h"
#include <WiFi.h>
const char *ssid = "PUT YOURS HERE";
const char *password = "SEEEDaliscous";
// Declare the WiFi SSID/IP label and a flag for toggling
static lv_obj_t *wifi_label;
static bool show_ssid = true;
// Timer callback to alternate between SSID and IP address
void wifi_label_update_cb(lv_timer_t *timer) {
if (show_ssid) {
// Display SSID
lv_label_set_text(wifi_label, ssid);
} else {
// Display IP address
String ip = WiFi.localIP().toString();
lv_label_set_text(wifi_label, ip.c_str());
}
show_ssid = !show_ssid; // Toggle between SSID and IP
}
void setup()
{
Serial.begin( 115200 ); //prepare for possible serial debug
Serial.println( "XIAO round screen - LVGL_Arduino" );
Serial.print("Connecting to ");
Serial.println(ssid);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("");
Serial.println("WiFi connected");
Serial.println("IP address: ");
Serial.println(WiFi.localIP());
lv_init();
lv_xiao_disp_init();
lv_xiao_touch_init();
// Run the hardware test
lv_hardware_test();
// Create a label to display the WiFi SSID or IP address
wifi_label = lv_label_create(lv_scr_act());
lv_label_set_text(wifi_label, ssid); // Initially set the label text to the WiFi SSID
lv_obj_set_pos(wifi_label, 65, 150); // Position the label between the slider and the TF-card
// Create a timer to alternate the label content every 3 seconds
lv_timer_create(wifi_label_update_cb, 3000, NULL);
}
void loop()
{
lv_timer_handler(); //let the GUI do its work
delay(5);
}
HTH
GL PJ
serial output…
Connecting to GlassSurf-2.4
.
WiFi connected
IP address:
192.168.1.188
XIAO round screen - LVGL_Arduino
Thanks I’ll give that a try!
HI there,
Ok
Your code appears to work BTW, here is the output.
serial output:
State: 0, hp: 0
State: 0, hp: 0
State: 0, hp: 0
State: 0, hp: 0
State: 0, hp: 0
State: 0, hp: 0
State: 0, hp: 0
compiler output
FQBN: esp32:esp32:XIAO_ESP32C3
Using board 'XIAO_ESP32C3' from platform in folder: C:\Users\Dude\AppData\Local\Arduino15\packages\esp32\hardware\esp32\3.0.5
Using core 'esp32' from platform in folder: C:\Users\Dude\AppData\Local\Arduino15\packages\esp32\hardware\esp32\3.0.5
edit_4_brevity...
Using library SPI at version 3.0.5 in folder: C:\Users\Dude\AppData\Local\Arduino15\packages\esp32\hardware\esp32\3.0.5\libraries\SPI
Using library TFT_eSPI at version 2.5.43 in folder: D:\Arduino_projects\libraries\TFT_eSPI
Using library FS at version 3.0.5 in folder: C:\Users\Dude\AppData\Local\Arduino15\packages\esp32\hardware\esp32\3.0.5\libraries\FS
Using library SPIFFS at version 3.0.5 in folder: C:\Users\Dude\AppData\Local\Arduino15\packages\esp32\hardware\esp32\3.0.5\libraries\SPIFFS
Using library I2C BM8563 RTC at version 1.0.4 in folder: D:\Arduino_projects\libraries\I2C_BM8563_RTC
Using library Wire at version 3.0.5 in folder: C:\Users\Dude\AppData\Local\Arduino15\packages\esp32\hardware\esp32\3.0.5\libraries\Wire
Using library Seeed Arduino Round display at version 1.0.0 in folder: D:\Arduino_projects\libraries\Seeed_Arduino_Round_display
Using library lvgl at version 8.3.7 in folder: D:\Arduino_projects\libraries\lvgl
Using library WiFi at version 3.0.5 in folder: C:\Users\Dude\AppData\Local\Arduino15\packages\esp32\hardware\esp32\3.0.5\libraries\WiFi
Using library Networking at version 3.0.5 in folder: C:\Users\Dude\AppData\Local\Arduino15\packages\esp32\hardware\esp32\3.0.5\libraries\Network
Using library HTTPClient at version 3.0.5 in folder: C:\Users\Dude\AppData\Local\Arduino15\packages\esp32\hardware\esp32\3.0.5\libraries\HTTPClient
Using library NetworkClientSecure at version 3.0.5 in folder: C:\Users\Dude\AppData\Local\Arduino15\packages\esp32\hardware\esp32\3.0.5\libraries\NetworkClientSecure
"C:\\Users\\Dude\\AppData\\Local\\Arduino15\\packages\\esp32\\tools\\esp-rv32\\2302/bin/riscv32-esp-elf-size" -A "C:\\Users\\Dude\\AppData\\Local\\Temp\\arduino\\sketches\\F2968E4704A032EC402C92A433B27890/sketch_oct19a.ino.elf"
Sketch uses 1000584 bytes (76%) of program storage space. Maximum is 1310720 bytes.
Global variables use 35124 bytes (10%) of dynamic memory, leaving 292556 bytes for local variables. Maximum is 327680 bytes.
"C:\Users\Dude\AppData\Local\Arduino15\packages\esp32\tools\esptool_py\4.6/esptool.exe" --chip esp32c3 --port "COM3" --baud 921600 --before default_reset --after hard_reset write_flash -z --flash_mode keep --flash_freq keep --flash_size keep 0x0 "C:\Users\Dude\AppData\Local\Temp\arduino\sketches\F2968E4704A032EC402C92A433B27890/sketch_oct19a.ino.bootloader.bin" 0x8000 "C:\Users\Dude\AppData\Local\Temp\arduino\sketches\F2968E4704A032EC402C92A433B27890/sketch_oct19a.ino.partitions.bin" 0xe000 "C:\Users\Dude\AppData\Local\Arduino15\packages\esp32\hardware\esp32\3.0.5/tools/partitions/boot_app0.bin" 0x10000 "C:\Users\Dude\AppData\Local\Temp\arduino\sketches\F2968E4704A032EC402C92A433B27890/sketch_oct19a.ino.bin"
HTH
GL PJ
I’m beginning to suspect the problem is to do with FreeRTOS. The problem comes up when the high power task is created, which is programmed to happen when battery level is high enough (looks like your battery pin is disabled from the dip switches, which is why the application seems to be working for you). I suspect if you were to enable battery level measurement you might start to see some bugs.
I’m going to try rewriting the application using just the standard arduino setup and loop and update here after!
#include <SPI.h>
#include <TFT_eSPI.h>
#include "I2C_BM8563.h"
#define USE_TFT_ESPI_LIBRARY
#include "lv_xiao_round_screen.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include <WiFi.h>
#include <HTTPClient.h>
// TFT_eSPI tft = TFT_eSPI();
TFT_eSprite img = TFT_eSprite(&tft);
I2C_BM8563 rtc(I2C_BM8563_DEFAULT_ADDRESS, Wire);
const char *ntpServer = "time.cloudflare.com";
const char *ssid = "ST";
const char *password = "test1234";
// TimerHandle_t hp_timer;
// #define USE_TFT_ESPI_LIBRARY
#define NUM_ADC_SAMPLE 20
#define BATTERY_DEFICIT_VOL 1850
#define BATTERY_FULL_VOL 2450
// https://rgbcolorpicker.com/565
#define WHITE 0xFFFF
#define BLACK 0x0000
#define BLUE 0x001F
#define RED 0xF800
#define GREEN 0x07E0
#define YELLOW 0xFFE0
#define GREY 0x4a49
#define TEAL 0x063f
#define DARK_GREY 0x3186
#define TEXT_COLOR 0xFFFF
#define SCALE0 0xC655
#define SCALE1 0x5DEE
#define DEG2RAD 0.0174532925
#define BATLVLFORHP 25
// TL_DATUM = 0 = Top left
// TC_DATUM = 1 = Top centre
// TR_DATUM = 2 = Top right
// ML_DATUM = 3 = Middle left
// MC_DATUM = 4 = Middle centre
// MR_DATUM = 5 = Middle right
// BL_DATUM = 6 = Bottom left
// BC_DATUM = 7 = Bottom centre
// BR_DATUM = 8 = Bottom right
double center_x = 120;
double center_y = 120;
int currentScreen = 0;
lv_coord_t touchX, touchY;
uint32_t primary_color = WHITE;
unsigned long currentTime = 0;
unsigned long timeBatCheck = 0;
unsigned long timeHP = 0;
I2C_BM8563_TimeTypeDef timeStruct;
int currentBattery = 0;
int high_power_state = 0;
bool init_wifi = false;
void state_machine_task()
{
if (chsc6x_is_pressed())
{
printf("Pressed\n");
}
switch (currentScreen)
{
case 0:
if (chsc6x_is_pressed())
{
currentScreen = 1;
tft.fillScreen(BLACK);
delay(300);
}
else
{
rtc.getTime(&timeStruct);
// printf("%d H %d m %d s\n", timeStruct.hours, timeStruct.minutes, timeStruct.seconds);
drawClock(timeStruct.hours * 60 + timeStruct.minutes + timeStruct.seconds / 60.0);
}
break;
case 1:
if (chsc6x_is_pressed())
{
chsc6x_get_xy(&touchX, &touchY);
tft.fillScreen(BLACK);
delay(300);
if (touchX < center_x && touchY < center_y) // Top Left
{
currentScreen = 0;
}
else if (touchX >= center_x && touchY < center_y) // Top Right
{
primary_color = RED;
}
else if (touchX >= center_x && touchY >= center_y) // BOT Right
{
primary_color = BLUE;
}
else if (touchX < center_x && touchY >= center_y) // BOT LEFT
{
primary_color = WHITE;
}
}
else
{
img.createSprite(240, 240);
img.fillScreen(TFT_TRANSPARENT);
int arrow_x = 40;
int arrow_y = 65;
img.fillTriangle(arrow_x, arrow_y, arrow_x + 15, arrow_y + 10, arrow_x + 15, arrow_y - 10, primary_color);
img.fillRect(arrow_x + 15, arrow_y - 2, 15, 5, primary_color);
img.fillCircle(180, 60, 10, RED);
img.fillCircle(180, 180, 10, BLUE);
img.fillCircle(60, 180, 10, WHITE);
img.pushSprite(0, 0, TFT_TRANSPARENT);
img.deleteSprite();
}
break;
}
}
void high_power_task()
{
if (currentTime - timeHP < 1000)
{
return;
}
timeHP = currentTime;
printf("State: %d\n", high_power_state);
switch (high_power_state)
{
case 0: // Low power
// if (currentBattery > BATLVLFORHP)
if (true)
{
high_power_state = 1;
init_wifi = false;
}
break;
case 1: // Go to high power
if (!init_wifi)
{
WiFi.disconnect();
WiFi.mode(WIFI_STA);
WiFi.enableSTA(true);
WiFi.begin(ssid, password);
init_wifi = true;
}
if (WiFi.status() == WL_CONNECTED)
{
high_power_state = 2;
}
// if (currentBattery < BATLVLFORHP)
if (false)
{
high_power_state = 3;
}
break;
case 2: // Hight power
// if (currentBattery < BATLVLFORHP)
if (false)
{
high_power_state = 3;
}
break;
case 3: // Go to low power
WiFi.mode(WIFI_OFF);
WiFi.disconnect();
high_power_state = 0;
break;
}
// if (currentBattery < BATLVLFORHP)
// {
// xTimerStop(hp_timer, 0);
// }
// // Connect to an access point
// Serial.print("Connecting to Wi-Fi ");
// WiFi.begin(ssid, password);
// Serial.print(" At this point ");
// while (WiFi.status() != WL_CONNECTED)
// {
// delay(500);
// Serial.print(".");
// }
// Serial.println(" CONNECTED");
// // Set ntp time to local
// configTime(6 * 3600, 0, ntpServer);
// // Get local time
// struct tm timeInfo;
// if (getLocalTime(&timeInfo))
// {
// printf("Got local time");
// // Set RTC time
// I2C_BM8563_TimeTypeDef timeStruct;
// timeStruct.hours = timeInfo.tm_hour;
// timeStruct.minutes = timeInfo.tm_min;
// timeStruct.seconds = timeInfo.tm_sec;
// rtc.setTime(&timeStruct);
// // Set RTC Date
// I2C_BM8563_DateTypeDef dateStruct;
// dateStruct.weekDay = timeInfo.tm_wday;
// dateStruct.month = timeInfo.tm_mon + 1;
// dateStruct.date = timeInfo.tm_mday;
// dateStruct.year = timeInfo.tm_year + 1900;
// rtc.setDate(&dateStruct);
// }
}
void battery_level_percent()
{
if (currentTime - timeBatCheck < 1000)
{
return;
}
timeBatCheck = currentTime;
int32_t mvolts = 0;
for (int8_t i = 0; i < NUM_ADC_SAMPLE; i++)
{
mvolts += analogReadMilliVolts(D0);
delay(1);
}
mvolts /= NUM_ADC_SAMPLE;
int32_t level = (mvolts - BATTERY_DEFICIT_VOL) * 100 / (BATTERY_FULL_VOL - BATTERY_DEFICIT_VOL); // 1850 ~ 2100
level = (level < 0) ? 0 : ((level > 100) ? 100 : level);
int prev_Battery = currentBattery;
currentBattery = level;
}
void drawClock(double minutes)
{
int x = 0;
int y = 0;
img.createSprite(240, 240);
img.fillScreen(TFT_TRANSPARENT);
// Draw the background
img.drawArc(center_x, center_y, 117, 90, 0, 360, BLACK, BLACK);
// Draw the hour ticks
for (int i = 0; i < 12; i++)
{
int a = i * 30;
int dx = 116 * cos((a - 90) * DEG2RAD) + center_x;
int dy = 116 * sin((a - 90) * DEG2RAD) + center_y;
img.fillCircle(dx, dy, 2, DARK_GREY);
}
// Draw the tracks
img.drawArc(center_x, center_y, 112, 110, 0, 360, DARK_GREY, BLACK);
img.drawArc(center_x, center_y, 97, 95, 0, 360, DARK_GREY, BLACK);
// Draw the minute hand
double minute_hand_angle = ((fmod(minutes, 60.0) * 6) - 90) * DEG2RAD;
x = 111 * cos(minute_hand_angle) + center_x;
y = 111 * sin(minute_hand_angle) + center_y;
img.fillCircle(x, y, 3, primary_color);
// Draw the hour hand
double hour_hand_angle = ((minutes * 360 / 720) - 90) * DEG2RAD;
x = 96 * cos(hour_hand_angle) + center_x;
y = 96 * sin(hour_hand_angle) + center_y;
img.fillCircle(x, y, 5, primary_color);
// Draw the battery level
int16_t textWidth = img.textWidth("000"); // Estimate the maximum width for a 3-digit number
int16_t textHeight = 24; // Adjust based on text size
img.fillRect(center_x - (textWidth / 2), 180, textWidth, textHeight, BLACK);
img.setTextSize(2);
img.drawCentreString(String(currentBattery) + "%", center_x, 180, 1);
// Update the high power indicator
uint32_t color = BLACK;
if (high_power_state == 1)
{
color = TEAL;
}
if (high_power_state == 2)
{
color = GREEN;
}
img.drawSmoothArc(center_x, center_y, 72, 65, 140, 220, color, BLACK, true);
img.pushSprite(0, 0, TFT_TRANSPARENT);
img.deleteSprite();
}
void setup()
{
// WiFi.mode(WIFI_STA);
// WiFi.disconnect();
// lv_init();
// lv_xiao_disp_init();
lv_xiao_touch_init();
Serial.begin(9600);
// Start I2C and RTC
Wire.begin();
rtc.begin();
pinMode(TOUCH_INT, INPUT_PULLUP);
WiFi.disconnect();
WiFi.mode(WIFI_OFF);
// WiFi.enableSTA(true);
tft.begin();
tft.setRotation(0);
tft.fillScreen(BLACK);
// /*Initialize the display buffer*/
// static lv_disp_draw_buf_t draw_buf;
// static lv_color_t buf[ SCREEN_WIDTH * LVGL_BUFF_SIZE ];
// lv_disp_draw_buf_init( &draw_buf, buf, NULL, SCREEN_WIDTH * LVGL_BUFF_SIZE );
// /*Initialize the display driver for lvgl*/
// static lv_disp_drv_t disp_drv;
// lv_disp_drv_init( &disp_drv );
// disp_drv.hor_res = SCREEN_WIDTH;
// disp_drv.ver_res = SCREEN_HEIGHT;
// disp_drv.flush_cb = xiao_disp_flush;
// disp_drv.draw_buf = &draw_buf;
// lv_disp_drv_register( &disp_drv );
static lv_indev_drv_t indev_drv;
lv_indev_drv_init(&indev_drv);
indev_drv.type = LV_INDEV_TYPE_POINTER;
indev_drv.read_cb = chsc6x_read;
lv_indev_drv_register(&indev_drv);
img.setColorDepth(16);
}
void loop()
{
currentTime = millis();
battery_level_percent();
high_power_task();
state_machine_task();
}
No, that doesn’t seem to be it. I changed it to use loop and setup (no FreeRTOS stuff at all) and am experiencing the same error. The difference between my application and the modified example you sent seems to be that I am connecting to wifi while writing to the display, whereas you connect before displaying anything, and then just query IP info in the loop.
For the code I just posted, I commented out the battery detection code and just set it to true so you can see the error. You can change the true in line 152 to false (which then doesn’t turn on wifi) and the application starts working.
sounds like you need to revise your code… just like i thought it was
HI there,
Ok I have a battery I can connect also, time permitting I’ll try it out tomorrow.
SO is it the Touch interrupt callback not firing? when you enable the WiFi ?
Well some good news is it all the newer BSP and LIB’s so there’s that
Is the fail , it freezes or doesn’t work at all? the wifi shouldn’t block Albeit but microseconds if so. Touch should still register.
HTH
GL PJ
Your close ,you’ll get it , seems timer related. I’ll try
Thank you for trying to help! I’ve revised the code and I have a much simpler example that demonstrates the problem. There is an animation in the center. After 10 loops of the animation, I try to turn on wifi and everything freezes:
#include <SPI.h>
#include <TFT_eSPI.h>
#include "I2C_BM8563.h"
#define USE_TFT_ESPI_LIBRARY
#include "lv_xiao_round_screen.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include <WiFi.h>
#include <HTTPClient.h>
TFT_eSprite img = TFT_eSprite(&tft);
const char *ssid = "ST";
const char *password = "test1234";
// https://rgbcolorpicker.com/565
#define WHITE 0xFFFF
#define BLACK 0x0000
#define BLUE 0x001F
#define RED 0xF800
#define GREEN 0x07E0
double center_x = 120;
double center_y = 120;
lv_coord_t touchX, touchY;
bool init_wifi = false;
bool connected_wifi = false;
void setup() {
Serial.begin(9600);
// Start I2C
Wire.begin();
WiFi.disconnect();
WiFi.mode(WIFI_OFF);
// WiFi.enableSTA(true);
tft.begin();
tft.setRotation(0);
tft.fillScreen(BLACK);
static lv_indev_drv_t indev_drv;
lv_indev_drv_init(&indev_drv);
indev_drv.type = LV_INDEV_TYPE_POINTER;
indev_drv.read_cb = chsc6x_read;
lv_indev_drv_register(&indev_drv);
img.setColorDepth(16);
}
int rad = 0;
uint32_t color = GREEN;
int cnt = 0;
void loop() {
// Process button inputs to color animation
if (chsc6x_is_pressed()) {
chsc6x_get_xy(&touchX, &touchY);
if (touchX > center_x) {
color = RED;
} else {
color = GREEN;
}
}
// Drive the animation
int rad = cnt % 40;
// Draw some buttons and a simple animation
img.createSprite(240, 240);
img.fillScreen(BLACK);
img.drawCircle(center_x, center_y, 40, WHITE);
img.drawCircle(center_x, center_y, rad, color);
img.fillCircle(center_x + 80, center_y, 10, RED);
img.fillCircle(center_x - 80, center_y, 10, GREEN);
img.fillCircle(center_x, center_y - 80, 10, init_wifi ? connected_wifi ? GREEN : BLUE : BLACK);
img.pushSprite(0, 0, TFT_TRANSPARENT);
img.deleteSprite();
// Enable wifi after 400 cnts have passed
if (cnt > 400)
{
// On first loop initialize wifi
if (!init_wifi) {
WiFi.mode(WIFI_STA);
WiFi.enableSTA(true);
WiFi.begin(ssid, password);
init_wifi = true;
}
// On every subsequent loop, check connection status
if (WiFi.status() == WL_CONNECTED) {
connected_wifi = true;
}
}
cnt++;
}
thanks… hopefully we can find the root of the problem
Did you try inserting some debugging printf statements? Which part of WiFi initialization is causing the freeze?
Obviously any crash inside of WiFi initialization is going to then freeze the animations since the loop will stop running.
If you comment out all animation code, but leave the rest as is…does it work? (perhaps instead of animation replace with simple printf() command?
Thats the strange part. The screen freezes, but code execution continues as normal. I did insert print statements to try to find what might be causing this, but as far as I can tell looking at them, there isn’t anything wrong. Just the screen stops updating…
Hi there,
Can you provide the compiler output from this code?
just first 3 lines and the last 10 or so before it begins upload.
TIA
I’ll look and see what it does.
HTH
GL PJ