Compare commits

...
2 Commits
4 changed files with 115 additions and 16 deletions

No files matched your search

+3
View File
@@ -0,0 +1,3 @@
{
"cmake.ignoreCMakeListsMissing": true
}
+1
View File
@@ -17,3 +17,4 @@ build_flags =
-I include -I include
-DPIO_FRAMEWORK_ARDUINO_ENABLE_FREERTOS -DPIO_FRAMEWORK_ARDUINO_ENABLE_FREERTOS
build_src_filter = +<main.cpp> build_src_filter = +<main.cpp>
lib_deps = bblanchon/ArduinoJson@7.4.3
+95 -6
View File
@@ -3,26 +3,115 @@
#include "FreeRTOS.h" #include "FreeRTOS.h"
#include "task.h" #include "task.h"
#include "secrets.h" #include "secrets.h"
#include "ArduinoJson.h"
struct race_info {
char session_name[50];
char date_start[32];
char circuit_short_name[50];
uint16_t session_key;
uint16_t meeting_key;
uint16_t circuit_key;
};
extern race_info next_race;
static int get_race_query_url(char* target, size_t target_size) {
if (target == NULL) return -1;
time_t now = time(nullptr);
struct tm timeinfo, futureTime;
localtime_r(&now, &timeinfo);
futureTime = timeinfo;
futureTime.tm_mon += 2;
mktime(&futureTime);
char date_buffer[12];
char fdate_buffer[12];
Serial.print("");
strftime(date_buffer, sizeof(date_buffer), "%Y-%m-%d", &timeinfo);
Serial.printf("Current Date: %s\n", date_buffer);
strftime(fdate_buffer, sizeof(fdate_buffer), "%Y-%m-%d", &futureTime);
Serial.printf("Future Date: %s\n", fdate_buffer);
snprintf(target, target_size, "https://api.openf1.org/v1/sessions?date_start>=%s&date_start<=%s&session_type=Race",
date_buffer,
fdate_buffer);
return 0;
}
int parse_session_json() {
}
void get_next_race(void *pvParameters) { void get_next_race(void *pvParameters) {
TickType_t retryDelay = pdMS_TO_TICKS(10000); TickType_t retryDelay = pdMS_TO_TICKS(10000);
while (true) { while (true) {
if (WiFi.status() == WL_CONNECTED) { if (WiFi.status() == WL_CONNECTED) {
retryDelay = pdMS_TO_TICKS(10000); retryDelay = pdMS_TO_TICKS(10000);
HTTPClient http; HTTPClient http;
http.setTimeout(10000);
http.setCACert(OPENF1_ROOT_CA); http.setCACert(OPENF1_ROOT_CA);
const bool requestReady = http.begin(
"https://api.openf1.org/v1/sessions?date_start%3E=2026-11-01&date_start%3C=2026-12-01&session_type=Race"); char query_url[103];
get_race_query_url(query_url, sizeof(query_url));
Serial.print("");
Serial.print("Query: ");
Serial.println(query_url);
const bool requestReady = http.begin(query_url);
if (!requestReady) { if (!requestReady) {
Serial.print(""); Serial.print("");
Serial.println("Failed to initialize OpenF1 request."); Serial.println("Failed to initialize OpenF1 request.");
} else { } else {
const int httpResponseCode = http.GET(); const int httpResponseCode = http.GET();
if (httpResponseCode > 0) { if (httpResponseCode > 0) {
String response = http.getString(); Stream& responseStream = http.getStream();
Serial.printf("HTTP Size: %d\n", http.getSize());
JsonDocument json;
const DeserializationError err = deserializeJson(json, responseStream);
if (err == DeserializationError::Ok) {
JsonArray sessions = json.as<JsonArray>();
if (sessions.size() != 0) {
JsonObject nextRaceJson = sessions[0];
const char* sessionName = nextRaceJson[F("session_name")];
const char* dateStart = nextRaceJson[F("date_start")];
const char* circuitName = nextRaceJson[F("circuit_short_name")];
next_race.session_key = nextRaceJson[F("session_key")];
next_race.meeting_key = nextRaceJson[F("meeting_key")];
next_race.circuit_key = nextRaceJson[F("circuit_key")];
if (sessionName != NULL) {
strlcpy(next_race.session_name, sessionName, sizeof(next_race.session_name));
}
if (dateStart != NULL) {
strlcpy(next_race.date_start, dateStart, sizeof(next_race.date_start));
}
if (circuitName != NULL) {
strlcpy(next_race.circuit_short_name, circuitName, sizeof(next_race.circuit_short_name));
}
Serial.print(""); Serial.print("");
Serial.println("Received response from OpenF1 API:"); Serial.print("Next race: ");
Serial.println(response); Serial.print(next_race.session_name);
Serial.print(" at ");
Serial.print(next_race.circuit_short_name);
Serial.print(" on ");
Serial.println(next_race.date_start);
}
} else {
Serial.print("");
Serial.print("Failed to parse JSON response: ");
Serial.println(err.c_str());
}
retryDelay = pdMS_TO_TICKS(900000); retryDelay = pdMS_TO_TICKS(900000);
} else { } else {
Serial.print(""); Serial.print("");
@@ -36,7 +125,7 @@ void get_next_race(void *pvParameters) {
http.end(); http.end();
} else { } else {
Serial.print(""); Serial.print("");
Serial.println("WiFi not connected."); Serial.println("WiFi not connecteFormattedd.");
} }
vTaskDelay(retryDelay); vTaskDelay(retryDelay);
} }
+16 -10
View File
@@ -21,6 +21,7 @@ static constexpr UWORD COUNTER_HEIGHT = 24;
static constexpr UWORD COUNTER_Y = 20; static constexpr UWORD COUNTER_Y = 20;
static UBYTE counterBuffer[(COUNTER_WIDTH / 8) * COUNTER_HEIGHT]; static UBYTE counterBuffer[(COUNTER_WIDTH / 8) * COUNTER_HEIGHT];
static int counter = 0; static int counter = 0;
race_info next_race;
void wifi_connect() { void wifi_connect() {
WiFi.setHostname(DEVICE_HOSTNAME); WiFi.setHostname(DEVICE_HOSTNAME);
@@ -89,12 +90,17 @@ void display_loop(void *pvParameters) {
lastRefresh = millis(); lastRefresh = millis();
counter++; counter++;
if (next_race.session_key == 0) {
snprintf(counterStr, sizeof(counterStr), "Counter: %d", counter); snprintf(counterStr, sizeof(counterStr), "Counter: %d", counter);
Serial.print(""); Serial.print("");
Serial.println(counterStr); Serial.println(counterStr);
} else {
snprintf(counterStr, sizeof(counterStr), "%s", next_race.circuit_short_name);
}
Paint_Clear(WHITE); Paint_Clear(WHITE);
Paint_DrawString_EN(10, 0, counterStr, &Font16, BLACK, WHITE); Paint_DrawString_EN(10, 0, counterStr, &Font16, WHITE, BLACK);
EPD_4IN2_V2_PartialDisplay( EPD_4IN2_V2_PartialDisplay(
counterBuffer, counterBuffer,
@@ -117,7 +123,14 @@ void setup() {
EPD_4IN2_V2_Init(); EPD_4IN2_V2_Init();
Serial.println("e-Paper initialization complete; clearing display..."); Serial.println("e-Paper initialization complete; clearing display...");
EPD_4IN2_V2_Clear(); //EPD_4IN2_V2_Clear();
Paint_NewImage(displayBuffer, EPD_4IN2_V2_WIDTH, EPD_4IN2_V2_HEIGHT, ROTATE_0, WHITE);
Paint_SelectImage(displayBuffer);
Paint_Clear(WHITE);
Paint_DrawString_EN(10, 0, "F1 Display Booting...", &Font16, WHITE, BLACK);
Paint_DrawString_EN(10, COUNTER_Y, "Counter: 0", &Font16, WHITE, BLACK);
EPD_4IN2_V2_Display(displayBuffer);
DEV_Delay_ms(500); DEV_Delay_ms(500);
@@ -125,16 +138,9 @@ void setup() {
sync_time(); sync_time();
printf("Begin display loop.\n"); printf("Begin display loop.\n");
Paint_NewImage(displayBuffer, EPD_4IN2_V2_WIDTH, EPD_4IN2_V2_HEIGHT, ROTATE_0, WHITE);
Paint_SelectImage(displayBuffer);
Paint_Clear(WHITE);
Paint_DrawString_EN(10, 0, "F1 Display Test", &Font16, BLACK, WHITE);
Paint_DrawString_EN(10, COUNTER_Y, "Counter: 0", &Font16, BLACK, WHITE);
EPD_4IN2_V2_Display(displayBuffer);
Paint_NewImage(counterBuffer, COUNTER_WIDTH, COUNTER_HEIGHT, ROTATE_0, WHITE); Paint_NewImage(counterBuffer, COUNTER_WIDTH, COUNTER_HEIGHT, ROTATE_0, WHITE);
Paint_SelectImage(counterBuffer); Paint_SelectImage(counterBuffer);
xTaskCreate(display_loop, "display_loop", 1024, NULL, 5, NULL); xTaskCreate(display_loop, "display_loop", 1024, NULL, 5, NULL);
xTaskCreate(get_next_race, "get_next_race", 4096, NULL, 5, NULL); xTaskCreate(get_next_race, "get_next_race", 2048, NULL, 5, NULL);
} }