From bba3a5d50bdb4fdd2fc9e4796a93a03b1d2dbdc5 Mon Sep 17 00:00:00 2001 From: Robin Cerny Date: Wed, 6 May 2026 20:47:46 +0200 Subject: [PATCH] added functionality for a camera controller --- .../ROFLS_Arena_Camera_Controller.ino | 116 ++++++++++++++++++ ROFLS_Arena_Remote/ROFLS_Arena_Remote.ino | 34 +++-- 2 files changed, 141 insertions(+), 9 deletions(-) create mode 100644 ROFLS_Arena_Camera_Controller/ROFLS_Arena_Camera_Controller.ino diff --git a/ROFLS_Arena_Camera_Controller/ROFLS_Arena_Camera_Controller.ino b/ROFLS_Arena_Camera_Controller/ROFLS_Arena_Camera_Controller.ino new file mode 100644 index 0000000..f50f0f1 --- /dev/null +++ b/ROFLS_Arena_Camera_Controller/ROFLS_Arena_Camera_Controller.ino @@ -0,0 +1,116 @@ +#include +#include +#include + +const int camPin = 16; // Any GPIO pin +const int pressTime = 250; // 0.25s HIGH pulse +const int gapTime = 250; // Gap between pulses for double press + +void doSinglePress() { + digitalWrite(camPin, HIGH); + delay(pressTime); + digitalWrite(camPin, LOW); +} + +void doDoublePress() { + doSinglePress(); + delay(gapTime); + doSinglePress(); +} + +// Must match the sender struct exactly +typedef struct struct_message_send { + int boardID; + bool buttonSTART; + bool buttonSTARTforced; + bool buttonPAUSE; + bool buttonPIT; + bool buttonPIThold; + bool buttonRESET; + bool buttonREDTEAM; + bool buttonREDTEAMtapout; + bool buttonBLUETEAM; + bool buttonBLUETEAMtapout; +} struct_message_send; + +struct_message_send incoming; + +// Recording state variable +bool RECORDING = false; +bool lastRECORDING = false; // for change detection + +// LED blink timing +unsigned long lastBlink = 0; +bool ledState = false; + +// ESP‑NOW receive callback +void onDataRecv(const esp_now_recv_info *info, const uint8_t *data, int len) { + if (len != sizeof(incoming)) return; + + memcpy(&incoming, data, sizeof(incoming)); + + // Only accept packets from boardID 0 (referee remote) + if (incoming.boardID != 0) return; + + // START or STARTforced → RECORDING = true + if (incoming.buttonSTART || incoming.buttonSTARTforced) { + RECORDING = true; + } + + // RESET → RECORDING = false + if (incoming.buttonRESET) { + RECORDING = false; + } +} + +void setup() { + pinMode(camPin, OUTPUT); + digitalWrite(camPin, LOW); // Idle state + + Serial.begin(115200); + delay(200); + + Serial.println("Extra Receiver Ready"); + + pinMode(LED_BUILTIN, OUTPUT); + digitalWrite(LED_BUILTIN, LOW); + + WiFi.mode(WIFI_STA); + WiFi.setSleep(false); + + if (esp_now_init() != ESP_OK) { + Serial.println("ESP‑NOW init failed!"); + return; + } + + esp_now_register_recv_cb(onDataRecv); +} + +void loop() { + // Detect changes in RECORDING state + if (RECORDING != lastRECORDING) { + + // Debug print + Serial.print("RECORDING state changed: "); + Serial.println(RECORDING ? "TRUE" : "FALSE"); + + // Trigger camera once on state change + doSinglePress(); + + lastRECORDING = RECORDING; + } + + // Non‑blocking LED blink when RECORDING = true + if (RECORDING) { + unsigned long now = millis(); + if (now - lastBlink >= 1000) { // blink every 1s + lastBlink = now; + ledState = !ledState; + digitalWrite(LED_BUILTIN, ledState); + } + } else { + // Ensure LED is off when not recording + digitalWrite(LED_BUILTIN, LOW); + ledState = false; + } +} diff --git a/ROFLS_Arena_Remote/ROFLS_Arena_Remote.ino b/ROFLS_Arena_Remote/ROFLS_Arena_Remote.ino index ab27b2a..006b624 100644 --- a/ROFLS_Arena_Remote/ROFLS_Arena_Remote.ino +++ b/ROFLS_Arena_Remote/ROFLS_Arena_Remote.ino @@ -13,7 +13,7 @@ // 1 = Red Team Button // 2 = Blue Team Button const bool writeBoardID = false; -int boardID = 1; +int boardID = 0; // set Arena, switches the MAC addresses out // 1 = Arena A (Ant) @@ -54,9 +54,13 @@ bool sendDATAvar = false; #if ARENA == 1 // A Arena Controller MAC Address uint8_t broadcastAddress[] = {0x84, 0xFC, 0xE6, 0xC7, 0x1A, 0x8C}; + // Additional receiver MAC address + uint8_t extraReceiverMAC[] = { 0x78, 0x42, 0x1C, 0x6B, 0x2A, 0x4C }; // replace with real MAC #elif ARENA == 2 // B Arena Controller MAC Address uint8_t broadcastAddress[] = {0xD8, 0x3B, 0xDA, 0xC9, 0x0C, 0xEE}; + // Additional receiver MAC address + uint8_t extraReceiverMAC[] = { 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF }; // replace with real MAC #endif // Structure example to send data @@ -86,8 +90,6 @@ typedef struct struct_message_receive { // Create instance for receiving ESP-NOW data struct_message_receive receiveDATA; -esp_now_peer_info_t peerInfo; - Preferences preferences; // callback when data is sent @@ -138,13 +140,25 @@ void setup() { // get the status of Transmitted packet esp_now_register_send_cb(OnDataSent); - // Register peer - memcpy(peerInfo.peer_addr, broadcastAddress, 6); - peerInfo.channel = 0; - peerInfo.encrypt = false; + // Register peer 1 (arena controller) + esp_now_peer_info_t peerInfo1 = {}; + memcpy(peerInfo1.peer_addr, broadcastAddress, 6); + peerInfo1.channel = 0; + peerInfo1.encrypt = false; // Add peer - if (esp_now_add_peer(&peerInfo) != ESP_OK){ - Serial.println("Failed to add peer"); + if (esp_now_add_peer(&peerInfo1) != ESP_OK){ + Serial.println("Failed to add peer1"); + return; + } + + // Register peer 2 (extra receiver) + esp_now_peer_info_t peerInfo2 = {}; + memcpy(peerInfo2.peer_addr, extraReceiverMAC, 6); + peerInfo2.channel = 0; + peerInfo2.encrypt = false; + // Add peer + if (esp_now_add_peer(&peerInfo2) != ESP_OK){ + Serial.println("Failed to add peer2"); return; } @@ -183,6 +197,8 @@ void sendDATA_to_controller() { sendDATA.buttonBLUETEAMtapout = buttonBLUETEAMtapout; // send data esp_err_t result = esp_now_send(broadcastAddress, (uint8_t *) &sendDATA, sizeof(sendDATA)); + esp_now_send(extraReceiverMAC, (uint8_t *) &sendDATA, sizeof(sendDATA)); + // check if transmission was successfull // if (result == ESP_OK) { // Serial.println("Sent with success");