#include #line 1 "C:\\Users\\chris\\Qsync\\Projects\\Scoreboard\\ScoreboardNumbers\\ScoreboardNumbers.ino" #include #include #include #include #include #include #include "objects.h" U8G2_SSD1306_128X64_NONAME_F_HW_I2C u8g2(U8G2_R0, /* clock=*/ SCL, /* data=*/ SDA, /* reset=*/ U8X8_PIN_NONE); // High speed I2C // Define pins for the 7-segment displays const int digitPins[4] = {2, 3, 4, 5}; // Common anode pins const int segmentPins[7] = {6, 7, 8, 9, 10, 11, 12}; // Segment pins (a, b, c, d, e, f, g) // Define the 7-segment display patterns const byte digitPatterns[10] = { B11111100, // 0 B01100000, // 1 B11011010, // 2 B11110010, // 3 B01100110, // 4 B10110110, // 5 B10111110, // 6 B11100000, // 7 B11111110, // 8 B11110110 // 9 }; // Wi-Fi settings const char* ssid = "study"; const char* password = "abcde54321"; const char* displayQueue = "dQ"; const char* jsonPoints = "points"; const int wifiLoopDelay = 5000 / portTICK_PERIOD_MS; const int displayLoopDelay = 1000 / portTICK_PERIOD_MS; const int httpPollDelay = 3000 / portTICK_PERIOD_MS; //FreeRTOS Queue Handles QueueHandle_t scoreQueue; // FreeRTOS task handles TaskHandle_t networkTaskHandle = NULL; TaskHandle_t displayTaskHandle = NULL; portMUX_TYPE critical = portMUX_INITIALIZER_UNLOCKED; // FreeRTOS Event Handles EventGroupHandle_t wifi_event_group; const int CONNECTED_BIT = BIT0; void networkTask(void * parameter); void displayTask(void * parameter); #line 55 "C:\\Users\\chris\\Qsync\\Projects\\Scoreboard\\ScoreboardNumbers\\ScoreboardNumbers.ino" void setup(); #line 104 "C:\\Users\\chris\\Qsync\\Projects\\Scoreboard\\ScoreboardNumbers\\ScoreboardNumbers.ino" void WiFiEvent(arduino_event_id_t event); #line 256 "C:\\Users\\chris\\Qsync\\Projects\\Scoreboard\\ScoreboardNumbers\\ScoreboardNumbers.ino" void displayNumber(int display, int digitValue); #line 287 "C:\\Users\\chris\\Qsync\\Projects\\Scoreboard\\ScoreboardNumbers\\ScoreboardNumbers.ino" void loop(); #line 55 "C:\\Users\\chris\\Qsync\\Projects\\Scoreboard\\ScoreboardNumbers\\ScoreboardNumbers.ino" void setup() { try { // Initialize Serial port Serial.begin(115200); #ifdef DEBUG Serial.println("Starting"); #endif //start display driver u8g2.begin(); u8g2.setFont(u8g2_font_ncenB08_tr); // choose a suitable font #ifdef DEBUG Serial.println("end dispInit"); #endif // Initialize the pins // for (int i = 0; i < 4; i++) { // pinMode(digitPins[i], OUTPUT); // digitalWrite(digitPins[i], HIGH); // Turn off all displays initially // } // for (int i = 0; i < 7; i++) { // pinMode(segmentPins[i], OUTPUT); // digitalWrite(segmentPins[i], LOW); // Turn off all segments initially // } WiFi.onEvent( WiFiEvent ); WiFi.mode(WIFI_STA); WiFi.disconnect(); #ifdef DEBUG Serial.println("end IO init"); #endif scoreQueue = xQueueCreate(2, sizeof( Scores ) ); wifi_event_group = xEventGroupCreate(); // Start the network task xTaskCreatePinnedToCore(networkTask, "Network Task", 20000, NULL, 3, &networkTaskHandle, 1); // Start the display task xTaskCreatePinnedToCore(displayTask, "Display Task", 20000, NULL, 4, &displayTaskHandle, 1 ); #ifdef DEBUG Serial.println("ended init"); #endif vTaskStartScheduler(); } catch(String err){ Serial.print("SetupError: "); Serial.println(err); } } void WiFiEvent(WiFiEvent_t event) { switch (event) { case SYSTEM_EVENT_STA_CONNECTED: Serial.println("Connected to access point"); break; case SYSTEM_EVENT_STA_DISCONNECTED: Serial.println("Disconnected from WiFi access point"); break; case SYSTEM_EVENT_AP_STADISCONNECTED: Serial.println("WiFi client disconnected"); break; default: break; } } void networkTask(void * parameter) { try { while(true){ while ( WiFi.status() != WL_CONNECTED ) { #ifdef DEBUG Serial.println("disconnected, connecting"); #endif WiFi.disconnect(); WiFi.begin( ssid, password ); #ifdef DEBUG Serial.println(" waiting on wifi connection" ); #endif vTaskDelay( 4000 ); } while (WiFi.status() != WL_CONNECTED) { xEventGroupClearBits(wifi_event_group, CONNECTED_BIT); #ifdef DEBUG Serial.println("Connecting to WiFi..."); #endif } xEventGroupSetBits(wifi_event_group, CONNECTED_BIT); #ifdef DEBUG Serial.println("Connected to WiFi"); #endif HTTPClient http; const String url = "https://192.168.1.141:7005/api/score/summary"; for (;;) { if(WiFi.status() != WL_CONNECTED){ continue; } #ifdef DEBUG Serial.println(url); #endif http.useHTTP10(true); http.begin(url.c_str()); http.addHeader("x-api-key", "396A62D6-0192-4738-8F45-8AAF7BCFA3EC"); int httpResponseCode = http.GET(); DynamicJsonDocument doc(2048); if (httpResponseCode>0) { //if no game, what code? #ifdef DEBUG Serial.print("HTTP Response code: "); Serial.println(httpResponseCode); #endif deserializeJson(doc, http.getStream()); } else { Serial.print("HTTP Req Error code: "); Serial.println(httpResponseCode); vTaskDelay(httpPollDelay); continue; } // Parse JSON Scores pts; pts.home = doc["home"].as(); pts.away = doc["away"].as(); pts.state = doc["state"].as(); #ifdef DEBUG Serial.print("Match State: "); Serial.print(doc["state"].as()); Serial.print("| Home: "); Serial.print(doc["home"].as()); Serial.print(" Away: "); Serial.println(doc["away"].as()); #endif http.end(); // Send the number to the display task xQueueSend(scoreQueue, &pts, portMAX_DELAY); vTaskDelay(httpPollDelay); // Wait before fetching the next update } vTaskDelay(wifiLoopDelay); } } catch (String err){ Serial.print("NetworkTaskError: "); Serial.println(err); } } void displayTask(void * parameter) { try { Scores matchScore; int wifiStateY = 10; int matchStateY = 35; int scoreY = 74-u8g2.getMaxCharHeight(); while(true) { u8g2.clearBuffer(); // clear the internal memory int bits = (xEventGroupGetBits( wifi_event_group)); if (bits & CONNECTED_BIT) { #ifdef DEBUG Serial.println("Connected"); #endif u8g2.drawStr(0,wifiStateY,"Connected! ;)"); // write something to the internal memory } else { #ifdef DEBUG Serial.println("Disconnected"); #endif u8g2.drawStr(0,wifiStateY,"Not Connected! :("); // write something to the internal memory } if (xQueueReceive(scoreQueue, &matchScore, portMAX_DELAY)) { // for (int i = 0; i < 4; i++) { // displayNumber(i, number / (int)pow(10, 3 - i) % 10); // Display the number // delay(5); // Delay to display the number // } u8g2.drawStr(0, matchStateY, matchScore.state.c_str()); String scoreMsg = "Home " + String(matchScore.home) + " Away " + String(matchScore.away); u8g2.drawStr(0,scoreY, scoreMsg.c_str()); } u8g2.sendBuffer(); // transfer internal memory to the display vTaskDelay(displayLoopDelay); // if (xQueueReceive(scoreQueue, &number, portMAX_DELAY)) { // for (int i = 0; i < 4; i++) { // displayNumber(i, number / (int)pow(10, 3 - i) % 10); // Display the number // delay(5); // Delay to display the number // } // } } } catch (String err){ Serial.print("DisplayLoopError: "); Serial.println(err); } } // Function to display a number on a specific 7-segment display void displayNumber(int display, int digitValue) { for (int i = 0; i < 7; i++) { if (bitRead(digitPatterns[digitValue], i)) { digitalWrite(segmentPins[i], HIGH); // Turn on the segment } else { digitalWrite(segmentPins[i], LOW); // Turn off the segment } } digitalWrite(digitPins[display], LOW); // Turn on the display } // String getStateString(GameState state){ // switch(state){ // case GameState::WaitingForStart: // return "Pending"; // case GameState::FirstHalf: // return "First Half"; // case GameState::SecondHalf: // return "Second Half"; // case GameState::HalfTime: // return "Half Time"; // case GameState::Finished: // return "Full Time"; // case GameState::None: // return "Not Configured"; // default: // "Other"; // } // } void loop() { // Empty loop, tasks handle everything }