Search Results
163 results found with an empty search
- FM Radio GUI Interface using ESP32 and a 3.5-inch TFT touchscreen display (ILI9488) with LVGL
To build an FM radio GUI interface using ESP32 and a 3.5-inch TFT touchscreen display (ILI9488) with LVGL (Light and Versatile Graphics Library) and Bodmer's TFT_eSPI Arduino library, we will create two distinct screens: FM Frequency and Volume Control Screen : This screen allows you to tune into FM frequencies and adjust the volume. Audio Equalizer Screen : This the screen offers control over the frequency range (0 to 20 kHz) and the balance between left and right audio channels The FM radio module isn't included in this guide, but the GUI setup, control logic, and screen transitions will be outlined. This guide assumes you're using the TFT_eSPI library to interface with the TFT display and LVGL to manage the graphical interface. Components Required ESP-32 Module (38Pin) 3.5 inch TFT ILI9488 SPI Interface Module 480x320 with Touch Screen Display Jumper Wires Circuit Diagram 3.5inch TFT display TFT refer blog: https://www.dofbot.com/post/esp32-dht-weather-monitor-with-3-5inch-tft-touch-display In the VCC pin, you can either use 5V or 3.3V depending upon if your J1 connection is open or closed, J1 = open=5V; J1=close=3.3V. LVGL refer: https://docs.lvgl.io/master/overview/index.html Hardware Requirements ESP32 Board : Any variant should work, but make sure it has enough GPIO pins. TFT LCD Touchscreen : Common models include ILI9488 Connecting Wires : Jumper wires for connections. Breadboard (optional): For easier connections. Software Requirements Arduino IDE : Make sure you have the latest version. Select “File>Preferences>settings>Additional Boards Manager URLs” to fill the link. Here are the steps to install the ESP32 board in Arduino IDE: Open the Arduino IDE Select File and then Preferences Find the Additional Board Manager URLs field and activate the text box Add the URL to the field Click OK to save the changes https:// raw.githubusercontent.com/espressif/arduino-esp32/gh-pages/package_esp32_dev_index.json , https://arduino.esp8266.com/stable/package_esp8266com_index.json , https://espressif.github.io/arduino-esp32/package_esp32_index.json LVGL Library : Available through the Library Manager in the Arduino IDE. Touch Driver Library : Depending on your touchscreen (e.g., TFT_eSPI) Configuring LVGL LVGL Configuration : You may need to configure LVGL for your specific display and touch screen. Create a lv_conf.h file or modify the existing one in the LVGL library folder: Set LVGL_DISPLAY_HOR_RES and LVGL_DISPLAY_VER_RES to match your display's resolution. Configure the display and touch input settings based on your library (e.g., TFT_eSPI settings). TFT_eSPI Configuration : A feature rich Arduino IDE compatible graphics and fonts library for 32-bit processors. The library is targeted at 32-bit processors, it has been performance optimised for RP2040, STM32, ESP8266 and ESP32 types, other 32-bit processors may be used but will use the slower generic Arduino interface calls. The library can be loaded using the Arduino IDE's Library Manager. Direct Memory Access (DMA) can be used with the ESP32, RP2040 and STM32 processors with SPI interface displays to improve rendering performance. DMA with a parallel interface (8 and 16-bit) is only supported with the RP2040. Go to the TFT_eSPI library folder and open the User_Setup.h file to configure the pins according to your wiring. Wiring the TFT Display TFT Pin ESP32 Pin VCC 3.3V GND GND CS GPIO 5 RESET GPIO EN DC/RS GPIO 17 SDI(MOSI) GPIO 23 SCK GPIO 18 LED 3.3V (or PWM pin for brightness) Wiring the Touchscreen (e.g., TFT_espi) Touch Pin ESP32 Pin T_CS GPIO 16 T_IRQ GPIO 21 T_DOUT GPIO 19 T_DIN GPIO 23 T_CLK GPIO 18 4. UI Library : User Interface (e.g., UI) FM Frequency and Volume Control Screen: Frequency Tuning : Use the touch-enabled knob with indicator to tune into FM radio stations. Volume Control : Adjust the volume using the touch-controlled with knob with indicator to set the desired value. Audio Equalizer Screen Design Frequency Bands (0 Hz to 20 kHz) Common bands Bass : 20 Hz - 250 Hz (affects low-end sound) Midrange : 250 Hz - 2 kHz (affects vocals, instruments) Treble : 2 kHz - 20 kHz (affects high-end sound) Slider Controls : Each band might have a vertical slider, where you can increase or decrease the volume of each frequency band. Balance Control Left and Right Audio Channels : A horizontal slider or knob that adjusts the balance between the left and right audio channels (stereo channels). Moving the slider to the left would emphasize the left speaker or headphone. Moving it to the right would emphasize the right speaker or headphone. The center point indicates a balanced audio output , where both channels are equally loud. Arduino Code Here’s a basic example to initialize the display and create a simple button using LVGL: ###################################################################### //Arduino-TFT_eSPI board-template main routine. There's a TFT_eSPI create+flush driver already in LVGL-9.1 but we create our own here for more control (like e.g. 16-bit color swap). #include "FS.h" #include #include #include #include /*Don't forget to set Sketchbook location in File/Preferences to the path of your UI project (the parent foder of this INO file)*/ /*Change to your screen resolution*/ static const uint16_t screenWidth = 480 ; static const uint16_t screenHeight = 320 ; enum { SCREENBUFFER_SIZE_PIXELS = screenWidth * screenHeight / 10 } ; static lv_color_t buf [SCREENBUFFER_SIZE_PIXELS]; TFT_eSPI tft = TFT_eSPI ( screenWidth, screenHeight ) ; /* TFT instance */ #define CALIBRATION_FILE "/calibrationData" #if LV_USE_LOG != 0 /* Serial debugging */ void my_print ( const char * buf) { Serial . printf ( buf ) ; Serial . flush () ; } #endif /* Display flushing */ void my_disp_flush ( lv_display_t disp , const lv_area_t area , uint8_t * pixelmap) { uint32_t w = ( area -> x2 - area -> x1 + 1 ) ; uint32_t h = ( area -> y2 - area -> y1 + 1 ) ; if ( LV_COLOR_16_SWAP ) { size_t len = lv_area_get_size ( area ) ; lv_draw_sw_rgb565_swap ( pixelmap, len ) ; } tft . startWrite () ; tft . setAddrWindow ( area -> x1 , area -> y1 , w, h ) ; tft . pushColors ( ( uint16_t * ) pixelmap, w * h, true ) ; tft . endWrite () ; lv_disp_flush_ready ( disp ) ; } /*Read the touchpad*/ void my_touchpad_read ( lv_indev_t indev_driver , lv_indev_data_t data) { uint16_t touchX = 0 , touchY = 0 ; bool touched = tft . getTouch ( &touchX, &touchY, 600 ) ; if ( !touched ) { data -> state = LV_INDEV_STATE_REL; } else { data -> state = LV_INDEV_STATE_PR; /*Set the coordinates*/ data -> point . x = touchX; data -> point . y = touchY; Serial . print ( "Data x " ) ; Serial . println ( touchX ) ; Serial . print ( "Data y " ) ; Serial . println ( touchY ) ; } } /*Set tick routine needed for LVGL internal timings*/ static uint32_t my_tick_get_cb ( void ) { return millis () ; } void setup () { uint16_t calibrationData [ 5 ]; uint8_t calDataOK = 0 ; Serial . begin ( 115200 ) ; /* prepare for possible serial debug */ String LVGL_Arduino = "Hello Arduino! " ; LVGL_Arduino += String ( 'V' ) + lv_version_major () + "." + lv_version_minor () + "." + lv_version_patch () ; Serial . println ( LVGL_Arduino ) ; Serial . println ( "I am LVGL_Arduino" ) ; lv_init () ; #if LV_USE_LOG != 0 lv_log_register_print_cb ( my_print ) ; /* register print function for debugging */ #endif tft . begin () ; /* TFT init */ tft . setRotation ( 3 ) ; /* Landscape orientation, flipped */ static lv_disp_t * disp; disp = lv_display_create ( screenWidth, screenHeight ) ; lv_display_set_buffers ( disp, buf, NULL , SCREENBUFFER_SIZE_PIXELS * sizeof ( lv_color_t ) , LV_DISPLAY_RENDER_MODE_PARTIAL ) ; lv_display_set_flush_cb ( disp, my_disp_flush ) ; static lv_indev_t * indev; indev = lv_indev_create () ; lv_indev_set_type ( indev, LV_INDEV_TYPE_POINTER ) ; lv_indev_set_read_cb ( indev, my_touchpad_read ) ; lv_tick_set_cb ( my_tick_get_cb ) ; ui_init () ; Serial . println ( "Setup done" ) ; // check file system if ( ! SPIFFS . begin ()) { Serial . println ( "formatting file system" ) ; SPIFFS . format () ; SPIFFS . begin () ; } // check if calibration file exists if ( SPIFFS . exists ( CALIBRATION_FILE )) { File f = SPIFFS . open ( CALIBRATION_FILE, "r" ) ; if ( f ) { if ( f . readBytes (( char * ) calibrationData, 14 ) == 14 ) calDataOK = 1 ; f . close () ; } } if ( calDataOK ) { // calibration data valid tft . setTouch ( calibrationData ) ; } else { // data not valid. recalibrate tft . calibrateTouch ( calibrationData, TFT_WHITE, TFT_RED, 15 ) ; // store data File f = SPIFFS . open ( CALIBRATION_FILE, "w" ) ; if ( f ) { f . write (( const unsigned char * ) calibrationData, 14 ) ; f . close () ; } } } void loop () { lv_timer_handler () ; /* let the GUI do its work */ delay ( 5 ) ; lv_label_set_text_fmt ( ui_Label_volume, "%" LV_PRId32 "%%" , lv_arc_get_value ( ui_Arc_volume )) ; /*Rotate the label to the current position of the arc*/ lv_arc_rotate_obj_to_angle ( ui_Arc_volume, ui_Label_volume, 0 ) ; int knob1R = map ( lv_arc_get_value ( ui_Arc_volume ) , 0 , 100 , 400 , 3200 ) ; lv_img_set_angle ( ui_knob1, knob1R ) ; lv_label_set_text_fmt ( ui_Label_tuner, "%" LV_PRId32 "%" , lv_arc_get_value ( ui_Arc_tuner )) ; int knob2R = map ( lv_arc_get_value ( ui_Arc_tuner ) , 880 , 1080 , 350 , 3200 ) ; lv_img_set_angle ( ui_knob2, knob2R ) ; //int DialR = map(lv_arc_get_value(ui_Arc_tuner), 880, 1080, 0, 700); //lv_image_set_rotation(ui_Dial, DialR); int DialR = map ( lv_arc_get_value ( ui_Arc_tuner ) , 880 , 1080 , 350 , - 355 ) ; lv_obj_set_x ( ui_Dial, DialR ) ; } ###################################################################### Final Steps Upload the code to your ESP32 using the Arduino IDE. Open the Serial Monitor to check for any debug messages. Interact with the touchscreen to see your UI in action! Explanation: FM Radio Control : The FM radio's frequency and volume can be controlled using the TFT Control. These are updated in the LVGL GUI in real-time. LVGL Interface : The interface includes a frequency display, and knobs to tune the radio up/down and adjust the volume. Tips Adjust the pin assignments based on your wiring. Explore LVGL's extensive documentation for more UI elements and functionalities. Use LVGL's built-in tools to design and customize your interfaces. This should give you a solid start on using LVGL with an ESP32 and a TFT LCD touchscreen. Happy coding! Demo:
- Gauge LVGL GUI with ESP32 and 3.5inch TFT display
Creating a demo Gauge GUI for an ESP32 and a 3.5-inch TFT display can be an exciting project! Below is a high-level overview of how to set up your project, including the necessary components, libraries, and a basic example of how to structure your code. Here to used the ESP32 board based 3.5inch touch display ILI9488 using the LVGL (Light and Versatile Graphics Library) and Bodmer's TFT_eSPI arduino Library. The LVGL is a popular free and open-source embedded graphics library to create UIs for arduino. In this Setting up LVGL (Light and Versatile Graphics Library) on an ESP32 with a TFT LCD touchscreen display ILI9488 is a great way to create interactive user interfaces for your projects. Here’s a step-by-step guide to help you get started Components Required ESP-32 Module (38Pin) 3.5 inch TFT ILI9488 SPI Interface Module 480x320 with Touch Screen Display 10k Potentiometer -5nos Jumper Wires Circuit Diagram 3.5inch TFT display TFT refer blog: https://www.dofbot.com/post/esp32-dht-weather-monitor-with-3-5inch-tft-touch-display In the VCC pin, you can either use 5V or 3.3V depending upon if your J1 connection is open or closed, J1 = open=5V; J1=close=3.3V. LVGL refer: https://docs.lvgl.io/master/overview/index.html Hardware Requirements ESP32 Board : Any variant should work, but make sure it has enough GPIO pins. TFT LCD Touchscreen : Common models include ILI9488 Connecting Wires : Jumper wires for connections. Breadboard (optional): For easier connections. Software Requirements Arduino IDE : Make sure you have the latest version. Select “File>Preferences>settings>Additional Boards Manager URLs” to fill the link. Here are the steps to install the ESP32 board in Arduino IDE: Open the Arduino IDE Select File and then Preferences Find the Additional Board Manager URLs field and activate the text box Add the URL to the field Click OK to save the changes https:// raw.githubusercontent.com/espressif/arduino-esp32/gh-pages/package_esp32_dev_index.json , https://arduino.esp8266.com/stable/package_esp8266com_index.json , https://espressif.github.io/arduino-esp32/package_esp32_index.json LVGL Library : Available through the Library Manager in the Arduino IDE. Touch Driver Library : Depending on your touchscreen (e.g., TFT_eSPI) Configuring LVGL LVGL Configuration : You may need to configure LVGL for your specific display and touch screen. Create a lv_conf.h file or modify the existing one in the LVGL library folder: Set LVGL_DISPLAY_HOR_RES and LVGL_DISPLAY_VER_RES to match your display's resolution. Configure the display and touch input settings based on your library (e.g., TFT_eSPI settings). TFT_eSPI Configuration : A feature rich Arduino IDE compatible graphics and fonts library for 32-bit processors. The library is targeted at 32-bit processors, it has been performance optimised for RP2040, STM32, ESP8266 and ESP32 types, other 32-bit processors may be used but will use the slower generic Arduino interface calls. The library can be loaded using the Arduino IDE's Library Manager. Direct Memory Access (DMA) can be used with the ESP32, RP2040 and STM32 processors with SPI interface displays to improve rendering performance. DMA with a parallel interface (8 and 16-bit) is only supported with the RP2040. Go to the TFT_eSPI library folder and open the User_Setup.h file to configure the pins according to your wiring. Wiring the TFT Display TFT Pin ESP32 Pin VCC 3.3V GND GND CS GPIO 5 RESET GPIO EN DC/RS GPIO 17 SDI(MOSI) GPIO 23 SCK GPIO 18 LED 3.3V (or PWM pin for brightness) Wiring the Touchscreen (e.g., TFT_espi) Touch Pin ESP32 Pin T_CS GPIO 16 T_IRQ GPIO 21 T_DOUT GPIO 19 T_DIN GPIO 23 T_CLK GPIO 18 4. UI Library : User Interface (e.g., UI) Arduino Code Here’s a basic example to initialize the display and create a simple button using LVGL: ###################################################################### #include #include #include /*Don't forget to set Sketchbook location in File/Preferences to the path of your UI project (the parent foder of this INO file)*/ /*Change to your screen resolution*/ static const uint16_t screenWidth = 480 ; static const uint16_t screenHeight = 320 ; static lv_disp_draw_buf_t draw_buf; static lv_color_t buf [ screenWidth * screenHeight / 10 ]; TFT_eSPI tft = TFT_eSPI ( screenWidth, screenHeight ) ; /* TFT instance */ int Gauge1 = 0 ; int Gauge2 = 0 ; int Gauge3 = 0 ; int Gauge4 = 0 ; int Gauge5 = 0 ; int compass_value = 0 ; // Current compass value bool compass_increasing = true ; // Flag for increasing/decreasing compass // Function declarations void simulate_compass () ; void update_compass_ui ( int compass) ; #if LV_USE_LOG != 0 /* Serial debugging */ void my_print ( const char * buf) { Serial . printf ( buf ) ; Serial . flush () ; } #endif /* Display flushing */ 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 () ; tft . setAddrWindow ( area -> x1 , area -> y1 , w, h ) ; tft . pushColors ( ( uint16_t ) & color_p -> full , w h, true ) ; tft . endWrite () ; lv_disp_flush_ready ( disp ) ; } /*Read the touchpad*/ void my_touchpad_read ( lv_indev_drv_t indev_driver , lv_indev_data_t data ) { uint16_t touchX = 0 , touchY = 0 ; bool touched = false ; //tft.getTouch( &touchX, &touchY, 600 ); if ( !touched ) { data -> state = LV_INDEV_STATE_REL; } else { data -> state = LV_INDEV_STATE_PR; /*Set the coordinates*/ data -> point . x = touchX; data -> point . y = touchY; Serial . print ( "Data x " ) ; Serial . println ( touchX ) ; Serial . print ( "Data y " ) ; Serial . println ( touchY ) ; } } void setup () { Serial . begin ( 115200 ) ; /* prepare for possible serial debug */ String LVGL_Arduino = "Hello Arduino! " ; LVGL_Arduino += String ( 'V' ) + lv_version_major () + "." + lv_version_minor () + "." + lv_version_patch () ; Serial . println ( LVGL_Arduino ) ; Serial . println ( "I am LVGL_Arduino" ) ; lv_init () ; #if LV_USE_LOG != 0 lv_log_register_print_cb ( my_print ) ; /* register print function for debugging */ #endif tft . begin () ; /* TFT init */ tft . setRotation ( 3 ) ; /* Landscape orientation, flipped */ lv_disp_draw_buf_init ( &draw_buf, buf, NULL , screenWidth * screenHeight / 10 ) ; /*Initialize the display*/ static lv_disp_drv_t disp_drv; lv_disp_drv_init ( &disp_drv ) ; /*Change the following line to your display resolution*/ disp_drv . hor_res = screenWidth; disp_drv . ver_res = screenHeight; disp_drv . flush_cb = my_disp_flush; disp_drv . draw_buf = &draw_buf; lv_disp_drv_register ( &disp_drv ) ; /*Initialize the (dummy) input device driver*/ static lv_indev_drv_t indev_drv; lv_indev_drv_init ( &indev_drv ) ; indev_drv . type = LV_INDEV_TYPE_POINTER; indev_drv . read_cb = my_touchpad_read; lv_indev_drv_register ( &indev_drv ) ; ui_init () ; Serial . println ( "Setup done" ) ; } // compass Simulation: Simulates the compass going from 0 to 10,000 and back with smoother transitions void simulate_compass () { const int max_compass = 360 ; // Maximum compass value (10,000 compass) const int compass_step = 2 ; // Smaller increment step for smoother transition (100 compass) if ( compass_increasing ) { if ( compass_value < max_compass ) { compass_value += compass_step; } else { compass_increasing = false ; // Start decrementing when max compass is reached } } else { if ( compass_value > 0 ) { compass_value -= compass_step; } else { compass_increasing = true ; // Start incrementing when 0 compass is reached } } update_compass_ui ( compass_value ) ; // Update the compass UI elements } // Update the LVGL UI elements based on compass value void update_compass_ui ( int compass) { // Update compass label with the current value char compass_str [ 10 ]; sprintf ( compass_str, "%d" , compass ) ; // Display the current compass value (e.g., 100, 200, etc.) //lv_label_set_text(ui_Label_compass, compass_str); // Update gauge needle based on compass value // Map 0 compass to 0 degrees and 10,000 compass to 2500 degrees int Needle_6R = map ( compass, 0 , 360 , 0 , 3600 ) ; lv_img_set_angle ( ui_Needle_6, Needle_6R ) ; } void loop () { lv_timer_handler () ; /* let the GUI do its work */ delay ( 5 ) ; // Update gauge label with the current value char Gauge1_str [ 10 ]; char Gauge2_str [ 10 ]; char Gauge3_str [ 10 ]; char Gauge4_str [ 10 ]; char Gauge5_str [ 10 ]; sprintf ( Gauge1_str, "%d" , Gauge1 ) ; // Display the current Gauge5 value (e.g., 100, 200, etc.) sprintf ( Gauge2_str, "%d" , Gauge2 ) ; // Display the current Gauge5 value (e.g., 100, 200, etc.) sprintf ( Gauge3_str, "%d" , Gauge3 ) ; // Display the current Gauge5 value (e.g., 100, 200, etc.) sprintf ( Gauge4_str, "%d" , Gauge4 ) ; // Display the current Gauge5 value (e.g., 100, 200, etc.) sprintf ( Gauge5_str, "%d" , Gauge5 ) ; // Display the current Gauge5 value (e.g., 100, 200, etc.) //lv_label_set_text(ui_Label_G5, Gauge5_str); // Update gauge needle based on Speed value // Map 0 Speed to 0 degrees and 1200 km to 3600 degrees int Gauge1 = map ( analogRead ( 12 ) , 0 , 4096 , 0 , 100 ) ; // change analog pin as you desired int Needle_1R = map ( Gauge1, 0 , 100 , 450 , 3250 ) ; lv_img_set_angle ( ui_Needle_1, Needle_1R ) ; int arc_1_value = map ( Gauge1, 0 , 100 , 0 , 100 ) ; lv_arc_set_value ( ui_Arc_1, arc_1_value ) ; // Update the arc based on analog value int Gauge2 = map ( analogRead ( 14 ) , 0 , 4096 , 0 , 140 ) ; // change analog pin as you desired int arc_2_value = map ( Gauge2, 0 , 140 , 0 , 140 ) ; lv_arc_set_value ( ui_Arc_2, arc_2_value ) ; // Update the arc based on analog value ui label_set_property ( ui_Label_G2, UI LABEL_PROPERTY_TEXT, String ( Gauge2 ) . c_str ()) ; ui label_set_property ( ui_Label_G21, UI LABEL_PROPERTY_TEXT, String ( Gauge2 ) . c_str ()) ; int Gauge3 = map ( analogRead ( 27 ) , 0 , 4096 , 0 , 80 ) ; // change analog pin as you desired ui label_set_property ( ui_Label_G3, UI LABEL_PROPERTY_TEXT, String ( Gauge3 ) . c_str ()) ; // Map Gauge value to the range of 0-100 for the arc int arc_3_value = map ( Gauge3, 0 , 80 , 0 , 80 ) ; lv_arc_set_value ( ui_Arc_3, arc_3_value ) ; // Update the arc based on analog value int Gauge4 = map ( analogRead ( 26 ) , 0 , 4096 , 0 , 230 ) ; // change analog pin as you desired ui label_set_property ( ui_Label_G4, UI LABEL_PROPERTY_TEXT, String ( Gauge4 ) . c_str ()) ; // Map Gauge value to the range of 0-100 for the arc int arc_4_value = map ( Gauge4, 0 , 230 , 0 , 230 ) ; lv_arc_set_value ( ui_Arc_4, arc_4_value ) ; // Update the arc based on analog value int Gauge5 = map ( analogRead ( 25 ) , 0 , 4096 , 0 , 120 ) ; // change analog pin as you desired int Needle_5R = map ( Gauge5, 0 , 120 , 875 , 3300 ) ; lv_img_set_angle ( ui_Needle_5, Needle_5R ) ; ui label_set_property ( ui_Label_G5, UI LABEL_PROPERTY_TEXT, String ( Gauge5 ) . c_str ()) ; // Map Gauge value to the range of 0-100 for the arc int arc_5_value = map ( Gauge5, 0 , 120 , 0 , 120 ) ; lv_arc_set_value ( ui_Arc_5, arc_5_value ) ; // Update the arc based on analog value //int Gauge6 = map(analogRead(12), 0, 4096, 0, 3600); // change analog pin as you desired //int Needle_6R = map(Gauge6, 0, 3600, 0, 3600); //lv_img_set_angle(ui_Needle_6, Needle_6R); simulate_compass () ; // Simulate compass and update the UI } ###################################################################### Final Steps Upload the code to your ESP32 using the Arduino IDE. Open the Serial Monitor to check for any debug messages. Interact with the touchscreen to see your UI in action! Tips Adjust the pin assignments based on your wiring. Explore LVGL's extensive documentation for more UI elements and functionalities. Use LVGL's built-in tools to design and customize your interfaces. This should give you a solid start on using LVGL with an ESP32 and a TFT LCD touchscreen. Happy coding! Demo:
- Speedometer Gauge with ESP32 and 3.5inch TFT display
Creating a demo GUI for a Speedometer gauge for car using an ESP32 and a 3.5-inch TFT display can be an exciting project! Below is a high-level overview of how to set up your project, including the necessary components, libraries, and a basic example of how to structure your code. Here to used the ESP32 board based 3.5inch touch display ILI9488 using the LVGL (Light and Versatile Graphics Library) and Bodmer's TFT_eSPI arduino Library. The LVGL is a popular free and open-source embedded graphics library to create UIs for arduino. In this Setting up LVGL (Light and Versatile Graphics Library) on an ESP32 with a TFT LCD touchscreen display ILI9488 is a great way to create interactive user interfaces for your projects. Here’s a step-by-step guide to help you get started Components Required ESP-32 Module (38Pin) 3.5 inch TFT ILI9488 SPI Interface Module 480x320 with Touch Screen Display 10k Potentiometer -5nos Jumper Wires Circuit Diagram 3.5inch TFT display TFT refer blog: https://www.dofbot.com/post/esp32-dht-weather-monitor-with-3-5inch-tft-touch-display In the VCC pin, you can either use 5V or 3.3V depending upon if your J1 connection is open or closed, J1 = open=5V; J1=close=3.3V. LVGL refer: https://docs.lvgl.io/master/overview/index.html Hardware Requirements ESP32 Board : Any variant should work, but make sure it has enough GPIO pins. TFT LCD Touchscreen : Common models include ILI9488 Connecting Wires : Jumper wires for connections. Breadboard (optional): For easier connections. Software Requirements Arduino IDE : Make sure you have the latest version. Select “File>Preferences>settings>Additional Boards Manager URLs” to fill the link. Here are the steps to install the ESP32 board in Arduino IDE: Open the Arduino IDE Select File and then Preferences Find the Additional Board Manager URLs field and activate the text box Add the URL to the field Click OK to save the changes https:// raw.githubusercontent.com/espressif/arduino-esp32/gh-pages/package_esp32_dev_index.json , https://arduino.esp8266.com/stable/package_esp8266com_index.json , https://espressif.github.io/arduino-esp32/package_esp32_index.json LVGL Library : Available through the Library Manager in the Arduino IDE. Touch Driver Library : Depending on your touchscreen (e.g., TFT_eSPI) Configuring LVGL LVGL Configuration : You may need to configure LVGL for your specific display and touch screen. Create a lv_conf.h file or modify the existing one in the LVGL library folder: Set LVGL_DISPLAY_HOR_RES and LVGL_DISPLAY_VER_RES to match your display's resolution. Configure the display and touch input settings based on your library (e.g., TFT_eSPI settings). TFT_eSPI Configuration : A feature rich Arduino IDE compatible graphics and fonts library for 32-bit processors. The library is targeted at 32-bit processors, it has been performance optimised for RP2040, STM32, ESP8266 and ESP32 types, other 32-bit processors may be used but will use the slower generic Arduino interface calls. The library can be loaded using the Arduino IDE's Library Manager. Direct Memory Access (DMA) can be used with the ESP32, RP2040 and STM32 processors with SPI interface displays to improve rendering performance. DMA with a parallel interface (8 and 16-bit) is only supported with the RP2040. Go to the TFT_eSPI library folder and open the User_Setup.h file to configure the pins according to your wiring. Wiring the TFT Display TFT Pin ESP32 Pin VCC 3.3V GND GND CS GPIO 5 RESET GPIO EN DC/RS GPIO 17 SDI(MOSI) GPIO 23 SCK GPIO 18 LED 3.3V (or PWM pin for brightness) Wiring the Touchscreen (e.g., TFT_espi) Touch Pin ESP32 Pin T_CS GPIO 16 T_IRQ GPIO 21 T_DOUT GPIO 19 T_DIN GPIO 23 T_CLK GPIO 18 4. UI Library : User Interface (e.g., UI) Arduino Code Here’s a basic example to initialize the display and create a simple button using LVGL: ###################################################################### #include #include #include /*Don't forget to set Sketchbook location in File/Preferences to the path of your UI project (the parent foder of this INO file)*/ /*Change to your screen resolution*/ static const uint16_t screenWidth = 480 ; static const uint16_t screenHeight = 320 ; static lv_disp_draw_buf_t draw_buf; static lv_color_t buf [ screenWidth * screenHeight / 10 ]; TFT_eSPI tft = TFT_eSPI ( screenWidth, screenHeight ) ; /* TFT instance */ #if LV_USE_LOG != 0 /* Serial debugging */ void my_print ( const char * buf) { Serial . printf ( buf ) ; Serial . flush () ; } #endif //inputs analog values int speed = 0 ; // Current speed value int fuel = 0 ; // Current fuel value int temp = 0 ; // Current temp value int battery = 0 ; // Current battery value int pressure = 0 ; // Current pressure value /* Display flushing */ 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 () ; tft . setAddrWindow ( area -> x1 , area -> y1 , w, h ) ; tft . pushColors ( ( uint16_t ) & color_p -> full , w h, true ) ; tft . endWrite () ; lv_disp_flush_ready ( disp ) ; } /*Read the touchpad*/ void my_touchpad_read ( lv_indev_drv_t indev_driver , lv_indev_data_t data ) { uint16_t touchX = 0 , touchY = 0 ; bool touched = false ; //tft.getTouch( &touchX, &touchY, 600 ); if ( !touched ) { data -> state = LV_INDEV_STATE_REL; } else { data -> state = LV_INDEV_STATE_PR; /*Set the coordinates*/ data -> point . x = touchX; data -> point . y = touchY; Serial . print ( "Data x " ) ; Serial . println ( touchX ) ; Serial . print ( "Data y " ) ; Serial . println ( touchY ) ; } } void setup () { Serial . begin ( 115200 ) ; /* prepare for possible serial debug */ String LVGL_Arduino = "Hello Arduino! " ; LVGL_Arduino += String ( 'V' ) + lv_version_major () + "." + lv_version_minor () + "." + lv_version_patch () ; Serial . println ( LVGL_Arduino ) ; Serial . println ( "I am LVGL_Arduino" ) ; lv_init () ; #if LV_USE_LOG != 0 lv_log_register_print_cb ( my_print ) ; /* register print function for debugging */ #endif tft . begin () ; /* TFT init */ tft . setRotation ( 3 ) ; /* Landscape orientation, flipped */ lv_disp_draw_buf_init ( &draw_buf, buf, NULL , screenWidth * screenHeight / 10 ) ; /*Initialize the display*/ static lv_disp_drv_t disp_drv; lv_disp_drv_init ( &disp_drv ) ; /*Change the following line to your display resolution*/ disp_drv . hor_res = screenWidth; disp_drv . ver_res = screenHeight; disp_drv . flush_cb = my_disp_flush; disp_drv . draw_buf = &draw_buf; lv_disp_drv_register ( &disp_drv ) ; /*Initialize the (dummy) input device driver*/ static lv_indev_drv_t indev_drv; lv_indev_drv_init ( &indev_drv ) ; indev_drv . type = LV_INDEV_TYPE_POINTER; indev_drv . read_cb = my_touchpad_read; lv_indev_drv_register ( &indev_drv ) ; ui_init () ; Serial . println ( "Setup done" ) ; } void loop () { lv_timer_handler () ; /* let the GUI do its work */ delay ( 5 ) ; // Update speed label with the current value char rpm_str [ 10 ]; sprintf ( rpm_str, "%d" , speed ) ; // Display the current RPM value (e.g., 100, 200, etc.) lv_label_set_text ( ui_Labelkm, rpm_str ) ; // am using demo purpose all the input in analog 12 please change each input to eash analog // Update gauge needle based on Speed value // Map 0 Speed to 0 degrees and 200 km to 3600 degrees int speed = map ( analogRead ( 12 ) , 0 , 4096 , 0 , 200 ) ; // change analog pin as you desired int Needle1R = map ( speed, 0 , 200 , 300 , 3300 ) ; lv_img_set_angle ( ui_Needle1, Needle1R ) ; ui label_set_property ( ui_Labelkm, UI LABEL_PROPERTY_TEXT, String ( speed ) . c_str ()) ; // Update gauge needle based on Fuel value int fuel = map ( analogRead ( 12 ) , 0 , 4096 , 0 , 100 ) ; // change analog pin as you desired int Needle2R = map ( fuel, 0 , 100 , 1500 , 3000 ) ; lv_img_set_angle ( ui_Needle2, Needle2R ) ; // Update gauge needle based on temp value int temp = map ( analogRead ( 12 ) , 0 , 4096 , 0 , 100 ) ; // change analog pin as you desired int Needle3R = map ( temp, 0 , 100 , 600 , 2000 ) ; lv_img_set_angle ( ui_Needle3, Needle3R ) ; // Update gauge needle based on battery value int battery = map ( analogRead ( 12 ) , 0 , 4096 , 0 , 100 ) ; // change analog pin as you desired int Needle4R = map ( battery, 0 , 100 , 1850 , 2350 ) ; lv_img_set_angle ( ui_Needle4, Needle4R ) ; // Update gauge needle based on Fuel value int pressure = map ( analogRead ( 12 ) , 0 , 4096 , 0 , 100 ) ; // change analog pin as you desired int Needle5R = map ( pressure, 0 , 100 , 1250 , 1750 ) ; lv_img_set_angle ( ui_Needle5, Needle5R ) ; } ###################################################################### Final Steps Upload the code to your ESP32 using the Arduino IDE. Open the Serial Monitor to check for any debug messages. Interact with the touchscreen to see your UI in action! Tips Adjust the pin assignments based on your wiring. Explore LVGL's extensive documentation for more UI elements and functionalities. Use LVGL's built-in tools to design and customize your interfaces. This should give you a solid start on using LVGL with an ESP32 and a TFT LCD touchscreen. Happy coding! Demo:
- eBike demo GUI with ESP32 and 3.5inch TFT display
Creating a demo GUI for an eBike using an ESP32 and a 3.5-inch TFT display can be an exciting project! Below is a high-level overview of how to set up your project, including the necessary components, libraries, and a basic example of how to structure your code. Components Required ESP-32 Module (38Pin) 3.5 inch TFT ILI9488 SPI Interface Module 480x320 with Touch Screen Display 10k Potentiometer -2nos Jumper Wires Circuit Diagram 3.5inch TFT display TFT refer blog: https://www.dofbot.com/post/esp32-dht-weather-monitor-with-3-5inch-tft-touch-display In the VCC pin, you can either use 5V or 3.3V depending upon if your J1 connection is open or closed, J1 = open=5V; J1=close=3.3V. LVGL refer: https://docs.lvgl.io/master/overview/index.html Hardware Requirements ESP32 Board : Any variant should work, but make sure it has enough GPIO pins. TFT LCD Touchscreen : Common models include ILI9488 Connecting Wires : Jumper wires for connections. Breadboard (optional): For easier connections. Software Requirements Arduino IDE : Make sure you have the latest version. Select “File>Preferences>settings>Additional Boards Manager URLs” to fill the link. Here are the steps to install the ESP32 board in Arduino IDE: Open the Arduino IDE Select File and then Preferences Find the Additional Board Manager URLs field and activate the text box Add the URL to the field Click OK to save the changes https:// raw.githubusercontent.com/espressif/arduino-esp32/gh-pages/package_esp32_dev_index.json , https://arduino.esp8266.com/stable/package_esp8266com_index.json , https://espressif.github.io/arduino-esp32/package_esp32_index.json LVGL Library : Available through the Library Manager in the Arduino IDE. Touch Driver Library : Depending on your touchscreen (e.g., TFT_eSPI) Configuring LVGL LVGL Configuration : You may need to configure LVGL for your specific display and touch screen. Create a lv_conf.h file or modify the existing one in the LVGL library folder: Set LVGL_DISPLAY_HOR_RES and LVGL_DISPLAY_VER_RES to match your display's resolution. Configure the display and touch input settings based on your library (e.g., TFT_eSPI settings). TFT_eSPI Configuration : A feature rich Arduino IDE compatible graphics and fonts library for 32-bit processors. The library is targeted at 32-bit processors, it has been performance optimised for RP2040, STM32, ESP8266 and ESP32 types, other 32-bit processors may be used but will use the slower generic Arduino interface calls. The library can be loaded using the Arduino IDE's Library Manager. Direct Memory Access (DMA) can be used with the ESP32, RP2040 and STM32 processors with SPI interface displays to improve rendering performance. DMA with a parallel interface (8 and 16-bit) is only supported with the RP2040. Go to the TFT_eSPI library folder and open the User_Setup.h file to configure the pins according to your wiring. Wiring the TFT Display TFT Pin ESP32 Pin VCC 3.3V GND GND CS GPIO 5 RESET GPIO EN DC/RS GPIO 17 SDI(MOSI) GPIO 23 SCK GPIO 18 LED 3.3V (or PWM pin for brightness) Wiring the Touchscreen (e.g., TFT_espi) Touch Pin ESP32 Pin T_CS GPIO 16 T_IRQ GPIO 21 T_DOUT GPIO 19 T_DIN GPIO 23 T_CLK GPIO 18 4. UI Library : User Interface (e.g., UI) Arduino Code Here’s a basic example to initialize the display and create a simple button using LVGL: ###################################################################### #include #include #include /*Don't forget to set Sketchbook location in File/Preferences to the path of your UI project (the parent foder of this INO file)*/ /*Change to your screen resolution*/ static const uint16_t screenWidth = 480 ; static const uint16_t screenHeight = 320 ; static lv_disp_draw_buf_t draw_buf; static lv_color_t buf [ screenWidth * screenHeight / 10 ]; TFT_eSPI tft = TFT_eSPI ( screenWidth, screenHeight ) ; /* TFT instance */ #if LV_USE_LOG != 0 /* Serial debugging */ void my_print ( const char * buf) { Serial . printf ( buf ) ; Serial . flush () ; } #endif /* Display flushing */ 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 () ; tft . setAddrWindow ( area -> x1 , area -> y1 , w, h ) ; tft . pushColors ( ( uint16_t ) & color_p -> full , w h, true ) ; tft . endWrite () ; lv_disp_flush_ready ( disp ) ; } /*Read the touchpad*/ void my_touchpad_read ( lv_indev_drv_t indev_driver , lv_indev_data_t data ) { uint16_t touchX = 0 , touchY = 0 ; bool touched = false ; //tft.getTouch( &touchX, &touchY, 600 ); if ( !touched ) { data -> state = LV_INDEV_STATE_REL; } else { data -> state = LV_INDEV_STATE_PR; /*Set the coordinates*/ data -> point . x = touchX; data -> point . y = touchY; Serial . print ( "Data x " ) ; Serial . println ( touchX ) ; Serial . print ( "Data y " ) ; Serial . println ( touchY ) ; } } void setup () { Serial . begin ( 115200 ) ; /* prepare for possible serial debug */ String LVGL_Arduino = "Hello Arduino! " ; LVGL_Arduino += String ( 'V' ) + lv_version_major () + "." + lv_version_minor () + "." + lv_version_patch () ; Serial . println ( LVGL_Arduino ) ; Serial . println ( "I am LVGL_Arduino" ) ; lv_init () ; #if LV_USE_LOG != 0 lv_log_register_print_cb ( my_print ) ; /* register print function for debugging */ #endif tft . begin () ; /* TFT init */ tft . setRotation ( 3 ) ; /* Landscape orientation, flipped */ lv_disp_draw_buf_init ( &draw_buf, buf, NULL , screenWidth * screenHeight / 10 ) ; /*Initialize the display*/ static lv_disp_drv_t disp_drv; lv_disp_drv_init ( &disp_drv ) ; /*Change the following line to your display resolution*/ disp_drv . hor_res = screenWidth; disp_drv . ver_res = screenHeight; disp_drv . flush_cb = my_disp_flush; disp_drv . draw_buf = &draw_buf; lv_disp_drv_register ( &disp_drv ) ; /*Initialize the (dummy) input device driver*/ static lv_indev_drv_t indev_drv; lv_indev_drv_init ( &indev_drv ) ; indev_drv . type = LV_INDEV_TYPE_POINTER; indev_drv . read_cb = my_touchpad_read; lv_indev_drv_register ( &indev_drv ) ; ui_init () ; Serial . println ( "Setup done" ) ; } void loop () { int rpm_value= map ( analogRead ( 12 ) , 0 , 4095 , 0 , 250 ) ; ui label_set_property ( ui_Speed_Number_1, UI LABEL_PROPERTY_TEXT, String ( rpm_value ) . c_str ()) ; ui label_set_property ( ui_Speed_Number_2, UI LABEL_PROPERTY_TEXT, String ( rpm_value ) . c_str ()) ; lv_slider_set_value ( ui_Slider_Speed, rpm_value,LV_ANIM_ON ) ; int Bat_value= map ( analogRead ( 14 ) , 0 , 4095 , 0 , 100 ) ; ui label_set_property ( ui_Label_Battery_Number, UI LABEL_PROPERTY_TEXT, String ( Bat_value ) . c_str ()) ; lv_slider_set_value ( ui_Slider_Battery, Bat_value,LV_ANIM_ON ) ; lv_timer_handler () ; /* let the GUI do its work */ delay ( 5 ) ; } ###################################################################### Final Steps Upload the code to your ESP32 using the Arduino IDE. Open the Serial Monitor to check for any debug messages. Interact with the touchscreen to see your UI in action! Tips Adjust the pin assignments based on your wiring. Explore LVGL's extensive documentation for more UI elements and functionalities. Use LVGL's built-in tools to design and customize your interfaces. This should give you a solid start on using LVGL with an ESP32 and a TFT LCD touchscreen. Happy coding! Demo:
- Speed and RPM Gauge with ESP32 and 3.5inch TFT display
Creating a demo GUI for an Speed and RPM using an ESP32 and a 3.5-inch TFT display can be an exciting project! Below is a high-level overview of how to set up your project, including the necessary components, libraries, and a basic example of how to structure your code. Here to used the ESP32 board based 3.5inch touch display ILI9488 using the LVGL (Light and Versatile Graphics Library) and Bodmer's TFT_eSPI arduino Library. The LVGL is a popular free and open-source embedded graphics library to create UIs for arduino. In this Setting up LVGL (Light and Versatile Graphics Library) on an ESP32 with a TFT LCD touchscreen display ILI9488 is a great way to create interactive user interfaces for your projects. Here’s a step-by-step guide to help you get started Components Required ESP-32 Module (38Pin) 3.5 inch TFT ILI9488 SPI Interface Module 480x320 with Touch Screen Display 10k Potentiometer -2nos Jumper Wires Circuit Diagram 3.5inch TFT display TFT refer blog: https://www.dofbot.com/post/esp32-dht-weather-monitor-with-3-5inch-tft-touch-display In the VCC pin, you can either use 5V or 3.3V depending upon if your J1 connection is open or closed, J1 = open=5V; J1=close=3.3V. LVGL refer: https://docs.lvgl.io/master/overview/index.html Hardware Requirements ESP32 Board : Any variant should work, but make sure it has enough GPIO pins. TFT LCD Touchscreen : Common models include ILI9488 Connecting Wires : Jumper wires for connections. Breadboard (optional): For easier connections. Software Requirements Arduino IDE : Make sure you have the latest version. Select “File>Preferences>settings>Additional Boards Manager URLs” to fill the link. Here are the steps to install the ESP32 board in Arduino IDE: Open the Arduino IDE Select File and then Preferences Find the Additional Board Manager URLs field and activate the text box Add the URL to the field Click OK to save the changes https:// raw.githubusercontent.com/espressif/arduino-esp32/gh-pages/package_esp32_dev_index.json , https://arduino.esp8266.com/stable/package_esp8266com_index.json , https://espressif.github.io/arduino-esp32/package_esp32_index.json LVGL Library : Available through the Library Manager in the Arduino IDE. Touch Driver Library : Depending on your touchscreen (e.g., TFT_eSPI) Configuring LVGL LVGL Configuration : You may need to configure LVGL for your specific display and touch screen. Create a lv_conf.h file or modify the existing one in the LVGL library folder: Set LVGL_DISPLAY_HOR_RES and LVGL_DISPLAY_VER_RES to match your display's resolution. Configure the display and touch input settings based on your library (e.g., TFT_eSPI settings). TFT_eSPI Configuration : A feature rich Arduino IDE compatible graphics and fonts library for 32-bit processors. The library is targeted at 32-bit processors, it has been performance optimised for RP2040, STM32, ESP8266 and ESP32 types, other 32-bit processors may be used but will use the slower generic Arduino interface calls. The library can be loaded using the Arduino IDE's Library Manager. Direct Memory Access (DMA) can be used with the ESP32, RP2040 and STM32 processors with SPI interface displays to improve rendering performance. DMA with a parallel interface (8 and 16-bit) is only supported with the RP2040. Go to the TFT_eSPI library folder and open the User_Setup.h file to configure the pins according to your wiring. Wiring the TFT Display TFT Pin ESP32 Pin VCC 3.3V GND GND CS GPIO 5 RESET GPIO EN DC/RS GPIO 17 SDI(MOSI) GPIO 23 SCK GPIO 18 LED 3.3V (or PWM pin for brightness) Wiring the Touchscreen (e.g., TFT_espi) Touch Pin ESP32 Pin T_CS GPIO 16 T_IRQ GPIO 21 T_DOUT GPIO 19 T_DIN GPIO 23 T_CLK GPIO 18 4. UI Library : User Interface (e.g., UI) Arduino Code Here’s a basic example to initialize the display and create a simple button using LVGL: ###################################################################### //Arduino-TFT_eSPI board-template main routine. There's a TFT_eSPI create+flush driver already in LVGL-9.1 but we create our own here for more control (like e.g. 16-bit color swap). #include "FS.h" #include #include #include #include /*Don't forget to set Sketchbook location in File/Preferences to the path of your UI project (the parent foder of this INO file)*/ /*Change to your screen resolution*/ static const uint16_t screenWidth = 480 ; static const uint16_t screenHeight = 320 ; enum { SCREENBUFFER_SIZE_PIXELS = screenWidth * screenHeight / 10 } ; static lv_color_t buf [SCREENBUFFER_SIZE_PIXELS]; TFT_eSPI tft = TFT_eSPI ( screenWidth, screenHeight ) ; /* TFT instance */ #define CALIBRATION_FILE "/calibrationData" #if LV_USE_LOG != 0 /* Serial debugging */ void my_print ( const char * buf) { Serial . printf ( buf ) ; Serial . flush () ; } #endif int rpm = 0 ; // Current RPM value int speed = 0 ; // Current speed value /* Display flushing */ void my_disp_flush ( lv_display_t disp , const lv_area_t area , uint8_t * pixelmap) { uint32_t w = ( area -> x2 - area -> x1 + 1 ) ; uint32_t h = ( area -> y2 - area -> y1 + 1 ) ; if ( LV_COLOR_16_SWAP ) { size_t len = lv_area_get_size ( area ) ; lv_draw_sw_rgb565_swap ( pixelmap, len ) ; } tft . startWrite () ; tft . setAddrWindow ( area -> x1 , area -> y1 , w, h ) ; tft . pushColors ( ( uint16_t * ) pixelmap, w * h, true ) ; tft . endWrite () ; lv_disp_flush_ready ( disp ) ; } /*Read the touchpad*/ void my_touchpad_read ( lv_indev_t indev_driver , lv_indev_data_t data) { uint16_t touchX = 0 , touchY = 0 ; bool touched = tft . getTouch ( &touchX, &touchY, 600 ) ; if ( !touched ) { data -> state = LV_INDEV_STATE_REL; } else { data -> state = LV_INDEV_STATE_PR; /*Set the coordinates*/ data -> point . x = touchX; data -> point . y = touchY; Serial . print ( "Data x " ) ; Serial . println ( touchX ) ; Serial . print ( "Data y " ) ; Serial . println ( touchY ) ; } } /*Set tick routine needed for LVGL internal timings*/ static uint32_t my_tick_get_cb ( void ) { return millis () ; } void setup () { uint16_t calibrationData [ 5 ]; uint8_t calDataOK = 0 ; Serial . begin ( 115200 ) ; /* prepare for possible serial debug */ String LVGL_Arduino = "Hello Arduino! " ; LVGL_Arduino += String ( 'V' ) + lv_version_major () + "." + lv_version_minor () + "." + lv_version_patch () ; Serial . println ( LVGL_Arduino ) ; Serial . println ( "I am LVGL_Arduino" ) ; lv_init () ; #if LV_USE_LOG != 0 lv_log_register_print_cb ( my_print ) ; /* register print function for debugging */ #endif tft . begin () ; /* TFT init */ tft . setRotation ( 3 ) ; /* Landscape orientation, flipped */ static lv_disp_t * disp; disp = lv_display_create ( screenWidth, screenHeight ) ; lv_display_set_buffers ( disp, buf, NULL , SCREENBUFFER_SIZE_PIXELS * sizeof ( lv_color_t ) , LV_DISPLAY_RENDER_MODE_PARTIAL ) ; lv_display_set_flush_cb ( disp, my_disp_flush ) ; static lv_indev_t * indev; indev = lv_indev_create () ; lv_indev_set_type ( indev, LV_INDEV_TYPE_POINTER ) ; lv_indev_set_read_cb ( indev, my_touchpad_read ) ; lv_tick_set_cb ( my_tick_get_cb ) ; ui_init () ; Serial . println ( "Setup done" ) ; // check file system if ( ! SPIFFS . begin ()) { Serial . println ( "formatting file system" ) ; SPIFFS . format () ; SPIFFS . begin () ; } // check if calibration file exists if ( SPIFFS . exists ( CALIBRATION_FILE )) { File f = SPIFFS . open ( CALIBRATION_FILE, "r" ) ; if ( f ) { if ( f . readBytes (( char * ) calibrationData, 14 ) == 14 ) calDataOK = 1 ; f . close () ; } } if ( calDataOK ) { // calibration data valid tft . setTouch ( calibrationData ) ; } else { // data not valid. recalibrate tft . calibrateTouch ( calibrationData, TFT_WHITE, TFT_RED, 15 ) ; // store data File f = SPIFFS . open ( CALIBRATION_FILE, "w" ) ; if ( f ) { f . write (( const unsigned char * ) calibrationData, 14 ) ; f . close () ; } } } void loop () { lv_timer_handler () ; /* let the GUI do its work */ delay ( 5 ) ; // Update RPM label with the current value char rpm_str [ 10 ]; sprintf ( rpm_str, "%d" , rpm ) ; // Display the current RPM value (e.g., 100, 200, etc.) lv_label_set_text ( ui_Label_RPM, rpm_str ) ; // Update gauge needle based on RPM value // Map 0 RPM to 0 degrees and 10,000 RPM to 2500 degrees int rpm = map ( analogRead ( 12 ) , 0 , 4096 , 0 , 8000 ) ; // change analog pin as you desired int needle_angle = map ( rpm, 0 , 8000 , 600 , 3000 ) ; lv_img_set_angle ( ui_Needle_rpm, needle_angle ) ; ui label_set_property ( ui_Label_RPM, UI LABEL_PROPERTY_TEXT, String ( rpm ) . c_str ()) ; // Update gauge needle based on SPEED value // Map 0 SPEED to 0 degrees and 10,000 Speed to 2500 degrees int speed = map ( analogRead ( 14 ) , 0 , 4096 , 0 , 240 ) ; // change analog pin as you desired int needle_angle1 = map ( speed, 0 , 240 , 600 , 3000 ) ; lv_img_set_angle ( ui_Neddle_speed, needle_angle1 ) ; ui label_set_property ( ui_Label_SPEED, UI LABEL_PROPERTY_TEXT, String ( speed ) . c_str ()) ; } ###################################################################### Final Steps Upload the code to your ESP32 using the Arduino IDE. Open the Serial Monitor to check for any debug messages. Interact with the touchscreen to see your UI in action! Tips Adjust the pin assignments based on your wiring. Explore LVGL's extensive documentation for more UI elements and functionalities. Use LVGL's built-in tools to design and customize your interfaces. This should give you a solid start on using LVGL with an ESP32 and a TFT LCD touchscreen. Happy coding! Demo:
- 1.28 inch GC9A01 Round LCD with ESP32 and LVGL UI Part4
Here to learn to create a 240x240 pixel GC9A01 Round LCD display using an ESP32 with the LVGL library and Bodmer's TFT_eSPI library, enabling interactive UIs for your projects. The LVGL Light and Versatile Graphics Library) is a popular free and open-source embedded graphics library to create UIs for Embedded boards. In this Setting up LVGL (Light and Versatile Graphics Library) on an ESP32 with a TFT 1.28 inch GC9A01 Round LCD display is a great way to create interactive user interfaces for your projects. Here’s a step-by-step guide to help you get started. Demo: Components Required ESP-32 Module (38Pin) 1.28 Inch Round Display Module GC9A01 7P 240X240 SPI 10K Potentiometer Jumper Wires Circuit Diagram GC9A01 7P 240X240 SPI This is a 1.28 Inch Round Display Module GC9A01 7P 240X240 SPI . This module is composed of a TFT LCD Panel, driver ICs, FPC and a Backlight unit. It uses a full-color LCD screen with a circular appearance and is suitable for making watches, clocks, or measuring instruments. It can also connect with ESP32, Raspberry Pi, or Arduino. Such displays support different communication protocols providing flexibility for integration into various applications. With vibrant colors and excellent clarity, these display modules are suitable for a wide array of projects, from consumer electronics to industrial controls. Features : High-Resolution Options Vibrant Colors and Clarity Compact and Lightweight Reliable Performance Customization Potential Specifications: Display Type: TFT Resolution: 240 x 240 Screen Size: (inch) 1.28 No. of Pins: 7 Communication Protocol: SPI IC Chip: GC9A01 Outside Diameter: (OD) mm 38 Operating Temperature: (°C) -20 to +70 Storage Temperature: (C) -30 to 80 Weight (g): 20g Pin Configuration: GND : LCD Power ground VCC : LCD power supply is positive (3.3V/5V) SCL : LCD SPI bus clock signal SDA : LCD SPI bus write data signal RES : LCD reset control signal(Low level reset,The module has a reset circuit, and this pin can not be connected) DC : LCD register / data selection control signal (Low level: register, high level: data) CS : LCD chip select control signal (low level enable) https://www.buydisplay.com/download/ic/GC9A01A.pdf Hardware Requirements ESP32 Board : Any variant should work, but make sure it has enough GPIO pins. TFT LCD Touchscreen : Common models include ILI9488 Connecting Wires : Jumper wires for connections. Breadboard (optional): For easier connections. Software Requirements Arduino IDE : Make sure you have the latest version. Select “File>Preferences>settings>Additional Boards Manager URLs” to fill the link. Here are the steps to install the ESP32 board in Arduino IDE: Open the Arduino IDE Select File and then Preferences Find the Additional Board Manager URLs field and activate the text box Add the URL to the field Click OK to save the changes https:// raw.githubusercontent.com/espressif/arduino-esp32/gh-pages/package_esp32_dev_index.json , https://arduino.esp8266.com/stable/package_esp8266com_index.json , https://espressif.github.io/arduino-esp32/package_esp32_index.json LVGL Library : Available through the Library Manager in the Arduino IDE. Configuring LVGL LVGL Configuration : You may need to configure LVGL for your specific display and touch screen. Create a lv_conf.h file or modify the existing one in the LVGL library folder: Set LVGL_DISPLAY_HOR_RES and LVGL_DISPLAY_VER_RES to match your display's resolution. Configure the display and touch input settings based on your library (e.g., TFT_eSPI settings). TFT_eSPI Configuration : A feature rich Arduino IDE compatible graphics and fonts library for 32-bit processors. The library is targeted at 32-bit processors, it has been performance optimised for RP2040, STM32, ESP8266 and ESP32 types, other 32-bit processors may be used but will use the slower generic Arduino interface calls. The library can be loaded using the Arduino IDE's Library Manager. Direct Memory Access (DMA) can be used with the ESP32, RP2040 and STM32 processors with SPI interface displays to improve rendering performance. DMA with a parallel interface (8 and 16-bit) is only supported with the RP2040. Go to the TFT_eSPI library folder and open the User_Setup.h file to configure the pins according to your wiring. TFT Pin ESP32 Pin VCC 3.3V GND GND CS GPIO 5 RESET GPIO 2 DC/RS GPIO 17 SDI(MOSI) GPIO 23 SCK GPIO 18 Arduino Code Here’s a basic example to initialize the display and create a simple button using LVGL: Example 1. ######################################################################### #include #include #include /*Don't forget to set Sketchbook location in File/Preferences to the path of your UI project (the parent foder of this INO file)*/ /*Change to your screen resolution*/ static const uint16_t screenWidth = 240 ; static const uint16_t screenHeight = 240 ; static lv_disp_draw_buf_t draw_buf; static lv_color_t buf [ screenWidth * screenHeight / 10 ]; TFT_eSPI tft = TFT_eSPI ( screenWidth, screenHeight ) ; /* TFT instance */ #if LV_USE_LOG != 0 /* Serial debugging */ void my_print ( const char * buf) { Serial . printf ( buf ) ; Serial . flush () ; } #endif int rpm_value = 0 ; // Current RPM value bool rpm_increasing = true ; // Flag for increasing/decreasing RPM // Function declarations void simulate_rpm () ; void update_rpm_ui ( int rpm) ; /* Display flushing */ 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 () ; tft . setAddrWindow ( area -> x1 , area -> y1 , w, h ) ; tft . pushColors ( ( uint16_t ) & color_p -> full , w h, true ) ; tft . endWrite () ; lv_disp_flush_ready ( disp ) ; } /*Read the touchpad*/ void my_touchpad_read ( lv_indev_drv_t indev_driver , lv_indev_data_t data ) { uint16_t touchX = 0 , touchY = 0 ; bool touched = false ; //tft.getTouch( &touchX, &touchY, 600 ); if ( !touched ) { data -> state = LV_INDEV_STATE_REL; } else { data -> state = LV_INDEV_STATE_PR; /*Set the coordinates*/ data -> point . x = touchX; data -> point . y = touchY; Serial . print ( "Data x " ) ; Serial . println ( touchX ) ; Serial . print ( "Data y " ) ; Serial . println ( touchY ) ; } } // RPM Simulation: Simulates the RPM going from 0 to 10,000 and back with smoother transitions void simulate_rpm () { const int max_rpm = 100 ; // Maximum RPM value (10,000 RPM) const int rpm_step = 1 ; // Smaller increment step for smoother transition (100 RPM) if ( rpm_increasing ) { if ( rpm_value < max_rpm ) { rpm_value += rpm_step; } else { rpm_increasing = false ; // Start decrementing when max RPM is reached } } else { if ( rpm_value > 0 ) { rpm_value -= rpm_step; } else { rpm_increasing = true ; // Start incrementing when 0 RPM is reached } } update_rpm_ui ( rpm_value ) ; // Update the RPM UI elements } // Update the LVGL UI elements based on RPM value void update_rpm_ui ( int rpm) { // Update RPM label with the current value char rpm_str [ 10 ]; sprintf ( rpm_str, "%d" , rpm ) ; // Display the current RPM value (e.g., 100, 200, etc.) lv_label_set_text ( ui_Label_rpm, rpm_str ) ; // Update gauge needle based on RPM value // Map 0 RPM to 0 degrees and 10,000 RPM to 2500 degrees int needle_angle = map ( rpm, 0 , 100 , 0 , 2500 ) ; lv_img_set_angle ( ui_Image_gauge_needle, needle_angle ) ; // Map RPM value to the range of 0-93 for the arc int arc_value = map ( rpm, 0 , 100 , 0 , 93 ) ; lv_arc_set_value ( ui_Arc_rpm, arc_value ) ; // Update the arc based on RPM value } void setup () { Serial . begin ( 115200 ) ; /* prepare for possible serial debug */ String LVGL_Arduino = "Hello Arduino! " ; LVGL_Arduino += String ( 'V' ) + lv_version_major () + "." + lv_version_minor () + "." + lv_version_patch () ; Serial . println ( LVGL_Arduino ) ; Serial . println ( "I am LVGL_Arduino" ) ; lv_init () ; #if LV_USE_LOG != 0 lv_log_register_print_cb ( my_print ) ; /* register print function for debugging */ #endif tft . begin () ; /* TFT init */ tft . setRotation ( 3 ) ; /* Landscape orientation, flipped */ lv_disp_draw_buf_init ( &draw_buf, buf, NULL , screenWidth * screenHeight / 10 ) ; /*Initialize the display*/ static lv_disp_drv_t disp_drv; lv_disp_drv_init ( &disp_drv ) ; /*Change the following line to your display resolution*/ disp_drv . hor_res = screenWidth; disp_drv . ver_res = screenHeight; disp_drv . flush_cb = my_disp_flush; disp_drv . draw_buf = &draw_buf; lv_disp_drv_register ( &disp_drv ) ; /*Initialize the (dummy) input device driver*/ static lv_indev_drv_t indev_drv; lv_indev_drv_init ( &indev_drv ) ; indev_drv . type = LV_INDEV_TYPE_POINTER; indev_drv . read_cb = my_touchpad_read; lv_indev_drv_register ( &indev_drv ) ; ui_init () ; Serial . println ( "Setup done" ) ; } void loop () { lv_timer_handler () ; /* let the GUI do its work */ delay ( 5 ) ; simulate_rpm () ; // Simulate RPM and update the UI } ######################################################################### Next Example: Final Steps Upload the code to your ESP32 using the Arduino IDE. Open the Serial Monitor to check for any debug messages. Tips Adjust the pin assignments based on your wiring. Explore LVGL's extensive documentation for more UI elements and functionalities. Use LVGL's built-in tools to design and customize your interfaces. This should give you a solid start on using LVGL with an ESP32 and a TFT LCD Happy coding!
- 1.28 inch GC9A01 Round LCD with ESP32 and LVGL UI Part3
Here to learn to create a 240x240 pixel GC9A01 Round LCD display using an ESP32 with the LVGL library and Bodmer's TFT_eSPI library, enabling interactive UIs for your projects. The LVGL Light and Versatile Graphics Library) is a popular free and open-source embedded graphics library to create UIs for Embedded boards. In this Setting up LVGL (Light and Versatile Graphics Library) on an ESP32 with a TFT 1.28 inch GC9A01 Round LCD display is a great way to create interactive user interfaces for your projects. Here’s a step-by-step guide to help you get started. Demo: Components Required ESP-32 Module (38Pin) 1.28 Inch Round Display Module GC9A01 7P 240X240 SPI 10K Potentiometer Jumper Wires Circuit Diagram GC9A01 7P 240X240 SPI This is a 1.28 Inch Round Display Module GC9A01 7P 240X240 SPI . This module is composed of a TFT LCD Panel, driver ICs, FPC and a Backlight unit. It uses a full-color LCD screen with a circular appearance and is suitable for making watches, clocks, or measuring instruments. It can also connect with ESP32, Raspberry Pi, or Arduino. Such displays support different communication protocols providing flexibility for integration into various applications. With vibrant colors and excellent clarity, these display modules are suitable for a wide array of projects, from consumer electronics to industrial controls. Features : High-Resolution Options Vibrant Colors and Clarity Compact and Lightweight Reliable Performance Customization Potential Specifications: Display Type: TFT Resolution: 240 x 240 Screen Size: (inch) 1.28 No. of Pins: 7 Communication Protocol: SPI IC Chip: GC9A01 Outside Diameter: (OD) mm 38 Operating Temperature: (°C) -20 to +70 Storage Temperature: (C) -30 to 80 Weight (g): 20g Pin Configuration: GND : LCD Power ground VCC : LCD power supply is positive (3.3V/5V) SCL : LCD SPI bus clock signal SDA : LCD SPI bus write data signal RES : LCD reset control signal(Low level reset,The module has a reset circuit, and this pin can not be connected) DC : LCD register / data selection control signal (Low level: register, high level: data) CS : LCD chip select control signal (low level enable) https://www.buydisplay.com/download/ic/GC9A01A.pdf Hardware Requirements ESP32 Board : Any variant should work, but make sure it has enough GPIO pins. TFT LCD Touchscreen : Common models include ILI9488 Connecting Wires : Jumper wires for connections. Breadboard (optional): For easier connections. Software Requirements Arduino IDE : Make sure you have the latest version. Select “File>Preferences>settings>Additional Boards Manager URLs” to fill the link. Here are the steps to install the ESP32 board in Arduino IDE: Open the Arduino IDE Select File and then Preferences Find the Additional Board Manager URLs field and activate the text box Add the URL to the field Click OK to save the changes https:// raw.githubusercontent.com/espressif/arduino-esp32/gh-pages/package_esp32_dev_index.json , https://arduino.esp8266.com/stable/package_esp8266com_index.json , https://espressif.github.io/arduino-esp32/package_esp32_index.json LVGL Library : Available through the Library Manager in the Arduino IDE. Configuring LVGL LVGL Configuration : You may need to configure LVGL for your specific display and touch screen. Create a lv_conf.h file or modify the existing one in the LVGL library folder: Set LVGL_DISPLAY_HOR_RES and LVGL_DISPLAY_VER_RES to match your display's resolution. Configure the display and touch input settings based on your library (e.g., TFT_eSPI settings). TFT_eSPI Configuration : A feature rich Arduino IDE compatible graphics and fonts library for 32-bit processors. The library is targeted at 32-bit processors, it has been performance optimised for RP2040, STM32, ESP8266 and ESP32 types, other 32-bit processors may be used but will use the slower generic Arduino interface calls. The library can be loaded using the Arduino IDE's Library Manager. Direct Memory Access (DMA) can be used with the ESP32, RP2040 and STM32 processors with SPI interface displays to improve rendering performance. DMA with a parallel interface (8 and 16-bit) is only supported with the RP2040. Go to the TFT_eSPI library folder and open the User_Setup.h file to configure the pins according to your wiring. TFT Pin ESP32 Pin VCC 3.3V GND GND CS GPIO 5 RESET GPIO 2 DC/RS GPIO 17 SDI(MOSI) GPIO 23 SCK GPIO 18 Arduino Code Here’s a basic example to initialize the display and create a simple button using LVGL: Example 1. ######################################################################### #include #include #include /*Don't forget to set Sketchbook location in File/Preferences to the path of your UI project (the parent foder of this INO file)*/ /*Change to your screen resolution*/ static const uint16_t screenWidth = 240 ; static const uint16_t screenHeight = 240 ; static lv_disp_draw_buf_t draw_buf; static lv_color_t buf [ screenWidth * screenHeight / 10 ]; TFT_eSPI tft = TFT_eSPI ( screenWidth, screenHeight ) ; /* TFT instance */ #if LV_USE_LOG != 0 /* Serial debugging */ void my_print ( const char * buf) { Serial . printf ( buf ) ; Serial . flush () ; } #endif /* Display flushing */ 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 () ; tft . setAddrWindow ( area -> x1 , area -> y1 , w, h ) ; tft . pushColors ( ( uint16_t ) & color_p -> full , w h, true ) ; tft . endWrite () ; lv_disp_flush_ready ( disp ) ; } /*Read the touchpad*/ void my_touchpad_read ( lv_indev_drv_t indev_driver , lv_indev_data_t data ) { uint16_t touchX = 0 , touchY = 0 ; bool touched = false ; //tft.getTouch( &touchX, &touchY, 600 ); if ( !touched ) { data -> state = LV_INDEV_STATE_REL; } else { data -> state = LV_INDEV_STATE_PR; /*Set the coordinates*/ data -> point . x = touchX; data -> point . y = touchY; Serial . print ( "Data x " ) ; Serial . println ( touchX ) ; Serial . print ( "Data y " ) ; Serial . println ( touchY ) ; } } void update_pitch ( lv_obj_t ui_img_pitch_scale , lv_obj_t ui_Label_pitch , int pitch_value , int pitch_rotation) { // Calculate the rotation angle in degrees for pitch int rotation_angle = pitch_rotation / 10 ; // Each 100 units corresponds to 10 degrees lv_img_set_angle ( ui_img_pitch_scale, rotation_angle * 10 ) ; // LVGL uses 0.1 degree units // Calculate the Y position int y_position = pitch_value * 2 ; // Each 10 pixels corresponds to 5 units lv_obj_set_y ( ui_img_pitch_scale, y_position ) ; // Update the pitch label with the current pitch value char buf [ 16 ]; snprintf ( buf, sizeof ( buf ) , "%d" , pitch_value ) ; lv_label_set_text ( ui_Label_pitch, buf ) ; } void update_roll ( lv_obj_t ui_img_roll_scale , lv_obj_t ui_Label_roll , int roll_value) { // Calculate the rotation angle in degrees int rotation_angle = roll_value; // Each unit corresponds to 1 degree lv_img_set_angle ( ui_img_roll_scale, rotation_angle * 10 ) ; // LVGL uses 0.1 degree units // Display positive degree on the right and negative degree on the left int display_angle = -roll_value; // Invert the roll value for display // Update the roll label with the current rotation angle in degrees char buf [ 16 ]; snprintf ( buf, sizeof ( buf ) , "%d" , display_angle ) ; lv_label_set_text ( ui_Label_roll, buf ) ; } void update_pitch_and_roll ( lv_obj_t ui_img_pitch_scale , lv_obj_t ui_img_roll_scale , lv_obj_t ui_Label_pitch , lv_obj_t ui_Label_roll , int pitch_value , int pitch_rotation , int roll_value) { update_pitch ( ui_img_pitch_scale, ui_Label_pitch, pitch_value, pitch_rotation ) ; update_roll ( ui_img_roll_scale, ui_Label_roll, roll_value ) ; } void mock_data ( int & pitch_value , int & pitch_rotation , int & roll_value , int speed_factor) { static bool increasing_pitch = true ; static bool increasing_pitch_rotation = true ; static bool increasing_roll = true ; // Update pitch if ( increasing_pitch ) { pitch_value += speed_factor; if ( pitch_value >= 20 ) { // 20 units is the max pitch value increasing_pitch = false ; } } else { pitch_value -= speed_factor; if ( pitch_value <= - 20 ) { // -20 units is the min pitch value increasing_pitch = true ; } } // Update pitch rotation if ( increasing_pitch_rotation ) { pitch_rotation += 10 * speed_factor; if ( pitch_rotation >= 900 ) { // 900 units is the max pitch rotation increasing_pitch_rotation = false ; } } else { pitch_rotation -= 10 * speed_factor; if ( pitch_rotation <= - 900 ) { // -900 units is the min pitch rotation increasing_pitch_rotation = true ; } } // Update roll if ( increasing_roll ) { roll_value -= speed_factor; // Decrease roll value for right rotation if ( roll_value <= - 90 ) { // -90 degrees is the max right roll value increasing_roll = false ; } } else { roll_value += speed_factor; // Increase roll value for left rotation if ( roll_value >= 90 ) { // 90 degrees is the max left roll value increasing_roll = true ; } } } void setup () { Serial . begin ( 115200 ) ; /* prepare for possible serial debug */ String LVGL_Arduino = "Hello Arduino! " ; LVGL_Arduino += String ( 'V' ) + lv_version_major () + "." + lv_version_minor () + "." + lv_version_patch () ; Serial . println ( LVGL_Arduino ) ; Serial . println ( "I am LVGL_Arduino" ) ; lv_init () ; #if LV_USE_LOG != 0 lv_log_register_print_cb ( my_print ) ; /* register print function for debugging */ #endif tft . begin () ; /* TFT init */ tft . setRotation ( 3 ) ; /* Landscape orientation, flipped */ lv_disp_draw_buf_init ( &draw_buf, buf, NULL , screenWidth * screenHeight / 10 ) ; /*Initialize the display*/ static lv_disp_drv_t disp_drv; lv_disp_drv_init ( &disp_drv ) ; /*Change the following line to your display resolution*/ disp_drv . hor_res = screenWidth; disp_drv . ver_res = screenHeight; disp_drv . flush_cb = my_disp_flush; disp_drv . draw_buf = &draw_buf; lv_disp_drv_register ( &disp_drv ) ; /*Initialize the (dummy) input device driver*/ static lv_indev_drv_t indev_drv; lv_indev_drv_init ( &indev_drv ) ; indev_drv . type = LV_INDEV_TYPE_POINTER; indev_drv . read_cb = my_touchpad_read; lv_indev_drv_register ( &indev_drv ) ; ui_init () ; Serial . println ( "Setup done" ) ; // Initialize with level pitch, pitch rotation, and no roll int pitch_value = 0 ; int pitch_rotation = 0 ; int roll_value = 0 ; update_pitch_and_roll ( ui_img_pitch_scale, ui_img_roll_scale, ui_Label_pitch, ui_Label_roll, pitch_value, pitch_rotation, roll_value ) ; } void loop () { lv_timer_handler () ; /* let the GUI do its work */ delay ( 5 ) ; // Example updates for testing static int pitch_value = 0 ; static int pitch_rotation = 0 ; static int roll_value = 0 ; // Simulate pitch and roll changes int speed_factor = 1 ; // Adjust this value to control speed of mock data generation mock_data ( pitch_value, pitch_rotation, roll_value, speed_factor ) ; update_pitch_and_roll ( ui_img_pitch_scale, ui_img_roll_scale, ui_Label_pitch, ui_Label_roll, pitch_value, pitch_rotation, roll_value ) ; } ######################################################################### Next Example: Final Steps Upload the code to your ESP32 using the Arduino IDE. Open the Serial Monitor to check for any debug messages. Tips Adjust the pin assignments based on your wiring. Explore LVGL's extensive documentation for more UI elements and functionalities. Use LVGL's built-in tools to design and customize your interfaces. This should give you a solid start on using LVGL with an ESP32 and a TFT LCD Happy coding!
- 1.28 inch GC9A01 Round LCD with ESP32 and LVGL UI Part2
Here to learn to create a 240x240 pixel GC9A01 Round LCD display using an ESP32 with the LVGL library and Bodmer's TFT_eSPI library, enabling interactive UIs for your projects. The LVGL Light and Versatile Graphics Library) is a popular free and open-source embedded graphics library to create UIs for Embedded boards. In this Setting up LVGL (Light and Versatile Graphics Library) on an ESP32 with a TFT 1.28 inch GC9A01 Round LCD display is a great way to create interactive user interfaces for your projects. Here’s a step-by-step guide to help you get started. Demo: Components Required ESP-32 Module (38Pin) 1.28 Inch Round Display Module GC9A01 7P 240X240 SPI 10K Potentiometer Jumper Wires Circuit Diagram GC9A01 7P 240X240 SPI This is a 1.28 Inch Round Display Module GC9A01 7P 240X240 SPI . This module is composed of a TFT LCD Panel, driver ICs, FPC and a Backlight unit. It uses a full-color LCD screen with a circular appearance and is suitable for making watches, clocks, or measuring instruments. It can also connect with ESP32, Raspberry Pi, or Arduino. Such displays support different communication protocols providing flexibility for integration into various applications. With vibrant colors and excellent clarity, these display modules are suitable for a wide array of projects, from consumer electronics to industrial controls. Features : High-Resolution Options Vibrant Colors and Clarity Compact and Lightweight Reliable Performance Customization Potential Specifications: Display Type: TFT Resolution: 240 x 240 Screen Size: (inch) 1.28 No. of Pins: 7 Communication Protocol: SPI IC Chip: GC9A01 Outside Diameter: (OD) mm 38 Operating Temperature: (°C) -20 to +70 Storage Temperature: (C) -30 to 80 Weight (g): 20g Pin Configuration: GND : LCD Power ground VCC : LCD power supply is positive (3.3V/5V) SCL : LCD SPI bus clock signal SDA : LCD SPI bus write data signal RES : LCD reset control signal(Low level reset,The module has a reset circuit, and this pin can not be connected) DC : LCD register / data selection control signal (Low level: register, high level: data) CS : LCD chip select control signal (low level enable) https://www.buydisplay.com/download/ic/GC9A01A.pdf Hardware Requirements ESP32 Board : Any variant should work, but make sure it has enough GPIO pins. TFT LCD Touchscreen : Common models include ILI9488 Connecting Wires : Jumper wires for connections. Breadboard (optional): For easier connections. Software Requirements Arduino IDE : Make sure you have the latest version. Select “File>Preferences>settings>Additional Boards Manager URLs” to fill the link. Here are the steps to install the ESP32 board in Arduino IDE: Open the Arduino IDE Select File and then Preferences Find the Additional Board Manager URLs field and activate the text box Add the URL to the field Click OK to save the changes https:// raw.githubusercontent.com/espressif/arduino-esp32/gh-pages/package_esp32_dev_index.json , https://arduino.esp8266.com/stable/package_esp8266com_index.json , https://espressif.github.io/arduino-esp32/package_esp32_index.json LVGL Library : Available through the Library Manager in the Arduino IDE. Configuring LVGL LVGL Configuration : You may need to configure LVGL for your specific display and touch screen. Create a lv_conf.h file or modify the existing one in the LVGL library folder: Set LVGL_DISPLAY_HOR_RES and LVGL_DISPLAY_VER_RES to match your display's resolution. Configure the display and touch input settings based on your library (e.g., TFT_eSPI settings). TFT_eSPI Configuration : A feature rich Arduino IDE compatible graphics and fonts library for 32-bit processors. The library is targeted at 32-bit processors, it has been performance optimised for RP2040, STM32, ESP8266 and ESP32 types, other 32-bit processors may be used but will use the slower generic Arduino interface calls. The library can be loaded using the Arduino IDE's Library Manager. Direct Memory Access (DMA) can be used with the ESP32, RP2040 and STM32 processors with SPI interface displays to improve rendering performance. DMA with a parallel interface (8 and 16-bit) is only supported with the RP2040. Go to the TFT_eSPI library folder and open the User_Setup.h file to configure the pins according to your wiring. TFT Pin ESP32 Pin VCC 3.3V GND GND CS GPIO 5 RESET GPIO 2 DC/RS GPIO 17 SDI(MOSI) GPIO 23 SCK GPIO 18 Arduino Code Here’s a basic example to initialize the display and create a simple button using LVGL: Example 1. ######################################################################### //Arduino-TFT_eSPI board-template main routine. There's a TFT_eSPI create+flush driver already in LVGL-9.1 but we create our own here for more control (like e.g. 16-bit color swap). #include #include #include /*Don't forget to set Sketchbook location in File/Preferences to the path of your UI project (the parent foder of this INO file)*/ /*Change to your screen resolution*/ static const uint16_t screenWidth = 240 ; static const uint16_t screenHeight = 240 ; enum { SCREENBUFFER_SIZE_PIXELS = screenWidth * screenHeight / 10 } ; static lv_color_t buf [SCREENBUFFER_SIZE_PIXELS]; TFT_eSPI tft = TFT_eSPI ( screenWidth, screenHeight ) ; /* TFT instance */ #if LV_USE_LOG != 0 /* Serial debugging */ void my_print ( const char * buf) { Serial . printf ( buf ) ; Serial . flush () ; } #endif /* Display flushing */ void my_disp_flush ( lv_display_t disp , const lv_area_t area , uint8_t * pixelmap) { uint32_t w = ( area -> x2 - area -> x1 + 1 ) ; uint32_t h = ( area -> y2 - area -> y1 + 1 ) ; if ( LV_COLOR_16_SWAP ) { size_t len = lv_area_get_size ( area ) ; lv_draw_sw_rgb565_swap ( pixelmap, len ) ; } tft . startWrite () ; tft . setAddrWindow ( area -> x1 , area -> y1 , w, h ) ; tft . pushColors ( ( uint16_t * ) pixelmap, w * h, true ) ; tft . endWrite () ; lv_disp_flush_ready ( disp ) ; } /*Read the touchpad*/ void my_touchpad_read ( lv_indev_t indev_driver , lv_indev_data_t data) { uint16_t touchX = 0 , touchY = 0 ; bool touched = false ; //tft.getTouch( &touchX, &touchY, 600 ); if ( !touched ) { data -> state = LV_INDEV_STATE_REL; } else { data -> state = LV_INDEV_STATE_PR; /*Set the coordinates*/ data -> point . x = touchX; data -> point . y = touchY; Serial . print ( "Data x " ) ; Serial . println ( touchX ) ; Serial . print ( "Data y " ) ; Serial . println ( touchY ) ; } } /*Set tick routine needed for LVGL internal timings*/ static uint32_t my_tick_get_cb ( void ) { return millis () ; } void setup () { Serial . begin ( 115200 ) ; /* prepare for possible serial debug */ String LVGL_Arduino = "Hello Arduino! " ; LVGL_Arduino += String ( 'V' ) + lv_version_major () + "." + lv_version_minor () + "." + lv_version_patch () ; Serial . println ( LVGL_Arduino ) ; Serial . println ( "I am LVGL_Arduino" ) ; lv_init () ; #if LV_USE_LOG != 0 lv_log_register_print_cb ( my_print ) ; /* register print function for debugging */ #endif tft . begin () ; /* TFT init */ tft . setRotation ( 3 ) ; /* Landscape orientation, flipped */ static lv_disp_t * disp; disp = lv_display_create ( screenWidth, screenHeight ) ; lv_display_set_buffers ( disp, buf, NULL , SCREENBUFFER_SIZE_PIXELS * sizeof ( lv_color_t ) , LV_DISPLAY_RENDER_MODE_PARTIAL ) ; lv_display_set_flush_cb ( disp, my_disp_flush ) ; static lv_indev_t * indev; indev = lv_indev_create () ; lv_indev_set_type ( indev, LV_INDEV_TYPE_POINTER ) ; lv_indev_set_read_cb ( indev, my_touchpad_read ) ; lv_tick_set_cb ( my_tick_get_cb ) ; ui_init () ; Serial . println ( "Setup done" ) ; } void loop () { int temp_value= map ( analogRead ( 12 ) , 0 , 4095 , 0 , 100 ) ; //Analog Pin GPIO 12 ui label_set_property ( ui_Label_Celsius, UI LABEL_PROPERTY_TEXT, String ( temp_value ) . c_str ()) ; lv_arc_set_value ( ui_Arc1, temp_value ) ; lv_timer_handler () ; /* let the GUI do its work */ delay ( 5 ) ; } ######################################################################### Next Example: Final Steps Upload the code to your ESP32 using the Arduino IDE. Open the Serial Monitor to check for any debug messages. Tips Adjust the pin assignments based on your wiring. Explore LVGL's extensive documentation for more UI elements and functionalities. Use LVGL's built-in tools to design and customize your interfaces. This should give you a solid start on using LVGL with an ESP32 and a TFT LCD Happy coding!
- 1.28 inch GC9A01 Round LCD with ESP32 and LVGL UI Part1
Here to learn to create a 240x240 pixel GC9A01 Round LCD display using an ESP32 with the LVGL library and Bodmer's TFT_eSPI library, enabling interactive UIs for your projects. The LVGL Light and Versatile Graphics Library) is a popular free and open-source embedded graphics library to create UIs for Embedded boards. In this Setting up LVGL (Light and Versatile Graphics Library) on an ESP32 with a TFT 1.28 inch GC9A01 Round LCD display is a great way to create interactive user interfaces for your projects. Here’s a step-by-step guide to help you get started. Demo: Components Required ESP-32 Module (38Pin) 1.28 Inch Round Display Module GC9A01 7P 240X240 SPI 10K Potentiometer Jumper Wires Circuit Diagram GC9A01 7P 240X240 SPI This is a 1.28 Inch Round Display Module GC9A01 7P 240X240 SPI . This module is composed of a TFT LCD Panel, driver ICs, FPC and a Backlight unit. It uses a full-color LCD screen with a circular appearance and is suitable for making watches, clocks, or measuring instruments. It can also connect with ESP32, Raspberry Pi, or Arduino. Such displays support different communication protocols providing flexibility for integration into various applications. With vibrant colors and excellent clarity, these display modules are suitable for a wide array of projects, from consumer electronics to industrial controls. Features : High-Resolution Options Vibrant Colors and Clarity Compact and Lightweight Reliable Performance Customization Potential Specifications: Display Type: TFT Resolution: 240 x 240 Screen Size: (inch) 1.28 No. of Pins: 7 Communication Protocol: SPI IC Chip: GC9A01 Outside Diameter: (OD) mm 38 Operating Temperature: (°C) -20 to +70 Storage Temperature: (C) -30 to 80 Weight (g): 20g Pin Configuration: GND : LCD Power ground VCC : LCD power supply is positive (3.3V/5V) SCL : LCD SPI bus clock signal SDA : LCD SPI bus write data signal RES : LCD reset control signal(Low level reset,The module has a reset circuit, and this pin can not be connected) DC : LCD register / data selection control signal (Low level: register, high level: data) CS : LCD chip select control signal (low level enable) https://www.buydisplay.com/download/ic/GC9A01A.pdf Hardware Requirements ESP32 Board : Any variant should work, but make sure it has enough GPIO pins. TFT LCD Touchscreen : Common models include ILI9488 Connecting Wires : Jumper wires for connections. Breadboard (optional): For easier connections. Software Requirements Arduino IDE : Make sure you have the latest version. Select “File>Preferences>settings>Additional Boards Manager URLs” to fill the link. Here are the steps to install the ESP32 board in Arduino IDE: Open the Arduino IDE Select File and then Preferences Find the Additional Board Manager URLs field and activate the text box Add the URL to the field Click OK to save the changes https:// raw.githubusercontent.com/espressif/arduino-esp32/gh-pages/package_esp32_dev_index.json , https://arduino.esp8266.com/stable/package_esp8266com_index.json , https://espressif.github.io/arduino-esp32/package_esp32_index.json LVGL Library : Available through the Library Manager in the Arduino IDE. Configuring LVGL LVGL Configuration : You may need to configure LVGL for your specific display and touch screen. Create a lv_conf.h file or modify the existing one in the LVGL library folder: Set LVGL_DISPLAY_HOR_RES and LVGL_DISPLAY_VER_RES to match your display's resolution. Configure the display and touch input settings based on your library (e.g., TFT_eSPI settings). TFT_eSPI Configuration : A feature rich Arduino IDE compatible graphics and fonts library for 32-bit processors. The library is targeted at 32-bit processors, it has been performance optimised for RP2040, STM32, ESP8266 and ESP32 types, other 32-bit processors may be used but will use the slower generic Arduino interface calls. The library can be loaded using the Arduino IDE's Library Manager. Direct Memory Access (DMA) can be used with the ESP32, RP2040 and STM32 processors with SPI interface displays to improve rendering performance. DMA with a parallel interface (8 and 16-bit) is only supported with the RP2040. Go to the TFT_eSPI library folder and open the User_Setup.h file to configure the pins according to your wiring. TFT Pin ESP32 Pin VCC 3.3V GND GND CS GPIO 5 RESET GPIO 2 DC/RS GPIO 17 SDI(MOSI) GPIO 23 SCK GPIO 18 Arduino Code Here’s a basic example to initialize the display and create a simple button using LVGL: ######################################################################### #include #include #include /*Don't forget to set Sketchbook location in File/Preferences to the path of your UI project (the parent foder of this INO file)*/ /*Change to your screen resolution*/ static const uint16_t screenWidth = 240 ; static const uint16_t screenHeight = 240 ; static lv_disp_draw_buf_t draw_buf; static lv_color_t buf [ screenWidth * screenHeight / 10 ]; TFT_eSPI tft = TFT_eSPI ( screenWidth, screenHeight ) ; /* TFT instance */ #if LV_USE_LOG != 0 /* Serial debugging */ void my_print ( const char * buf) { Serial . printf ( buf ) ; Serial . flush () ; } #endif /* Display flushing */ 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 () ; tft . setAddrWindow ( area -> x1 , area -> y1 , w, h ) ; tft . pushColors ( ( uint16_t ) & color_p -> full , w h, true ) ; tft . endWrite () ; lv_disp_flush_ready ( disp ) ; } /*Read the touchpad*/ void my_touchpad_read ( lv_indev_drv_t indev_driver , lv_indev_data_t data ) { uint16_t touchX = 0 , touchY = 0 ; bool touched = false ; //tft.getTouch( &touchX, &touchY, 600 ); if ( !touched ) { data -> state = LV_INDEV_STATE_REL; } else { data -> state = LV_INDEV_STATE_PR; /*Set the coordinates*/ data -> point . x = touchX; data -> point . y = touchY; Serial . print ( "Data x " ) ; Serial . println ( touchX ) ; Serial . print ( "Data y " ) ; Serial . println ( touchY ) ; } } void setup () { Serial . begin ( 115200 ) ; /* prepare for possible serial debug */ String LVGL_Arduino = "Hello Arduino! " ; LVGL_Arduino += String ( 'V' ) + lv_version_major () + "." + lv_version_minor () + "." + lv_version_patch () ; Serial . println ( LVGL_Arduino ) ; Serial . println ( "I am LVGL_Arduino" ) ; lv_init () ; #if LV_USE_LOG != 0 lv_log_register_print_cb ( my_print ) ; /* register print function for debugging */ #endif tft . begin () ; /* TFT init */ tft . setRotation ( 3 ) ; /* Landscape orientation, flipped */ lv_disp_draw_buf_init ( &draw_buf, buf, NULL , screenWidth * screenHeight / 10 ) ; /*Initialize the display*/ static lv_disp_drv_t disp_drv; lv_disp_drv_init ( &disp_drv ) ; /*Change the following line to your display resolution*/ disp_drv . hor_res = screenWidth; disp_drv . ver_res = screenHeight; disp_drv . flush_cb = my_disp_flush; disp_drv . draw_buf = &draw_buf; lv_disp_drv_register ( &disp_drv ) ; /*Initialize the (dummy) input device driver*/ static lv_indev_drv_t indev_drv; lv_indev_drv_init ( &indev_drv ) ; indev_drv . type = LV_INDEV_TYPE_POINTER; indev_drv . read_cb = my_touchpad_read; lv_indev_drv_register ( &indev_drv ) ; ui_init () ; Serial . println ( "Setup done" ) ; } void loop () { int print_value= map ( analogRead ( 12 ) , 0 , 4095 , 0 , 100 ) ; //ANALOG PIN GPIO 12 ui label_set_property ( ui_printing_persent, UI LABEL_PROPERTY_TEXT, String ( print_value ) . c_str ()) ; lv_slider_set_value ( ui_Slider1, print_value,LV_ANIM_ON ) ; lv_timer_handler () ; /* let the GUI do its work */ delay ( 5 ) ; } ######################################################################### Next Example: Final Steps Upload the code to your ESP32 using the Arduino IDE. Open the Serial Monitor to check for any debug messages. Tips Adjust the pin assignments based on your wiring. Explore LVGL's extensive documentation for more UI elements and functionalities. Use LVGL's built-in tools to design and customize your interfaces. This should give you a solid start on using LVGL with an ESP32 and a TFT LCD Happy coding!
- ESP32 3.5inch TFT Touch display ILI9488 with LVGL UI Part5
Here to learn how to make a ESP32 board based 3.5inch touch display ILI9488 using the LVGL (Light and Versatile Graphics Library) and Bodmer's TFT_eSPI arduino Library. The LVGL is a popular free and open-source embedded graphics library to create UIs for arduino. In this Setting up LVGL (Light and Versatile Graphics Library) on an ESP32 with a TFT LCD touchscreen display ILI9488 is a great way to create interactive user interfaces for your projects. Here’s a step-by-step guide to help you get started. Demo: Components Required ESP-32 Module (38Pin) 3.5 inch TFT LCD Display Module SPI Interface 320x480 with Touch Screen Jumper Wires Circuit Diagram TFT refer blog: https://www.dofbot.com/post/esp32-dht-weather-monitor-with-3-5inch-tft-touch-display In the VCC pin, you can either use 5V or 3.3V depending upon if your J1 connection is open or closed, J1 = open=5V; J1=close=3.3V. LVGL refer: https://docs.lvgl.io/master/overview/index.html Hardware Requirements ESP32 Board : Any variant should work, but make sure it has enough GPIO pins. TFT LCD Touchscreen : Common models include ILI9488 Connecting Wires : Jumper wires for connections. Breadboard (optional): For easier connections. Software Requirements Arduino IDE : Make sure you have the latest version. Select “File>Preferences>settings>Additional Boards Manager URLs” to fill the link. Here are the steps to install the ESP32 board in Arduino IDE: Open the Arduino IDE Select File and then Preferences Find the Additional Board Manager URLs field and activate the text box Add the URL to the field Click OK to save the changes https:// raw.githubusercontent.com/espressif/arduino-esp32/gh-pages/package_esp32_dev_index.json , https://arduino.esp8266.com/stable/package_esp8266com_index.json , https://espressif.github.io/arduino-esp32/package_esp32_index.json LVGL Library : Available through the Library Manager in the Arduino IDE. Touch Driver Library : Depending on your touchscreen (e.g., TFT_eSPI) Configuring LVGL LVGL Configuration : You may need to configure LVGL for your specific display and touch screen. Create a lv_conf.h file or modify the existing one in the LVGL library folder: Set LVGL_DISPLAY_HOR_RES and LVGL_DISPLAY_VER_RES to match your display's resolution. Configure the display and touch input settings based on your library (e.g., TFT_eSPI settings). TFT_eSPI Configuration : A feature rich Arduino IDE compatible graphics and fonts library for 32-bit processors. The library is targeted at 32-bit processors, it has been performance optimised for RP2040, STM32, ESP8266 and ESP32 types, other 32-bit processors may be used but will use the slower generic Arduino interface calls. The library can be loaded using the Arduino IDE's Library Manager. Direct Memory Access (DMA) can be used with the ESP32, RP2040 and STM32 processors with SPI interface displays to improve rendering performance. DMA with a parallel interface (8 and 16-bit) is only supported with the RP2040. Go to the TFT_eSPI library folder and open the User_Setup.h file to configure the pins according to your wiring. Wiring the TFT Display TFT Pin ESP32 Pin VCC 3.3V GND GND CS GPIO 5 RESET GPIO 2 DC/RS GPIO 17 SDI(MOSI) GPIO 23 SCK GPIO 18 LED 3.3V (or PWM pin for brightness) Wiring the Touchscreen (e.g., TFT_espi) Touch Pin ESP32 Pin T_CS GPIO 16 T_IRQ GPIO 21 T_DOUT GPIO 19 T_DIN GPIO 23 T_CLK GPIO 18 Sample Code Here’s a basic example to initialize the display and create a simple button using LVGL: Example 5. ########################################################################### //Arduino-TFT_eSPI board-template main routine. There's a TFT_eSPI create+flush driver already in LVGL-9.1 but we create our own here for more control (like e.g. 16-bit color swap). #include "FS.h" #include #include #include #include /*Don't forget to set Sketchbook location in File/Preferences to the path of your UI project (the parent foder of this INO file)*/ /*Change to your screen resolution*/ static const uint16_t screenWidth = 480 ; static const uint16_t screenHeight = 320 ; enum { SCREENBUFFER_SIZE_PIXELS = screenWidth * screenHeight / 10 } ; static lv_color_t buf [SCREENBUFFER_SIZE_PIXELS]; TFT_eSPI tft = TFT_eSPI ( screenWidth, screenHeight ) ; /* TFT instance */ #define CALIBRATION_FILE "/calibrationData" #if LV_USE_LOG != 0 /* Serial debugging */ void my_print ( const char * buf) { Serial . printf ( buf ) ; Serial . flush () ; } #endif /* Display flushing */ void my_disp_flush ( lv_display_t disp , const lv_area_t area , uint8_t * pixelmap) { uint32_t w = ( area -> x2 - area -> x1 + 1 ) ; uint32_t h = ( area -> y2 - area -> y1 + 1 ) ; if ( LV_COLOR_16_SWAP ) { size_t len = lv_area_get_size ( area ) ; lv_draw_sw_rgb565_swap ( pixelmap, len ) ; } tft . startWrite () ; tft . setAddrWindow ( area -> x1 , area -> y1 , w, h ) ; tft . pushColors ( ( uint16_t * ) pixelmap, w * h, true ) ; tft . endWrite () ; lv_disp_flush_ready ( disp ) ; } /*Read the touchpad*/ void my_touchpad_read ( lv_indev_t indev_driver , lv_indev_data_t data) { uint16_t touchX = 0 , touchY = 0 ; bool touched = tft . getTouch ( &touchX, &touchY, 600 ) ; if ( !touched ) { data -> state = LV_INDEV_STATE_REL; } else { data -> state = LV_INDEV_STATE_PR; /*Set the coordinates*/ data -> point . x = touchX; data -> point . y = touchY; Serial . print ( "Data x " ) ; Serial . println ( touchX ) ; Serial . print ( "Data y " ) ; Serial . println ( touchY ) ; } } /*Set tick routine needed for LVGL internal timings*/ static uint32_t my_tick_get_cb ( void ) { return millis () ; } void setup () { uint16_t calibrationData [ 5 ]; uint8_t calDataOK = 0 ; Serial . begin ( 115200 ) ; /* prepare for possible serial debug */ String LVGL_Arduino = "Hello Arduino! " ; LVGL_Arduino += String ( 'V' ) + lv_version_major () + "." + lv_version_minor () + "." + lv_version_patch () ; Serial . println ( LVGL_Arduino ) ; Serial . println ( "I am LVGL_Arduino" ) ; lv_init () ; #if LV_USE_LOG != 0 lv_log_register_print_cb ( my_print ) ; /* register print function for debugging */ #endif tft . begin () ; /* TFT init */ tft . setRotation ( 3 ) ; /* Landscape orientation, flipped */ static lv_disp_t * disp; disp = lv_display_create ( screenWidth, screenHeight ) ; lv_display_set_buffers ( disp, buf, NULL , SCREENBUFFER_SIZE_PIXELS * sizeof ( lv_color_t ) , LV_DISPLAY_RENDER_MODE_PARTIAL ) ; lv_display_set_flush_cb ( disp, my_disp_flush ) ; static lv_indev_t * indev; indev = lv_indev_create () ; lv_indev_set_type ( indev, LV_INDEV_TYPE_POINTER ) ; lv_indev_set_read_cb ( indev, my_touchpad_read ) ; lv_tick_set_cb ( my_tick_get_cb ) ; ui_init () ; Serial . println ( "Setup done" ) ; // check file system if ( ! SPIFFS . begin ()) { Serial . println ( "formatting file system" ) ; SPIFFS . format () ; SPIFFS . begin () ; } // check if calibration file exists if ( SPIFFS . exists ( CALIBRATION_FILE )) { File f = SPIFFS . open ( CALIBRATION_FILE, "r" ) ; if ( f ) { if ( f . readBytes (( char * ) calibrationData, 14 ) == 14 ) calDataOK = 1 ; f . close () ; } } if ( calDataOK ) { // calibration data valid tft . setTouch ( calibrationData ) ; } else { // data not valid. recalibrate tft . calibrateTouch ( calibrationData, TFT_WHITE, TFT_RED, 15 ) ; // store data File f = SPIFFS . open ( CALIBRATION_FILE, "w" ) ; if ( f ) { f . write (( const unsigned char * ) calibrationData, 14 ) ; f . close () ; } } } void loop () { lv_timer_handler () ; /* let the GUI do its work */ delay ( 5 ) ; } ############################################################################ Final Steps Upload the code to your ESP32 using the Arduino IDE. Open the Serial Monitor to check for any debug messages. Interact with the touchscreen to see your UI in action! Tips Adjust the pin assignments based on your wiring. Explore LVGL's extensive documentation for more UI elements and functionalities. Use LVGL's built-in tools to design and customize your interfaces. This should give you a solid start on using LVGL with an ESP32 and a TFT LCD touchscreen. Happy coding!
- ESP32 3.5inch TFT Touch display ILI9488 with LVGL UI Part4
Here to learn how to make a ESP32 board based 3.5inch touch display ILI9488 using the LVGL (Light and Versatile Graphics Library) and Bodmer's TFT_eSPI arduino Library. The LVGL is a popular free and open-source embedded graphics library to create UIs for arduino. In this Setting up LVGL (Light and Versatile Graphics Library) on an ESP32 with a TFT LCD touchscreen display ILI9488 is a great way to create interactive user interfaces for your projects. Here’s a step-by-step guide to help you get started. Demo: Components Required ESP-32 Module (38Pin) 3.5 inch TFT LCD Display Module SPI Interface 320x480 with Touch Screen Jumper Wires Circuit Diagram TFT refer blog: https://www.dofbot.com/post/esp32-dht-weather-monitor-with-3-5inch-tft-touch-display In the VCC pin, you can either use 5V or 3.3V depending upon if your J1 connection is open or closed, J1 = open=5V; J1=close=3.3V. LVGL refer: https://docs.lvgl.io/master/overview/index.html Hardware Requirements ESP32 Board : Any variant should work, but make sure it has enough GPIO pins. TFT LCD Touchscreen : Common models include ILI9488 Connecting Wires : Jumper wires for connections. Breadboard (optional): For easier connections. Software Requirements Arduino IDE : Make sure you have the latest version. Select “File>Preferences>settings>Additional Boards Manager URLs” to fill the link. Here are the steps to install the ESP32 board in Arduino IDE: Open the Arduino IDE Select File and then Preferences Find the Additional Board Manager URLs field and activate the text box Add the URL to the field Click OK to save the changes https:// raw.githubusercontent.com/espressif/arduino-esp32/gh-pages/package_esp32_dev_index.json , https://arduino.esp8266.com/stable/package_esp8266com_index.json , https://espressif.github.io/arduino-esp32/package_esp32_index.json LVGL Library : Available through the Library Manager in the Arduino IDE. Touch Driver Library : Depending on your touchscreen (e.g., TFT_eSPI) Configuring LVGL LVGL Configuration : You may need to configure LVGL for your specific display and touch screen. Create a lv_conf.h file or modify the existing one in the LVGL library folder: Set LVGL_DISPLAY_HOR_RES and LVGL_DISPLAY_VER_RES to match your display's resolution. Configure the display and touch input settings based on your library (e.g., TFT_eSPI settings). TFT_eSPI Configuration : A feature rich Arduino IDE compatible graphics and fonts library for 32-bit processors. The library is targeted at 32-bit processors, it has been performance optimised for RP2040, STM32, ESP8266 and ESP32 types, other 32-bit processors may be used but will use the slower generic Arduino interface calls. The library can be loaded using the Arduino IDE's Library Manager. Direct Memory Access (DMA) can be used with the ESP32, RP2040 and STM32 processors with SPI interface displays to improve rendering performance. DMA with a parallel interface (8 and 16-bit) is only supported with the RP2040. Go to the TFT_eSPI library folder and open the User_Setup.h file to configure the pins according to your wiring. Wiring the TFT Display TFT Pin ESP32 Pin VCC 3.3V GND GND CS GPIO 5 RESET GPIO 2 DC/RS GPIO 17 SDI(MOSI) GPIO 23 SCK GPIO 18 LED 3.3V (or PWM pin for brightness) Wiring the Touchscreen (e.g., TFT_espi) Touch Pin ESP32 Pin T_CS GPIO 16 T_IRQ GPIO 21 T_DOUT GPIO 19 T_DIN GPIO 23 T_CLK GPIO 18 Sample Code Here’s a basic example to initialize the display and create a simple button using LVGL: Example 4. ########################################################################## //Arduino-TFT_eSPI board-template main routine. There's a TFT_eSPI create+flush driver already in LVGL-9.1 but we create our own here for more control (like e.g. 16-bit color swap). #include "FS.h" #include #include #include #include /*Don't forget to set Sketchbook location in File/Preferences to the path of your UI project (the parent foder of this INO file)*/ /*Change to your screen resolution*/ static const uint16_t screenWidth = 480 ; static const uint16_t screenHeight = 320 ; enum { SCREENBUFFER_SIZE_PIXELS = screenWidth * screenHeight / 10 } ; static lv_color_t buf [SCREENBUFFER_SIZE_PIXELS]; TFT_eSPI tft = TFT_eSPI ( screenWidth, screenHeight ) ; /* TFT instance */ #define CALIBRATION_FILE "/calibrationData" #if LV_USE_LOG != 0 /* Serial debugging */ void my_print ( const char * buf) { Serial . printf ( buf ) ; Serial . flush () ; } #endif /* Display flushing */ void my_disp_flush ( lv_display_t disp , const lv_area_t area , uint8_t * pixelmap) { uint32_t w = ( area -> x2 - area -> x1 + 1 ) ; uint32_t h = ( area -> y2 - area -> y1 + 1 ) ; if ( LV_COLOR_16_SWAP ) { size_t len = lv_area_get_size ( area ) ; lv_draw_sw_rgb565_swap ( pixelmap, len ) ; } tft . startWrite () ; tft . setAddrWindow ( area -> x1 , area -> y1 , w, h ) ; tft . pushColors ( ( uint16_t * ) pixelmap, w * h, true ) ; tft . endWrite () ; lv_disp_flush_ready ( disp ) ; } /*Read the touchpad*/ void my_touchpad_read ( lv_indev_t indev_driver , lv_indev_data_t data) { uint16_t touchX = 0 , touchY = 0 ; bool touched = tft . getTouch ( &touchX, &touchY, 600 ) ; if ( !touched ) { data -> state = LV_INDEV_STATE_REL; } else { data -> state = LV_INDEV_STATE_PR; /*Set the coordinates*/ data -> point . x = touchX; data -> point . y = touchY; Serial . print ( "Data x " ) ; Serial . println ( touchX ) ; Serial . print ( "Data y " ) ; Serial . println ( touchY ) ; } } /*Set tick routine needed for LVGL internal timings*/ static uint32_t my_tick_get_cb ( void ) { return millis () ; } void setup () { uint16_t calibrationData [ 5 ]; uint8_t calDataOK = 0 ; Serial . begin ( 115200 ) ; /* prepare for possible serial debug */ String LVGL_Arduino = "Hello Arduino! " ; LVGL_Arduino += String ( 'V' ) + lv_version_major () + "." + lv_version_minor () + "." + lv_version_patch () ; Serial . println ( LVGL_Arduino ) ; Serial . println ( "I am LVGL_Arduino" ) ; lv_init () ; #if LV_USE_LOG != 0 lv_log_register_print_cb ( my_print ) ; /* register print function for debugging */ #endif tft . begin () ; /* TFT init */ tft . setRotation ( 3 ) ; /* Landscape orientation, flipped */ static lv_disp_t * disp; disp = lv_display_create ( screenWidth, screenHeight ) ; lv_display_set_buffers ( disp, buf, NULL , SCREENBUFFER_SIZE_PIXELS * sizeof ( lv_color_t ) , LV_DISPLAY_RENDER_MODE_PARTIAL ) ; lv_display_set_flush_cb ( disp, my_disp_flush ) ; static lv_indev_t * indev; indev = lv_indev_create () ; lv_indev_set_type ( indev, LV_INDEV_TYPE_POINTER ) ; lv_indev_set_read_cb ( indev, my_touchpad_read ) ; lv_tick_set_cb ( my_tick_get_cb ) ; ui_init () ; Serial . println ( "Setup done" ) ; // check file system if ( ! SPIFFS . begin ()) { Serial . println ( "formatting file system" ) ; SPIFFS . format () ; SPIFFS . begin () ; } // check if calibration file exists if ( SPIFFS . exists ( CALIBRATION_FILE )) { File f = SPIFFS . open ( CALIBRATION_FILE, "r" ) ; if ( f ) { if ( f . readBytes (( char * ) calibrationData, 14 ) == 14 ) calDataOK = 1 ; f . close () ; } } if ( calDataOK ) { // calibration data valid tft . setTouch ( calibrationData ) ; } else { // data not valid. recalibrate tft . calibrateTouch ( calibrationData, TFT_WHITE, TFT_RED, 15 ) ; // store data File f = SPIFFS . open ( CALIBRATION_FILE, "w" ) ; if ( f ) { f . write (( const unsigned char * ) calibrationData, 14 ) ; f . close () ; } } } void loop () { lv_timer_handler () ; /* let the GUI do its work */ delay ( 5 ) ; } ########################################################################## Next Example: https://www.dofbot.com/post/esp32-3-5inch-tft-touch-display-ili9488-with-lvgl-ui-part5 Final Steps Upload the code to your ESP32 using the Arduino IDE. Open the Serial Monitor to check for any debug messages. Interact with the touchscreen to see your UI in action! Tips Adjust the pin assignments based on your wiring. Explore LVGL's extensive documentation for more UI elements and functionalities. Use LVGL's built-in tools to design and customize your interfaces. This should give you a solid start on using LVGL with an ESP32 and a TFT LCD touchscreen. Happy coding!
- ESP32 3.5inch TFT Touch display ILI9488 with LVGL UI Part3
Here to learn how to make a ESP32 board based 3.5inch touch display ILI9488 using the LVGL (Light and Versatile Graphics Library) and Bodmer's TFT_eSPI arduino Library. The LVGL is a popular free and open-source embedded graphics library to create UIs for arduino. In this Setting up LVGL (Light and Versatile Graphics Library) on an ESP32 with a TFT LCD touchscreen display ILI9488 is a great way to create interactive user interfaces for your projects. Here’s a step-by-step guide to help you get started. Demo: Components Required ESP-32 Module (38Pin) 3.5 inch TFT LCD Display Module SPI Interface 320x480 with Touch Screen Jumper Wires Circuit Diagram TFT refer blog: https://www.dofbot.com/post/esp32-dht-weather-monitor-with-3-5inch-tft-touch-display In the VCC pin, you can either use 5V or 3.3V depending upon if your J1 connection is open or closed, J1 = open=5V; J1=close=3.3V. LVGL refer: https://docs.lvgl.io/master/overview/index.html Hardware Requirements ESP32 Board : Any variant should work, but make sure it has enough GPIO pins. TFT LCD Touchscreen : Common models include ILI9488 Connecting Wires : Jumper wires for connections. Breadboard (optional): For easier connections. Software Requirements Arduino IDE : Make sure you have the latest version. Select “File>Preferences>settings>Additional Boards Manager URLs” to fill the link. Here are the steps to install the ESP32 board in Arduino IDE: Open the Arduino IDE Select File and then Preferences Find the Additional Board Manager URLs field and activate the text box Add the URL to the field Click OK to save the changes https:// raw.githubusercontent.com/espressif/arduino-esp32/gh-pages/package_esp32_dev_index.json , https://arduino.esp8266.com/stable/package_esp8266com_index.json , https://espressif.github.io/arduino-esp32/package_esp32_index.json LVGL Library : Available through the Library Manager in the Arduino IDE. Touch Driver Library : Depending on your touchscreen (e.g., TFT_eSPI) Configuring LVGL LVGL Configuration : You may need to configure LVGL for your specific display and touch screen. Create a lv_conf.h file or modify the existing one in the LVGL library folder: Set LVGL_DISPLAY_HOR_RES and LVGL_DISPLAY_VER_RES to match your display's resolution. Configure the display and touch input settings based on your library (e.g., TFT_eSPI settings). TFT_eSPI Configuration : A feature rich Arduino IDE compatible graphics and fonts library for 32-bit processors. The library is targeted at 32-bit processors, it has been performance optimised for RP2040, STM32, ESP8266 and ESP32 types, other 32-bit processors may be used but will use the slower generic Arduino interface calls. The library can be loaded using the Arduino IDE's Library Manager. Direct Memory Access (DMA) can be used with the ESP32, RP2040 and STM32 processors with SPI interface displays to improve rendering performance. DMA with a parallel interface (8 and 16-bit) is only supported with the RP2040. Go to the TFT_eSPI library folder and open the User_Setup.h file to configure the pins according to your wiring. Wiring the TFT Display TFT Pin ESP32 Pin VCC 3.3V GND GND CS GPIO 5 RESET GPIO 2 DC/RS GPIO 17 SDI(MOSI) GPIO 23 SCK GPIO 18 LED 3.3V (or PWM pin for brightness) Wiring the Touchscreen (e.g., TFT_espi) Touch Pin ESP32 Pin T_CS GPIO 16 T_IRQ GPIO 21 T_DOUT GPIO 19 T_DIN GPIO 23 T_CLK GPIO 18 Sample Code Here’s a basic example to initialize the display and create a simple button using LVGL: Example 3. ####################################################################### //Arduino-TFT_eSPI board-template main routine. There's a TFT_eSPI create+flush driver already in LVGL-9.1 but we create our own here for more control (like e.g. 16-bit color swap). #include "FS.h" #include #include #include #include /*Don't forget to set Sketchbook location in File/Preferences to the path of your UI project (the parent foder of this INO file)*/ /*Change to your screen resolution*/ static const uint16_t screenWidth = 480 ; static const uint16_t screenHeight = 320 ; enum { SCREENBUFFER_SIZE_PIXELS = screenWidth * screenHeight / 10 } ; static lv_color_t buf [SCREENBUFFER_SIZE_PIXELS]; TFT_eSPI tft = TFT_eSPI ( screenWidth, screenHeight ) ; /* TFT instance */ #define CALIBRATION_FILE "/calibrationData" #if LV_USE_LOG != 0 /* Serial debugging */ void my_print ( const char * buf) { Serial . printf ( buf ) ; Serial . flush () ; } #endif /* Display flushing */ void my_disp_flush ( lv_display_t disp , const lv_area_t area , uint8_t * pixelmap) { uint32_t w = ( area -> x2 - area -> x1 + 1 ) ; uint32_t h = ( area -> y2 - area -> y1 + 1 ) ; if ( LV_COLOR_16_SWAP ) { size_t len = lv_area_get_size ( area ) ; lv_draw_sw_rgb565_swap ( pixelmap, len ) ; } tft . startWrite () ; tft . setAddrWindow ( area -> x1 , area -> y1 , w, h ) ; tft . pushColors ( ( uint16_t * ) pixelmap, w * h, true ) ; tft . endWrite () ; lv_disp_flush_ready ( disp ) ; } /*Read the touchpad*/ void my_touchpad_read ( lv_indev_t indev_driver , lv_indev_data_t data) { uint16_t touchX = 0 , touchY = 0 ; bool touched = tft . getTouch ( &touchX, &touchY, 600 ) ; if ( !touched ) { data -> state = LV_INDEV_STATE_REL; } else { data -> state = LV_INDEV_STATE_PR; /*Set the coordinates*/ data -> point . x = touchX; data -> point . y = touchY; Serial . print ( "Data x " ) ; Serial . println ( touchX ) ; Serial . print ( "Data y " ) ; Serial . println ( touchY ) ; } } /*Set tick routine needed for LVGL internal timings*/ static uint32_t my_tick_get_cb ( void ) { return millis () ; } void setup () { uint16_t calibrationData [ 5 ]; uint8_t calDataOK = 0 ; Serial . begin ( 115200 ) ; /* prepare for possible serial debug */ String LVGL_Arduino = "Hello Arduino! " ; LVGL_Arduino += String ( 'V' ) + lv_version_major () + "." + lv_version_minor () + "." + lv_version_patch () ; Serial . println ( LVGL_Arduino ) ; Serial . println ( "I am LVGL_Arduino" ) ; lv_init () ; #if LV_USE_LOG != 0 lv_log_register_print_cb ( my_print ) ; /* register print function for debugging */ #endif tft . begin () ; /* TFT init */ tft . setRotation ( 3 ) ; /* Landscape orientation, flipped */ static lv_disp_t * disp; disp = lv_display_create ( screenWidth, screenHeight ) ; lv_display_set_buffers ( disp, buf, NULL , SCREENBUFFER_SIZE_PIXELS * sizeof ( lv_color_t ) , LV_DISPLAY_RENDER_MODE_PARTIAL ) ; lv_display_set_flush_cb ( disp, my_disp_flush ) ; static lv_indev_t * indev; indev = lv_indev_create () ; lv_indev_set_type ( indev, LV_INDEV_TYPE_POINTER ) ; lv_indev_set_read_cb ( indev, my_touchpad_read ) ; lv_tick_set_cb ( my_tick_get_cb ) ; ui_init () ; Serial . println ( "Setup done" ) ; // check file system if ( ! SPIFFS . begin ()) { Serial . println ( "formatting file system" ) ; SPIFFS . format () ; SPIFFS . begin () ; } // check if calibration file exists if ( SPIFFS . exists ( CALIBRATION_FILE )) { File f = SPIFFS . open ( CALIBRATION_FILE, "r" ) ; if ( f ) { if ( f . readBytes (( char * ) calibrationData, 14 ) == 14 ) calDataOK = 1 ; f . close () ; } } if ( calDataOK ) { // calibration data valid tft . setTouch ( calibrationData ) ; } else { // data not valid. recalibrate tft . calibrateTouch ( calibrationData, TFT_WHITE, TFT_RED, 15 ) ; // store data File f = SPIFFS . open ( CALIBRATION_FILE, "w" ) ; if ( f ) { f . write (( const unsigned char * ) calibrationData, 14 ) ; f . close () ; } } } void loop () { lv_timer_handler () ; /* let the GUI do its work */ delay ( 5 ) ; } ####################################################################### Next Example: https://www.dofbot.com/post/esp32-3-5inch-tft-touch-display-ili9488-with-lvgl-ui-part4 Final Steps Upload the code to your ESP32 using the Arduino IDE. Open the Serial Monitor to check for any debug messages. Interact with the touchscreen to see your UI in action! Tips Adjust the pin assignments based on your wiring. Explore LVGL's extensive documentation for more UI elements and functionalities. Use LVGL's built-in tools to design and customize your interfaces. This should give you a solid start on using LVGL with an ESP32 and a TFT LCD touchscreen. Happy coding!