In this project, you’ll learn how to turn your ESP32 Cheap Yellow Display (CYD) board into a GPS reader that displays the current location, altitude, speed, date, and time using LVGL (Light Versatile Graphics Library). We’ll use the NEO-6M GPS Module to get the GPS data and the ESP32 chip will be programmed using Arduino IDE.
New to the ESP32 Cheap Yellow Display? Start here: Getting Started with ESP32 Cheap Yellow Display Board – CYD (ESP32-2432S028R).
Project Overview
We’ll display the current GPS data (latitude and longitude), altitude, speed, time and date on the ESP32 CYD board. We’ll be using the NEO-6M GPS Module (read our NEO-6M getting started guide).
Prerequisites
Before proceeding, make sure you follow the next prerequisites. You must follow all steps, otherwise, your project will not work.
1) Parts Required
For this project, you need the following parts
- ESP32-2432S028R – 2.8 inch 240×320 Smart Display TFT with Touchscreen
- NEO-6M GPS Module (with external antenna)
2) Wiring the NEO-6M GPS Module
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’ll connect the NEO-6M GPS Module to the CYD CN1 connector.
You can use the following table as a reference.
NEO-6M GPS Module | ESP32 CYD CN1 Connector |
VCC | 3V3 |
RX | GPIO 27 |
TX | GPIO 22 |
GND | GND |
You also need to connect an external antenna to the GPS module. The figure below shows two different options of antennas for GPS modules.
3) Install ESP32 Boards in Arduino IDE
We’ll program the ESP32 using Arduino IDE. Make sure you have the ESP32 boards installed. Follow the next tutorial:
4) Get familiar with the ESP32 Cheap Yellow Display
The ESP32-2432S028R development board has become known in the maker community as the “Cheap Yellow Display” 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.
If this is your first time using the ESP32 Cheap Yellow Display, make sure to follow our getting started guide:
5) Install TFT and LVGL Libraries
LVGL (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).
Follow the next tutorial to install and configure the required libraries to use LVGL with the ESP32 Cheap Yellow Display using Arduino IDE.
6) Install TinyGPSPlus Library
For this project, you need to install the TinyGPSPlus library to prepare the GPS data.
In the Arduino IDE, go to Sketch > Include Library > Manage Libraries. Search for TinyGPSPlus and install the library by Mikal Hart. We’re using version 1.0.3 and we recommend using the same version.
ESP32 CYD GPS Data – gps_image.h file
To load custom images using LVGL, you need to create an extra file called gps_image.h 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.
Important: the gps_image.h file should be placed next to the .ino file in the sketch folder of your project.
Your Arduino IDE should have two tabs:
If you want to learn more about loading images using LVGL, we recommend reading our Guide ESP32 CYD with LVGL: Display Image on the Screen
ESP32 CYD GPS Data – Arduino Code
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.
/* Rui Santos & Sara Santos - Random Nerd Tutorials - https://RandomNerdTutorials.com/esp32-cyd-lvgl-gps-location/ | https://RandomNerdTutorials.com/esp32-tft-lvgl-gps-data/
THIS EXAMPLE WAS TESTED WITH THE FOLLOWING HARDWARE:
1) ESP32-2432S028R 2.8 inch 240Ă—320 also known as the Cheap Yellow Display (CYD): https://makeradvisor.com/tools/cyd-cheap-yellow-display-esp32-2432s028r/
SET UP INSTRUCTIONS: https://RandomNerdTutorials.com/cyd-lvgl/
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/
SET UP INSTRUCTIONS: https://RandomNerdTutorials.com/esp32-tft-lvgl/
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files.
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
*/
/* Install the "lvgl" library version 9.X by kisvegabor to interface with the TFT Display - https://lvgl.io/
*** IMPORTANT: lv_conf.h available on the internet will probably NOT work with the examples available at Random Nerd Tutorials ***
*** YOU MUST USE THE lv_conf.h FILE PROVIDED IN THE LINK BELOW IN ORDER TO USE THE EXAMPLES FROM RANDOM NERD TUTORIALS ***
FULL INSTRUCTIONS AVAILABLE ON HOW CONFIGURE THE LIBRARY: https://RandomNerdTutorials.com/cyd-lvgl/ or https://RandomNerdTutorials.com/esp32-tft-lvgl/ */
#include <lvgl.h>
/* Install the "TFT_eSPI" library by Bodmer to interface with the TFT Display - https://github.com/Bodmer/TFT_eSPI
*** IMPORTANT: User_Setup.h available on the internet will probably NOT work with the examples available at Random Nerd Tutorials ***
*** YOU MUST USE THE User_Setup.h FILE PROVIDED IN THE LINK BELOW IN ORDER TO USE THE EXAMPLES FROM RANDOM NERD TUTORIALS ***
FULL INSTRUCTIONS AVAILABLE ON HOW CONFIGURE THE LIBRARY: https://RandomNerdTutorials.com/cyd-lvgl/ or https://RandomNerdTutorials.com/esp32-tft-lvgl/ */
#include <TFT_eSPI.h>
#include <TinyGPS++.h>
#include "gps_image.h"
// Define the RX and TX pins for Serial 2
#define RXD2 22
#define TXD2 27
#define GPS_BAUD 9600
// The TinyGPS++ object
TinyGPSPlus gps;
// Create an instance of the HardwareSerial class for Serial 2
HardwareSerial gpsSerial(2);
#define SCREEN_WIDTH 240
#define SCREEN_HEIGHT 320
#define DRAW_BUF_SIZE (SCREEN_WIDTH * SCREEN_HEIGHT / 10 * (LV_COLOR_DEPTH / 8))
uint32_t draw_buf[DRAW_BUF_SIZE / 4];
String current_date;
String utc_time;
String latitude;
String longitude;
String altitude;
String speed;
String hdop;
String satellites;
// If logging is enabled, it will inform the user about what is happening in the library
void log_print(lv_log_level_t level, const char * buf) {
LV_UNUSED(level);
Serial.println(buf);
Serial.flush();
}
String format_time(int time) {
return (time < 10) ? "0" + String(time) : String(time);
}
static lv_obj_t * text_label_date;
static lv_obj_t * text_label_latitude;
static lv_obj_t * text_label_longitude;
static lv_obj_t * text_label_altitude;
static lv_obj_t * text_label_speed;
static lv_obj_t * text_label_utc_time;
static lv_obj_t * text_label_hdop_satellites;
static lv_obj_t * text_label_gps_data;
static void timer_cb(lv_timer_t * timer){
LV_UNUSED(timer);
lv_label_set_text(text_label_date, current_date.c_str());
lv_label_set_text(text_label_hdop_satellites, String("HDOP " + hdop + " SAT. " + satellites).c_str());
lv_label_set_text(text_label_gps_data, String("LAT " + latitude + "\nLON " + longitude + "\nALT "
+ altitude + "m" + "\nSPEED " + speed + "km/h").c_str());
lv_label_set_text(text_label_utc_time, String("UTC TIME - " + utc_time).c_str());
}
void lv_create_main_gui(void) {
LV_IMAGE_DECLARE(image_gpsmap);
lv_obj_t * img_gpsmap = lv_image_create(lv_screen_active());
lv_obj_align(img_gpsmap, LV_ALIGN_LEFT_MID, 10, -20);
lv_image_set_src(img_gpsmap, &image_gpsmap);
text_label_hdop_satellites = lv_label_create(lv_screen_active());
lv_label_set_text(text_label_hdop_satellites, String("HDOP " + hdop + " SAT. " + satellites).c_str());
lv_obj_align(text_label_hdop_satellites, LV_ALIGN_BOTTOM_LEFT, 30, -50);
lv_obj_set_style_text_font((lv_obj_t*) text_label_hdop_satellites, &lv_font_montserrat_12, 0);
lv_obj_set_style_text_color((lv_obj_t*) text_label_hdop_satellites, lv_palette_main(LV_PALETTE_GREY), 0);
text_label_date = lv_label_create(lv_screen_active());
lv_label_set_text(text_label_date, current_date.c_str());
lv_obj_align(text_label_date, LV_ALIGN_CENTER, 60, -80);
lv_obj_set_style_text_font((lv_obj_t*) text_label_date, &lv_font_montserrat_26, 0);
lv_obj_set_style_text_color((lv_obj_t*) text_label_date, lv_palette_main(LV_PALETTE_TEAL), 0);
lv_obj_t * text_label_location = lv_label_create(lv_screen_active());
lv_label_set_text(text_label_location, "LOCATION");
lv_obj_align(text_label_location, LV_ALIGN_CENTER, 50, -40);
lv_obj_set_style_text_font((lv_obj_t*) text_label_location, &lv_font_montserrat_20, 0);
text_label_gps_data = lv_label_create(lv_screen_active());
lv_label_set_text(text_label_gps_data, String("LAT " + latitude + "\nLON " + longitude + "\nALT "
+ altitude + "m" + "\nSPEED " + speed + "km/h").c_str());
lv_obj_align(text_label_gps_data, LV_ALIGN_CENTER, 60, 20);
lv_obj_set_style_text_font((lv_obj_t*) text_label_gps_data, &lv_font_montserrat_14, 0);
text_label_utc_time = lv_label_create(lv_screen_active());
lv_label_set_text(text_label_utc_time, String("UTC TIME - " + utc_time).c_str());
lv_obj_align(text_label_utc_time, LV_ALIGN_BOTTOM_MID, 0, -10);
lv_obj_set_style_text_font((lv_obj_t*) text_label_utc_time, &lv_font_montserrat_20, 0);
lv_obj_set_style_text_color((lv_obj_t*) text_label_utc_time, lv_palette_main(LV_PALETTE_TEAL), 0);
lv_timer_t * timer = lv_timer_create(timer_cb, 1, NULL);
lv_timer_ready(timer);
}
void setup() {
String LVGL_Arduino = String("LVGL Library Version: ") + lv_version_major() + "." + lv_version_minor() + "." + lv_version_patch();
Serial.begin(115200);
Serial.println(LVGL_Arduino);
// Start Serial 2 with the defined RX and TX pins and a baud rate of 9600
gpsSerial.begin(GPS_BAUD, SERIAL_8N1, RXD2, TXD2);
Serial.println("Serial 2 started at 9600 baud rate");
// Start LVGL
lv_init();
// Register print function for debugging
lv_log_register_print_cb(log_print);
// Create a display object
lv_display_t * disp;
// Initialize the TFT display using the TFT_eSPI library
disp = lv_tft_espi_create(SCREEN_WIDTH, SCREEN_HEIGHT, draw_buf, sizeof(draw_buf));
lv_display_set_rotation(disp, LV_DISPLAY_ROTATION_270);
// Function to draw the GUI
lv_create_main_gui();
}
void loop() {
lv_task_handler(); // let the GUI do its work
lv_tick_inc(5); // tell LVGL how much time has passed
delay(5); // let this time pass
// This sketch displays information every time a new sentence is correctly encoded.
unsigned long start = millis();
while (millis() - start < 1000) {
while (gpsSerial.available() > 0) {
gps.encode(gpsSerial.read());
}
if (gps.location.isUpdated()) {
Serial.print("LAT: ");
latitude = String(gps.location.lat(), 6);
Serial.println(latitude);
Serial.print("LONG: ");
longitude = String(gps.location.lng(), 6);
Serial.println(longitude);
Serial.print("SPEED (km/h) = ");
speed = String(gps.speed.kmph(), 2);
Serial.println(speed);
Serial.print("ALT (min)= ");
altitude = String(gps.altitude.meters(), 2);
Serial.println(altitude);
Serial.print("HDOP = ");
hdop = String(gps.hdop.value() / 100.0, 2);
Serial.println(hdop);
Serial.print("Satellites = ");
satellites = String(gps.satellites.value());
Serial.println(satellites);
Serial.print("Time in UTC: ");
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()));
current_date = String(gps.date.year()) + "-" + String(gps.date.month()) + "-" + String(gps.date.day());
Serial.println(current_date);
utc_time = String(format_time(gps.time.hour())) + ":" + String(format_time(gps.time.minute())) + ":" + String(format_time(gps.time.second()));
Serial.println(utc_time);
Serial.println("");
}
}
}
How Does the Code Work?
Let’s take a look at how to get GPS location and update the screen with the current values. Alternatively, you can skip to the Demonstration section.
Including Libraries and Images
You need to include the lvgl.h and the TFT_eSPI.h libraries to draw the GUI on the screen.
#include <lvgl.h>
#include <TFT_eSPI.h>
You need to include the TinyGPS++.h library to handle the GPS data.
#include <TinyGPS++.h>
Include the gps_image.h file that contains all the data to draw the map image.
#include "gps_image.h"
GPS Serial
This sketch uses GPIO 22 and GPIO 27 as RX and TX serial pins to establish serial communication with the GPS module.
// Define the RX and TX pins for Serial 2
#define RXD2 22
#define TXD2 27
Also, if your module uses a different default baud rate than 9600 bps, you should modify the code on the following line:
#define GPS_BAUD 9600
Then, we create an instance of the HardwareSerial to use UART 2 called gpsSerial.
// Create an instance of the HardwareSerial class for Serial 2
HardwareSerial gpsSerial(2);
Declaring Other Variables
Create some auxiliary variables to hold the GPS data and other values.
String current_date;
String utc_time;
String latitude;
String longitude;
String altitude;
String speed;
String hdop;
String satellites;
Global LVGL Objects
We create some global LVGL objects, so that we can access them inside all functions later on.
static lv_obj_t * text_label_date;
static lv_obj_t * text_label_latitude;
static lv_obj_t * text_label_longitude;
static lv_obj_t * text_label_altitude;
static lv_obj_t * text_label_speed;
static lv_obj_t * text_label_utc_time;
static lv_obj_t * text_label_hdop_satellites;
static lv_obj_t * text_label_gps_data;
setup()
In the setup(), include the following lines for debugging. These will print the version of LVGL that you’re using. You must be using version 9.
String LVGL_Arduino = String("LVGL Library Version: ") + lv_version_major() + "." + lv_version_minor() + "." + lv_version_patch();
Serial.begin(115200);
Serial.println(LVGL_Arduino);
Start GPS Serial
To connect the CYD board to the GPS module via serial, we use the following code.
gpsSerial.begin(GPS_BAUD, SERIAL_8N1, RXD2, TXD2);
Serial.println("Serial 2 started at 9600 baud rate");
Initialize the LVGL Library
Initialize the LVGL Library by calling the lv_init() function in the setup().
// Start LVGL
lv_init();
Register Debugging Function
Register your log_print() function declared previously as a function associated with debugging LVGL.
// Register print function for debugging
lv_log_register_print_cb(log_print);
Create a Display Object
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 disp with the screen width, screen height, and drawing buffer defined earlier.
// Create a display object
lv_display_t * disp;
// Initialize the TFT display using the TFT_eSPI library
disp = lv_tft_espi_create(SCREEN_WIDTH, SCREEN_HEIGHT, draw_buf, sizeof(draw_buf));
lv_display_set_rotation(disp, LV_DISPLAY_ROTATION_270);
Drawing the GUI
The LVGL library works asynchronously. You must call the function to draw on the display in the setup(). 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’t need to check for any events in the loop().
Throughout most of our examples, the function that will draw to the screen will be called lv_create_main_gui(). Then, inside that function, we’ll add the instructions to build the interface.
// Function to draw the GUI
lv_create_main_gui();
Preparing the GUI
Before drawing the main GUI, we start by declaring an image that will be displayed in the CYD.
void lv_create_main_gui(void) {
LV_IMAGE_DECLARE(image_gpsmap);
(...)
Load the GPS image
We create an image and set it to the left side of the display.
lv_obj_t * img_gpsmap = lv_image_create(lv_screen_active());
lv_obj_align(img_gpsmap, LV_ALIGN_LEFT_MID, 10, -20);
lv_image_set_src(img_gpsmap, &image_gpsmap);
Text Labels
To create a text label, we can call the LVGL function lv_label_create() and pass as argument where we want to display the text. We want to add it to the current screen (lv_screen_active()). The following line is creating a text label to display the HDOP and the number of satellites.
text_label_hdop_satellites = lv_label_create(lv_screen_active());
After creating the text label, we can set its text by using the lv_label_set_text() function that accepts as arguments the text label we’re referring to and the text we want to add to that label. In our case, we’re setting this label to the current HDOP and visible satellites.
lv_label_set_text(text_label_hdop_satellites, String("HDOP " + hdop + " SAT. " + satellites).c_str());
The following lines align the text label. You can use the lv_obj_align() function. Pass as arguments, the LVGL object, the alignment and x and y offsets in pixels.
lv_obj_align(text_label_hdop_satellites, LV_ALIGN_BOTTOM_LEFT, 30, -50);
Then, we can set the font type and size using the lv_style_set_text_font() function. We pass as argument the object we’re referring to and the font type.
lv_obj_set_style_text_font((lv_obj_t*) text_label_hdop_satellites, &lv_font_montserrat_12, 0);
For the text_label_date we’re also setting a custom text grey color:
lv_obj_set_style_text_color((lv_obj_t*) text_label_hdop_satellites, lv_palette_main(LV_PALETTE_GREY), 0);
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
text_label_date = lv_label_create(lv_screen_active());
lv_label_set_text(text_label_date, current_date.c_str());
lv_obj_align(text_label_date, LV_ALIGN_CENTER, 60, -80);
lv_obj_set_style_text_font((lv_obj_t*) text_label_date, &lv_font_montserrat_26, 0);
lv_obj_set_style_text_color((lv_obj_t*) text_label_date, lv_palette_main(LV_PALETTE_TEAL), 0);
lv_obj_t * text_label_location = lv_label_create(lv_screen_active());
lv_label_set_text(text_label_location, "LOCATION");
lv_obj_align(text_label_location, LV_ALIGN_CENTER, 50, -40);
lv_obj_set_style_text_font((lv_obj_t*) text_label_location, &lv_font_montserrat_20, 0);
text_label_gps_data = lv_label_create(lv_screen_active());
lv_label_set_text(text_label_gps_data, String("LAT " + latitude + "\nLON " + longitude + "\nALT " + altitude + "m" + "\nSPEED " + speed + "km/h").c_str());
lv_obj_align(text_label_gps_data, LV_ALIGN_CENTER, 60, 20);
lv_obj_set_style_text_font((lv_obj_t*) text_label_gps_data, &lv_font_montserrat_14, 0);
text_label_utc_time = lv_label_create(lv_screen_active());
lv_label_set_text(text_label_utc_time, String("UTC TIME - " + utc_time).c_str());
lv_obj_align(text_label_utc_time, LV_ALIGN_BOTTOM_MID, 0, -10);
lv_obj_set_style_text_font((lv_obj_t*) text_label_utc_time, &lv_font_montserrat_20, 0);
lv_obj_set_style_text_color((lv_obj_t*) text_label_utc_time, lv_palette_main(LV_PALETTE_TEAL), 0);
Timer
To update the data on the screen, we can create an LVGL timer that will run a specific function periodically. In this case, we’ll update it every second. Create an LVGL timer called timer and assign the timer_cb callback function.
lv_timer_t * timer = lv_timer_create(timer_cb, 1, NULL);
lv_timer_ready(timer);
Timer Callback Function
The timer_cb 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.
static void timer_cb(lv_timer_t * timer){
LV_UNUSED(timer);
(...)
Finally, we set all the text labels to the current data returned from the GPS module:
lv_label_set_text(text_label_date, current_date.c_str());
lv_label_set_text(text_label_hdop_satellites, String("HDOP " + hdop + " SAT. " + satellites).c_str());
lv_label_set_text(text_label_gps_data, String("LAT " + latitude + "\nLON " + longitude + "\nALT " + altitude + "m" + "\nSPEED " + speed + "km/h").c_str());
lv_label_set_text(text_label_utc_time, String("UTC TIME - " + utc_time).c_str());
loop()
In the loop(), you can add any other tasks that you need your ESP32 to do like in any regular Arduino sketch. In our case, we’ll be requesting the latest GPS data from the NEO-6M module every second and update the auxiliary variables.
void loop() {
lv_task_handler(); // let the GUI do its work
lv_tick_inc(5); // tell LVGL how much time has passed
delay(5); // let this time pass
(...)
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.
// This sketch displays information every time a new sentence is correctly encoded.
unsigned long start = millis();
while (millis() - start < 1000) {
while (gpsSerial.available() > 0) {
gps.encode(gpsSerial.read());
}
if (gps.location.isUpdated()) {
Serial.print("LAT: ");
latitude = String(gps.location.lat(), 6);
Serial.println(latitude);
Serial.print("LONG: ");
longitude = String(gps.location.lng(), 6);
Serial.println(longitude);
Serial.print("SPEED (km/h) = ");
speed = String(gps.speed.kmph(), 2);
Serial.println(speed);
Serial.print("ALT (min)= ");
altitude = String(gps.altitude.meters(), 2);
Serial.println(altitude);
Serial.print("HDOP = ");
hdop = String(gps.hdop.value() / 100.0, 2);
Serial.println(hdop);
Serial.print("Satellites = ");
satellites = String(gps.satellites.value());
Serial.println(satellites);
Serial.print("Time in UTC: ");
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()));
current_date = String(gps.date.year()) + "-" + String(gps.date.month()) + "-" + String(gps.date.day());
Serial.println(current_date);
utc_time = String(format_time(gps.time.hour())) + ":" + String(format_time(gps.time.minute())) + ":" + String(format_time(gps.time.second()));
Serial.println(utc_time);
Serial.println("");
}
}
Demonstration
Upload the code to your board. Go to Tools > Board and select ESP32 > ESP32 Dev Module. Then, select the right COM port in Tools > Port.
Finally, click the upload button.
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’s blue LED starts blinking, it means it’s ready.
You’ll get GPS data on the Serial Monitor about your current location, speed, altitude, number of visible satellites HDOP, date, and time.
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.
Wrapping Up
In this tutorial, you’ve created a simple GPS reader with your Cheap Yellow Display (CYD) board using the LVGL library that displays the current location, altitude, speed, date, and time.
We hope you found this tutorial useful. We’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:
Other guides you might like reading:
- ESP32 CYD with LVGL: Weather Station (Description, Temperature, Humidity)
- ESP32 CYD with LVGL: Digital Clock with Time and Date
To learn more about the ESP32, make sure to take a look at our resources:
Hi Sara and Rui, Just wanted to say thank you for another great project which, as usual, was very well explained. After referring to and following your other page, on setting up the required libraries ( LVGL with ESP32 Cheap Yellow Display Board (ESP32-2432S028R) ) the compile and download to my CYD esp32 board went smoothly and the GPS project worked first time.
I really appreciate the learning journey into single board computing that you have taken me on.
Steve (Australia)
That’s great! I’m really glad the project worked out of the box.
Regards,
Rui
Hi.
That’s great.
Thank you for your feedback.
Regards,
Sara
Hi Sara,
That’s great! I’m really glad the project worked out of the box.
I found one NEO-6M GPS board in my “circuit cellar” put it together with the CYD board and it worked from the scratch! Thanks a lot for this LVGL- project with the ESP32/CYD board!
Something else, concerning the LDR sensor module on the CYD board: Something is totally wrong with the voltage divider R15 – R19 of 1 M-Ohm as described by different folks on the Internet! I unsoldered R15 and the RDR sensor – in any case a wrong luminosity measurement –
and I soldered a micro plug on the place of the LDR and you will get a 12 Bit ADC input on GPIO-34! Many kind regards, Bruno
Dear Sara,
for the first time, I am unable to get your sketch to work and despite my best efforts I am unable to get it to compile. this is the error
.c:\Users\user\Documents\Arduino\libraries\lvgl\src\examples\styles\lv_example_style_14.c:1:10: fatal error: ../../src/themes/lv_theme_private.h: No such file or directory
1 | #include “../../src/themes/lv_theme_private.h”
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
compilation terminated.
exit status 1
Compilation error: exit status 1
despite the correct lv_conf.h from your other LVGL sketches in the correct place and also the path ../../src/themes/lv_theme_private.h does exist in the path place.
please could you advise
regards
Mark D
sorry ignore that, i forgot that i no longer need to move examples and demos folder on latest LVGL 9.2xxxx reinatlled and worked like a charm….once again thanks
Please provide the code to get RTK data corrections on the readout. The added precision would be very helpful.
Thanks for all your excellent work, I look forward to all your projects!
Hi Harry,
I’m afraid it’s not that simple.
To enhance your GPS data precision using RTK, you need a dedicated high precision GNSS receiver (the Base). This receiver must be stationary for some time, so it can calculate its own position with very high accuracy. Once the base position is established (or known from other sources), the base receiver (still remaining on the same spot!) calculates the GPS corrections in Lat and Lon as the difference between its known position and a ‘new position’ which it calculates continuously from GNSS data received from satellites. These corrections are then sent (usually via WiFi) to other GPS unit(s) nearby.
So, to write the code you are asking for, one will have to know the specs of a GNSS base receiver you have, and what is the communication protocol between the (stationary) base and your (presumably mobile) GPS unit.
Cheers,
Ben
Is there a way to read other time zones? I need AEST with amended date. Adding 10 hours to gps.time.hour doesn’t work, 2200hrs becomes 3200hrs and it’s still yesterday.
Also, what is the ‘.reserved’ non static data member line 168 in the gps_image.h file? Program would not compile, seems ok when this line is commented out.
Hi.
You can use a library like timezone.h: https://github.com/JChristensen/Timezone
Regards,
Sara
Cool, https://github.com/JChristensen/Timezone looks like a comprehensive library, I will see what I can do. I’m still puzzled about line 168 on the image file.
Would not compile with .reserved = NULL in program
Nice project. I hv one question,when I not use external gps antenna so how it works.
Hi.
What do you mean?
All GPS modules should come with an antenna.
Regards,
Sara
Hi,
actually I’ve a few questions. I’ve implemented this project but, to have a reading, both on the serial port of the PC and on the CYD, I had to comment the line:
if (gps.location.isUpdated()) and the curly brackets associated to the if. Then, at the end of the block with all the Serial.print, I’ve added a delay(2000); to keep the printed results stable enough to read them.
Any idea why this is happening?
The second point is that Latitude and Longitude need to specify E,W,S and N to be complete. I believe it is not complex to add these letters. I’ll try to do it and, in case I’ll post the modified sketch.
The third point is about the relative speed. I see on the above picture, and also on my CYD the our GPS modules are moving. Yours at 0,19Km/h, mine, in this very moment is leisurely walking at 0.81Km/h. Of course mine, as well as yours, I believe, are quietly resting near a window.
Any idea why ?
Last but not least, has anybody tried to have the local time instead of UTC?
It would be nice to have the local time with automatic switch from DST to SDT. Probably the ezTime library could help at the price of making the sketch more complex.
Hi Fabrizio,
The coordinates (Lat and Lon) are expressed as numbers: Lat -> [-90,+90] , Lon -> [-180,+180]. Lat < 0 means S, Lat > 0 means N; Lon < 0 means W, Lon > 0 means E. I’m sure you will be able to modify the code.
As to the speed not showing up as ZERO for a stationary GNSS receiver, the reason is position inaccuracy. You will notice that the Lat, Lon and Alt values are constantly changing (usually only at the last decimal places). So, the system ‘thinks’ that the receiver is moving and calculates its velocity accordingly. One way to rectify this could be to average the position data over a few readings.
Hope this helps.
Ben
Hi Ben,
many thanks for the info about the coordinates, being accustomed to seeing the four poles I’ll try to modify the code accordingly.
About the speed, actually, I thought it could be a matter of precision but I didn’t pay attention to the fact that the last digits were constantly flickering as I thought they weren’t influential on the speed calculation.
I still have a point that, perhaps, you might help to solve. As I wrote in my post, I’ve to comment the if clause ” if (gps.location.isUpdated()) {….} ” to get a reading displayed on the CYD, but also on the monitor. I was wondering if it could be caused by the fact that, very best case, my GPS antenna receives 5-6 satellites, most of cases 4. In addition, living in a big town, and in a block where surrounding buildings are 9-10 stories, I may have stability issue. Any thought on the matter?
Thank you again for you help
Fabrizio
Hi Fabrizio,
I’m not sure why did you need to comment-out the ” if (gps.location.isUpdated()) {…} ” section of the code. It simply outputs GPS data to the serial monitor (if you activate one) without affecting anything else.
Your problem could indeed be caused by the insufficient number of satellites and weak signal in the urban environment. A theoretical minimum of satellites for a GPS 3D “fix” (i.e. Lat, Lon, Alt) is 4. Practically, however, with only 4 satellites the “fix” will be very inaccurate. You need at least 6-8 satellites for a reasonable result. Between tall buildings you will also have additional problems, mainly weak signal, multipath errors (when the GPS satellite signal bounces off of nearby structures), and poor satellite geometry (you and your GPS receiver can only “see” a small section of the sky directly above). There is little you can do about it.
Hi Sara,
Thank you another great project. Works really well. My only question is there a way to change date and time to my local time in Sydney , Australia. ? The time is and date are 10 hours behind.
Kind regards
Bob E
Hi.
You can use a library like timezone.h: https://github.com/JChristensen/Timezone to adjust to your timezone.
Regards,
Sara
Thanks Sara.
Hello,
Is there a CYD version that writes comma delimited data to SD card for later used with GPSVisualizer?
Hi.
At the moment, we don’t have any project like that.
Regards,
Sara
Hi Sara, I would be willing to pay for the addition of writing lat, lon, speed, date and time to SD card to this CYD script. 200$.
Donnie
Hi.
Unfortunately, we don’t create custom projects on demand.
We’ll try to create some projects using the CYD board with a microSD card soon (but might take some time).
Regards,
Sara
Hi Sara,
I’ve modified your code to include data logging to an SD card. It’s free to share: https://github.com/ilvento/CYD_GPS_LVGL_SD
I’m running it on VS Code with PlatformIO, but it should run on Arduino IDE with relevant libraries.
Cheers,
Ben
Hi Ben,
That’s impressive! Works great loading with Arduino IDE. Adds a lot of value to this project as now you can take that logged data, upload to GPSVisualizer to produce a map of the outing.
I struggled the last several days to get my code to work and some same as yours, but I kept getting a panic. I see now what I did incorrectly. I’m a 75YO assembly coder, retired from UNIX environment.
Also, a drone pilot.
Thanks, Donnie
Hi Alfonso,
I’m glad that it works also with Arduino IDE and, more importantly, that is useful to somebody. I need the log to get centimetre accuracy for an RTK Base Station I’m building. Hope to be able to achieve this with a u-blox NEO-8MN chip. It will be useful for our work with drone surveys (https://www.southerncrossdrones.com/).
Good to know that people of our age are still active mentally. I’ve written my first Assembler code on an ICL computer in the early 70s of the last century, using punch tape…
All the best,
Ben
Thx for the logging update. Works for me too using imac dev tools and the cheap GPS with only onboard antenna. The GPS Visualizer is a lot more usable than my spreadsheet plotting macros 🙂 . https://www.sparkfun.com/gps shows a range of GPS systems down to 1cm accuracy. In my experience you cant rely on altitude and you have to remember all the satellites are moving so things will change quickly.
Worked with no changes for me. Thx!
Had to swap the tx and rx lines and take it outside to get get good satellite visibility.
Note that the green light on the back of the gps flashes when it has position to report.
Another ICL coder here. A room full of equipment and people for what we can do on our phones today.
Hi Sara
Have you tested the HMI screen 3.5″ yellow one? I want to use it with the same project
No. I haven’t tested it.
But, you should be able to use it by setting its size and driver on the User_Setup file. (But I didn’t test this)
However, if you also want to build other of our projects that use touchscreen, it should have a resistive touchscreen. If is has capacitive touchscreen, you need to use a different touchscreen library and at the moment, we don’t have examples for that.
Regards,
Sara
Regards,
Sara
Hi, thanks for the response, I have problems with the library XPT2046 , the scrren is resistive the pin of the driver are different both pins SPI are shared the pins that are to communicate the touch are the same for the vizualization.
The sreen works perfect to visualice the data GPS DATA and the image.