Google Chat: zj734465502@gmail.com
+86-0755-88291180
sales01@spotpear.com
dragon_manager@163.com
services01@spotpear.com
manager01@spotpear.com
WhatsApp:13246739196
RP2350-Touch-LCD-1.28 is a low-cost, high-performance MCU board designed by Waveshare. Despite its compact size, it integrates a 1.28-inch capacitive touch LCD, a lithium-ion battery charging chip, an IMU sensor, and various other peripherals on board for easy development and embedding into the product.
LCD parameters | |||
Touch chip | CST816S | Touch interface | I2C |
Display chip | GC9A01A | Display interface | SPI |
Resolution | 240(H)RGB x 240(V) | Display size | Φ32.4mm |
Display panel | IPS | Pixel size | 0.135(H)x0.135(V)mm |
IMU parameters | |||
Sensor name | QMI8658 | ||
Accelerometer characteristics | Resolution: 16 bits Range (optional): ±2, ±4, ±8, ±16g | ||
Gyroscope characteristics | Resolution: 16 bits Range (optional): ±16, ±32, ±64, ±128, ±256, ±512, ±1024, ±2048°/sec |
In order to facilitate the development of Pico/Pico2 boards using MicroPython on a computer, it is recommended to download the Thonny IDE
【MicroPython】 machine.Pin class function details
【MicroPython】machine.PWM class function details
【MicroPython】machine.ADC class function details
【MicroPython】machine.UART class function details
【MicroPython】machine.I2C class function details
【MicroPython】machine.SPI class function details
【MicroPython】rp2.StateMachine class function details
For C/C++, it is recommended to use Pico VS Code for development. This is a Microsoft Visual Studio Code extension designed to make it easier for you to create, develop, and debug projects for the Raspberry Pi Pico series development boards. No matter if you are a beginner or an experienced professional, this tool can assist you in developing Pico with confidence and ease. Here's how to install and use the extension.
Cmake Path: ${HOME}/.pico-sdk/cmake/v3.28.6/bin/cmake.exe Git Path: ${HOME}/.pico-sdk/git/cmd/git.exe Ninja Path: ${HOME}/.pico-sdk/ninja/v1.12.1/ninja.exe Python3 Path: ${HOME}/.pico-sdk/python/3.12.1/python.exe
set(PICO_BOARD pico CACHE STRING "Board type")
https://github.com/earlephilhower/arduino-pico/releases/download/4.0.2/package_rp2040_index.json
Note: If you already have an ESP32 board URL, you can use a comma to separate the URLs as follows:
https://dl.espressif.com/dl/package_esp32_index.json,https://github.com/earlephilhower/arduino-pico/releases/download/4.0.2/package_rp2040_index.json
MircoPython video demo (github)
MicroPython firmware/Blink demos (C)
Raspberry Pi official C/C++ demo (github)
Raspberry Pi official micropython demo (github)
Arduino official C/C++ demo (github)
If you have used our SPI screen before, you should be familiar with this example program
We have encapsulated the underlying layer, and due to different hardware platforms, the internal implementation is different. If you need to understand the internal implementation, you can check the corresponding directory
You can see a lot of definitions in DEV_Config.c(.h), which can be found in the directory: c\lib\Config
#define UBYTE uint8_t #define UWORD uint16_t #define UDOUBLE uint32_t
void DEV_Module_Init(void); void DEV_Module_Exit(void); Note: 1. Here are some GPIOs before and after using the LCD screen.
void DEV_Digital_Write(UWORD Pin, UBYTE Value); UBYTE DEV_Digital_Read(UWORD Pin);
void DEV_SPI_WriteByte(UBYTE Value);
For the screen, what if you need to paint, display Chinese and English characters, display pictures, etc., these are all done by the upper layer applications. Many of you have asked about some graphics processing, and we have provided some basic functions here The GUI can be found in the directory: c\lib\GUI\GUI_Paint.c(.h)
In the following directory are the character fonts that the GUI depends on: c\lib\Fonts
void Paint_NewImage(UWORD *image, UWORD Width, UWORD Height, UWORD Rotate, UWORD Color) Parameters: image: The name of the image cache, which is actually a pointer to the first address of the image cache; Width: The width of the image cache; Height: The height of image cache; Rotate: The angle of image rotation; Color: The initial color of the image;
void Paint_SelectImage(UBYTE *image) Parameters: image: The name of the image cache, which is actually a pointer to the first address of the image cache;
void Paint_SetRotate(UWORD Rotate) Parameters: Rotate: Image rotation angles can be chosen as ROTATE_0, ROTATE_90, ROTATE_180, ROTATE_270 corresponding to 0, 90, 180, 270 degrees
void Paint_SetMirroring(UBYTE mirror) Parameters: mirror: The mirroring method of the image can be selected as MIRROR_NONE, MIRROR_HORIZONTAL, MIRROR_VERTICAL, and MIRROR_ORIGIN, which correspond to no mirroring, horizontal mirroring, vertical mirroring, and mirroring around the image center, respectively
void Paint_SetPixel(UWORD Xpoint, UWORD Ypoint, UWORD Color) Parameters: Xpoint: The X position of the point in the image cache Ypoint: The Y position of the point in the image cache Color: The color of the point
void Paint_Clear(UWORD Color) Parameters: Color: The filled color
void Paint_ClearWindows(UWORD Xstart, UWORD Ystart, UWORD Xend, UWORD Yend, UWORD Color) Parameters: Xstart: The starting point X coordinate of the window Ystart: The starting point Y coordinate of the window Xend: The endpoint X coordinate of the window Yend: The endpoint Y coordinate of the window Color: The filled color
void Paint_DrawPoint(UWORD Xpoint, UWORD Ypoint, UWORD Color, DOT_PIXEL Dot_Pixel, DOT_STYLE Dot_Style) Parameters: Xpoint: The X coordinate of the dot Ypoint: The Y coordinate of the dot Color: The filled color Dot_Pixel: The size of the dots, which provides the default 8 sizes of dots typedef enum { DOT_PIXEL_1X1 = 1, // 1 x 1 DOT_PIXEL_2X2 , // 2 X 2 DOT_PIXEL_3X3 , // 3 X 3 DOT_PIXEL_4X4 , // 4 X 4 DOT_PIXEL_5X5 , // 5 X 5 DOT_PIXEL_6X6 , // 6 X 6 DOT_PIXEL_7X7 , // 7 X 7 DOT_PIXEL_8X8 , // 8 X 8 } DOT_PIXEL; Dot_Style: The style of the dot, the method to expand the size of the dot is that, whether to expand from the dot as the center or from the dot as the lower left corner to the upper right typedef enum { DOT_FILL_AROUND = 1, DOT_FILL_RIGHTUP, } DOT_STYLE;
void Paint_DrawLine(UWORD Xstart, UWORD Ystart, UWORD Xend, UWORD Yend, UWORD Color, LINE_STYLE Line_Style , LINE_STYLE Line_Style) Parameters: Xstart: The starting point X coordinate of the line Ystart: The starting point Y coordinate of the line Xend: The endpoint X coordinate of the line Yend: The endpoint Y coordinate of the line Color: The filled color Line_width: The width of the lines, which provides the default 8 widths typedef enum { DOT_PIXEL_1X1 = 1, // 1 x 1 DOT_PIXEL_2X2 , // 2 X 2 DOT_PIXEL_3X3 , // 3 X 3 DOT_PIXEL_4X4 , // 4 X 4 DOT_PIXEL_5X5 , // 5 X 5 DOT_PIXEL_6X6 , // 6 X 6 DOT_PIXEL_7X7 , // 7 X 7 DOT_PIXEL_8X8 , // 8 X 8 } DOT_PIXEL; Line_Style: The style of the line, which selects whether the line is connected in a straight line or as a dashed line typedef enum { LINE_STYLE_SOLID = 0, LINE_STYLE_DOTTED, } LINE_STYLE;
void Paint_DrawRectangle(UWORD Xstart, UWORD Ystart, UWORD Xend, UWORD Yend, UWORD Color, DOT_PIXEL Line_width, DRAW_FILL Draw_Fill) Parameters: Xstart: The starting point X coordinate of the rectangle Ystart: The starting point Y coordinate of the rectangle Xend: The endpoint X coordinate of the rectangle Yend: The endpoint Y coordinate of the rectangle Color: The filled color Line_width: The width of the four sides of the rectangle, providing the default 8 widths typedef enum { DOT_PIXEL_1X1 = 1, // 1 x 1 DOT_PIXEL_2X2 , // 2 X 2 DOT_PIXEL_3X3 , // 3 X 3 DOT_PIXEL_4X4 , // 4 X 4 DOT_PIXEL_5X5 , // 5 X 5 DOT_PIXEL_6X6 , // 6 X 6 DOT_PIXEL_7X7 , // 7 X 7 DOT_PIXEL_8X8 , // 8 X 8 } DOT_PIXEL; Draw_Fill: Filling, whether to fill the inside of the rectangle typedef enum { DRAW_FILL_EMPTY = 0, DRAW_FILL_FULL, } DRAW_FILL;
void Paint_DrawCircle(UWORD X_Center, UWORD Y_Center, UWORD Radius, UWORD Color, DOT_PIXEL Line_width, DRAW_FILL Draw_Fill) Parameters: X_Center: The X coordinate of the center of the circle Y_Center: The Y coordinate of the center of the circle Radius: The radius of the circle Color: The filled color Line_width: The width of the arc, which provides the default 8 widths typedef enum { DOT_PIXEL_1X1 = 1, // 1 x 1 DOT_PIXEL_2X2 , // 2 X 2 DOT_PIXEL_3X3 , // 3 X 3 DOT_PIXEL_4X4 , // 4 X 4 DOT_PIXEL_5X5 , // 5 X 5 DOT_PIXEL_6X6 , // 6 X 6 DOT_PIXEL_7X7 , // 7 X 7 DOT_PIXEL_8X8 , // 8 X 8 } DOT_PIXEL; Draw_Fill: Filling, whether to fill the inside of the circle typedef enum { DRAW_FILL_EMPTY = 0, DRAW_FILL_FULL, } DRAW_FILL;
void Paint_DrawChar(UWORD Xstart, UWORD Ystart, const char Ascii_Char, sFONT* Font, UWORD Color_Foreground, UWORD Color_Background) Parameters: Xstart: The left vertex X coordinate of the character Ystart: The left vertex Y coordinate of the character Ascii_Char: Ascii character Font: The Ascii code visual character font library, provides the following fonts in the Fonts folder: font8: 5*8 font font12: 7*12 font font16: 11*16 font font20: 14*20 font font24: 17*24 font Color_Foreground: Font color Color_Background: Background color
void Paint_DrawString_EN(UWORD Xstart, UWORD Ystart, const char * pString, sFONT* Font, UWORD Color_Foreground, UWORD Color_Background) Parameters: Xstart: The left vertex X coordinate of the character Ystart: The left vertex Y coordinate of the character pString: A string, a string is a pointer Font: The Ascii code visual character font library, provides the following fonts in the Fonts folder: font8: 5*8 font font12: 7*12 font font16: 11*16 font font20: 14*20 font font24: 17*24 font Color_Foreground: Font color Color_Background: Background color
void Paint_DrawString_CN(UWORD Xstart, UWORD Ystart, const char * pString, cFONT* font, UWORD Color_Foreground, UWORD Color_Background) Parameters: Xstart: The left vertex X coordinate of the character Ystart: The left vertex Y coordinate of the character pString: A string, a string is a pointer Font: The GB2312 encoding character library, the following fonts are provided in the Fonts folder: font12CN: Ascii character font 11*21, Chinese font 16*21 font24CN: Ascii character font 24*41, Chinese font 32*41 Color_Foreground: Font color Color_Background: Background color
void Paint_DrawNum(UWORD Xpoint, UWORD Ypoint, double Nummber, sFONT* Font, UWORD Digit,UWORD Color_Foreground, UWORD Color_Background); Parameters: Xstart: The left vertex X coordinate of the character Ystart: The left vertex Y coordinate of the character Number: The displayed number, here is stored in a 32-bit long int type, which can be displayed up to 2147483647. Font: The Ascii code visual character font library, provides the following fonts in the Fonts folder: font8: 5*8 font font12: 7*12 font font16: 11*16 font font20: 14*20 font font24: 17*24 font Digit: Display decimal places Color_Foreground: Font color Color_Background: Background color
void Paint_DrawTime(UWORD Xstart, UWORD Ystart, PAINT_TIME *pTime, sFONT* Font, UWORD Color_Background, UWORD Color_Foreground) Parameters: Xstart: The left vertex X coordinate of the character Ystart: The left vertex Y coordinate of the character pTime: The displayed time, here defines a time structure, just pass the numbers of the hour, minute, second to the parameters Font: The Ascii code visual character font library, provides the following fonts in the Fonts folder: font8: 5*8 font font12: 7*12 font font16: 11*16 font font20: 14*20 font font24: 17*24 font Color_Foreground: Font color Color_Background: Background color
unsigned char QMI8658_init(void);
void QMI8658_read_xyz(float acc[3], float gyro[3], unsigned int *tim_count); Parameters: float acc[3]: The array that stores acceleration values, represented as floating-point numbers, contains three elements, which are acceleration on the X, Y, and Z axes float gyro[3]: The array that stores gyroscope values, represented as floating-point numbers, contains three elements, which are angular velocities on the X, Y, and Z axes
def __init__(self)
def write_cmd(self, cmd)
def write_data(self, buf)
def set_bl_pwm(self,duty)
import framebuf
The custom class LCD_1inch28 inherits the framebuf.FrameBuffer class from MicroPython, which provides many methods to draw images, let's create the LCD_1inch28 class object first
LCD = LCD_1inch28()
LCD.line(x1, y1, x2, y2, color) Parameters: x1, y1: The x and y coordinates of the starting point x2, y2: The x and y coordinates of the endpoint color: The color of the line
LCD.fill_rect(x1, y1, w, h, color) Parameters: x1, y1: The x and y coordinates of the upper left corner of the rectangle w, h: The width and height of the rectangle color: The filling color of the rectangle
LCD.text(str, x, y, color) Parameters: str: Display text x, y: The x and y coordinates of the upper left corner of the text color: The color of the text
LCD.write_text(str, x, y, size, color) Parameters: size: The difference between this function and LCD.text is that it supports custom font size, which is used to specify the font size
LCD.show()
qmi8658=QMI8658()
xyz=qmi8658.Read_XYZ() Return values: xyz[0]~xyz[2]: The function returns an array, with the first three elements representing acceleration on the X, Y, and Z axes xyz[3]~xyz[5]: These three elements represent the angular velocities on the X, Y, and Z axes
This example shows three interfaces that can be switched by swiping on the touchscreen or by lifting the IMU sensor.
This example is used to test the interaction and style beautification of LVGL widgets. For specific development of LVGL, please refer to LVGL development documentation.
mkdir build
cd build export PICO_SDK_PATH=../../pico-sdk
Note: The path of the pico-sdk needs to be adjusted according to the actual situation
cmake ..
make
After compilation, copy the generated file in the .uf2 format to the pico.
void LVGL_Init(void);
// LVGL static lv_disp_draw_buf_t disp_buf; //LVGL displays buffer static lv_color_t buf0[DISP_HOR_RES * DISP_VER_RES/2];//LVGL color data buffer 0 static lv_color_t buf1[DISP_HOR_RES * DISP_VER_RES/2];//LVGL color data buffer 1 static lv_disp_drv_t disp_drv; //LVGL display driver static lv_indev_drv_t indev_ts; //LVGL touch screen input device driver static lv_indev_drv_t indev_en; //LVGL IMU sensor analog encoder input device drive static lv_group_t *group; //Encoder widget group
// Initialize LVGL core lv_init(); // Initialize the LVGL display buffer structure variable disp_buf lv_disp_draw_buf_init(&disp_buf, buf0, buf1, DISP_HOR_RES * DISP_VER_RES / 2); lv_disp_drv_init(&disp_drv); disp_drv.flush_cb = disp_flush_cb; disp_drv.draw_buf = &disp_buf; disp_drv.hor_res = DISP_HOR_RES; disp_drv.ver_res = DISP_VER_RES; lv_disp_t *disp= lv_disp_drv_register(&disp_drv); // Initialize touch screen input device lv_indev_drv_init(&indev_ts); indev_ts.type = LV_INDEV_TYPE_POINTER; indev_ts.read_cb = ts_read_cb; lv_indev_t * ts_indev = lv_indev_drv_register(&indev_ts); // Initialize the encoder input device lv_indev_drv_init(&indev_en); indev_en.type = LV_INDEV_TYPE_ENCODER; indev_en.read_cb = encoder_read_cb; lv_indev_t * encoder_indev = lv_indev_drv_register(&indev_en); group = lv_group_create(); lv_indev_set_group(encoder_indev, group);//Add the encoder widget device to the widget group
add_repeating_timer_ms(5, repeating_lvgl_timer_callback, NULL, &lvgl_timer);//The timer callback function is called every 5 ms static bool repeating_lvgl_timer_callback(struct repeating_timer *t) { lv_tick_inc(5); return true; } int main() { ... while(1) { lv_task_handler(); DEV_Delay_ms(5); } }
void disp_flush( lv_disp_drv_t *disp_drv, const lv_area_t *area, lv_color_t *color_p ) Parameter: lv_disp_drv_t *disp_drv: Displays driver structure pointers, which contain information about the display and function pointers. This parameter is often used to notify you that a refresh is complete const lv_area_t *area : Region structure pointer, containing the position information of the area to be refreshed. In this case, the window used to create the TFT display lv_color_t *color_p : Color structure pointer, indicating the color data to be displayed in the refresh area. In this case, the DMA input reads the address to transfer data to the SPI bus, completing the drawing of the image
#define LV_COLOR_16_SWAP 1
#define LV_DISP_DEF_REFR_PERIOD 10 /*[ms]*/
static void disp_flush_cb(lv_disp_drv_t * disp, const lv_area_t * area, lv_color_t * color_p) { LCD_1IN28_SetWindows(area->x1, area->y1, area->x2 , area->y2);//Set the display area for the image dma_channel_configure(dma_tx, &c, &spi_get_hw(LCD_SPI_PORT)->dr, //The output data register address of the SPI bus color_p, //The address of the color data array to be refreshed ((area->x2 + 1 - area-> x1)*(area->y2 + 1 - area -> y1))*2, true //Transfers are made as soon as they are set up ); }
static void dma_handler(void) { if (dma_channel_get_irq0_status(dma_tx)) { dma_channel_acknowledge_irq0(dma_tx); lv_disp_flush_ready(&disp_drv); } }
static void ts_read_cb(lv_indev_drv_t * drv, lv_indev_data_t*data); Parameter: lv_indev_drv_t *indev_drv: Pointer to the input device driver structure in LVGL. In this case, the structure is for a touch screen input device driver lv_indev_data_t *data : Pointer to the input device data structure in LVGL. In this case, the structure is used to store the status and data of the input device, including the current touch state (pressed or released) and the coordinates of the touch points static void encoder_read_cb(lv_indev_drv_t * drv, lv_indev_data_t*data); Parameter: lv_indev_drv_t *indev_drv: Pointer to the input device driver structure in LVGL. In this case, the structure is a driver for an encoder input device simulating an IMU sensor lv_indev_data_t *data : Pointer to the input device data structure in LVGL. In this case, the structure is used to store the status and data of the input device, including the current switch events (up or down) and the determining events (right up)
#define LV_INDEV_DEF_READ_PERIOD 30 /*[ms]*/
static void touch_callback(uint gpio, uint32_t events) { if (gpio == Touch_INT_PIN) { CST816S_Get_Point();//Update global variable Touch_CTS816 ts_x = Touch_CTS816.x_point; ts_y = Touch_CTS816.y_point; ts_act = LV_INDEV_STATE_PRESSED; } } static void ts_read_cb(lv_indev_drv_t * drv, lv_indev_data_t*data) { data->point.x = ts_x; data->point.y = ts_y; data->state = ts_act; ts_act = LV_INDEV_STATE_RELEASED; }
static bool repeating_imu_diff_timer_callback(struct repeating_timer *t);//Input events are updated every 50ms { get_diff_data();//Multiple sampling identification of input events updates the global variables encoder_diff and encoder_act return true; } static void encoder_read_cb(lv_indev_drv_t * drv, lv_indev_data_t*data) { data->enc_diff = encoder_diff; data->state = encoder_act; }
void Widgets_Init(void);
lv_obj_t *btn = lv_btn_create(lv_scr_act()); //Create a widget in which the lv_scr_act layer is the parent object of the key, which can be replaced with a widget that can have child objects, such as list and title
lv_obj_align(btn, LV_ALIGN_CENTER, -50 , 50);//Position the btn widget at the center point to offset it by 50 pixels to the left and 50 pixels down
static lv_style_t style_base; lv_style_init(&style_base); //Initialization style lv_style_set_bg_color(&style_base, lv_palette_main(LV_PALETTE_LIGHT_GREEN)); //Set the background color lv_style_set_border_color(&style_base, lv_palette_darken(LV_PALETTE_LIGHT_GREEN, 3));//Sets the color of the border lv_style_set_border_width(&style_base, 2); //Set the width of the editor lv_style_set_radius(&style_base, 10); //Set the size of the chamfer lv_style_set_shadow_width(&style_base, 10); //Sets the width of the shadow lv_obj_add_style(btn,&style_base,0); //Set the style of the btn theme, 0 can be replaced with position and status
lv_group_add_obj(group, btn);//Add the btn widget to the widget group
This example shows four interfaces that can be switched by the IMU sensor.
This demo is for testing LVGL widget interaction, style design and so on. The version used is 9.1. As the development document of LVGL V9 does not provide Python example, you can refer to LVGL development documentation.
Before using LVGL image library, you need to import the LVGL library and initialize the LVGL objects
import lvgl as lv
# Init LVGL LVGL(LCD=LCD,TSC=TSC)
if not lv.is_initialized(): lv.init()
The LVGL library periodically calls the heartbeat interface function lv.tick_inc to inform LVGL of the past time so that LVGL can update its internal time state to handle time-related tasks such as animations, timers, and so on. In addition, the lv.task_handler function needs to be called so that LVGL can handle events and tasks in time to ensure that the user interface responds and refreshes.
# Create event loop if not yet present if not lv_utils.event_loop.is_running(): self.event_loop=lv_utils.event_loop()
#Timer callback function called every 5ms self.timer.init(mode=Timer.PERIODIC, period=self.delay, callback=self.timer_cb) // In this case, self.delay = 5 def timer_cb(self, t): lv.tick_inc(self.delay) if self.scheduled < self.max_scheduled: try: micropython.schedule(self.task_handler_ref, 0) self.scheduled += 1 # The number of tasks being processed has increased except: pass
def task_handler(self, _): try: if lv._nesting.value == 0: lv.task_handler() if self.refresh_cb: self.refresh_cb() self.scheduled -= 1 # The number of tasks being processed has decreased except Exception as e: if self.exception_sink: self.exception_sink(e)
To implement LVGL display, you must initialize a display driver and set the various properties of the display driver, such as color format, draw buffer, rendering mode, and display callback function. At each LV_DEF_REFR_PERIOD (set in lv_conf.h), LVGL detects if something has happened on the UI that needs to be redrawn. For example, a button is pressed, a chart is changed, an animation occurs, etc. When redrawing is needed, LVGL calls the display callback function to complete the drawing of the image in the refresh area.
#define LV_DEF_REFR_PERIOD 10 // Unit: ms, here is 10ms
# Init LVGL display buf1 = lv.draw_buf_create(self.LCD.width, self.LCD.height // 3 , color_format, 0) buf2 = lv.draw_buf_create(self.LCD.width, self.LCD.height // 3, color_format, 0)
self.disp_drv = lv.display_create(self.LCD.width, self.LCD.height) # Create a display driver object and set the width and height self.disp_drv.set_color_format(color_format) # Set color format to RGB565 self.disp_drv.set_draw_buffers(buf1, buf2) # Set the drawing buffer self.disp_drv.set_render_mode(lv.DISPLAY_RENDER_MODE.PARTIAL) # Set the rendering mode to partial refresh mode self.disp_drv.set_flush_cb(self.disp_drv_flush_cb) # Set display callback function
def disp_drv_flush_cb(self,disp_drv,area,color_p) Parameters: disp_drv : Displays driver structure pointers, which contain information about the display and function pointers. This parameter is often used to notify you that a refresh is complete area : Region structure pointer, containing the position information of the area to be refreshed. In this demo, you can use it for creating TFT display window. color_p : Color structure pointer, indicating the color data to be displayed in the refresh area. In this demo, it reads the address as DMA input to transmit data to the SPI bus and completes the image drawing
def disp_drv_flush_cb(self,disp_drv,area,color_p): ...... self.rgb565_swap_func(data_view, size) # Convert color format self.LCD.setWindows(area.x1, area.y1, area.x2+1, area.y2+1) # Set LVGL interface display position ...... # DMA configuration is executed immediately while self.dma.active(): # Wait for DMA to be idle pass self.disp_drv.flush_ready() # Notify LVGL that data transfer is complete
In LVGL, users can register input devices such as touchpads, mice, keyboards, or encoders, etc. Users can control the user interface through these input devices to achieve better interaction.
#define LV_DEF_REFR_PERIOD 10 // Unit: ms, here is 10ms
# Init touch screen as input device self.indev_drv = lv.indev_create() # Create an object self.indev_drv.set_type(lv.INDEV_TYPE.ENCODER) # Register encoder device self.indev_drv.set_read_cb(self.indev_drv_read_cb) # Set callback function
def indev_drv_read_cb(indev_drv, data) Parameters: indev_drv : Pointer to the input device driver structure in LVGL. In this case, the structure is an encoder input device driver data : Pointer to the input device driver structure in LVGL. In this case, the structure is used to store the status and data of the input device, including the current encoder state (pressed or released) and the incremental movement
def indev_drv_read_cb( self, indev_drv, data): for i in range(3): xyz = self.IMU.Read_XYZ() ud_diff += xyz[4] lr_diff += xyz[3] ud_diff /= 3 lr_diff /= 3 # up or down if ud_diff > self.IMU.offset and ud_diff > 0 and self.IMU.but_flag: self.IMU.encoder_diff -= 2 self.IMU.but_flag = False elif ud_diff < -self.IMU.offset and ud_diff < 0 and self.IMU.but_flag: self.IMU.encoder_diff += 2 self.IMU.but_flag = False else: self.IMU.encoder_diff = 0 self.IMU.but_flag = True # left or right if lr_diff > self.IMU.offset_x: self.IMU.encoder_act = lv.INDEV_STATE.PRESSED else: self.IMU.encoder_act = lv.INDEV_STATE.RELEASED data.enc_diff = self.IMU.encoder_diff data.state = self.IMU.encoder_act
In LVGL, we can create various user interfaces. The basic components of the interface are objects, also called widgets, such as buttons, labels, images, lists, charts, or text areas. In a interface, we can create multiple widgets simultaneously and set their positions, sizes, parent objects, styles, and event handlers and other basic properties.
# Init WIDGETS WIDGETS(LCD=LCD,IMU=IMU)
//Create a tile at (0,0) with support for sliding down to (0,1) self.tv = lv.tileview(self.scr) self.tile1 = self.tv.add_tile(0, 0, lv.DIR.BOTTOM)
//Create a table widget where tile2 is the parent object of the widget, which can be replaced with a widget such as list, title, etc. that can have child objects self.table_imu_data = lv.table(self.tile2)
//Position the widget 15 pixels to the right from the center point self.table_imu_data.align(lv.ALIGN.CENTER, 15 ,0)
#define LV_FONT_MONTSERRAT_16 1 // Enable font 16 #define LV_FONT_MONTSERRAT_18 1 // Enable font 18 #define LV_FONT_DEFAULT &lv_font_montserrat_18 // Set the default font size as 18 table_imu_data= lv.style_t() // Create an object table_imu_data.init() // Initialize table_imu_data.set_text_font(lv.font_montserrat_16) // Set the font size as 16 self.table_imu_data.add_style(style_imu_table, 0) // Set the style
//Add handler function sw_event_cb for event LV_EVENT_VALUE_CHANGED to widget sw self.sw.add_event_cb(self.sw_event_cb, lv.EVENT.VALUE_CHANGED, None)
You can refer to the RP2350-E9 section in the RP2350 Datasheet
Monday-Friday (9:30-6:30) Saturday (9:30-5:30)
Email: services01@spotpear.com