{"id":163170,"date":"2024-11-14T12:26:18","date_gmt":"2024-11-14T12:26:18","guid":{"rendered":"https:\/\/randomnerdtutorials.com\/?p=163170"},"modified":"2024-11-14T12:26:21","modified_gmt":"2024-11-14T12:26:21","slug":"esp32-tft-lvgl-gps-data","status":"publish","type":"post","link":"https:\/\/randomnerdtutorials.com\/esp32-tft-lvgl-gps-data\/","title":{"rendered":"ESP32 TFT with LVGL: Display GPS Location, Date, and Time"},"content":{"rendered":"\n<p>In this guide, you\u2019ll learn how to turn your ESP32 and a TFT display into a GPS reader that displays the current location, altitude, speed, date, and time using LVGL (Light Versatile Graphics Library). We&#8217;ll use the NEO-6M GPS Module to get the GPS data and the ESP32 chip 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\/10\/ESP32-TFT-Display-GPS-Data-LVGL-Location-Date-Time.jpg?resize=1200%2C675&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"ESP32 TFT Display with LVGL Display GPS Location Date and Time Arduino IDE\" class=\"wp-image-163090\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/10\/ESP32-TFT-Display-GPS-Data-LVGL-Location-Date-Time.jpg?w=1920&amp;quality=100&amp;strip=all&amp;ssl=1 1920w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/10\/ESP32-TFT-Display-GPS-Data-LVGL-Location-Date-Time.jpg?resize=300%2C169&amp;quality=100&amp;strip=all&amp;ssl=1 300w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/10\/ESP32-TFT-Display-GPS-Data-LVGL-Location-Date-Time.jpg?resize=1024%2C576&amp;quality=100&amp;strip=all&amp;ssl=1 1024w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/10\/ESP32-TFT-Display-GPS-Data-LVGL-Location-Date-Time.jpg?resize=768%2C432&amp;quality=100&amp;strip=all&amp;ssl=1 768w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/10\/ESP32-TFT-Display-GPS-Data-LVGL-Location-Date-Time.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\">Are you using a CYD board? <a href=\"https:\/\/randomnerdtutorials.com\/esp32-cyd-lvgl-gps-location\/\">Read this guide: ESP32 CYD with LVGL: Display GPS Location, Date, and Time<\/a><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Project Overview<\/h2>\n\n\n\n<p>We\u2019ll display the current GPS data (latitude and longitude), altitude, speed, time and date on a 2.8-inch ILI9341 TFT LCD Touchscreen (240&#215;320). We&#8217;ll be using the NEO-6M GPS Module (<a href=\"https:\/\/randomnerdtutorials.com\/esp32-neo-6m-gps-module-arduino\/\">read our NEO-6M getting started guide<\/a>).<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full is-resized\"><img data-recalc-dims=\"1\" decoding=\"async\" width=\"900\" height=\"514\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/10\/ESP32-TFT-LVGL-Display-GPS-Location-Date-Time-Demonstration-Screen.png?resize=900%2C514&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"ESP32 TFT LVGL Display GPS Location Date Time Demonstration Screen\" class=\"wp-image-163074\" style=\"width:613px;height:auto\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/10\/ESP32-TFT-LVGL-Display-GPS-Location-Date-Time-Demonstration-Screen.png?w=900&amp;quality=100&amp;strip=all&amp;ssl=1 900w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/10\/ESP32-TFT-LVGL-Display-GPS-Location-Date-Time-Demonstration-Screen.png?resize=300%2C171&amp;quality=100&amp;strip=all&amp;ssl=1 300w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/10\/ESP32-TFT-LVGL-Display-GPS-Location-Date-Time-Demonstration-Screen.png?resize=768%2C439&amp;quality=100&amp;strip=all&amp;ssl=1 768w\" sizes=\"(max-width: 900px) 100vw, 900px\" \/><\/figure><\/div>\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<\/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\/2-8-inch-ili9341-tft-240x320\/\" target=\"_blank\" rel=\"noreferrer noopener\">TFT LCD Touchscreen Display \u2013 2.8 inch ILI9341 240\u00d7320<\/a><\/li>\n\n\n\n<li>ESP32 board with enough pins to wire the display (for example an <a href=\"https:\/\/makeradvisor.com\/tools\/esp32-dev-board-wi-fi-bluetooth\/\" target=\"_blank\" rel=\"noopener\" title=\"\">ESP32 DOIT V1 board<\/a>)<\/li>\n\n\n\n<li><a href=\"https:\/\/makeradvisor.com\/tools\/neo-6m-gps-module\/\" target=\"_blank\" rel=\"noopener\" title=\"\">NEO-6M GPS Module<\/a> (with external antenna)<\/li>\n\n\n\n<li><a href=\"https:\/\/makeradvisor.com\/tools\/mb-102-solderless-breadboard-830-points\/\" target=\"_blank\" rel=\"noopener\" title=\"\">Breadboard<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/makeradvisor.com\/tools\/jumper-wires-kit-120-pieces\/\" target=\"_blank\" rel=\"noopener\" title=\"\">Jumper wires<\/a><\/li>\n<\/ul>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img data-recalc-dims=\"1\" decoding=\"async\" width=\"750\" height=\"422\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/10\/ESP32-TFT-LVGL-Display-GPS-Location-Date-Time-Parts-Required-1.jpg?resize=750%2C422&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"ESP32 TFT LVGL Display GPS Location Date Time Parts Required\" class=\"wp-image-163079\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/10\/ESP32-TFT-LVGL-Display-GPS-Location-Date-Time-Parts-Required-1.jpg?w=750&amp;quality=100&amp;strip=all&amp;ssl=1 750w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/10\/ESP32-TFT-LVGL-Display-GPS-Location-Date-Time-Parts-Required-1.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<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 ILI9341 TFT LCD Touchscreen Display<\/h3>\n\n\n\n<p>The display we\u2019re using in this guide is the 2.8. inch TFT LCD that also comes with a touchscreen. The display communicates via SPI communication protocol and uses the ILI9341 driver. The touchscreen also uses the SPI communication protocol.<\/p>\n\n\n\n<p>The TFT LCD touchscreen also comes with an SD card interface if you need to load files for your specific project. This display is also available with different screen sizes, but we&#8217;ll use the one with 240 x 320 pixels).<\/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\/TFT-LCD-Touchscreen-display.jpg?resize=750%2C421&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"ILI9341 TFT LCD Touchscreen Display\" class=\"wp-image-150003\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/03\/TFT-LCD-Touchscreen-display.jpg?w=750&amp;quality=100&amp;strip=all&amp;ssl=1 750w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/03\/TFT-LCD-Touchscreen-display.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 this display, make sure to follow our getting started guide:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong><a href=\"https:\/\/randomnerdtutorials.com\/lvgl-esp32-tft-touchscreen-display-ili9341-arduino\/\" title=\"\">ESP32 with LVGL: TFT LCD Touchscreen Display \u2013 2.8 inch ILI9341 240\u00d7320 (Arduino IDE)<\/a><\/strong><\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">4) Wire the Display to the ESP32<\/h3>\n\n\n\n<p>Wire the TFT LCD and touchscreen pins to the ESP32 GPIOs according to the next table (you must use these exact pins, otherwise the project will not work).<\/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\/03\/ESP32-TFT-Display-Screen-Wiring.jpg?resize=750%2C422&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"Wiring TFT LCD Touchscreen display to ESP32\" class=\"wp-image-150007\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/03\/ESP32-TFT-Display-Screen-Wiring.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-TFT-Display-Screen-Wiring.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<figure class=\"wp-block-table\"><table><tbody><tr><td><strong>TFT LCD Touchscreen<\/strong><\/td><td><strong>ESP32<\/strong><\/td><\/tr><tr><td>T_IRQ<\/td><td>GPIO 36<\/td><\/tr><tr><td>T_OUT<\/td><td>GPIO 39<\/td><\/tr><tr><td>T_DIN<\/td><td>GPIO 32<\/td><\/tr><tr><td>T_CS<\/td><td>GPIO 33<\/td><\/tr><tr><td>T_CLK<\/td><td>GPIO 25<\/td><\/tr><tr><td>SDO(MISO)<\/td><td>GPIO 12<\/td><\/tr><tr><td>LED<\/td><td>GPIO 21<\/td><\/tr><tr><td>SCK<\/td><td>GPIO 14<\/td><\/tr><tr><td>SDI(MOSI)<\/td><td>GPIO 13<\/td><\/tr><tr><td>D\/C<\/td><td>GPIO 2<\/td><\/tr><tr><td>RESET<\/td><td>EN\/RESET<\/td><\/tr><tr><td>CS<\/td><td>GPIO 15<\/td><\/tr><tr><td>GND<\/td><td>GND<\/td><\/tr><tr><td>VCC<\/td><td>5V (or 3.3V)*<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p>* In the VCC pin, you can either use 5V or 3.3V depending if your <strong>J1<\/strong> connection is open or closed (by default it&#8217;s usually open as you can see in the figure below).<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>VCC = 5V | J1=OPEN\nVCC = 3.3V | J1=CLOSE<\/code><\/pre>\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\/03\/TFT-LCD-touchscreen-J1-connection.jpg?resize=750%2C422&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"TFT LCD Touchscreen display J1 connection\" class=\"wp-image-150009\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/03\/TFT-LCD-touchscreen-J1-connection.jpg?w=750&amp;quality=100&amp;strip=all&amp;ssl=1 750w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/03\/TFT-LCD-touchscreen-J1-connection.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<h3 class=\"wp-block-heading\">5) Wiring the NEO-6M GPS Module<\/h3>\n\n\n\n<p>The NEO-6M GPS module is a GPS receiver compatible with most microcontroller boards. It can get data about location, speed, altitude, and time. We\u2019ll connect the NEO-6M GPS Module to the ESP32 board.<\/p>\n\n\n\n<p>You can use the following table as a reference.<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table><tbody><tr><td><strong>NEO-6M GPS Module<\/strong><\/td><td><strong>ESP32<\/strong><\/td><\/tr><tr><td>VCC<\/td><td><span class=\"rnthl rntcred\">3V3<\/span><\/td><\/tr><tr><td>RX<\/td><td><span class=\"rnthl rntcyellow\">GPIO 27<\/span><\/td><\/tr><tr><td>TX<\/td><td><span class=\"rnthl rntcblue\">GPIO 22<\/span><\/td><\/tr><tr><td>GND<\/td><td><span class=\"rnthl rntcblack\">GND<\/span><\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p>You also need to connect an external antenna to the GPS module. The figure below shows two different options of antennas for GPS modules.<\/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\/07\/antennas-for-GPS-Modules.jpg?resize=750%2C422&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"antennas for GPS modules\" class=\"wp-image-160852\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/07\/antennas-for-GPS-Modules.jpg?w=750&amp;quality=100&amp;strip=all&amp;ssl=1 750w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/07\/antennas-for-GPS-Modules.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<h3 class=\"wp-block-heading\">6) 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 with the 2.8 inch ILI9341 240\u00d7320 TFT LCD Touchscreen using Arduino IDE.<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><a href=\"https:\/\/randomnerdtutorials.com\/lvgl-esp32-tft-touchscreen-display-ili9341-arduino\/\" title=\"\"><strong>LVGL with ESP32 TFT LCD Touchscreen Display \u2013 2.8 inch ILI9341 240\u00d7320 (Arduino IDE)<\/strong><\/a><\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">7) Install TinyGPSPlus Library<\/h3>\n\n\n\n<p>For this project, you need to install the TinyGPSPlus library to prepare the GPS data.<\/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>TinyGPSPlus<\/strong> and install the library by <em>Mikal Hart<\/em>. We\u2019re using version 1.0.3 and 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=\"321\" height=\"405\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/10\/Installing-TinyGPSPlus-Library-Arduino-IDE.png?resize=321%2C405&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"Installing TinyGPSPlus Library Arduino IDE\" class=\"wp-image-163082\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/10\/Installing-TinyGPSPlus-Library-Arduino-IDE.png?w=321&amp;quality=100&amp;strip=all&amp;ssl=1 321w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/10\/Installing-TinyGPSPlus-Library-Arduino-IDE.png?resize=238%2C300&amp;quality=100&amp;strip=all&amp;ssl=1 238w\" sizes=\"(max-width: 321px) 100vw, 321px\" \/><\/figure><\/div>\n\n\n<h2 class=\"wp-block-heading\">ESP32 TFT GPS Data &#8211; <em>gps_image.h<\/em> file<\/h2>\n\n\n\n<p>To load custom images using LVGL, you need to create an extra file called <em>gps_image.h<\/em> that must be placed inside the sketch folder. We already prepared that file for you. To load the custom image for this GPS reader, you need to download the next file.<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong><a href=\"https:\/\/github.com\/RuiSantosdotme\/ESP32-TFT-Touchscreen\/raw\/refs\/heads\/main\/examples\/ESP32_LVGL_GPS_Location\/gps_image.zip\" target=\"_blank\" rel=\"noopener\" title=\"\">Click here to download the <em>gps_image.h<\/em> file<\/a><\/strong><\/li>\n<\/ul>\n\n\n\n<p><strong>Important:<\/strong> the <em>gps_image.h<\/em> file should be placed next to the <em>.ino<\/em> file in the sketch folder of your project.<\/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=\"297\" height=\"229\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/10\/LVGL-Load-Image-Arduino-Code-example-folder-GPS-image-file.png?resize=297%2C229&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"LVGL Load Image Arduino Code example folder GPS image file\" class=\"wp-image-163080\"\/><\/figure><\/div>\n\n\n<p>Your Arduino IDE should have two tabs:<\/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=\"441\" height=\"134\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/10\/Arduino-IDE-tabs-LVGL-Load-Image-Arduino-Code-example-folder-GPS-image-file.png?resize=441%2C134&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"Arduino IDE tabs LVGL Load Image Arduino Code example folder GPS image file\" class=\"wp-image-163081\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/10\/Arduino-IDE-tabs-LVGL-Load-Image-Arduino-Code-example-folder-GPS-image-file.png?w=441&amp;quality=100&amp;strip=all&amp;ssl=1 441w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/10\/Arduino-IDE-tabs-LVGL-Load-Image-Arduino-Code-example-folder-GPS-image-file.png?resize=300%2C91&amp;quality=100&amp;strip=all&amp;ssl=1 300w\" sizes=\"(max-width: 441px) 100vw, 441px\" \/><\/figure><\/div>\n\n\n<p>If you want to learn more about loading images using LVGL, we recommend reading our <a href=\"https:\/\/randomnerdtutorials.com\/esp32-tft-display-image-lvgl-arduino\/\">Guide ESP32 with TFT: Display Image using LVGL \u2013 2.8 inch ILI9341 240\u00d7320 (Arduino)<\/a><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">ESP32 TFT GPS Data &#8211; Arduino Code<\/h2>\n\n\n\n<p>The following code will create some text labels with the GPS data, altitude, speed, time, and date. It will also load an image to illustrate the project application.<\/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-gps-location\/  |  https:\/\/RandomNerdTutorials.com\/esp32-tft-lvgl-gps-data\/\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#include &lt;TinyGPS++.h&gt;\n\n#include &quot;gps_image.h&quot;\n\n\/\/ Define the RX and TX pins for Serial 2\n#define RXD2 22\n#define TXD2 27\n\n#define GPS_BAUD 9600\n\n\/\/ The TinyGPS++ object\nTinyGPSPlus gps;\n\n\/\/ Create an instance of the HardwareSerial class for Serial 2\nHardwareSerial gpsSerial(2);\n\n#define SCREEN_WIDTH 240\n#define SCREEN_HEIGHT 320\n\n#define DRAW_BUF_SIZE (SCREEN_WIDTH * SCREEN_HEIGHT \/ 10 * (LV_COLOR_DEPTH \/ 8))\nuint32_t draw_buf[DRAW_BUF_SIZE \/ 4];\n\nString current_date;\nString utc_time;\nString latitude;\nString longitude;\nString altitude;\nString speed;\nString hdop;\nString satellites;\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\nString format_time(int time) {\n  return (time &lt; 10) ? &quot;0&quot; + String(time) : String(time);\n}\n\nstatic lv_obj_t * text_label_date;\nstatic lv_obj_t * text_label_latitude;\nstatic lv_obj_t * text_label_longitude;\nstatic lv_obj_t * text_label_altitude;\nstatic lv_obj_t * text_label_speed;\nstatic lv_obj_t * text_label_utc_time;\nstatic lv_obj_t * text_label_hdop_satellites;\nstatic lv_obj_t * text_label_gps_data;\n\nstatic void timer_cb(lv_timer_t * timer){\n  LV_UNUSED(timer);\n  lv_label_set_text(text_label_date, current_date.c_str());\n  lv_label_set_text(text_label_hdop_satellites, String(&quot;HDOP &quot; + hdop + &quot;  SAT. &quot; + satellites).c_str());\n  lv_label_set_text(text_label_gps_data, String(&quot;LAT   &quot; + latitude + &quot;\\nLON   &quot; + longitude + &quot;\\nALT   &quot; \n                                                + altitude + &quot;m&quot; + &quot;\\nSPEED   &quot; + speed + &quot;km\/h&quot;).c_str());\n  lv_label_set_text(text_label_utc_time, String(&quot;UTC TIME - &quot; + utc_time).c_str());\n}\n\nvoid lv_create_main_gui(void) {\n  LV_IMAGE_DECLARE(image_gpsmap);\n\n  lv_obj_t * img_gpsmap = lv_image_create(lv_screen_active());\n  lv_obj_align(img_gpsmap, LV_ALIGN_LEFT_MID, 10, -20);\n  lv_image_set_src(img_gpsmap, &amp;image_gpsmap);\n\n  text_label_hdop_satellites = lv_label_create(lv_screen_active());\n  lv_label_set_text(text_label_hdop_satellites, String(&quot;HDOP &quot; + hdop + &quot;  SAT. &quot; + satellites).c_str());\n  lv_obj_align(text_label_hdop_satellites, LV_ALIGN_BOTTOM_LEFT, 30, -50);\n  lv_obj_set_style_text_font((lv_obj_t*) text_label_hdop_satellites, &amp;lv_font_montserrat_12, 0);\n  lv_obj_set_style_text_color((lv_obj_t*) text_label_hdop_satellites, lv_palette_main(LV_PALETTE_GREY), 0);\n\n  text_label_date = lv_label_create(lv_screen_active());\n  lv_label_set_text(text_label_date, current_date.c_str());\n  lv_obj_align(text_label_date, LV_ALIGN_CENTER, 60, -80);\n  lv_obj_set_style_text_font((lv_obj_t*) text_label_date, &amp;lv_font_montserrat_26, 0);\n  lv_obj_set_style_text_color((lv_obj_t*) text_label_date, lv_palette_main(LV_PALETTE_TEAL), 0);\n\n  lv_obj_t * text_label_location = lv_label_create(lv_screen_active());\n  lv_label_set_text(text_label_location, &quot;LOCATION&quot;);\n  lv_obj_align(text_label_location, LV_ALIGN_CENTER, 50, -40);\n  lv_obj_set_style_text_font((lv_obj_t*) text_label_location, &amp;lv_font_montserrat_20, 0);\n  \n  text_label_gps_data = lv_label_create(lv_screen_active());\n  lv_label_set_text(text_label_gps_data, String(&quot;LAT   &quot; + latitude + &quot;\\nLON   &quot; + longitude + &quot;\\nALT   &quot; \n                                                 + altitude + &quot;m&quot; + &quot;\\nSPEED   &quot; + speed + &quot;km\/h&quot;).c_str());\n  lv_obj_align(text_label_gps_data, LV_ALIGN_CENTER, 60, 20);\n  lv_obj_set_style_text_font((lv_obj_t*) text_label_gps_data, &amp;lv_font_montserrat_14, 0);\n\n  text_label_utc_time = lv_label_create(lv_screen_active());\n  lv_label_set_text(text_label_utc_time, String(&quot;UTC TIME - &quot; + utc_time).c_str());\n  lv_obj_align(text_label_utc_time, LV_ALIGN_BOTTOM_MID, 0, -10);\n  lv_obj_set_style_text_font((lv_obj_t*) text_label_utc_time, &amp;lv_font_montserrat_20, 0);\n  lv_obj_set_style_text_color((lv_obj_t*) text_label_utc_time, lv_palette_main(LV_PALETTE_TEAL), 0);\n \n  lv_timer_t * timer = lv_timer_create(timer_cb, 1, NULL);\n  lv_timer_ready(timer);\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  \/\/ Start Serial 2 with the defined RX and TX pins and a baud rate of 9600\n  gpsSerial.begin(GPS_BAUD, SERIAL_8N1, RXD2, TXD2);\n  Serial.println(&quot;Serial 2 started at 9600 baud rate&quot;);\n\n  \/\/ Start LVGL\n  lv_init();\n  \/\/ Register print function for debugging\n  lv_log_register_print_cb(log_print);\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  \/\/ 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  \/\/ This sketch displays information every time a new sentence is correctly encoded.\n  unsigned long start = millis();\n\n  while (millis() - start &lt; 1000) {\n    while (gpsSerial.available() &gt; 0) {\n      gps.encode(gpsSerial.read());\n    }\n    if (gps.location.isUpdated()) {\n      Serial.print(&quot;LAT: &quot;);\n      latitude = String(gps.location.lat(), 6);\n      Serial.println(latitude);\n      Serial.print(&quot;LONG: &quot;); \n      longitude = String(gps.location.lng(), 6);\n      Serial.println(longitude);\n      Serial.print(&quot;SPEED (km\/h) = &quot;); \n      speed = String(gps.speed.kmph(), 2);\n      Serial.println(speed);\n      Serial.print(&quot;ALT (min)= &quot;); \n      altitude = String(gps.altitude.meters(), 2);\n      Serial.println(altitude);\n      Serial.print(&quot;HDOP = &quot;); \n      hdop = String(gps.hdop.value() \/ 100.0, 2);\n      Serial.println(hdop);\n      Serial.print(&quot;Satellites = &quot;); \n      satellites = String(gps.satellites.value());\n      Serial.println(satellites);\n      Serial.print(&quot;Time in UTC: &quot;);\n      Serial.println(String(gps.date.year()) + &quot;-&quot; + String(gps.date.month()) + &quot;-&quot; + String(gps.date.day()) + &quot;,&quot; + String(gps.time.hour()) + &quot;:&quot; + String(gps.time.minute()) + &quot;:&quot; + String(gps.time.second()));\n      current_date = String(gps.date.year()) + &quot;-&quot; + String(gps.date.month()) + &quot;-&quot; + String(gps.date.day());\n      Serial.println(current_date);\n      utc_time = String(format_time(gps.time.hour())) + &quot;:&quot; + String(format_time(gps.time.minute())) + &quot;:&quot; + String(format_time(gps.time.second()));\n      Serial.println(utc_time);\n      Serial.println(&quot;&quot;);\n    }\n  }\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_GPS_Location\/ESP32_LVGL_GPS_Location.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 take a look at how to get GPS location and update the screen with the current values. 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 and Images<\/h3>\n\n\n\n<p>You need to include the <span class=\"rnthl rntliteral\">lvgl.h<\/span> and the <span class=\"rnthl rntliteral\">TFT_eSPI.h<\/span> libraries to draw the GUI 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;<\/code><\/pre>\n\n\n\n<p>You need to include the <span class=\"rnthl rntliteral\">TinyGPS++.h<\/span> library to handle the GPS data.<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>#include &lt;TinyGPS++.h&gt;<\/code><\/pre>\n\n\n\n<p>Include the <span class=\"rnthl rntliteral\">gps_image.h<\/span> file that contains all the data to draw the map image.<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>#include \"gps_image.h\"<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">GPS Serial<\/h3>\n\n\n\n<p>This sketch uses <span class=\"rnthl rntcblue\">GPIO 22<\/span> and <span class=\"rnthl rntcyellow\">GPIO 27<\/span> as RX and TX serial pins to establish serial communication with the GPS module.<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>\/\/ Define the RX and TX pins for Serial 2\n#define RXD2   22\n#define TXD2    27<\/code><\/pre>\n\n\n\n<p>Also, if your module uses a different default baud rate than 9600 bps, you should modify the code on the following line:<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>#define GPS_BAUD 9600<\/code><\/pre>\n\n\n\n<p>Then, we create an instance of the <span class=\"rnthl rntliteral\">HardwareSerial<\/span> to use UART 2 called <span class=\"rnthl rntliteral\">gpsSerial<\/span>.<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>\/\/ Create an instance of the HardwareSerial class for Serial 2\nHardwareSerial gpsSerial(2);<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">Declaring Other Variables<\/h3>\n\n\n\n<p>Create some auxiliary variables to hold the GPS data and other values.<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>String current_date;\nString utc_time;\nString latitude;\nString longitude;\nString altitude;\nString speed;\nString hdop;\nString satellites;<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">Global LVGL Objects<\/h3>\n\n\n\n<p>We create some global LVGL objects, so that we can access them inside all functions later on.<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>static lv_obj_t * text_label_date;\nstatic lv_obj_t * text_label_latitude;\nstatic lv_obj_t * text_label_longitude;\nstatic lv_obj_t * text_label_altitude;\nstatic lv_obj_t * text_label_speed;\nstatic lv_obj_t * text_label_utc_time;\nstatic lv_obj_t * text_label_hdop_satellites;\nstatic lv_obj_t * text_label_gps_data;<\/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\">Start GPS Serial<\/h4>\n\n\n\n<p>To connect the ESP32 board to the GPS module via serial, we use the following code.<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>gpsSerial.begin(GPS_BAUD, SERIAL_8N1, RXD2, TXD2);\nSerial.println(\"Serial 2 started at 9600 baud rate\");<\/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\">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\">Preparing the GUI<\/h3>\n\n\n\n<p>Before drawing the main GUI, we start by declaring an image that will be displayed in the TFT screen.<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>void lv_create_main_gui(void) {\n  LV_IMAGE_DECLARE(image_gpsmap);\n(...)<\/code><\/pre>\n\n\n\n<h4 class=\"wp-block-heading\">Load the GPS image<\/h4>\n\n\n\n<p>We create an image and set it to the left side of the display.<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>lv_obj_t * img_gpsmap = lv_image_create(lv_screen_active());\nlv_obj_align(img_gpsmap, LV_ALIGN_LEFT_MID, 10, -20);\nlv_image_set_src(img_gpsmap, &amp;image_gpsmap);<\/code><\/pre>\n\n\n\n<h4 class=\"wp-block-heading\">Text Labels<\/h4>\n\n\n\n<p>To create a text label, we can call the LVGL function <span class=\"rnthl rntliteral\">lv_label_create()<\/span> and pass as argument where we want to display the text. We want to add it to the current screen (<span class=\"rnthl rntliteral\">lv_screen_active()<\/span>). The following line is creating a text label to display the HDOP and the number of satellites.<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>text_label_hdop_satellites = lv_label_create(lv_screen_active());<\/code><\/pre>\n\n\n\n<p>After creating the text label, we can set its text by using the <span class=\"rnthl rntliteral\">lv_label_set_text()<\/span> function that accepts as arguments the text label we\u2019re referring to and the text we want to add to that label. In our case, we\u2019re setting this label to the current HDOP and visible satellites.<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>lv_label_set_text(text_label_hdop_satellites, String(\"HDOP \" + hdop + \"  SAT. \" + satellites).c_str());<\/code><\/pre>\n\n\n\n<p>The following lines align the text label. You can use the <span class=\"rnthl rntliteral\">lv_obj_align()<\/span> function. Pass as arguments, the LVGL object, the alignment and x and y offsets in pixels.<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>lv_obj_align(text_label_hdop_satellites, LV_ALIGN_BOTTOM_LEFT, 30, -50);<\/code><\/pre>\n\n\n\n<p>Then, we can set the font type and size using the <span class=\"rnthl rntliteral\">lv_style_set_text_font()<\/span> function. We pass as argument the object we\u2019re referring to and the font type.<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>lv_obj_set_style_text_font((lv_obj_t*) text_label_hdop_satellites, &amp;lv_font_montserrat_12, 0);<\/code><\/pre>\n\n\n\n<p>For the <span class=\"rnthl rntliteral\">text_label_date<\/span> we&#8217;re also setting a custom text grey color:<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>lv_obj_set_style_text_color((lv_obj_t*) text_label_hdop_satellites, lv_palette_main(LV_PALETTE_GREY), 0);<\/code><\/pre>\n\n\n\n<p>A similar procedure is applied to all other labels (date, location, GPS data, and UTC time), but we put them on different places and set different font sizes and colors<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>text_label_date = lv_label_create(lv_screen_active());\nlv_label_set_text(text_label_date, current_date.c_str());\nlv_obj_align(text_label_date, LV_ALIGN_CENTER, 60, -80);\nlv_obj_set_style_text_font((lv_obj_t*) text_label_date, &amp;lv_font_montserrat_26, 0);\nlv_obj_set_style_text_color((lv_obj_t*) text_label_date, lv_palette_main(LV_PALETTE_TEAL), 0);\n\nlv_obj_t * text_label_location = lv_label_create(lv_screen_active());\nlv_label_set_text(text_label_location, \"LOCATION\");\nlv_obj_align(text_label_location, LV_ALIGN_CENTER, 50, -40);\nlv_obj_set_style_text_font((lv_obj_t*) text_label_location, &amp;lv_font_montserrat_20, 0);\n  \ntext_label_gps_data = lv_label_create(lv_screen_active());\nlv_label_set_text(text_label_gps_data, String(\"LAT   \" + latitude + \"\\nLON   \" + longitude + \"\\nALT   \" + altitude + \"m\" + \"\\nSPEED   \" + speed + \"km\/h\").c_str());\nlv_obj_align(text_label_gps_data, LV_ALIGN_CENTER, 60, 20);\nlv_obj_set_style_text_font((lv_obj_t*) text_label_gps_data, &amp;lv_font_montserrat_14, 0);\n\ntext_label_utc_time = lv_label_create(lv_screen_active());\nlv_label_set_text(text_label_utc_time, String(\"UTC TIME - \" + utc_time).c_str());\nlv_obj_align(text_label_utc_time, LV_ALIGN_BOTTOM_MID, 0, -10);\nlv_obj_set_style_text_font((lv_obj_t*) text_label_utc_time, &amp;lv_font_montserrat_20, 0);\nlv_obj_set_style_text_color((lv_obj_t*) text_label_utc_time, lv_palette_main(LV_PALETTE_TEAL), 0);<\/code><\/pre>\n\n\n\n<h4 class=\"wp-block-heading\">Timer<\/h4>\n\n\n\n<p>To update the data on the screen, we can create an LVGL timer that will run a specific function periodically. In this case, we\u2019ll update it every second. Create an LVGL timer called <span class=\"rnthl rntliteral\">timer<\/span> and assign the <span class=\"rnthl rntliteral\">timer_cb<\/span> callback function.<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>lv_timer_t * timer = lv_timer_create(timer_cb, 1, NULL);\nlv_timer_ready(timer);<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">Timer Callback Function<\/h3>\n\n\n\n<p>The <span class=\"rnthl rntliteral\">timer_cb<\/span> function runs every second. Each time the callback function runs, we get the latest GPS data from the NEO-6M module and update the GUI.<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>static void timer_cb(lv_timer_t * timer){\n  LV_UNUSED(timer);\n  \n(...)<\/code><\/pre>\n\n\n\n<p>Finally, we set all the text labels to the current data returned from the GPS module:<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>lv_label_set_text(text_label_date, current_date.c_str());\nlv_label_set_text(text_label_hdop_satellites, String(\"HDOP \" + hdop + \"  SAT. \" + satellites).c_str());\nlv_label_set_text(text_label_gps_data, String(\"LAT   \" + latitude + \"\\nLON   \" + longitude + \"\\nALT   \"  + altitude + \"m\" + \"\\nSPEED   \" + speed + \"km\/h\").c_str());\nlv_label_set_text(text_label_utc_time, String(\"UTC TIME - \" + utc_time).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. In our case, we&#8217;ll be requesting the latest GPS data from the NEO-6M module every second and update the auxiliary variables.<\/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<p>The next code listens to the GPS serial port, and when data is received from the module, it is printed in the serial monitor and stored in the auxiliary variables.<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>\/\/ This sketch displays information every time a new sentence is correctly encoded.\nunsigned long start = millis();\n\nwhile (millis() - start &lt; 1000) {\n  while (gpsSerial.available() &gt; 0) {\n    gps.encode(gpsSerial.read());\n  }\n  if (gps.location.isUpdated()) {\n    Serial.print(\"LAT: \");\n    latitude = String(gps.location.lat(), 6);\n    Serial.println(latitude);\n    Serial.print(\"LONG: \"); \n    longitude = String(gps.location.lng(), 6);\n    Serial.println(longitude);\n    Serial.print(\"SPEED (km\/h) = \"); \n    speed = String(gps.speed.kmph(), 2);\n    Serial.println(speed);\n    Serial.print(\"ALT (min)= \"); \n    altitude = String(gps.altitude.meters(), 2);\n    Serial.println(altitude);\n    Serial.print(\"HDOP = \"); \n    hdop = String(gps.hdop.value() \/ 100.0, 2);\n    Serial.println(hdop);\n    Serial.print(\"Satellites = \"); \n    satellites = String(gps.satellites.value());\n    Serial.println(satellites);\n    Serial.print(\"Time in UTC: \");\n    Serial.println(String(gps.date.year()) + \"-\" + String(gps.date.month()) + \"-\" + String(gps.date.day()) + \",\" + String(gps.time.hour()) + \":\" + String(gps.time.minute()) + \":\" + String(gps.time.second()));\n    current_date = String(gps.date.year()) + \"-\" + String(gps.date.month()) + \"-\" + String(gps.date.day());\n    Serial.println(current_date);\n    utc_time = String(format_time(gps.time.hour())) + \":\" + String(format_time(gps.time.minute())) + \":\" + String(format_time(gps.time.second()));\n    Serial.println(utc_time);\n    Serial.println(\"\");\n  }\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>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>Open the Serial Monitor at a baud rate of 115200. Make sure your GPS module is placed outside or next to a window to get data from satellites. It may take some time. When the GPS module&#8217;s blue LED starts blinking, it means it&#8217;s ready.<\/p>\n\n\n\n<p>You\u2019ll get GPS data on the Serial Monitor about your current location, speed, altitude, number of visible satellites HDOP, date, and time.<\/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=\"627\" height=\"250\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/10\/ESP32-Display-GPS-Data-Arduino-IDE-Serial-Monitor-Demonstration.png?resize=627%2C250&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"ESP32 Display GPS Data Arduino IDE Serial Monitor Demonstration\" class=\"wp-image-163086\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/10\/ESP32-Display-GPS-Data-Arduino-IDE-Serial-Monitor-Demonstration.png?w=627&amp;quality=100&amp;strip=all&amp;ssl=1 627w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/10\/ESP32-Display-GPS-Data-Arduino-IDE-Serial-Monitor-Demonstration.png?resize=300%2C120&amp;quality=100&amp;strip=all&amp;ssl=1 300w\" sizes=\"(max-width: 627px) 100vw, 627px\" \/><\/figure><\/div>\n\n\n<p>You might need to wait a couple of minutes for the GPS module to establish a connection with enough satellites to get the GPS data. The info will be displayed 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=\"422\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/10\/ESP32-TFT-LVGL-Display-GPS-Location-Date-Time-Demonstration-1.jpg?resize=750%2C422&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"ESP32 TFT LVGL Display GPS Location Date Time Demonstration\" class=\"wp-image-163078\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/10\/ESP32-TFT-LVGL-Display-GPS-Location-Date-Time-Demonstration-1.jpg?w=750&amp;quality=100&amp;strip=all&amp;ssl=1 750w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/10\/ESP32-TFT-LVGL-Display-GPS-Location-Date-Time-Demonstration-1.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<h2 class=\"wp-block-heading\">Wrapping Up<\/h2>\n\n\n\n<p>In this project, you&#8217;ve learned how to build a simple GPS reader with a TFT LCD Touchscreen with the ESP32 using the LVGL library. It displays the current location, altitude, speed, date, and time.<\/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\/esp32-tft-lvgl-weather-station\/\">ESP32 TFT with LVGL: Weather Station (Description, Temperature, Humidity)<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/randomnerdtutorials.com\/esp32-tft-lvgl-digital-clock\/\">ESP32 TFT with LVGL: Digital Clock with Time and Date<\/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 turn your ESP32 and a TFT display into a GPS reader that displays the current location, altitude, speed, date, and time using LVGL &#8230; <\/p>\n<p class=\"read-more-container\"><a title=\"ESP32 TFT with LVGL: Display GPS Location, Date, and Time\" class=\"read-more button\" href=\"https:\/\/randomnerdtutorials.com\/esp32-tft-lvgl-gps-data\/#more-163170\" aria-label=\"Read more about ESP32 TFT with LVGL: Display GPS Location, Date, and Time\">CONTINUE READING \u00bb<\/a><\/p>\n","protected":false},"author":1,"featured_media":163090,"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-163170","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\/10\/ESP32-TFT-Display-GPS-Data-LVGL-Location-Date-Time.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\/163170","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=163170"}],"version-history":[{"count":3,"href":"https:\/\/randomnerdtutorials.com\/wp-json\/wp\/v2\/posts\/163170\/revisions"}],"predecessor-version":[{"id":163945,"href":"https:\/\/randomnerdtutorials.com\/wp-json\/wp\/v2\/posts\/163170\/revisions\/163945"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/randomnerdtutorials.com\/wp-json\/wp\/v2\/media\/163090"}],"wp:attachment":[{"href":"https:\/\/randomnerdtutorials.com\/wp-json\/wp\/v2\/media?parent=163170"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/randomnerdtutorials.com\/wp-json\/wp\/v2\/categories?post=163170"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/randomnerdtutorials.com\/wp-json\/wp\/v2\/tags?post=163170"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}