Description
I just discovered that I can use the core lvgl library in arduino and not use the lv_arduino library. (According to these instructions).
Using the core lvgl I can build but I’m running into a touch pad issue… I’m using a FT6206 capacitive touch device and I know its working because I can print its touch point in the main loop.
But I’m not getting any input in the my_touchpad_read function to the point where I feel like the function\callback is not being called at all. To test this theory, I put a print statement into the function and saw nothing in my output console. So I switched back to the lv_arduino library (same exact code, no changes) and the print statement and touch code worked as expected.
What MCU/Processor/Board and compiler are you using?
- ST Nucleo 144 (STM32F767zi)
- Arduino on PlatformIO IDE
- ILI9488 3.5" SPI screen (480*320) with FT6206 touch
- TFT_eSPI library for screen
What do you experience?
my_touchpad_read() is not called when using the core lvgl library. But simply switching out to the lv_arduino library with no code changes, the my_touchpad_read() works as expected.
What do you expect?
my_touchpad_read() works in both lvgl and lv_arduino libraries.
Code to reproduce
//Created by Hamid Saffari @ Apr 2020. https://github.com/HamidSaffari/ Released into the public domain.
#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include "lvgl.h"
#include <TFT_eSPI.h>
#include <Adafruit_FT6206.h>
#define LED_PIN PB0
TFT_eSPI tft = TFT_eSPI(); /* TFT instance */
static lv_disp_buf_t disp_buf;
static lv_color_t buf[LV_HOR_RES_MAX * 10];
// The FT6206 uses hardware I2C (SCL/SDA)
Adafruit_FT6206 touch = Adafruit_FT6206();
lv_obj_t * slider_label;
int screenWidth = 480;
int screenHeight = 320;
/* By Bodmer in https://github.com/Bodmer/TFT_eSPI/issues/581
faster and more efficient than previous one: */
void my_disp_flush(lv_disp_drv_t *disp, const lv_area_t *area, lv_color_t *color_p)
{
uint32_t w = (area->x2 - area->x1 + 1);
uint32_t h = (area->y2 - area->y1 + 1);
tft.startWrite();
#ifdef USE_DMA
tft.pushImageDMA(area->x1, area->y1, w, h, &color_p->full);
// Note: tft.endWrite(); must be called in my_lv_tick_handler when DMA is complete
#else
tft.setAddrWindow(area->x1, area->y1, w, h);
tft.pushColors(&color_p->full, w * h, true);
tft.endWrite();
#endif
lv_disp_flush_ready(disp);
}
bool my_touchpad_read(lv_indev_drv_t * indev_driver, lv_indev_data_t * data)
{
// int16_t touchX, touchY;
TS_Point tp = touch.getPoint();
int16_t touchX = tp.x;
int16_t touchY = tp.y;
bool touched = false;
if ((touchX > 0) || (touchY > 0)) {
touched = true;
}
if(!touched)
{
data->state = LV_INDEV_STATE_REL;
return false;
}
else
{
data->state = LV_INDEV_STATE_PR;
}
Serial.println(touchX);
Serial.println(touchY);
Serial.println(touched);
Serial.println("==================\n");
return false; /*Return `false` because we are not buffering and no more data to read*/
}
void printEvent(String Event, lv_event_t event)
{
Serial.print(Event);
Serial.printf(" ");
switch(event) {
case LV_EVENT_PRESSED:
Serial.printf("Pressed\n");
break;
case LV_EVENT_SHORT_CLICKED:
Serial.printf("Short clicked\n");
break;
case LV_EVENT_CLICKED:
Serial.printf("Clicked\n");
break;
case LV_EVENT_LONG_PRESSED:
Serial.printf("Long press\n");
break;
case LV_EVENT_LONG_PRESSED_REPEAT:
Serial.printf("Long press repeat\n");
break;
case LV_EVENT_RELEASED:
Serial.printf("Released\n");
break;
}
}
void slider_event_cb(lv_obj_t * slider, lv_event_t event)
{
printEvent("Slider", event);
if(event == LV_EVENT_VALUE_CHANGED) {
static char buf[4]; /* max 3 bytes for number plus 1 null terminating byte */
snprintf(buf, 4, "%u", lv_slider_get_value(slider));
lv_label_set_text(slider_label, buf); /*Refresh the text*/
int16_t value = lv_slider_get_value(slider);
value = map(value, 0, 100, 0, 255);
//analogWriteFrequency(2000); // Set PMW period to 2000 Hz instead of 1000
analogWrite(LED_PIN, value);//8-bit by default
}
}
void setup() {
Serial.begin(115200); /* prepare for possible serial debug */
pinMode(LED_PIN, OUTPUT);
pinMode(PF14, OUTPUT);
digitalWrite(PF14, HIGH);
delay(2000);
lv_init();
tft.begin(); /* TFT init */
tft.setRotation(3);
if (!touch.begin(40)) { // pass in 'sensitivity' coefficient
Serial.println("Couldn't start FT6206 touchscreen controller");
} else {
Serial.println("FT6206 touchscreen controller CONNECTED!");
}
lv_disp_buf_init(&disp_buf, buf, NULL, LV_HOR_RES_MAX * 10);
/*Initialize the display*/
lv_disp_drv_t disp_drv;
lv_disp_drv_init(&disp_drv);
disp_drv.hor_res = screenWidth;
disp_drv.ver_res = screenHeight;
disp_drv.flush_cb = my_disp_flush;
disp_drv.buffer = &disp_buf;
lv_disp_drv_register(&disp_drv);
lv_indev_drv_t indev_drv;
lv_indev_drv_init(&indev_drv); /*Descriptor of a input device driver*/
indev_drv.type = LV_INDEV_TYPE_POINTER; /*Touch pad is a pointer-like device*/
indev_drv.read_cb = my_touchpad_read; /*Set your driver function*/
lv_indev_drv_register(&indev_drv); /*Finally register the driver*/
//Set the theme..
//lv_theme_t * th = lv_theme_night_init(210, NULL); //Set a HUE value and a Font for the Night Theme
//lv_theme_set_current(th);
lv_obj_t * scr = lv_cont_create(NULL, NULL);
lv_disp_load_scr(scr);
//lv_obj_t * tv = lv_tabview_create(scr, NULL);
//lv_obj_set_size(tv, lv_disp_get_hor_res(NULL), lv_disp_get_ver_res(NULL));
/* Create simple label */
lv_obj_t *label = lv_label_create(lv_scr_act(), NULL);
lv_label_set_text(label, "PB6 LED DIMMER");
lv_obj_align(label, NULL, LV_ALIGN_CENTER, 0, -50);
/* Create a slider in the center of the display */
lv_obj_t * slider = lv_slider_create(lv_scr_act(), NULL);
lv_obj_set_width(slider, screenWidth-50); /*Set the width*/
lv_obj_set_height(slider, 50);
lv_obj_align(slider, NULL, LV_ALIGN_CENTER, 0, 0); /*Align to the center of the parent (screen)*/
lv_obj_set_event_cb(slider, slider_event_cb); /*Assign an event function*/
/* Create a label below the slider */
slider_label = lv_label_create(lv_scr_act(), NULL);
lv_label_set_text(slider_label, "0");
lv_obj_set_auto_realign(slider, true);
lv_obj_align(slider_label, slider, LV_ALIGN_OUT_BOTTOM_MID, 0, 10);
}
void loop() {
lv_task_handler(); /* let the GUI do its work */
delay(5);
}
Screenshot and/or video
If possible, add screenshots and/or videos about the current issue.