{"id":162190,"date":"2024-10-15T18:36:45","date_gmt":"2024-10-15T18:36:45","guid":{"rendered":"https:\/\/randomnerdtutorials.com\/?p=162190"},"modified":"2025-06-02T09:19:57","modified_gmt":"2025-06-02T09:19:57","slug":"esp32-cyd-lvgl-display-bme280-data-table","status":"publish","type":"post","link":"https:\/\/randomnerdtutorials.com\/esp32-cyd-lvgl-display-bme280-data-table\/","title":{"rendered":"ESP32 CYD with LVGL: Display BME280 Sensor Data on a Table"},"content":{"rendered":"\n<p>In this guide, you\u2019ll learn how to create a responsive table using LVGL. We\u2019ll display temperature, humidity, and pressure from the BME280 sensor, and luminosity from the LDR on the display. We\u2019ll also display the timestamp associated with the readings (date and time). The ESP32 will be programmed using Arduino IDE.<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img data-recalc-dims=\"1\" fetchpriority=\"high\" decoding=\"async\" width=\"1200\" height=\"675\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/09\/ESP32-Cheap-Yellow-Display-CYD-Board-BME280-Table-Readings-LVGL-Arduino.jpg?resize=1200%2C675&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"ESP32 Cheap Yellow Display CYD Board BME280 Table Readings LVGL Arduino\" class=\"wp-image-162207\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/09\/ESP32-Cheap-Yellow-Display-CYD-Board-BME280-Table-Readings-LVGL-Arduino.jpg?w=1920&amp;quality=100&amp;strip=all&amp;ssl=1 1920w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/09\/ESP32-Cheap-Yellow-Display-CYD-Board-BME280-Table-Readings-LVGL-Arduino.jpg?resize=300%2C169&amp;quality=100&amp;strip=all&amp;ssl=1 300w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/09\/ESP32-Cheap-Yellow-Display-CYD-Board-BME280-Table-Readings-LVGL-Arduino.jpg?resize=1024%2C576&amp;quality=100&amp;strip=all&amp;ssl=1 1024w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/09\/ESP32-Cheap-Yellow-Display-CYD-Board-BME280-Table-Readings-LVGL-Arduino.jpg?resize=768%2C432&amp;quality=100&amp;strip=all&amp;ssl=1 768w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/09\/ESP32-Cheap-Yellow-Display-CYD-Board-BME280-Table-Readings-LVGL-Arduino.jpg?resize=1536%2C864&amp;quality=100&amp;strip=all&amp;ssl=1 1536w\" sizes=\"(max-width: 1200px) 100vw, 1200px\" \/><\/figure><\/div>\n\n\n<p class=\"rntbox rntclblue\"><strong>New to the ESP32 Cheap Yellow Display?<\/strong> Start here: <a href=\"https:\/\/randomnerdtutorials.com\/cheap-yellow-display-esp32-2432s028r\/\">Getting Started with ESP32 Cheap Yellow Display Board \u2013 CYD (ESP32-2432S028R)<\/a>.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Project Overview<\/h2>\n\n\n\n<p>In this project, we\u2019ll create a table with sensor readings from the BME280 sensor and the LDR on the ESP32 CYD board. We\u2019ll also display the date and time, and your board IP address.<\/p>\n\n\n\n<figure class=\"wp-block-gallery has-nested-images columns-default is-cropped wp-block-gallery-1 is-layout-flex wp-block-gallery-is-layout-flex\">\n<figure class=\"wp-block-image size-large\"><img data-recalc-dims=\"1\" decoding=\"async\" width=\"750\" height=\"462\" data-id=\"162197\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/09\/ESP32-CYD-LVGL-Display-BME280-Sensor-Data-Table-Demonstration-Screen-Temp-Hum-Pressure.png?resize=750%2C462&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"ESP32 CYD LVGL Display BME280 Sensor Data Table Demonstration Screen Temp Hum Pressure\" class=\"wp-image-162197\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/09\/ESP32-CYD-LVGL-Display-BME280-Sensor-Data-Table-Demonstration-Screen-Temp-Hum-Pressure.png?w=750&amp;quality=100&amp;strip=all&amp;ssl=1 750w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/09\/ESP32-CYD-LVGL-Display-BME280-Sensor-Data-Table-Demonstration-Screen-Temp-Hum-Pressure.png?resize=300%2C185&amp;quality=100&amp;strip=all&amp;ssl=1 300w\" sizes=\"(max-width: 750px) 100vw, 750px\" \/><\/figure>\n\n\n\n<figure class=\"wp-block-image size-large\"><img data-recalc-dims=\"1\" decoding=\"async\" width=\"750\" height=\"462\" data-id=\"162196\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/09\/ESP32-CYD-LVGL-Display-BME280-Sensor-Data-Table-Demonstration-Screen-Lum-Date-Time.png?resize=750%2C462&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"ESP32 CYD LVGL Display BME280 Sensor Data Table Demonstration Screen Lum Date Time\" class=\"wp-image-162196\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/09\/ESP32-CYD-LVGL-Display-BME280-Sensor-Data-Table-Demonstration-Screen-Lum-Date-Time.png?w=750&amp;quality=100&amp;strip=all&amp;ssl=1 750w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/09\/ESP32-CYD-LVGL-Display-BME280-Sensor-Data-Table-Demonstration-Screen-Lum-Date-Time.png?resize=300%2C185&amp;quality=100&amp;strip=all&amp;ssl=1 300w\" sizes=\"(max-width: 750px) 100vw, 750px\" \/><\/figure>\n<\/figure>\n\n\n\n<p>To get an accurate date and time for your timezone, we\u2019ll use the <a href=\"https:\/\/worldtimeapi.org\/\" target=\"_blank\" rel=\"noopener\" title=\"\">WorldTimeAPI<\/a>. To get the time from the API, the ESP32 needs to connect to the internet, so you need to have a router in your surroundings so that the ESP32 can connect to it.<\/p>\n\n\n\n<p>If you don\u2019t have an internet connection where the ESP32 will operate, you can omit the date and time section or use an RTC module.<\/p>\n\n\n\n<p>We\u2019ll also display a floating button with the refresh icon that when clicked will update the values on the table.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Prerequisites<\/h2>\n\n\n\n<p>Before proceeding, make sure you follow the next prerequisites.<strong> You must follow all steps, otherwise, your project will not work.<\/strong><\/p>\n\n\n\n<h3 class=\"wp-block-heading\">1) Parts Required and Wiring the Circuit<\/h3>\n\n\n\n<p>For this project, you need the following parts:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><a href=\"https:\/\/makeradvisor.com\/tools\/cyd-cheap-yellow-display-esp32-2432s028r\/\" target=\"_blank\" rel=\"noreferrer noopener\">ESP32-2432S028R \u2013 2.8 inch 240\u00d7320 Smart Display TFT with Touchscreen<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/makeradvisor.com\/tools\/bme280-sensor-module\/\" target=\"_blank\" rel=\"noopener\" title=\"\">BME280 Sensor<\/a><\/li>\n<\/ul>\n\n\n\n<p>We\u2019ll use I2C communication protocol to get data from the BME280 sensor. On the ESP32 CYD board there is an <a href=\"https:\/\/randomnerdtutorials.com\/esp32-cheap-yellow-display-cyd-pinout-esp32-2432s028r\/\">extended IO socket<\/a> that allows you to connect external peripherals. We\u2019ll connect the sensor to the CN1 connector.<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"750\" height=\"422\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/09\/ESP32-CYD-Cheap-Yellow-Display-Board-JST-Connector-Connecting-BME280-Sensor.jpg?resize=750%2C422&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"ESP32 CYD Cheap Yellow Display Board JST Connector Connecting BME280 Sensor\" class=\"wp-image-162195\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/09\/ESP32-CYD-Cheap-Yellow-Display-Board-JST-Connector-Connecting-BME280-Sensor.jpg?w=750&amp;quality=100&amp;strip=all&amp;ssl=1 750w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/09\/ESP32-CYD-Cheap-Yellow-Display-Board-JST-Connector-Connecting-BME280-Sensor.jpg?resize=300%2C169&amp;quality=100&amp;strip=all&amp;ssl=1 300w\" sizes=\"(max-width: 750px) 100vw, 750px\" \/><\/figure><\/div>\n\n\n<p>Your board should have come with a little JST connector to access those GPIOs.<\/p>\n\n\n\n<p>We&#8217;ll connect SDA to GPIO 27, and SCL to GPIO 22.<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"750\" height=\"422\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/09\/ESP32-CYD-Cheap-Yellow-Display-Board-JST-Connector.jpg?resize=750%2C422&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"ESP32 CYD Cheap Yellow Display Board JST Connector\" class=\"wp-image-162194\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/09\/ESP32-CYD-Cheap-Yellow-Display-Board-JST-Connector.jpg?w=750&amp;quality=100&amp;strip=all&amp;ssl=1 750w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/09\/ESP32-CYD-Cheap-Yellow-Display-Board-JST-Connector.jpg?resize=300%2C169&amp;quality=100&amp;strip=all&amp;ssl=1 300w\" sizes=\"(max-width: 750px) 100vw, 750px\" \/><\/figure><\/div>\n\n\n<p>If you\u2019re not familiar with the BME280 sensor, we recommend that you read our getting started guide: <a href=\"https:\/\/randomnerdtutorials.com\/esp32-bme280-arduino-ide-pressure-temperature-humidity\/\">ESP32 with BME280 Sensor using Arduino IDE (Pressure, Temperature, Humidity)<\/a><\/p>\n\n\n\n<p>The CYD board should have a built-in LDR (light-dependent resistor) next to the screen and connected to GPIO 34.<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"750\" height=\"423\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/06\/ESP32-Cheap-Yellow-Display-LDR.jpg?resize=750%2C423&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"ESP32 Cheap Yellow Display LDR (Light Dependent ResistorESP32-Cheap-Yellow-)\" class=\"wp-image-159209\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/06\/ESP32-Cheap-Yellow-Display-LDR.jpg?w=750&amp;quality=100&amp;strip=all&amp;ssl=1 750w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/06\/ESP32-Cheap-Yellow-Display-LDR.jpg?resize=300%2C169&amp;quality=100&amp;strip=all&amp;ssl=1 300w\" sizes=\"(max-width: 750px) 100vw, 750px\" \/><\/figure><\/div>\n\n\n<p class=\"rntbox rntclgreen\">Recommended reading: <a href=\"https:\/\/randomnerdtutorials.com\/esp32-cheap-yellow-display-cyd-pinout-esp32-2432s028r\/\">ESP32 Cheap Yellow Display (CYD) Pinout (ESP32-2432S028R)<\/a>.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">2) Install ESP32 Boards in Arduino IDE<\/h3>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"204\" height=\"204\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/06\/arduino-ide-2.jpg?resize=204%2C204&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"Arduino IDE 2 Logo\" class=\"wp-image-159109\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/06\/arduino-ide-2.jpg?w=204&amp;quality=100&amp;strip=all&amp;ssl=1 204w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/06\/arduino-ide-2.jpg?resize=150%2C150&amp;quality=100&amp;strip=all&amp;ssl=1 150w\" sizes=\"(max-width: 204px) 100vw, 204px\" \/><\/figure><\/div>\n\n\n<p>We&#8217;ll program the ESP32 using Arduino IDE. Make sure you have the ESP32 boards installed. Follow the next tutorial:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><a href=\"https:\/\/randomnerdtutorials.com\/installing-esp32-arduino-ide-2-0\/\" title=\"\">Installing ESP32 Board in Arduino IDE 2 (Windows, Mac OS X, Linux)<\/a><\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">3) Get familiar with the ESP32 Cheap Yellow Display<\/h3>\n\n\n\n<p>The&nbsp;<a href=\"https:\/\/makeradvisor.com\/tools\/cyd-cheap-yellow-display-esp32-2432s028r\/\" target=\"_blank\" rel=\"noreferrer noopener\">ESP32-2432S028R<\/a>&nbsp;development board has become known in the maker community as the \u201c<em>Cheap Yellow Display<\/em>\u201d or CYD for short. This development board, whose main chip is an ESP32-WROOM-32 module, comes with a 2.8-inch TFT touchscreen LCD, a microSD card interface, an RGB LED, and all the required circuitry to program and apply power to the board.<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"750\" height=\"421\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/03\/ESP32-Cheap-Yellow-Display-CYD-Board-ESP32-2432S028R-front.jpg?resize=750%2C421&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"ESP32 Cheap Yellow Display CYD Board ESP32-2432S028R front\" class=\"wp-image-149592\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/03\/ESP32-Cheap-Yellow-Display-CYD-Board-ESP32-2432S028R-front.jpg?w=750&amp;quality=100&amp;strip=all&amp;ssl=1 750w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/03\/ESP32-Cheap-Yellow-Display-CYD-Board-ESP32-2432S028R-front.jpg?resize=300%2C168&amp;quality=100&amp;strip=all&amp;ssl=1 300w\" sizes=\"(max-width: 750px) 100vw, 750px\" \/><\/figure><\/div>\n\n\n<p>If this is your first time using the ESP32 Cheap Yellow Display, make sure to follow our getting started guide:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><a href=\"https:\/\/randomnerdtutorials.com\/lvgl-cheap-yellow-display-esp32-2432s028r\/\">Getting Started with ESP32 Cheap Yellow Display Board and LVGL<\/a><\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">4) Install TFT and LVGL Libraries<\/h3>\n\n\n\n<p><a href=\"https:\/\/docs.lvgl.io\/master\/\" target=\"_blank\" rel=\"noreferrer noopener\">LVGL<\/a>&nbsp;(Light and Versatile Graphics Library) is a free and open-source graphics library that provides a wide range of easy-to-use graphical elements for your microcontroller projects that require a graphical user interface (GUI).<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full is-resized\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"622\" height=\"194\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/08\/LVGL-new-logo.png?resize=622%2C194&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"LVGL new logo\" class=\"wp-image-161339\" style=\"width:340px\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/08\/LVGL-new-logo.png?w=622&amp;quality=100&amp;strip=all&amp;ssl=1 622w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/08\/LVGL-new-logo.png?resize=300%2C94&amp;quality=100&amp;strip=all&amp;ssl=1 300w\" sizes=\"(max-width: 622px) 100vw, 622px\" \/><\/figure><\/div>\n\n\n<p>Follow the next tutorial to install and configure the required libraries to use LVGL for the ESP32 Cheap Yellow Display using Arduino IDE.<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><a href=\"https:\/\/randomnerdtutorials.com\/lvgl-cheap-yellow-display-esp32-2432s028r\/\" title=\"\"><strong>Get started with LVGL using the ESP32 Cheap Yellow Display Board (ESP32-2432S028R)<\/strong><\/a><\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">5) Install ArduinoJson and BME280 Libraries<\/h3>\n\n\n\n<p>For this project, you need to install the ArduinoJSON library to handle the JSON response when you make a request to the WorldTimeAPI.<\/p>\n\n\n\n<p>In the Arduino IDE, go to <strong>Sketch <\/strong>&gt; <strong>Include Library<\/strong> &gt; <strong>Manage Libraries<\/strong>. Search for <strong>ArduinoJSON <\/strong>and install the library by <em>Benoit Blanchon<\/em>. We\u2019re using version 7.0.4. We recommend using the same version.<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"749\" height=\"514\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/06\/install-arduinojsonlibrary-arduino-ide-2.png?resize=749%2C514&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"\" class=\"wp-image-158855\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/06\/install-arduinojsonlibrary-arduino-ide-2.png?w=749&amp;quality=100&amp;strip=all&amp;ssl=1 749w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/06\/install-arduinojsonlibrary-arduino-ide-2.png?resize=300%2C206&amp;quality=100&amp;strip=all&amp;ssl=1 300w\" sizes=\"(max-width: 749px) 100vw, 749px\" \/><\/figure><\/div>\n\n\n<p>We&#8217;ll use the Adafruit BME280 library to get data from the BME280. In the Arduino IDE, go to <strong>Sketch <\/strong>&gt; <strong>Include Library<\/strong> &gt; <strong>Manage Libraries<\/strong>. Search for<strong> Adafruit BME280<\/strong> Library on the search box and install the library. Also, install any dependencies that are currently not installed (usually the Adafruit Bus IO and the Adafruit Unified Sensor libraries).<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"290\" height=\"305\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/09\/Installing-Adafruit-BME280-Sensor-Library-Arduino-IDE.png?resize=290%2C305&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"Installing Adafruit BME280 Sensor Library Arduino IDE\" class=\"wp-image-162191\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/09\/Installing-Adafruit-BME280-Sensor-Library-Arduino-IDE.png?w=290&amp;quality=100&amp;strip=all&amp;ssl=1 290w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/09\/Installing-Adafruit-BME280-Sensor-Library-Arduino-IDE.png?resize=285%2C300&amp;quality=100&amp;strip=all&amp;ssl=1 285w\" sizes=\"(max-width: 290px) 100vw, 290px\" \/><\/figure><\/div>\n\n\n<h2 class=\"wp-block-heading\">ESP32 CYD: Display BME280 Sensor Readings on a Table &#8211; Arduino Code<\/h2>\n\n\n\n<p>The following code will create the table and display the sensor readings. Before uploading the code to your board, you need to insert your network credentials so that the ESP32 can connect to the internet to get the time. You also need to insert your timezone.<\/p>\n\n\n<pre style=\"max-height: 40em; margin-bottom: 20px;\"><code class=\"language-c\">\/*  Rui Santos &amp; Sara Santos - Random Nerd Tutorials - https:\/\/RandomNerdTutorials.com\/esp32-cyd-lvgl-display-bme280-data-table\/   |   https:\/\/RandomNerdTutorials.com\/esp32-tft-lvgl-display-bme280-data-table\/\n    THIS EXAMPLE WAS TESTED WITH THE FOLLOWING HARDWARE:\n    1) ESP32-2432S028R 2.8 inch 240\u00d7320 also known as the Cheap Yellow Display (CYD): https:\/\/makeradvisor.com\/tools\/cyd-cheap-yellow-display-esp32-2432s028r\/\n      SET UP INSTRUCTIONS: https:\/\/RandomNerdTutorials.com\/cyd-lvgl\/\n    2) REGULAR ESP32 Dev Board + 2.8 inch 240x320 TFT Display: https:\/\/makeradvisor.com\/tools\/2-8-inch-ili9341-tft-240x320\/ and https:\/\/makeradvisor.com\/tools\/esp32-dev-board-wi-fi-bluetooth\/\n      SET UP INSTRUCTIONS: https:\/\/RandomNerdTutorials.com\/esp32-tft-lvgl\/\n    Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files.\n    The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\n*\/\n\n\/*  Install the &quot;lvgl&quot; library version 9.X by kisvegabor to interface with the TFT Display - https:\/\/lvgl.io\/\n    *** IMPORTANT: lv_conf.h available on the internet will probably NOT work with the examples available at Random Nerd Tutorials ***\n    *** YOU MUST USE THE lv_conf.h FILE PROVIDED IN THE LINK BELOW IN ORDER TO USE THE EXAMPLES FROM RANDOM NERD TUTORIALS ***\n    FULL INSTRUCTIONS AVAILABLE ON HOW CONFIGURE THE LIBRARY: https:\/\/RandomNerdTutorials.com\/cyd-lvgl\/ or https:\/\/RandomNerdTutorials.com\/esp32-tft-lvgl\/   *\/\n#include &lt;lvgl.h&gt;\n\n\/*  Install the &quot;TFT_eSPI&quot; library by Bodmer to interface with the TFT Display - https:\/\/github.com\/Bodmer\/TFT_eSPI\n    *** IMPORTANT: User_Setup.h available on the internet will probably NOT work with the examples available at Random Nerd Tutorials ***\n    *** YOU MUST USE THE User_Setup.h FILE PROVIDED IN THE LINK BELOW IN ORDER TO USE THE EXAMPLES FROM RANDOM NERD TUTORIALS ***\n    FULL INSTRUCTIONS AVAILABLE ON HOW CONFIGURE THE LIBRARY: https:\/\/RandomNerdTutorials.com\/cyd-lvgl\/ or https:\/\/RandomNerdTutorials.com\/esp32-tft-lvgl\/   *\/\n#include &lt;TFT_eSPI.h&gt;\n\n\/\/ Install the &quot;XPT2046_Touchscreen&quot; library by Paul Stoffregen to use the Touchscreen - https:\/\/github.com\/PaulStoffregen\/XPT2046_Touchscreen - Note: this library doesn't require further configuration\n#include &lt;XPT2046_Touchscreen.h&gt;\n\n#include &lt;WiFi.h&gt;\n#include &lt;HTTPClient.h&gt;\n#include &lt;ArduinoJson.h&gt;\n\n\/\/ Replace with your network credentials\nconst char* ssid = &quot;REPLACE_WITH_YOUR_SSID&quot;;\nconst char* password = &quot;REPLACE_WITH_YOUR_PASSWORD&quot;;\n\n\/\/ Specify the timezone you want to get the time for\nconst char* timezone = &quot;Europe\/Lisbon&quot;;\n\n\/\/ Store date and time\nString current_date;\nString current_time;\n\n\/\/ Install Adafruit Unified Sensor and Adafruit BME280 Library\n#include &lt;Wire.h&gt;\n#include &lt;Adafruit_Sensor.h&gt;\n#include &lt;Adafruit_BME280.h&gt;\n#define I2C_SDA 27\n#define I2C_SCL 22\n#define SEALEVELPRESSURE_HPA (1013.25)\nTwoWire I2CBME = TwoWire(0);\nAdafruit_BME280 bme;\n\n\/\/ SET VARIABLE TO 0 FOR TEMPERATURE IN FAHRENHEIT DEGREES\n#define TEMP_CELSIUS 1    \n\n#define LDR_PIN 34\n\n\/\/ Touchscreen pins\n#define XPT2046_IRQ 36   \/\/ T_IRQ\n#define XPT2046_MOSI 32  \/\/ T_DIN\n#define XPT2046_MISO 39  \/\/ T_OUT\n#define XPT2046_CLK 25   \/\/ T_CLK\n#define XPT2046_CS 33    \/\/ T_CS\n\nSPIClass touchscreenSPI = SPIClass(VSPI);\nXPT2046_Touchscreen touchscreen(XPT2046_CS, XPT2046_IRQ);\n\n#define SCREEN_WIDTH 240\n#define SCREEN_HEIGHT 320\n\n\/\/ Touchscreen coordinates: (x, y) and pressure (z)\nint x, y, z;\n\n#define DRAW_BUF_SIZE (SCREEN_WIDTH * SCREEN_HEIGHT \/ 10 * (LV_COLOR_DEPTH \/ 8))\nuint32_t draw_buf[DRAW_BUF_SIZE \/ 4];\n\n\/\/ If logging is enabled, it will inform the user about what is happening in the library\nvoid log_print(lv_log_level_t level, const char * buf) {\n  LV_UNUSED(level);\n  Serial.println(buf);\n  Serial.flush();\n}\n\n\/\/ Get the Touchscreen data\nvoid touchscreen_read(lv_indev_t * indev, lv_indev_data_t * data) {\n  \/\/ Checks if Touchscreen was touched, and prints X, Y and Pressure (Z)\n  if(touchscreen.tirqTouched() &amp;&amp; touchscreen.touched()) {\n    \/\/ Get Touchscreen points\n    TS_Point p = touchscreen.getPoint();\n\n    \/\/ Advanced Touchscreen calibration, LEARN MORE \u00bb https:\/\/RandomNerdTutorials.com\/touchscreen-calibration\/\n    float alpha_x, beta_x, alpha_y, beta_y, delta_x, delta_y;\n\n    \/\/ REPLACE WITH YOUR OWN CALIBRATION VALUES \u00bb https:\/\/RandomNerdTutorials.com\/touchscreen-calibration\/\n    alpha_x = -0.000;\n    beta_x = 0.090;\n    delta_x = -33.771;\n    alpha_y = 0.066;\n    beta_y = 0.000;\n    delta_y = -14.632;\n\n    x = alpha_y * p.x + beta_y * p.y + delta_y;\n    \/\/ clamp x between 0 and SCREEN_WIDTH - 1\n    x = max(0, x);\n    x = min(SCREEN_WIDTH - 1, x);\n\n    y = alpha_x * p.x + beta_x * p.y + delta_x;\n    \/\/ clamp y between 0 and SCREEN_HEIGHT - 1\n    y = max(0, y);\n    y = min(SCREEN_HEIGHT - 1, y);\n\n    \/\/ Basic Touchscreen calibration points with map function to the correct width and height\n    \/\/x = map(p.x, 200, 3700, 1, SCREEN_WIDTH);\n    \/\/y = map(p.y, 240, 3800, 1, SCREEN_HEIGHT);\n\n    z = p.z;\n\n    data-&gt;state = LV_INDEV_STATE_PRESSED;\n\n    \/\/ Set the coordinates\n    data-&gt;point.x = x;\n    data-&gt;point.y = y;\n\n    \/\/ Print Touchscreen info about X, Y and Pressure (Z) on the Serial Monitor\n    Serial.print(&quot;X = &quot;);\n    Serial.print(x);\n    Serial.print(&quot; | Y = &quot;);\n    Serial.print(y);\n    Serial.print(&quot; | Pressure = &quot;);\n    Serial.print(z);\n    Serial.println();\n  }\n  else {\n    data-&gt;state = LV_INDEV_STATE_RELEASED;\n  }\n}\n\nstatic void float_button_event_cb(lv_event_t * e) {\n  update_table_values();\n}\n\nstatic lv_obj_t * table;\nstatic void update_table_values(void) {\n  \/\/ Get the latest temperature reading in Celsius or Fahrenheit\n  #if TEMP_CELSIUS\n    float bme_temp = bme.readTemperature();\n    const char degree_symbol[] = &quot;\\u00B0C&quot;;\n  #else\n    float bme_temp = 1.8 * bme.readTemperature() + 32;\n    const char degree_symbol[] = &quot;\\u00B0F&quot;;\n  #endif\n  \n  String bme_temp_value = String(bme_temp) + degree_symbol;\n  String bme_humi_value = String(bme.readHumidity()) + &quot;%&quot;;\n  String bme_press_value = String(bme.readPressure() \/ 100.0F) + &quot; hPa&quot;;\n  String ldr_value = String(analogRead(LDR_PIN));\n  \n  \/\/ Get the time from WorldTimeAPI\n  get_date_and_time();\n  \/\/Serial.println(&quot;Current Date: &quot; + current_date);\n  \/\/Serial.println(&quot;Current Time: &quot; + current_time);\n\n  \/\/ Fill the first column\n  lv_table_set_cell_value(table, 0, 0, &quot;Data&quot;);\n  lv_table_set_cell_value(table, 1, 0, &quot;Temperature&quot;);\n  lv_table_set_cell_value(table, 2, 0, &quot;Humidity&quot;);\n  lv_table_set_cell_value(table, 3, 0, &quot;Pressure&quot;);\n  lv_table_set_cell_value(table, 4, 0, &quot;Luminosity&quot;);\n  lv_table_set_cell_value(table, 5, 0, &quot;Date&quot;);\n  lv_table_set_cell_value(table, 6, 0, &quot;Time&quot;);\n  lv_table_set_cell_value(table, 7, 0, &quot;IP Address&quot;);\n\n  \/\/ Fill the second column\n  lv_table_set_cell_value(table, 0, 1, &quot;Value&quot;);\n  lv_table_set_cell_value(table, 1, 1, bme_temp_value.c_str());\n  lv_table_set_cell_value(table, 2, 1, bme_humi_value.c_str());\n  lv_table_set_cell_value(table, 3, 1, bme_press_value.c_str());\n  lv_table_set_cell_value(table, 4, 1, ldr_value.c_str());\n  lv_table_set_cell_value(table, 5, 1, current_date.c_str());\n  lv_table_set_cell_value(table, 6, 1, current_time.c_str());\n  lv_table_set_cell_value(table, 7, 1, WiFi.localIP().toString().c_str());\n}\n\nstatic void draw_event_cb(lv_event_t * e) {\n  lv_draw_task_t * draw_task = lv_event_get_draw_task(e);\n  lv_draw_dsc_base_t * base_dsc = (lv_draw_dsc_base_t*) draw_task-&gt;draw_dsc;\n  \/\/ If the cells are drawn\n  if(base_dsc-&gt;part == LV_PART_ITEMS) {\n    uint32_t row = base_dsc-&gt;id1;\n    uint32_t col = base_dsc-&gt;id2;\n\n    \/\/ Make the texts in the first cell center aligned\n    if(row == 0) {\n      lv_draw_label_dsc_t * label_draw_dsc = lv_draw_task_get_label_dsc(draw_task);\n      if(label_draw_dsc) {\n        label_draw_dsc-&gt;align = LV_TEXT_ALIGN_CENTER;\n      }\n      lv_draw_fill_dsc_t * fill_draw_dsc = lv_draw_task_get_fill_dsc(draw_task);\n      if(fill_draw_dsc) {\n        fill_draw_dsc-&gt;color = lv_color_mix(lv_palette_main(LV_PALETTE_BLUE), fill_draw_dsc-&gt;color, LV_OPA_20);\n        fill_draw_dsc-&gt;opa = LV_OPA_COVER;\n      }\n    }\n    \/\/ In the first column align the texts to the right\n    else if(col == 0) {\n      lv_draw_label_dsc_t * label_draw_dsc = lv_draw_task_get_label_dsc(draw_task);\n      if(label_draw_dsc) {\n        label_draw_dsc-&gt;align = LV_TEXT_ALIGN_RIGHT;\n      }\n    }\n\n    \/\/ Make every 2nd row gray color\n    if((row != 0 &amp;&amp; row % 2) == 0) {\n      lv_draw_fill_dsc_t * fill_draw_dsc = lv_draw_task_get_fill_dsc(draw_task);\n      if(fill_draw_dsc) {\n        fill_draw_dsc-&gt;color = lv_color_mix(lv_palette_main(LV_PALETTE_GREY), fill_draw_dsc-&gt;color, LV_OPA_10);\n        fill_draw_dsc-&gt;opa = LV_OPA_COVER;\n      }\n    }\n  }\n}\n\nvoid lv_create_main_gui(void) {\n  table = lv_table_create(lv_screen_active());\n\n  \/\/ Inserts or updates all table values\n  update_table_values();\n\n  \/\/ Set a smaller height to the table. It will make it scrollable\n  lv_obj_set_height(table, 200);\n  lv_obj_center(table);\n\n  \/\/ Add an event callback to apply some custom drawing\n  lv_obj_add_event_cb(table, draw_event_cb, LV_EVENT_DRAW_TASK_ADDED, NULL);\n  lv_obj_add_flag(table, LV_OBJ_FLAG_SEND_DRAW_TASK_EVENTS);\n\n  \/\/ Create floating button\n  lv_obj_t * float_button = lv_button_create(lv_screen_active());\n  lv_obj_set_size(float_button, 50, 50);\n  lv_obj_add_flag(float_button, LV_OBJ_FLAG_FLOATING);\n  lv_obj_align(float_button, LV_ALIGN_BOTTOM_RIGHT, -15, -15);\n  lv_obj_add_event_cb(float_button, float_button_event_cb, LV_EVENT_CLICKED, NULL);\n  lv_obj_set_style_radius(float_button, LV_RADIUS_CIRCLE, 0);\n  lv_obj_set_style_bg_image_src(float_button, LV_SYMBOL_REFRESH, 0);\n  lv_obj_set_style_text_font(float_button, lv_theme_get_font_large(float_button), 0);\n  lv_obj_set_style_bg_color(float_button, lv_palette_main(LV_PALETTE_GREEN), LV_PART_MAIN);\n}\n\nvoid get_date_and_time() {\n  if (WiFi.status() == WL_CONNECTED) {\n    HTTPClient http;\n\n    \/\/ Construct the API endpoint\n    String url = String(&quot;http:\/\/worldtimeapi.org\/api\/timezone\/&quot;) + timezone;\n\n    http.begin(url);\n\n    int httpCode = http.GET(); \/\/ Make the GET request\n\n    if (httpCode &gt; 0) {\n      \/\/ Check for the response\n      if (httpCode == HTTP_CODE_OK) {\n        String payload = http.getString();\n        \/\/Serial.println(&quot;Time information:&quot;);\n        \/\/Serial.println(payload);\n        \n        \/\/ Parse the JSON to extract the time\n        JsonDocument doc;\n        DeserializationError error = deserializeJson(doc, payload);\n\n        if (!error) {\n          const char* datetime = doc[&quot;datetime&quot;];\n          \/\/Serial.println(&quot;Datetime: &quot; + String(datetime));\n          \n          \/\/ Split the datetime into date and time\n          String datetimeStr = String(datetime);\n          int splitIndex = datetimeStr.indexOf('T');\n          current_date = datetimeStr.substring(0, splitIndex);\n          current_time = datetimeStr.substring(splitIndex + 1, splitIndex + 9); \/\/ Extract time portion\n\n        } else {\n          Serial.print(&quot;deserializeJson() failed: &quot;);\n          Serial.println(error.c_str());\n        }\n      }\n    } else {\n      Serial.printf(&quot;GET request failed, error: %s\\n&quot;, http.errorToString(httpCode).c_str());\n    }\n\n    http.end(); \/\/ Close connection\n  } else {\n    Serial.println(&quot;Not connected to Wi-Fi&quot;);\n  }\n}\n\nvoid setup() {\n  String LVGL_Arduino = String(&quot;LVGL Library Version: &quot;) + lv_version_major() + &quot;.&quot; + lv_version_minor() + &quot;.&quot; + lv_version_patch();\n  Serial.begin(115200);\n  Serial.println(LVGL_Arduino);\n\n  \/\/ Set analog read resolution\n  analogReadResolution(12);\n\n  \/\/ Connect to Wi-Fi\n  WiFi.begin(ssid, password);\n  Serial.print(&quot;Connecting&quot;);\n  while (WiFi.status() != WL_CONNECTED) {\n    delay(500);\n    Serial.print(&quot;.&quot;);\n  }\n  Serial.print(&quot;\\nConnected to Wi-Fi network with IP Address: &quot;);\n  Serial.println(WiFi.localIP());\n\n  I2CBME.begin(I2C_SDA, I2C_SCL, 100000);\n  bool status;\n  \/\/ Passing a &amp;Wire2 to set custom I2C ports\n  status = bme.begin(0x76, &amp;I2CBME);\n  if (!status) {\n    Serial.println(&quot;Could not find a valid BME280 sensor, check wiring!&quot;);\n    while (1);\n  }\n  \n  \/\/ Start LVGL\n  lv_init();\n  \/\/ Register print function for debugging\n  lv_log_register_print_cb(log_print);\n\n  \/\/ Start the SPI for the touchscreen and init the touchscreen\n  touchscreenSPI.begin(XPT2046_CLK, XPT2046_MISO, XPT2046_MOSI, XPT2046_CS);\n  touchscreen.begin(touchscreenSPI);\n  \/\/ Set the Touchscreen rotation in landscape mode\n  \/\/ Note: in some displays, the touchscreen might be upside down, so you might need to set the rotation to 0: touchscreen.setRotation(0);\n  touchscreen.setRotation(2);\n\n  \/\/ Create a display object\n  lv_display_t * disp;\n  \/\/ Initialize the TFT display using the TFT_eSPI library\n  disp = lv_tft_espi_create(SCREEN_WIDTH, SCREEN_HEIGHT, draw_buf, sizeof(draw_buf));\n  lv_display_set_rotation(disp, LV_DISPLAY_ROTATION_270);\n  \n  \/\/ Initialize an LVGL input device object (Touchscreen)\n  lv_indev_t * indev = lv_indev_create();\n  lv_indev_set_type(indev, LV_INDEV_TYPE_POINTER);\n  \/\/ Set the callback function to read Touchscreen input\n  lv_indev_set_read_cb(indev, touchscreen_read);\n\n  \/\/ Function to draw the GUI\n  lv_create_main_gui();\n}\n\nvoid loop() {\n  lv_task_handler();  \/\/ let the GUI do its work\n  lv_tick_inc(5);     \/\/ tell LVGL how much time has passed\n  delay(5);           \/\/ let this time pass\n}\n<\/code><\/pre>\n\t<p style=\"text-align:center\"><a class=\"rntwhite\" href=\"https:\/\/github.com\/RuiSantosdotme\/ESP32-TFT-Touchscreen\/raw\/main\/examples\/ESP32_LVGL_BME280_Table\/ESP32_LVGL_BME280_Table.ino\" target=\"_blank\">View raw code<\/a><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">How Does the Code Work?<\/h2>\n\n\n\n<p>Let\u2019s see how to get the time from the internet and display all data on a table. Alternatively, you can skip to the <a href=\"#demonstration\" title=\"\">Demonstration <\/a>section.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Including Libraries<\/h3>\n\n\n\n<p>You need to include the <span class=\"rnthl rntliteral\">lvgl<\/span>, <span class=\"rnthl rntliteral\">TFT_eSPI<\/span>, and the <span class=\"rnthl rntliteral\">XPT2046_Touchscreen<\/span> libraries to communicate and display text on the screen.<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>#include &lt;lvgl.h&gt;\n#include &lt;TFT_eSPI.h&gt;\n#include &lt;XPT2046_Touchscreen.h&gt;<\/code><\/pre>\n\n\n\n<p>You need to include the <span class=\"rnthl rntliteral\">WiFi<\/span>, <span class=\"rnthl rntliteral\">HTTPClient<\/span>, and the <span class=\"rnthl rntliteral\">ArduinoJson<\/span> libraries to make HTTP requests and handle JSON data.<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>#include &lt;WiFi.h&gt;\n#include &lt;HTTPClient.h&gt;\n#include &lt;ArduinoJson.h&gt;<\/code><\/pre>\n\n\n\n<p>To use the BME280, we need to include the following libraries.<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>#include &lt;Wire.h&gt;\n#include &lt;Adafruit_Sensor.h&gt;\n#include &lt;Adafruit_BME280.h&gt;<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">Insert Your Credentials and Timezone<\/h3>\n\n\n\n<p>In the following lines, you must insert your network credentials so that the ESP32 can connect to your router.<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>const char* ssid = \"REPLACE_WITH_YOUR_SSID\";\nconst char* password = \"REPLACE_WITH_YOUR_PASSWORD\";<\/code><\/pre>\n\n\n\n<p>Set your timezone in the <span class=\"rnthl rntliteral\">timezone<\/span> variable at the beginning of the code (list of all available <a href=\"http:\/\/worldtimeapi.org\/api\/timezone\" target=\"_blank\" rel=\"noopener\" title=\"\">timezones<\/a>).<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>const char* timezone = \"Europe\/Lisbon\";<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">Declaring Other Variables<\/h3>\n\n\n\n<p>We need to create an I2C instance on custom I2C pins and an <span class=\"rnthl rntliteral\">Adafruit_BME280<\/span> object to refer to the sensor.<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>#define I2C_SDA 27\n#define I2C_SCL 22\n#define SEALEVELPRESSURE_HPA (1013.25)\nTwoWire I2CBME = TwoWire(0);\nAdafruit_BME280 bme;<\/code><\/pre>\n\n\n\n<p class=\"rntbox rntclblue\">Related content: <a href=\"https:\/\/randomnerdtutorials.com\/esp32-i2c-communication-arduino-ide\/\">ESP32 I2C Communication: Set Pins, Multiple Bus Interfaces and Peripherals (Arduino IDE)<\/a><\/p>\n\n\n\n<p>Our code is prepared to display the temperature in Celsius or Fahrenheit degrees. To choose your desired Unit, you can set the value of the <span class=\"rnthl rntliteral\">TEMP_CELSIUS<\/span> variable. It is set to <span class=\"rnthl rntliteral\">1<\/span> by default to display the temperature in Celsius degrees.<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>#define TEMP_CELSIUS 1<\/code><\/pre>\n\n\n\n<p>If you want to display in Fahrenheit degrees instead, set it to <span class=\"rnthl rntliteral\">0<\/span>.<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>#define TEMP_CELSIUS 0<\/code><\/pre>\n\n\n\n<p>Create a LVGL table object, so that we can access it inside all functions later on.<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>static lv_obj_t * table;<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">setup()<\/h3>\n\n\n\n<p>In the <span class=\"rnthl rntliteral\">setup()<\/span>, include the following lines for debugging. These will print the version of LVGL that you\u2019re using. You must be using version 9.<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>String LVGL_Arduino = String(\"LVGL Library Version: \") + lv_version_major() + \".\" + lv_version_minor() + \".\" + lv_version_patch();\nSerial.begin(115200);\nSerial.println(LVGL_Arduino);<\/code><\/pre>\n\n\n\n<h4 class=\"wp-block-heading\">Connect to the Internet<\/h4>\n\n\n\n<p>To connect the ESP32 to the internet we use the following code.<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>\/\/ Connect to Wi-Fi\nWiFi.begin(ssid, password);\nSerial.print(\"Connecting\");\nwhile (WiFi.status() != WL_CONNECTED) {\n  delay(500);\n  Serial.print(\".\");\n}\nSerial.print(\"\\nConnected to Wi-Fi network with IP Address: \");\nSerial.println(WiFi.localIP());<\/code><\/pre>\n\n\n\n<h4 class=\"wp-block-heading\">Init BME280<\/h4>\n\n\n\n<p>The following lines initialize the sensor on the I2C bus created:<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>I2CBME.begin(I2C_SDA, I2C_SCL, 100000);\nbool status;\n\/\/ Passing a &amp;Wire2 to set custom I2C ports\nstatus = bme.begin(0x76, &amp;I2CBME);\nif (!status) {\n  Serial.println(\"Could not find a valid BME280 sensor, check wiring!\");\n  while (1);\n}  <\/code><\/pre>\n\n\n\n<h4 class=\"wp-block-heading\">Initialize the LVGL Library<\/h4>\n\n\n\n<p>Initialize the LVGL Library by calling the <span class=\"rnthl rntliteral\">lv_init()<\/span> function in the <span class=\"rnthl rntliteral\">setup()<\/span>.<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>\/\/ Start LVGL\nlv_init();<\/code><\/pre>\n\n\n\n<h4 class=\"wp-block-heading\">Register Debugging Function<\/h4>\n\n\n\n<p>Register your <span class=\"rnthl rntliteral\">log_print()<\/span> function declared previously as a function associated with debugging LVGL.<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>\/\/ Register print function for debugging\nlv_log_register_print_cb(log_print);<\/code><\/pre>\n\n\n\n<h4 class=\"wp-block-heading\">Preparing the Touchscreen<\/h4>\n\n\n\n<p>Initialize the touchscreen.<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>\/\/ Start the SPI for the touchscreen and init the touchscreen\ntouchscreenSPI.begin(XPT2046_CLK, XPT2046_MISO, XPT2046_MOSI, XPT2046_CS);\ntouchscreen.begin(touchscreenSPI);\n\/\/ Set the Touchscreen rotation in landscape mode\n\/\/ Note: in some displays, the touchscreen might be upside down\n\/\/ so you might need to set the rotation to 0: touchscreen.setRotation(0);\ntouchscreen.setRotation(2);<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">Touchscreen Calibration<\/h3>\n\n\n\n<p>On the <span class=\"rnthl rntliteral\">touchscreen_read()<\/span> function, we adjust the touchscreen points to calibrate them with the display. You must insert the calibration values on the following lines. <a href=\"https:\/\/randomnerdtutorials.com\/esp32-cheap-yellow-display-cyd-resistive-touchscreen-calibration\/\" title=\"\">Check this tutorial to get the calibration values for your display<\/a>.<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>\/\/ REPLACE WITH YOUR OWN CALIBRATION VALUES \u00bb https:\/\/RandomNerdTutorials.com\/touchscreen-calibration\/\nalpha_x = -0.000;\nbeta_x = 0.090;\ndelta_x = -33.771;\nalpha_y = 0.066;\nbeta_y = 0.000;\ndelta_y = -14.632;<\/code><\/pre>\n\n\n\n<h4 class=\"wp-block-heading\">Create a Display Object<\/h4>\n\n\n\n<p>To write to the display, you must create a display object first. You need to do this in all your LVGL sketches. The following lines will create an LVGL display object called <span class=\"rnthl rntliteral\">disp<\/span> with the screen width, screen height, and drawing buffer defined earlier.<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>\/\/ Create a display object\nlv_display_t * disp;\n\/\/ Initialize the TFT display using the TFT_eSPI library\ndisp = lv_tft_espi_create(SCREEN_WIDTH, SCREEN_HEIGHT, draw_buf, sizeof(draw_buf));\nlv_display_set_rotation(disp, LV_DISPLAY_ROTATION_270);<\/code><\/pre>\n\n\n\n<h4 class=\"wp-block-heading\">Drawing the GUI<\/h4>\n\n\n\n<p>The LVGL library works asynchronously. You must call the function to draw on the display in the <span class=\"rnthl rntliteral\">setup()<\/span>. Then, everything works with events and callbacks. The code will always be listening for events in the background. When something happens, it will run the callback function associated with the event. You don\u2019t need to check for any events in the <span class=\"rnthl rntliteral\">loop()<\/span>.<\/p>\n\n\n\n<p>Throughout most of our examples, the function that will draw to the screen will be called <span class=\"rnthl rntliteral\">lv_create_main_gui()<\/span>. Then, inside that function, we\u2019ll add the instructions to build the interface.<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>\/\/ Function to draw the GUI\nlv_create_main_gui();<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">get_date_and_time()<\/h3>\n\n\n\n<p>We create two global variables <span class=\"rnthl rntliteral\">current_date<\/span> and <span class=\"rnthl rntliteral\">current_time<\/span> at the beginning of the code to save the current date and time.<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>String current_date;\nString current_time;<\/code><\/pre>\n\n\n\n<p>Create a function called <span class=\"rnthl rntliteral\">get_date_and_time()<\/span> that makes a request to the WorldTimeAPI and updates the <span class=\"rnthl rntliteral\">current_date<\/span> and <span class=\"rnthl rntliteral\">current_time<\/span> variables with the current date and time.<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>void get_date_and_time() {\n  if (WiFi.status() == WL_CONNECTED) {\n    HTTPClient http;\n\n    \/\/ Construct the API endpoint\n    String url = String(\"http:\/\/worldtimeapi.org\/api\/timezone\/\") + timezone;\n    http.begin(url);\n    int httpCode = http.GET(); \/\/ Make the GET request\n\n    if (httpCode &gt; 0) {\n      \/\/ Check for the response\n      if (httpCode == HTTP_CODE_OK) {\n        String payload = http.getString();\n        \/\/Serial.println(\"Time information:\");\n        \/\/Serial.println(payload);\n        \/\/ Parse the JSON to extract the time\n        JsonDocument doc;\n        DeserializationError error = deserializeJson(doc, payload);\n        if (!error) {\n          const char* datetime = doc&#091;\"datetime\"];          \n          \/\/ Split the datetime into date and time\n          String datetime_str = String(datetime);\n          int splitIndex = datetime_str.indexOf('T');\n          current_date = datetime_str.substring(0, splitIndex);\n          current_time = datetime_str.substring(splitIndex + 1, splitIndex + 9); \/\/ Extract time portion\n          hour = current_time.substring(0, 2).toInt();\n          minute = current_time.substring(3, 5).toInt();\n          second = current_time.substring(6, 8).toInt();\n        } else {\n          Serial.print(\"deserializeJson() failed: \");\n          Serial.println(error.c_str());\n        }\n      }\n    } else {\n      Serial.printf(\"GET request failed, error: %s\\n\", http.errorToString(httpCode).c_str());\n      sync_time_date = true;\n    }\n    http.end(); \/\/ Close connection\n  } else {\n    Serial.println(\"Not connected to Wi-Fi\");\n  }\n}<\/code><\/pre>\n\n\n\n<p>We won\u2019t cover how HTTP requests work. If you want to learn more, you can check the following tutorial: <a href=\"https:\/\/randomnerdtutorials.com\/esp32-http-get-open-weather-map-thingspeak-arduino\/\">ESP32 HTTP GET with Arduino IDE<\/a>.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Preparing the GUI<\/h3>\n\n\n\n<p>We create the table inside the <span class=\"rnthl rntliteral\">lv_create_main_gui()<\/span> function.<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>void lv_create_main_gui(void) {<\/code><\/pre>\n\n\n\n<p>We can create a table object using the <span class=\"rnthl rntliteral\">lv_table_create()<\/span> function as follows.<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>table = lv_table_create(lv_screen_active());<\/code><\/pre>\n\n\n\n<p>Next, we write a function called <span class=\"rnthl rntliteral\">update_table_values()<\/span> that fills the table with the readings. We\u2019ll take a look at that function in just a moment.<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>update_table_values();<\/code><\/pre>\n\n\n\n<p>Set the table height and center it on the screen.<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>\/\/ Set a smaller height to the table. It will make it scrollable\nlv_obj_set_height(table, 200);\nlv_obj_center(table);                                                                          <\/code><\/pre>\n\n\n\n<p>Add a callback and a flag to the table. Those will allow us to draw the table with a specific style (different colors for the headers and alternating grey and white rows).<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>\/\/ Add an event callback to apply some custom drawing\nlv_obj_add_event_cb(table, draw_event_cb, LV_EVENT_DRAW_TASK_ADDED, NULL);\nlv_obj_add_flag(table, LV_OBJ_FLAG_SEND_DRAW_TASK_EVENTS);<\/code><\/pre>\n\n\n\n<h4 class=\"wp-block-heading\">Creating the Floating Button<\/h4>\n\n\n\n<p>Still, inside the <span class=\"rnthl rntliteral\">lv_create_main_gui()<\/span> function, we create the floating button. This is a regular button, but it\u2019s circular and with a specific style.<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>\/\/ Create floating button\nlv_obj_t * float_button = lv_button_create(lv_screen_active());\nlv_obj_set_size(float_button, 50, 50);\nlv_obj_add_flag(float_button, LV_OBJ_FLAG_FLOATING);\nlv_obj_align(float_button, LV_ALIGN_BOTTOM_RIGHT, -15, -15);\nlv_obj_add_event_cb(float_button, float_button_event_cb, LV_EVENT_CLICKED, NULL);\nlv_obj_set_style_radius(float_button, LV_RADIUS_CIRCLE, 0);\nlv_obj_set_style_bg_image_src(float_button, LV_SYMBOL_REFRESH, 0);\nlv_obj_set_style_text_font(float_button, lv_theme_get_font_large(float_button), 0);\nlv_obj_set_style_bg_color(float_button, lv_palette_main(LV_PALETTE_GREEN), LV_PART_MAIN);<\/code><\/pre>\n\n\n\n<p>The button when clicked will trigger the <span class=\"rnthl rntliteral\">float_button_event_cb<\/span> function.<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>lv_obj_add_event_cb(float_button, float_button_event_cb, LV_EVENT_CLICKED, NULL);<\/code><\/pre>\n\n\n\n<p>To add the refresh symbol to the button, we use the <span class=\"rnthl rntliteral\">lv_obj_set_style_bg_image_src()<\/span> function. To add the refresh symbol we need to use <span class=\"rnthl rntliteral\">LV_SYMBOL_REFRESH<\/span>.<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>lv_obj_set_style_bg_image_src(float_button, LV_SYMBOL_REFRESH, 0);<\/code><\/pre>\n\n\n\n<h4 class=\"wp-block-heading\">Adding Data to the Table<\/h4>\n\n\n\n<p>In the <span class=\"rnthl rntliteral\">update_table_values()<\/span> is where we\u2019ll add some data to the table.<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>static void update_table_values(void) {<\/code><\/pre>\n\n\n\n<p>This function is called when we create the GUI in the <span class=\"rnthl rntliteral\">lv_create_main_gui()<\/span> function, and when you click the button on the <span class=\"rnthl rntliteral\">float_button_event_cb()<\/span> function.<\/p>\n\n\n\n<p>First, we start by getting readings from the BME280 sensor as well as luminosity from the LDR.<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>\/\/ Get the latest temperature reading in Celsius or Fahrenheit\n#if TEMP_CELSIUS\n  float bme_temp = bme.readTemperature();\n  const char degree_symbol&#091;] = \"\\u00B0C\";\n#else\n  float bme_temp = 1.8 * bme.readTemperature() + 32;\n  const char degree_symbol&#091;] = \"\\u00B0F\";\n#endif\n  \nString bme_temp_value = String(bme_temp) + degree_symbol;\nString bme_humi_value = String(bme.readHumidity()) + \"%\";\nString bme_press_value = String(bme.readPressure() \/ 100.0F) + \" hPa\";\nString ldr_value = String(analogRead(LDR_PIN));<\/code><\/pre>\n\n\n\n<p>The readings are saved on the <span class=\"rnthl rntliteral\">bme_temp_value<\/span>, <span class=\"rnthl rntliteral\">bme_humi_value<\/span>, <span class=\"rnthl rntliteral\">bme_pres_value<\/span> and <span class=\"rnthl rntliteral\">ldr_value<\/span> variables. We update the time variables by calling the <span class=\"rnthl rntliteral\">get_date_and_time()<\/span> function that we\u2019ve seen previously.<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>\/\/ Get the time from WorldTimeAPI\nget_date_and_time();<\/code><\/pre>\n\n\n\n<p>After getting all the data, we can finally start adding rows to the table. For that, we can use the <span class=\"rnthl rntliteral\">lv_table_set_cell_value()<\/span> function. This function accepts as argument the table you\u2019re referring to, the row number, the column number, and the data you want to display.<\/p>\n\n\n\n<p>The following lines fill the first column.<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>\/\/ Fill the first column\nlv_table_set_cell_value(table, 0, 0, \"Data\");\nlv_table_set_cell_value(table, 1, 0, \"Temperature\");\nlv_table_set_cell_value(table, 2, 0, \"Humidity\");\nlv_table_set_cell_value(table, 3, 0, \"Pressure\");\nlv_table_set_cell_value(table, 4, 0, \"Luminosity\");\nlv_table_set_cell_value(table, 5, 0, \"Date\");\nlv_table_set_cell_value(table, 6, 0, \"Time\");\nlv_table_set_cell_value(table, 7, 0, \"IP Address\");<\/code><\/pre>\n\n\n\n<p>Finally, we fill the second column with the values from the sensors, the date and time, and the ESP32 IP address.<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>\/\/ Fill the second column\nlv_table_set_cell_value(table, 0, 1, \"Value\");\nlv_table_set_cell_value(table, 1, 1, bme_temp_value.c_str());\nlv_table_set_cell_value(table, 2, 1, bme_humi_value.c_str());\nlv_table_set_cell_value(table, 3, 1, bme_press_value.c_str());\nlv_table_set_cell_value(table, 4, 1, ldr_value.c_str());\nlv_table_set_cell_value(table, 5, 1, current_date.c_str());\nlv_table_set_cell_value(table, 6, 1, current_time.c_str());\nlv_table_set_cell_value(table, 7, 1, WiFi.localIP().toString().c_str());<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">loop()<\/h3>\n\n\n\n<p>In the <span class=\"rnthl rntliteral\">loop()<\/span>, you can add any other tasks that you need your ESP32 to do like in any regular Arduino sketch.<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>void loop() {\n  lv_task_handler();   \/\/ let the GUI do its work\n  lv_tick_inc(5);         \/\/ tell LVGL how much time has passed\n  delay(5);                 \/\/ let this time pass\n}<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"demonstration\">Demonstration<\/h2>\n\n\n\n<p>Upload the code to your board. Go to <strong>Tools <\/strong>&gt; <strong>Board <\/strong>and select <strong>ESP32 <\/strong>&gt; <strong>ESP32 Dev Module<\/strong>. Then, select the right COM port in <strong>Tools <\/strong>&gt; <strong>Port<\/strong>.<\/p>\n\n\n\n<p class=\"rntbox rntcred\">If you see an Error like this: &#8220;Sketch too big&#8221; during the uploading process, in Arduino IDE go to <strong>Tools <\/strong>&gt; <strong>Partition scheme<\/strong> &gt; choose anything that has more than 1.4MB APP, for example: &#8220;<strong>Huge APP (3MB No OTA\/1MB SPIFFS<\/strong>&#8220;.<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"768\" height=\"817\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/08\/Select-Huge-App-Partion-Scheme-Arduino-IDE-Tools-Menu.png?resize=768%2C817&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"Select Huge App Partion Scheme Arduino IDE Tools Menu\" class=\"wp-image-161757\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/08\/Select-Huge-App-Partion-Scheme-Arduino-IDE-Tools-Menu.png?w=768&amp;quality=100&amp;strip=all&amp;ssl=1 768w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/08\/Select-Huge-App-Partion-Scheme-Arduino-IDE-Tools-Menu.png?resize=282%2C300&amp;quality=100&amp;strip=all&amp;ssl=1 282w\" sizes=\"(max-width: 768px) 100vw, 768px\" \/><\/figure><\/div>\n\n\n<p>Finally, click the upload button.<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full is-resized\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"36\" height=\"39\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2021\/05\/arduino-ide-2-upload-button.png?resize=36%2C39&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"Arduino IDE 2 Upload Button\" class=\"wp-image-146269\" style=\"width:36px;height:auto\"\/><\/figure><\/div>\n\n\n<p>After a few seconds, it will display the current data on the screen as shown in the picture below.<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"750\" height=\"463\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/09\/ESP32-CYD-BME280-Sensor-Data-Table-Demonstration-Testing.jpg?resize=750%2C463&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"ESP32 CYD BME280 Sensor Data Table Demonstration Testing\" class=\"wp-image-162199\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/09\/ESP32-CYD-BME280-Sensor-Data-Table-Demonstration-Testing.jpg?w=750&amp;quality=100&amp;strip=all&amp;ssl=1 750w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/09\/ESP32-CYD-BME280-Sensor-Data-Table-Demonstration-Testing.jpg?resize=300%2C185&amp;quality=100&amp;strip=all&amp;ssl=1 300w\" sizes=\"(max-width: 750px) 100vw, 750px\" \/><\/figure><\/div>\n\n\n<p>To update the data on the table, you just need to click on the refresh button.<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"750\" height=\"422\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/09\/ESP32-CYD-BME280-Sensor-Data-Table-Demonstration-Refresh-Update-Values.jpg?resize=750%2C422&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"ESP32 CYD BME280 Sensor Data Table Demonstration Refresh Update Values\" class=\"wp-image-162200\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/09\/ESP32-CYD-BME280-Sensor-Data-Table-Demonstration-Refresh-Update-Values.jpg?w=750&amp;quality=100&amp;strip=all&amp;ssl=1 750w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/09\/ESP32-CYD-BME280-Sensor-Data-Table-Demonstration-Refresh-Update-Values.jpg?resize=300%2C169&amp;quality=100&amp;strip=all&amp;ssl=1 300w\" sizes=\"(max-width: 750px) 100vw, 750px\" \/><\/figure><\/div>\n\n\n<p>You can cover the LDR with your finger to see the luminosity values changing.<\/p>\n\n\n\n<p><strong>Note:<\/strong> on many CYD boards, the LDR will not work as expected without modifying the internal circuit. So, if you\u2019re only getting 0 that\u2019s \u201cnormal\u201d.<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"750\" height=\"422\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/09\/ESP32-CYD-BME280-Sensor-Data-Table-Demonstration-LDR-Sensor.jpg?resize=750%2C422&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"ESP32 CYD BME280 Sensor Data Table Demonstration LDR Sensor\" class=\"wp-image-162198\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/09\/ESP32-CYD-BME280-Sensor-Data-Table-Demonstration-LDR-Sensor.jpg?w=750&amp;quality=100&amp;strip=all&amp;ssl=1 750w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/09\/ESP32-CYD-BME280-Sensor-Data-Table-Demonstration-LDR-Sensor.jpg?resize=300%2C169&amp;quality=100&amp;strip=all&amp;ssl=1 300w\" sizes=\"(max-width: 750px) 100vw, 750px\" \/><\/figure><\/div>\n\n\n<p>The table is scrollable. You can scroll down to check the date and time of the last update.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Troubleshooting<\/h2>\n\n\n\n<p>If you are experiencing issues opening the WorldTimeAPI website or if your HTTP request is failing to retrieve time, you can change the following line 252.<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>String url = String(\"http:\/\/worldtimeapi.org\/api\/timezone\/\") + timezone;<\/code><\/pre>\n\n\n\n<p>From their domain name (worldtimeapi.org) to their IP address as follows:<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>String url = String(\"http:\/\/213.188.196.246\/api\/timezone\/\") + timezone;<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Wrapping Up<\/h2>\n\n\n\n<p>In this tutorial, you learned to display sensor data on a responsive table on the Cheap Yellow Display (CYD) board using the LVGL library.<\/p>\n\n\n\n<p>We hope you found this tutorial useful. We&#8217;re preparing more guides about this board, so stay tuned. If you would like to learn more about creating graphical user interfaces using the LVGL library with the ESP32, check out our latest eBook:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong><a href=\"https:\/\/randomnerdtutorials.com\/learn-lvgl-esp32-ebook\/\">Learn LVGL: Build GUIs for ESP32 Projects (eBook)<\/a><\/strong><\/li>\n<\/ul>\n\n\n\n<p>Other guides you might like reading:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><a href=\"https:\/\/randomnerdtutorials.com\/cheap-yellow-display-esp32-2432s028r\/\">Getting Started with ESP32 Cheap Yellow Display Board \u2013 CYD (ESP32-2432S028R)<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/randomnerdtutorials.com\/touchscreen-on-off-button-cheap-yellow-display-esp32-2432s028r\/\">ESP32 Touchscreen On\/Off Button \u2013 Cheap Yellow Display (ESP32-2432S028R)<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/randomnerdtutorials.com\/esp32-cheap-yellow-display-cyd-pinout-esp32-2432s028r\/\">ESP32 Cheap Yellow Display (CYD) Pinout (ESP32-2432S028R)<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/randomnerdtutorials.com\/lvgl-cheap-yellow-display-esp32-2432s028r\/\">LVGL with ESP32 Cheap Yellow Display Board (ESP32-2432S028R)<\/a><\/li>\n<\/ul>\n\n\n\n<p>To learn more about the ESP32, make sure to take a look at our resources:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><a href=\"https:\/\/randomnerdtutorials.com\/learn-esp32-with-arduino-ide\/\">Learn ESP32 with Arduino IDE (eBook)<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/randomnerdtutorials.com\/smart-home-ebook\/\" title=\"\">SMART HOME with Raspberry Pi, ESP32, and ESP8266 eBook<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/randomnerdtutorials.com\/projects-esp32\/\" title=\"\"><strong>Free ESP32 Guides and Tutorials<\/strong><\/a><\/li>\n<\/ul>\n\n\n\n<p><\/p>\n","protected":false},"excerpt":{"rendered":"<p>In this guide, you\u2019ll learn how to create a responsive table using LVGL. We\u2019ll display temperature, humidity, and pressure from the BME280 sensor, and luminosity from the LDR on the &#8230; <\/p>\n<p class=\"read-more-container\"><a title=\"ESP32 CYD with LVGL: Display BME280 Sensor Data on a Table\" class=\"read-more button\" href=\"https:\/\/randomnerdtutorials.com\/esp32-cyd-lvgl-display-bme280-data-table\/#more-162190\" aria-label=\"Read more about ESP32 CYD with LVGL: Display BME280 Sensor Data on a Table\">CONTINUE READING \u00bb<\/a><\/p>\n","protected":false},"author":1,"featured_media":162207,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"jetpack_post_was_ever_published":false,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":""},"categories":[281,276,277,299,264],"tags":[],"class_list":["post-162190","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-esp32-project","category-esp32","category-esp32-arduino-ide","category-0-esp32","category-project"],"aioseo_notices":[],"jetpack_featured_media_url":"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/09\/ESP32-Cheap-Yellow-Display-CYD-Board-BME280-Table-Readings-LVGL-Arduino.jpg?fit=1920%2C1080&quality=100&strip=all&ssl=1","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/randomnerdtutorials.com\/wp-json\/wp\/v2\/posts\/162190","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/randomnerdtutorials.com\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/randomnerdtutorials.com\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/randomnerdtutorials.com\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/randomnerdtutorials.com\/wp-json\/wp\/v2\/comments?post=162190"}],"version-history":[{"count":16,"href":"https:\/\/randomnerdtutorials.com\/wp-json\/wp\/v2\/posts\/162190\/revisions"}],"predecessor-version":[{"id":170715,"href":"https:\/\/randomnerdtutorials.com\/wp-json\/wp\/v2\/posts\/162190\/revisions\/170715"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/randomnerdtutorials.com\/wp-json\/wp\/v2\/media\/162207"}],"wp:attachment":[{"href":"https:\/\/randomnerdtutorials.com\/wp-json\/wp\/v2\/media?parent=162190"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/randomnerdtutorials.com\/wp-json\/wp\/v2\/categories?post=162190"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/randomnerdtutorials.com\/wp-json\/wp\/v2\/tags?post=162190"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}