From 7bb6f5c0a0b57ea532ffa7287a95962201e64c3b Mon Sep 17 00:00:00 2001 From: Vadim Date: Wed, 6 May 2026 09:14:35 +0300 Subject: [PATCH] sptite --- src/main.cpp | 251 ++++++++++++++++++++++++++++----------------------- 1 file changed, 137 insertions(+), 114 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index 9b62cdf..f91d211 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -11,12 +11,12 @@ #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_X 0 // start X +#define KEY_Y 0 +#define KEY_W 240 // Key width +#define KEY_H 40 // Key height +#define KEY_SPACING_X 1 // X gap +#define KEY_SPACING_Y 1 // Y gap #define KEY_TEXTSIZE 1 // Font size multiplier #define BUTTON_X_DELTA 22 #define NUM_KEYS 3 @@ -32,7 +32,7 @@ SemaphoreHandle_t spiMutex; QueueHandle_t gpsQueue = NULL; 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] = { 314, 3512, 424, 3489, 0 }; @@ -44,6 +44,10 @@ struct GpsData { float lat; float lng; + float speed; + float altitude; + uint8_t satellites; + bool isValid; uint8_t hour; uint8_t minute; @@ -52,11 +56,6 @@ struct GpsData uint16_t year; uint8_t month; uint8_t day; - - uint32_t sat; - float speed; - float alt; - bool isValid; }; // struct GPSData1 { @@ -72,12 +71,11 @@ struct GpsData 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 drawString(const char *title, uint32_t x, uint32_t y); //------------------------------------------------------------------------------------------ void setup() @@ -87,10 +85,20 @@ void setup() Serial.printf("Starting FreeRTOS: Memory Usage\nInitial Free Heap: %u bytes\n", xPortGetFreeHeapSize()); 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(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() @@ -110,6 +118,7 @@ void taskGPS(void *pvParameters) Serial.println(xPortGetCoreID()); GpsData data; + unsigned long lastSendTime = 0; while (true) { @@ -118,34 +127,36 @@ void taskGPS(void *pvParameters) gps.encode(serialGPS.read()); } - if (gps.location.isUpdated()) + if (gps.location.isUpdated() && (millis() - lastSendTime > 1000)) { 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(); + data.altitude = gps.altitude.meters(); + 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.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); + + // 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 (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)); } } @@ -171,25 +182,101 @@ void taskBlink(void *pvParameters) void taskTFT(void *pvParameters) { 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)); - 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() { - if (gps.location.isUpdated()) - { - displayGPSInfo(); - } - uint16_t t_x = 0, t_y = 0; // To store the touch coordinates // Get current touch state and coordinates @@ -242,15 +329,16 @@ void loop_1() void drawButtons() { + tft.setFreeFont(FF1); for (int i = 0; i < NUM_KEYS; i++) { key[i].initButtonUL(&tft, - KEY_X + i * (KEY_W + KEY_SPACING_X), - KEY_Y, + KEY_X, + KEY_Y + i * (KEY_H + KEY_SPACING_Y), KEY_W, KEY_H, - TFT_LIGHTGREY, - TFT_DARKGREY, + TFT_WHITE, + TFT_BLACK, TFT_WHITE, label, KEY_TEXTSIZE); @@ -275,81 +363,16 @@ void initDisplay() digitalWrite(TFT_BL, HIGH); #endif + tft.setFreeFont(FF1); + tft.setTextColor(TFT_WHITE, 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.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(); + tft.setFreeFont(FF1); + tft.setTextColor(TFT_WHITE, TFT_BLACK); + tft.drawString(title, x, y, GFXFF); } void smartDelay(unsigned long ms)