#include #include #include // ---------- GOAL SENSORS ---------- #define SENSOR_LOCAL_TEAM D2 #define SENSOR_VISITOR_TEAM D9 int lastLocalSensorState = HIGH; int lastVisitorSensorState = HIGH; // ---------- BUTTONS ---------- #define BUTTON1 D4 #define BUTTON2 D6 int lastButton1State = HIGH; int lastButton2State = HIGH; // ---------- LEDS ---------- #define LED_LOCAL D3 #define LED_VISITOR D5 bool localLedActive = false; bool visitorLedActive = false; unsigned long localLedStart = 0; unsigned long visitorLedStart = 0; const unsigned long ledDuration = 1000; // ---------- DATA STRUCT ---------- typedef struct struct_message { bool goalLocal; bool goalVisitor; bool startStop; bool reset; } struct_message; struct_message message; // ---------- WAVESHARE MAC ---------- uint8_t receiverAddress[] = {0xE4, 0xB3, 0x23, 0xB1, 0xA4, 0x7C}; // ---------- SEND CALLBACK ---------- void onSent(const wifi_tx_info_t *info, esp_now_send_status_t status) { Serial.print("Send status: "); Serial.println(status == ESP_NOW_SEND_SUCCESS ? "OK" : "ERROR"); } void sendMessage() { esp_err_t result = esp_now_send(receiverAddress, (uint8_t *) &message, sizeof(message)); Serial.print("esp_now_send result: "); if (result == ESP_OK) { Serial.println("ESP_OK"); } else { Serial.print("ERROR code: "); Serial.println(result); } } // ---------- NON-BLOCKING LED TRIGGERS ---------- void triggerLocalLED() { digitalWrite(LED_LOCAL, HIGH); localLedActive = true; localLedStart = millis(); } void triggerVisitorLED() { digitalWrite(LED_VISITOR, HIGH); visitorLedActive = true; visitorLedStart = millis(); } void updateLeds() { unsigned long currentMillis = millis(); if (localLedActive && (currentMillis - localLedStart >= ledDuration)) { digitalWrite(LED_LOCAL, LOW); localLedActive = false; } if (visitorLedActive && (currentMillis - visitorLedStart >= ledDuration)) { digitalWrite(LED_VISITOR, LOW); visitorLedActive = false; } } void setup() { Serial.begin(115200); delay(2000); pinMode(SENSOR_LOCAL_TEAM, INPUT); pinMode(SENSOR_VISITOR_TEAM, INPUT); pinMode(BUTTON1, INPUT_PULLUP); pinMode(BUTTON2, INPUT_PULLUP); pinMode(LED_LOCAL, OUTPUT); pinMode(LED_VISITOR, OUTPUT); digitalWrite(LED_LOCAL, LOW); digitalWrite(LED_VISITOR, LOW); lastLocalSensorState = digitalRead(SENSOR_LOCAL_TEAM); lastVisitorSensorState = digitalRead(SENSOR_VISITOR_TEAM); lastButton1State = digitalRead(BUTTON1); lastButton2State = digitalRead(BUTTON2); WiFi.mode(WIFI_STA); WiFi.disconnect(); if (esp_now_init() != ESP_OK) { Serial.println("ESP-NOW init error"); return; } esp_now_register_send_cb(onSent); esp_now_peer_info_t peerInfo = {}; memcpy(peerInfo.peer_addr, receiverAddress, 6); peerInfo.channel = 0; peerInfo.encrypt = false; if (esp_now_add_peer(&peerInfo) != ESP_OK) { Serial.println("Peer add failed"); return; } Serial.println("XIAO ready (2 goal sensors + buttons sender)"); } void loop() { updateLeds(); message.goalLocal = false; message.goalVisitor = false; message.startStop = false; message.reset = false; // ---------- SENSOR LOCAL ---------- int currentLocalSensorState = digitalRead(SENSOR_LOCAL_TEAM); if (lastLocalSensorState == HIGH && currentLocalSensorState == LOW) { delay(20); if (digitalRead(SENSOR_LOCAL_TEAM) == LOW) { Serial.println("GOAL LOCAL ⚽"); message.goalLocal = true; sendMessage(); triggerLocalLED(); delay(200); } } lastLocalSensorState = currentLocalSensorState; // ---------- SENSOR VISITOR ---------- int currentVisitorSensorState = digitalRead(SENSOR_VISITOR_TEAM); if (lastVisitorSensorState == HIGH && currentVisitorSensorState == LOW) { delay(20); if (digitalRead(SENSOR_VISITOR_TEAM) == LOW) { Serial.println("GOAL VISITOR ⚽"); message.goalVisitor = true; sendMessage(); triggerVisitorLED(); delay(200); } } lastVisitorSensorState = currentVisitorSensorState; // ---------- BUTTON 1 ---------- int currentButton1State = digitalRead(BUTTON1); if (lastButton1State == HIGH && currentButton1State == LOW) { Serial.println("START / STOP"); message.startStop = true; sendMessage(); delay(200); } lastButton1State = currentButton1State; // ---------- BUTTON 2 ---------- int currentButton2State = digitalRead(BUTTON2); if (lastButton2State == HIGH && currentButton2State == LOW) { Serial.println("RESET"); message.reset = true; sendMessage(); delay(200); } lastButton2State = currentButton2State; }