This commit is contained in:
2026-05-06 09:14:35 +03:00
parent 4149376f54
commit 7bb6f5c0a0

View File

@@ -11,12 +11,12 @@
#define GPS_BAUD 9600 #define GPS_BAUD 9600
#define LED 2 #define LED 2
#define KEY_X 3 // start X #define KEY_X 0 // start X
#define KEY_Y 24 #define KEY_Y 0
#define KEY_W 76 // Key width #define KEY_W 240 // Key width
#define KEY_H 36 // Key height #define KEY_H 40 // Key height
#define KEY_SPACING_X 3 // X gap #define KEY_SPACING_X 1 // X gap
#define KEY_SPACING_Y 3 // Y gap #define KEY_SPACING_Y 1 // Y gap
#define KEY_TEXTSIZE 1 // Font size multiplier #define KEY_TEXTSIZE 1 // Font size multiplier
#define BUTTON_X_DELTA 22 #define BUTTON_X_DELTA 22
#define NUM_KEYS 3 #define NUM_KEYS 3
@@ -32,7 +32,7 @@ SemaphoreHandle_t spiMutex;
QueueHandle_t gpsQueue = NULL; QueueHandle_t gpsQueue = NULL;
char label[] = "label"; char label[] = "label";
String btnLabel[] = {"GPS", "DATE", "LOC"}; String btnLabel[3] = {"GPS DATA", "led state", "Other"};
// uint16_t calData[5] = { 293, 3474, 445, 3470, 0 }; // uint16_t calData[5] = { 293, 3474, 445, 3470, 0 };
// uint16_t calData[5] = { 314, 3512, 424, 3489, 0 }; // uint16_t calData[5] = { 314, 3512, 424, 3489, 0 };
@@ -44,6 +44,10 @@ struct GpsData
{ {
float lat; float lat;
float lng; float lng;
float speed;
float altitude;
uint8_t satellites;
bool isValid;
uint8_t hour; uint8_t hour;
uint8_t minute; uint8_t minute;
@@ -52,11 +56,6 @@ struct GpsData
uint16_t year; uint16_t year;
uint8_t month; uint8_t month;
uint8_t day; uint8_t day;
uint32_t sat;
float speed;
float alt;
bool isValid;
}; };
// struct GPSData1 { // struct GPSData1 {
@@ -72,12 +71,11 @@ struct GpsData
void smartDelay(unsigned long ms); void smartDelay(unsigned long ms);
void initDisplay(); void initDisplay();
void displayGPSInfo();
void drawButtons(); void drawButtons();
void taskBlink(void *pvParameters); void taskBlink(void *pvParameters);
void taskGPS(void *pvParameters); void taskGPS(void *pvParameters);
void taskTFT(void *pvParameters); void taskTFT(void *pvParameters);
void drawTitle(const char *title); void drawString(const char *title, uint32_t x, uint32_t y);
//------------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------------
void setup() void setup()
@@ -87,10 +85,20 @@ void setup()
Serial.printf("Starting FreeRTOS: Memory Usage\nInitial Free Heap: %u bytes\n", xPortGetFreeHeapSize()); Serial.printf("Starting FreeRTOS: Memory Usage\nInitial Free Heap: %u bytes\n", xPortGetFreeHeapSize());
gpsQueue = xQueueCreate(QUEUE_SIZE, sizeof(GpsData)); gpsQueue = xQueueCreate(QUEUE_SIZE, sizeof(GpsData));
spiMutex = xSemaphoreCreateMutex();
if (gpsQueue == NULL && spiMutex == NULL)
{
Serial.println("[Error] Failed to create queue or mutex");
while (1)
{
delay(100);
}
}
xTaskCreatePinnedToCore(taskBlink, "taskBlink", 2000, NULL, 1, &taskBlinkHandle, 0); xTaskCreatePinnedToCore(taskBlink, "taskBlink", 2000, NULL, 1, &taskBlinkHandle, 0);
xTaskCreatePinnedToCore(taskGPS, "taskGPS", 2000, NULL, 1, &taskGPSHandle, 0); xTaskCreatePinnedToCore(taskGPS, "taskGPS", 2000, NULL, 1, &taskGPSHandle, 0);
xTaskCreatePinnedToCore(taskTFT, "taskTFT", 2000, NULL, 1, NULL, 1); xTaskCreatePinnedToCore(taskTFT, "taskTFT", 32000, NULL, 1, NULL, 1);
} }
void loop() void loop()
@@ -110,6 +118,7 @@ void taskGPS(void *pvParameters)
Serial.println(xPortGetCoreID()); Serial.println(xPortGetCoreID());
GpsData data; GpsData data;
unsigned long lastSendTime = 0;
while (true) while (true)
{ {
@@ -118,22 +127,15 @@ void taskGPS(void *pvParameters)
gps.encode(serialGPS.read()); gps.encode(serialGPS.read());
} }
if (gps.location.isUpdated()) if (gps.location.isUpdated() && (millis() - lastSendTime > 1000))
{ {
data.lat = gps.location.lat(); data.lat = gps.location.lat();
data.lng = gps.location.lng(); data.lng = gps.location.lng();
data.speed = gps.speed.kmph(); data.speed = gps.speed.kmph();
data.alt = gps.altitude.meters(); data.altitude = gps.altitude.meters();
data.sat = gps.satellites.value(); data.satellites = gps.satellites.value();
data.isValid = gps.location.isValid();
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.year = gps.date.year();
data.month = gps.date.month(); data.month = gps.date.month();
data.day = gps.date.day(); data.day = gps.date.day();
@@ -141,11 +143,20 @@ void taskGPS(void *pvParameters)
data.minute = gps.time.minute(); data.minute = gps.time.minute();
data.second = gps.time.second(); data.second = gps.time.second();
Serial.printf("Date: %04d-%02d-%02d\n", data.year, data.month, data.day); // Serial.printf("Lat: %.6f, Lon: %.6f, Speed: %.1f km/h, Alt: %.1f m, Satellites: %d\n", data.lat, data.lng, data.speed, data.alt, data.sat);
Serial.printf("Time: %02d:%02d:%02d\n", data.hour, data.minute, data.second); // Serial.printf("Date: %04d-%02d-%02d Time: %02d:%02d:%02d\n", data.year, data.month, data.day, data.hour, data.minute, data.second);
if (xQueueSend(gpsQueue, &data, pdMS_TO_TICKS(100)) != pdTRUE)
{
Serial.println("[Gps] queue is full!");
}
else
{
lastSendTime = millis();
}
} }
vTaskDelay(1000 / portTICK_PERIOD_MS); vTaskDelay(100 / portTICK_PERIOD_MS);
// Serial.printf("TaskGPS Stack Free: %u bytes\n", uxTaskGetStackHighWaterMark(NULL)); // Serial.printf("TaskGPS Stack Free: %u bytes\n", uxTaskGetStackHighWaterMark(NULL));
} }
} }
@@ -171,25 +182,101 @@ void taskBlink(void *pvParameters)
void taskTFT(void *pvParameters) void taskTFT(void *pvParameters)
{ {
initDisplay(); initDisplay();
// drawTitle("Hello world!");
// drawButtons();
drawTitle("Hello world!"); TFT_eSprite spr = TFT_eSprite(&tft);
spr.createSprite(tft.width(), tft.height()/2);
drawButtons(); GpsData data;
bool hasNewData = false;
char latBuffer[20], lngBuffer[20], altBuffer[20], timeBuffer[20], dateBuffer[20];
char satelitesBuffer[20];
for (;;) while (true)
{ {
// Serial.printf("taskTFT Stack Free: %u bytes\n", uxTaskGetStackHighWaterMark(NULL)); // Serial.printf("taskTFT Stack Free: %u bytes\n", uxTaskGetStackHighWaterMark(NULL));
vTaskDelay(2000 / portTICK_PERIOD_MS);
if (xQueueReceive(gpsQueue, &data, 0) == pdTRUE)
{
hasNewData = true;
Serial.println("[UI] get new data from gps");
}
if (hasNewData)
{
// Serial.printf("Lat: %.6f, Lon: %.6f, Speed: %.1f km/h, Alt: %.1f m, Satellites: %d\n", data.lat, data.lng, data.speed, data.alt, data.sat);
// Serial.printf("Date: %04d-%02d-%02d Time: %02d:%02d:%02d\n", data.year, data.month, data.day, data.hour, data.minute, data.second);
if (xSemaphoreTake(spiMutex, pdMS_TO_TICKS(100)) == pdTRUE)
{
snprintf(latBuffer, sizeof(latBuffer), "LAT: %.6f", data.lat);
snprintf(lngBuffer, sizeof(lngBuffer), "LNG: %.6f", data.lng);
snprintf(altBuffer, sizeof(altBuffer), "ALTITUDE: %.1f m", data.altitude);
snprintf(satelitesBuffer, sizeof(satelitesBuffer), "Satellites: %d", data.satellites);
snprintf(timeBuffer, sizeof(timeBuffer), "TIME: %02d:%02d:%02d", data.hour, data.minute, data.second);
snprintf(dateBuffer, sizeof(dateBuffer), "DATE: %04d-%02d-%02d", data.year, data.month, data.day);
// tft.fillScreen(TFT_BLACK);
// tft.setCursor(0, 20);
// tft.printf("Date: %04d-%02d-%02d", data.year, data.month, data.day);
// tft.setCursor(0, 40);
// tft.printf("Time: %02d:%02d:%02d", data.hour, data.minute, data.second);
// tft.setCursor(0, 60);
// tft.setTextPadding(240);
// tft.print(latBuffer);
// tft.setCursor(0, 80);
// tft.printf("Lon: %.6f", data.lng);
// tft.setCursor(0, 100);
// tft.printf("Speed: %.1f km/h", data.speed);
// tft.setCursor(0, 120);
// tft.printf("Satellites: %d", data.satellites);
// spr.printf("Alt: %.1f m", data.altitude);
// drawString("ABCDEFGHIJKLMNOPQRST", 0,0);
// drawString(timeBuffer, 0, 100);
// drawString(altBuffer, 0, 150);
spr.fillSprite(TFT_BLUE);
spr.setTextDatum(TL_DATUM);
spr.drawString(dateBuffer, 0, 0, FONT4);
spr.drawString(timeBuffer, 0, 20, FONT4);
spr.drawString(latBuffer, 0, 40, FONT4);
spr.drawString(lngBuffer, 0, 60, FONT4);
spr.drawString(satelitesBuffer, 0, 80, FONT4);
spr.pushSprite(0, 0);
uint16_t x = 0, y = 0;
if (tft.getTouch(&x, &y))
{
tft.fillCircle(x, y, 3, TFT_BLUE);
}
xSemaphoreGive(spiMutex);
hasNewData = false;
}
}
vTaskDelay(50 / portTICK_PERIOD_MS);
Serial.printf("TaskTFT Stack Free: %u bytes\n", uxTaskGetStackHighWaterMark(NULL));
} }
} }
void loop_1() void loop_1()
{ {
if (gps.location.isUpdated())
{
displayGPSInfo();
}
uint16_t t_x = 0, t_y = 0; // To store the touch coordinates uint16_t t_x = 0, t_y = 0; // To store the touch coordinates
// Get current touch state and coordinates // Get current touch state and coordinates
@@ -242,15 +329,16 @@ void loop_1()
void drawButtons() void drawButtons()
{ {
tft.setFreeFont(FF1);
for (int i = 0; i < NUM_KEYS; i++) for (int i = 0; i < NUM_KEYS; i++)
{ {
key[i].initButtonUL(&tft, key[i].initButtonUL(&tft,
KEY_X + i * (KEY_W + KEY_SPACING_X), KEY_X,
KEY_Y, KEY_Y + i * (KEY_H + KEY_SPACING_Y),
KEY_W, KEY_W,
KEY_H, KEY_H,
TFT_LIGHTGREY, TFT_WHITE,
TFT_DARKGREY, TFT_BLACK,
TFT_WHITE, TFT_WHITE,
label, label,
KEY_TEXTSIZE); KEY_TEXTSIZE);
@@ -275,81 +363,16 @@ void initDisplay()
digitalWrite(TFT_BL, HIGH); digitalWrite(TFT_BL, HIGH);
#endif #endif
tft.setFreeFont(FF1);
tft.setTextColor(TFT_WHITE, TFT_BLACK);
tft.fillScreen(TFT_BLACK); tft.fillScreen(TFT_BLACK);
} }
void drawTitle(const char *title) void drawString(const char *title, uint32_t x, uint32_t y)
{ {
tft.setFreeFont(FF5); tft.setFreeFont(FF1);
tft.setTextColor(TFT_YELLOW, TFT_BLACK); tft.setTextColor(TFT_WHITE, TFT_BLACK);
tft.drawString(title, 0, 0, GFXFF); tft.drawString(title, x, y, 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) void smartDelay(unsigned long ms)