top of page

Search Results

206 items found for ""

Blog Posts (163)

  • 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:

View All

Other Pages (13)

  • Books | DOFBOT

    Servo Magazine collection Free For You elektor Magazine collection Free For You Data Book collection Free For You Dummies collection Free For You Engineering collection Free For You LINUX Magazine collection Free For You fine Cooking Magazine collection Free For You Knitting Magazine collection Free For You Tattoo Magazine collection Free For You Magazine collection Free For You Magazine collection Free For You

  • Plans & Pricing | DOFBOT

    No plans available Once there are plans available for purchase, you’ll see them here. Back to Home Page

View All
bottom of page