This commit is contained in:
2026-05-04 09:45:46 +03:00
commit 4149376f54
9 changed files with 882 additions and 0 deletions

5
.gitignore vendored Normal file
View File

@@ -0,0 +1,5 @@
.pio
.vscode/.browse.c_cpp.db*
.vscode/c_cpp_properties.json
.vscode/launch.json
.vscode/ipch

10
.vscode/extensions.json vendored Normal file
View File

@@ -0,0 +1,10 @@
{
// See http://go.microsoft.com/fwlink/?LinkId=827846
// for the documentation about the extensions.json format
"recommendations": [
"platformio.platformio-ide"
],
"unwantedRecommendations": [
"ms-vscode.cpptools-extension-pack"
]
}

37
include/README Normal file
View File

@@ -0,0 +1,37 @@
This directory is intended for project header files.
A header file is a file containing C declarations and macro definitions
to be shared between several project source files. You request the use of a
header file in your project source file (C, C++, etc) located in `src` folder
by including it, with the C preprocessing directive `#include'.
```src/main.c
#include "header.h"
int main (void)
{
...
}
```
Including a header file produces the same results as copying the header file
into each source file that needs it. Such copying would be time-consuming
and error-prone. With a header file, the related declarations appear
in only one place. If they need to be changed, they can be changed in one
place, and programs that include the header file will automatically use the
new version when next recompiled. The header file eliminates the labor of
finding and changing all the copies as well as the risk that a failure to
find one copy will result in inconsistencies within a program.
In C, the convention is to give header files names that end with `.h'.
Read more about using header files in official GCC documentation:
* Include Syntax
* Include Operation
* Once-Only Headers
* Computed Includes
https://gcc.gnu.org/onlinedocs/cpp/Header-Files.html

46
lib/README Normal file
View File

@@ -0,0 +1,46 @@
This directory is intended for project specific (private) libraries.
PlatformIO will compile them to static libraries and link into the executable file.
The source code of each library should be placed in a separate directory
("lib/your_library_name/[Code]").
For example, see the structure of the following example libraries `Foo` and `Bar`:
|--lib
| |
| |--Bar
| | |--docs
| | |--examples
| | |--src
| | |- Bar.c
| | |- Bar.h
| | |- library.json (optional. for custom build options, etc) https://docs.platformio.org/page/librarymanager/config.html
| |
| |--Foo
| | |- Foo.c
| | |- Foo.h
| |
| |- README --> THIS FILE
|
|- platformio.ini
|--src
|- main.c
Example contents of `src/main.c` using Foo and Bar:
```
#include <Foo.h>
#include <Bar.h>
int main (void)
{
...
}
```
The PlatformIO Library Dependency Finder will find automatically dependent
libraries by scanning project source files.
More information about PlatformIO Library Dependency Finder
- https://docs.platformio.org/page/librarymanager/ldf.html

18
platformio.ini Normal file
View File

@@ -0,0 +1,18 @@
; PlatformIO Project Configuration File
;
; Build options: build flags, source filter
; Upload options: custom upload port, speed and extra flags
; Library options: dependencies, extra library storages
; Advanced options: extra scripting
;
; Please visit documentation for the other options and examples
; https://docs.platformio.org/page/projectconf.html
[env:esp32dev]
platform = espressif32
board = esp32dev
monitor_speed = 115200
framework = arduino
lib_deps =
bodmer/TFT_eSPI@^2.5.43
mikalhart/TinyGPSPlus@^1.1.0

377
src/Free_Fonts.h Normal file
View File

@@ -0,0 +1,377 @@
// Attach this header file to your sketch to use the GFX Free Fonts. You can write
// sketches without it, but it makes referencing them easier.
// This calls up ALL the fonts but they only get loaded if you actually
// use them in your sketch.
//
// No changes are needed to this header file unless new fonts are added to the
// library "Fonts/GFXFF" folder.
//
// To save a lot of typing long names, each font can easily be referenced in the
// sketch in three ways, either with:
//
// 1. Font file name with the & in front such as &FreeSansBoldOblique24pt7b
// an example being:
//
// tft.setFreeFont(&FreeSansBoldOblique24pt7b);
//
// 2. FF# where # is a number determined by looking at the list below
// an example being:
//
// tft.setFreeFont(FF32);
//
// 3. An abbreviation of the file name. Look at the list below to see
// the abbreviations used, for example:
//
// tft.setFreeFont(FSSBO24)
//
// Where the letters mean:
// F = Free font
// M = Mono
// SS = Sans Serif (double S to distinguish is form serif fonts)
// S = Serif
// B = Bold
// O = Oblique (letter O not zero)
// I = Italic
// # = point size, either 9, 12, 18 or 24
//
// Setting the font to NULL will select the GLCD font:
//
// tft.setFreeFont(NULL); // Set font to GLCD
#ifdef LOAD_GFXFF // Only include the fonts if LOAD_GFXFF is defined in User_Setup.h
// Use these when printing or drawing text in GLCD and high rendering speed fonts
#define GFXFF 1
#define GLCD 0
#define FONT2 2
#define FONT4 4
#define FONT6 6
#define FONT7 7
#define FONT8 8
// Use the following when calling setFont()
//
// Reserved for GLCD font // FF0
//
#define TT1 &TomThumb
#define FM9 &FreeMono9pt7b
#define FM12 &FreeMono12pt7b
#define FM18 &FreeMono18pt7b
#define FM24 &FreeMono24pt7b
#define FMB9 &FreeMonoBold9pt7b
#define FMB12 &FreeMonoBold12pt7b
#define FMB18 &FreeMonoBold18pt7b
#define FMB24 &FreeMonoBold24pt7b
#define FMO9 &FreeMonoOblique9pt7b
#define FMO12 &FreeMonoOblique12pt7b
#define FMO18 &FreeMonoOblique18pt7b
#define FMO24 &FreeMonoOblique24pt7b
#define FMBO9 &FreeMonoBoldOblique9pt7b
#define FMBO12 &FreeMonoBoldOblique12pt7b
#define FMBO18 &FreeMonoBoldOblique18pt7b
#define FMBO24 &FreeMonoBoldOblique24pt7b
#define FSS9 &FreeSans9pt7b
#define FSS12 &FreeSans12pt7b
#define FSS18 &FreeSans18pt7b
#define FSS24 &FreeSans24pt7b
#define FSSB9 &FreeSansBold9pt7b
#define FSSB12 &FreeSansBold12pt7b
#define FSSB18 &FreeSansBold18pt7b
#define FSSB24 &FreeSansBold24pt7b
#define FSSO9 &FreeSansOblique9pt7b
#define FSSO12 &FreeSansOblique12pt7b
#define FSSO18 &FreeSansOblique18pt7b
#define FSSO24 &FreeSansOblique24pt7b
#define FSSBO9 &FreeSansBoldOblique9pt7b
#define FSSBO12 &FreeSansBoldOblique12pt7b
#define FSSBO18 &FreeSansBoldOblique18pt7b
#define FSSBO24 &FreeSansBoldOblique24pt7b
#define FS9 &FreeSerif9pt7b
#define FS12 &FreeSerif12pt7b
#define FS18 &FreeSerif18pt7b
#define FS24 &FreeSerif24pt7b
#define FSI9 &FreeSerifItalic9pt7b
#define FSI12 &FreeSerifItalic12pt7b
#define FSI19 &FreeSerifItalic18pt7b
#define FSI24 &FreeSerifItalic24pt7b
#define FSB9 &FreeSerifBold9pt7b
#define FSB12 &FreeSerifBold12pt7b
#define FSB18 &FreeSerifBold18pt7b
#define FSB24 &FreeSerifBold24pt7b
#define FSBI9 &FreeSerifBoldItalic9pt7b
#define FSBI12 &FreeSerifBoldItalic12pt7b
#define FSBI18 &FreeSerifBoldItalic18pt7b
#define FSBI24 &FreeSerifBoldItalic24pt7b
#define FF0 NULL //ff0 reserved for GLCD
#define FF1 &FreeMono9pt7b
#define FF2 &FreeMono12pt7b
#define FF3 &FreeMono18pt7b
#define FF4 &FreeMono24pt7b
#define FF5 &FreeMonoBold9pt7b
#define FF6 &FreeMonoBold12pt7b
#define FF7 &FreeMonoBold18pt7b
#define FF8 &FreeMonoBold24pt7b
#define FF9 &FreeMonoOblique9pt7b
#define FF10 &FreeMonoOblique12pt7b
#define FF11 &FreeMonoOblique18pt7b
#define FF12 &FreeMonoOblique24pt7b
#define FF13 &FreeMonoBoldOblique9pt7b
#define FF14 &FreeMonoBoldOblique12pt7b
#define FF15 &FreeMonoBoldOblique18pt7b
#define FF16 &FreeMonoBoldOblique24pt7b
#define FF17 &FreeSans9pt7b
#define FF18 &FreeSans12pt7b
#define FF19 &FreeSans18pt7b
#define FF20 &FreeSans24pt7b
#define FF21 &FreeSansBold9pt7b
#define FF22 &FreeSansBold12pt7b
#define FF23 &FreeSansBold18pt7b
#define FF24 &FreeSansBold24pt7b
#define FF25 &FreeSansOblique9pt7b
#define FF26 &FreeSansOblique12pt7b
#define FF27 &FreeSansOblique18pt7b
#define FF28 &FreeSansOblique24pt7b
#define FF29 &FreeSansBoldOblique9pt7b
#define FF30 &FreeSansBoldOblique12pt7b
#define FF31 &FreeSansBoldOblique18pt7b
#define FF32 &FreeSansBoldOblique24pt7b
#define FF33 &FreeSerif9pt7b
#define FF34 &FreeSerif12pt7b
#define FF35 &FreeSerif18pt7b
#define FF36 &FreeSerif24pt7b
#define FF37 &FreeSerifItalic9pt7b
#define FF38 &FreeSerifItalic12pt7b
#define FF39 &FreeSerifItalic18pt7b
#define FF40 &FreeSerifItalic24pt7b
#define FF41 &FreeSerifBold9pt7b
#define FF42 &FreeSerifBold12pt7b
#define FF43 &FreeSerifBold18pt7b
#define FF44 &FreeSerifBold24pt7b
#define FF45 &FreeSerifBoldItalic9pt7b
#define FF46 &FreeSerifBoldItalic12pt7b
#define FF47 &FreeSerifBoldItalic18pt7b
#define FF48 &FreeSerifBoldItalic24pt7b
// >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
// Now we define "s"tring versions for easy printing of the font name so:
// tft.println(sFF5);
// will print
// Mono bold 9
// >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
#define sFF0 "GLCD"
#define sTT1 "Tom Thumb"
#define sFF1 "Mono 9"
#define sFF2 "Mono 12"
#define sFF3 "Mono 18"
#define sFF4 "Mono 24"
#define sFF5 "Mono bold 9"
#define sFF6 "Mono bold 12"
#define sFF7 "Mono bold 18"
#define sFF8 "Mono bold 24"
#define sFF9 "Mono oblique 9"
#define sFF10 "Mono oblique 12"
#define sFF11 "Mono oblique 18"
#define sFF12 "Mono oblique 24"
#define sFF13 "Mono bold oblique 9"
#define sFF14 "Mono bold oblique 12"
#define sFF15 "Mono bold oblique 18"
#define sFF16 "Mono bold obl. 24" // Full text line is too big for 480 pixel wide screen
#define sFF17 "Sans 9"
#define sFF18 "Sans 12"
#define sFF19 "Sans 18"
#define sFF20 "Sans 24"
#define sFF21 "Sans bold 9"
#define sFF22 "Sans bold 12"
#define sFF23 "Sans bold 18"
#define sFF24 "Sans bold 24"
#define sFF25 "Sans oblique 9"
#define sFF26 "Sans oblique 12"
#define sFF27 "Sans oblique 18"
#define sFF28 "Sans oblique 24"
#define sFF29 "Sans bold oblique 9"
#define sFF30 "Sans bold oblique 12"
#define sFF31 "Sans bold oblique 18"
#define sFF32 "Sans bold oblique 24"
#define sFF33 "Serif 9"
#define sFF34 "Serif 12"
#define sFF35 "Serif 18"
#define sFF36 "Serif 24"
#define sFF37 "Serif italic 9"
#define sFF38 "Serif italic 12"
#define sFF39 "Serif italic 18"
#define sFF40 "Serif italic 24"
#define sFF41 "Serif bold 9"
#define sFF42 "Serif bold 12"
#define sFF43 "Serif bold 18"
#define sFF44 "Serif bold 24"
#define sFF45 "Serif bold italic 9"
#define sFF46 "Serif bold italic 12"
#define sFF47 "Serif bold italic 18"
#define sFF48 "Serif bold italic 24"
#else // LOAD_GFXFF not defined so setup defaults to prevent error messages
// >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
// Free fonts are not loaded in User_Setup.h so we must define all as font 1
// to prevent compile error messages
// >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
#define GFXFF 1
#define GLCD 1
#define FONT2 2
#define FONT4 4
#define FONT6 6
#define FONT7 7
#define FONT8 8
#define TT1 1
#define FF0 1
#define FF1 1
#define FF2 1
#define FF3 1
#define FF4 1
#define FF5 1
#define FF6 1
#define FF7 1
#define FF8 1
#define FF9 1
#define FF10 1
#define FF11 1
#define FF12 1
#define FF13 1
#define FF14 1
#define FF15 1
#define FF16 1
#define FF17 1
#define FF18 1
#define FF19 1
#define FF20 1
#define FF21 1
#define FF22 1
#define FF23 1
#define FF24 1
#define FF25 1
#define FF26 1
#define FF27 1
#define FF28 1
#define FF29 1
#define FF30 1
#define FF31 1
#define FF32 1
#define FF33 1
#define FF34 1
#define FF35 1
#define FF36 1
#define FF37 1
#define FF38 1
#define FF39 1
#define FF40 1
#define FF41 1
#define FF42 1
#define FF43 1
#define FF44 1
#define FF45 1
#define FF46 1
#define FF47 1
#define FF48 1
#define FM9 1
#define FM12 1
#define FM18 1
#define FM24 1
#define FMB9 1
#define FMB12 1
#define FMB18 1
#define FMB24 1
#define FMO9 1
#define FMO12 1
#define FMO18 1
#define FMO24 1
#define FMBO9 1
#define FMBO12 1
#define FMBO18 1
#define FMBO24 1
#define FSS9 1
#define FSS12 1
#define FSS18 1
#define FSS24 1
#define FSSB9 1
#define FSSB12 1
#define FSSB18 1
#define FSSB24 1
#define FSSO9 1
#define FSSO12 1
#define FSSO18 1
#define FSSO24 1
#define FSSBO9 1
#define FSSBO12 1
#define FSSBO18 1
#define FSSBO24 1
#define FS9 1
#define FS12 1
#define FS18 1
#define FS24 1
#define FSI9 1
#define FSI12 1
#define FSI19 1
#define FSI24 1
#define FSB9 1
#define FSB12 1
#define FSB18 1
#define FSB24 1
#define FSBI9 1
#define FSBI12 1
#define FSBI18 1
#define FSBI24 1
#endif // LOAD_GFXFF

15
src/help.cpp Normal file
View File

@@ -0,0 +1,15 @@
void setup1(void)
{
// tft.begin();
// tft.setRotation(2);
// tft.fillScreen(TFT_BLACK);
// tft.setTextColor(TFT_WHITE, TFT_BLACK);
// tft.print("Hello, world! Foo bar!!!");
// tft.setFreeFont(FM9);
// tft.drawString("test", 5, 20, GFXFF);
// tft.setTextFont(1);
// tft.setTextSize(2);
// tft.setTextColor(TFT_WHITE, TFT_BLACK);
// tft.setTextDatum(CC_DATUM);
// tft.drawString("Makerguides", TFT_HEIGHT / 2, TFT_WIDTH / 2);
}

363
src/main.cpp Normal file
View File

@@ -0,0 +1,363 @@
#include <TFT_eSPI.h>
#include <TinyGPSPlus.h>
#include <HardwareSerial.h>
#include <Arduino.h>
#include <SPI.h>
#include "Free_Fonts.h"
#define RX2_PIN 16
#define TX2_PIN 17
#define GPS_BAUD 9600
#define LED 2
#define KEY_X 3 // start X
#define KEY_Y 24
#define KEY_W 76 // Key width
#define KEY_H 36 // Key height
#define KEY_SPACING_X 3 // X gap
#define KEY_SPACING_Y 3 // Y gap
#define KEY_TEXTSIZE 1 // Font size multiplier
#define BUTTON_X_DELTA 22
#define NUM_KEYS 3
#define QUEUE_SIZE 5
TFT_eSPI tft = TFT_eSPI();
TinyGPSPlus gps;
HardwareSerial serialGPS(1);
TaskHandle_t taskBlinkHandle = NULL; // for task control: suspend / resume
TaskHandle_t taskGPSHandle = NULL;
TFT_eSPI_Button key[NUM_KEYS];
SemaphoreHandle_t spiMutex;
QueueHandle_t gpsQueue = NULL;
char label[] = "label";
String btnLabel[] = {"GPS", "DATE", "LOC"};
// uint16_t calData[5] = { 293, 3474, 445, 3470, 0 };
// uint16_t calData[5] = { 314, 3512, 424, 3489, 0 };
// uint16_t calData[5] = { 233, 3558, 390, 3514, 0 };
// uint16_t calData[5] = { 283, 3553, 416, 3514, 0 };
// Initial Free Heap: 274996 bytes
struct GpsData
{
float lat;
float lng;
uint8_t hour;
uint8_t minute;
uint8_t second;
uint16_t year;
uint8_t month;
uint8_t day;
uint32_t sat;
float speed;
float alt;
bool isValid;
};
// struct GPSData1 {
// float lat = 0.0f;
// float lon = 0.0f;
// float alt = 0.0f;
// uint8_t satellites = 0;
// float speed = 0.0f;
// float course = 0.0f;
// bool valid = false;
// };
// packet.lat = gps.location.isValid() ? gps.location.lat() : 0.0f;
void smartDelay(unsigned long ms);
void initDisplay();
void displayGPSInfo();
void drawButtons();
void taskBlink(void *pvParameters);
void taskGPS(void *pvParameters);
void taskTFT(void *pvParameters);
void drawTitle(const char *title);
//------------------------------------------------------------------------------------------
void setup()
{
Serial.begin(115200);
spiMutex = xSemaphoreCreateMutex();
Serial.printf("Starting FreeRTOS: Memory Usage\nInitial Free Heap: %u bytes\n", xPortGetFreeHeapSize());
gpsQueue = xQueueCreate(QUEUE_SIZE, sizeof(GpsData));
xTaskCreatePinnedToCore(taskBlink, "taskBlink", 2000, NULL, 1, &taskBlinkHandle, 0);
xTaskCreatePinnedToCore(taskGPS, "taskGPS", 2000, NULL, 1, &taskGPSHandle, 0);
xTaskCreatePinnedToCore(taskTFT, "taskTFT", 2000, NULL, 1, NULL, 1);
}
void loop()
{
static uint32_t lastCheck = 0;
if (millis() - lastCheck > 5000)
{
Serial.printf("Free Heap: %u bytes\n", xPortGetFreeHeapSize());
lastCheck = millis();
}
}
void taskGPS(void *pvParameters)
{
serialGPS.begin(GPS_BAUD, SERIAL_8N1, RX2_PIN, TX2_PIN);
Serial.print("Task GPS running on core ");
Serial.println(xPortGetCoreID());
GpsData data;
while (true)
{
while (serialGPS.available() > 0)
{
gps.encode(serialGPS.read());
}
if (gps.location.isUpdated())
{
data.lat = gps.location.lat();
data.lng = gps.location.lng();
data.speed = gps.speed.kmph();
data.alt = gps.altitude.meters();
data.sat = gps.satellites.value();
Serial.printf("Lat: %.6f, Lon: %.6f\n", data.lat, data.lng);
Serial.printf("Speed: %.1f km/h\n", data.speed);
Serial.printf("Alt: %.1f m\n", data.alt);
Serial.printf("Satellites: %d\n", data.sat);
}
if (gps.date.isUpdated() && gps.time.isUpdated())
{
data.year = gps.date.year();
data.month = gps.date.month();
data.day = gps.date.day();
data.hour = gps.time.hour();
data.minute = gps.time.minute();
data.second = gps.time.second();
Serial.printf("Date: %04d-%02d-%02d\n", data.year, data.month, data.day);
Serial.printf("Time: %02d:%02d:%02d\n", data.hour, data.minute, data.second);
}
vTaskDelay(1000 / portTICK_PERIOD_MS);
// Serial.printf("TaskGPS Stack Free: %u bytes\n", uxTaskGetStackHighWaterMark(NULL));
}
}
void taskBlink(void *pvParameters)
{
pinMode(LED, OUTPUT);
for (;;)
{ // Infinite loop
digitalWrite(LED, HIGH);
// Serial.println("BlinkTask: LED ON");
vTaskDelay(1000 / portTICK_PERIOD_MS); // 1000ms
digitalWrite(LED, LOW);
// Serial.println("BlinkTask: LED OFF");
vTaskDelay(1000 / portTICK_PERIOD_MS);
// Serial.print("Task Blink running on core ");
// Serial.println(xPortGetCoreID());
// Serial.printf("TaskBlink Stack Free: %u bytes\n", uxTaskGetStackHighWaterMark(NULL));
}
}
void taskTFT(void *pvParameters)
{
initDisplay();
drawTitle("Hello world!");
drawButtons();
for (;;)
{
// Serial.printf("taskTFT Stack Free: %u bytes\n", uxTaskGetStackHighWaterMark(NULL));
vTaskDelay(2000 / portTICK_PERIOD_MS);
}
}
void loop_1()
{
if (gps.location.isUpdated())
{
displayGPSInfo();
}
uint16_t t_x = 0, t_y = 0; // To store the touch coordinates
// Get current touch state and coordinates
bool pressed = tft.getTouch(&t_x, &t_y);
if (pressed)
{
Serial.println("pressed");
digitalWrite(LED, HIGH);
}
else
{
digitalWrite(LED, LOW);
}
// Adjust press state of each key appropriately
for (uint8_t b = 0; b < NUM_KEYS; b++)
{
if (pressed && key[b].contains(t_x, t_y))
{
key[b].press(true);
}
else
{
key[b].press(false);
}
}
// Check if any key has changed state
for (uint8_t b = 0; b < NUM_KEYS; b++)
{
// If button was just pressed, redraw inverted button
if (key[b].justPressed())
{
Serial.println("Button " + (String)b + " pressed");
tft.setFreeFont(FF5);
key[b].drawButton(true, btnLabel[b]);
}
// If button was just released, redraw normal color button
if (key[b].justReleased())
{
Serial.println("Button " + (String)b + " released");
tft.setFreeFont(FF5);
key[b].drawButton(false, btnLabel[b]);
}
}
smartDelay(100);
}
void drawButtons()
{
for (int i = 0; i < NUM_KEYS; i++)
{
key[i].initButtonUL(&tft,
KEY_X + i * (KEY_W + KEY_SPACING_X),
KEY_Y,
KEY_W,
KEY_H,
TFT_LIGHTGREY,
TFT_DARKGREY,
TFT_WHITE,
label,
KEY_TEXTSIZE);
key[i].setLabelDatum(0, 2, MC_DATUM);
key[i].drawButton(false, btnLabel[i]);
}
}
void initDisplay()
{
tft.init();
tft.setRotation(2);
uint16_t calData[5] = {283, 3553, 416, 3514, 0};
tft.setTouch(calData);
#ifndef TFT_BL
Serial.println("No TFT backlight pin defined");
#else
pinMode(TFT_BL, OUTPUT);
digitalWrite(TFT_BL, HIGH);
#endif
tft.fillScreen(TFT_BLACK);
}
void drawTitle(const char *title)
{
tft.setFreeFont(FF5);
tft.setTextColor(TFT_YELLOW, TFT_BLACK);
tft.drawString(title, 0, 0, GFXFF);
}
void displayGPSInfo()
{
Serial.print(F("Location: "));
if (gps.location.isValid())
{
Serial.print(gps.location.lat(), 6);
Serial.print(F(","));
Serial.print(gps.location.lng(), 6);
}
else
{
Serial.print(F("INVALID"));
}
Serial.print(F(" Date/Time: "));
if (gps.date.isValid())
{
Serial.print(gps.date.month());
Serial.print(F("/"));
Serial.print(gps.date.day());
Serial.print(F("/"));
Serial.print(gps.date.year());
}
else
{
Serial.print(F("INVALID"));
}
Serial.print(F(" "));
if (gps.time.isValid())
{
if (gps.time.hour() < 10)
Serial.print(F("0"));
Serial.print(gps.time.hour());
Serial.print(F(":"));
if (gps.time.minute() < 10)
Serial.print(F("0"));
Serial.print(gps.time.minute());
Serial.print(F(":"));
if (gps.time.second() < 10)
Serial.print(F("0"));
Serial.print(gps.time.second());
Serial.print(F("."));
if (gps.time.centisecond() < 10)
Serial.print(F("0"));
Serial.print(gps.time.centisecond());
String a = "";
a += String(gps.time.hour());
a += ":";
a += String(gps.time.minute());
a += ":";
a += String(gps.time.second());
tft.setFreeFont(FF30);
tft.setTextColor(TFT_CYAN, TFT_BLACK);
tft.drawString(a, 5, 100, GFXFF);
}
else
{
Serial.print(F("INVALID"));
}
Serial.println();
}
void smartDelay(unsigned long ms)
{
unsigned long start = millis();
do
{
while (serialGPS.available())
gps.encode(serialGPS.read());
} while (millis() - start < ms);
}

11
test/README Normal file
View File

@@ -0,0 +1,11 @@
This directory is intended for PlatformIO Test Runner and project tests.
Unit Testing is a software testing method by which individual units of
source code, sets of one or more MCU program modules together with associated
control data, usage procedures, and operating procedures, are tested to
determine whether they are fit for use. Unit testing finds problems early
in the development cycle.
More information about PlatformIO Unit Testing:
- https://docs.platformio.org/en/latest/advanced/unit-testing/index.html