Hello, I need some help/advice on how to improve my interactive game setup. I am trying to create an interactive agility light pod system where when one lights up you run to that pod and it will register with a hand and then randomly choose another pod to light up.
Any help is greatly appreciated!
Here is a list of everything I am using.
- NodeMCU ESP8266 CP2102 ESP-12E Module:
- NeoPixel LED Strip: 30 Leds
- TCRT5000 IR Sensor
- Power Supply using a 18650 battery with a capacity of 3300mAh and a TP4056 charger module with an integrated step-up converter.
- Resistors and Capacitors: For protection I pur a 1000µF capacitor across the power supply lines.
The setup:
Here is the code.
#include <Adafruit_NeoPixel.h>
#include <ESP8266WiFi.h>
#include <espnow.h>
#define RGBDATAPIN D2 // Adjust if needed, GPIO4
#define RGBLEDNUM 30
#define IRSENSOR_PIN D1 // Digital pin connected to the IR sensor, GPIO5
#define MY_ECU 3 // Change for each module (1, 2, 3)
#define ACTIVITY_TIMEOUT 120000 // 2 minutes of inactivity
// Colors defined as RGB tuples
#define COLOR_HAND_DETECTED pixels.Color(50, 50, 0) // Yellow
#define COLOR_COMM_SUCCESS pixels.Color(0, 255, 0) // Green
Adafruit_NeoPixel pixels(RGBLEDNUM, RGBDATAPIN, NEO_GRB + NEO_KHZ800);
// Replace these with the MAC addresses of your other modules
uint8_t receiverAddresses[][6] = {
{0x48, 0x55, 0x19, 0xED, 0xC9, 0x98}, // Module 1 MAC
{0x48, 0x55, 0x19, 0xED, 0xAA, 0xA4}, // Module 2 MAC
{0x48, 0x55, 0x19, 0xED, 0x0A, 0xD8} // Module 3 MAC
};
struct dataPacket {
int LED_Token = MY_ECU;
};
dataPacket packet;
unsigned long lastActivityTime = millis();
void setup() {
Serial.begin(115200);
pixels.begin();
pixels.show(); // Turn off all LEDs at the start
WiFi.mode(WIFI_STA);
WiFi.disconnect();
if (esp_now_init() != 0) {
Serial.println("ESP-NOW initialization failed");
return;
}
esp_now_set_self_role(ESP_NOW_ROLE_COMBO);
// Add ESP-NOW peers
for (int i = 0; i < sizeof(receiverAddresses) / 6; i++) {
if (i != MY_ECU - 1) { // Exclude its own address
esp_now_add_peer(receiverAddresses[i], ESP_NOW_ROLE_COMBO, 1, NULL, 0);
}
}
esp_now_register_recv_cb(OnDataRecv);
esp_now_register_send_cb(OnDataSent);
pinMode(IRSENSOR_PIN, INPUT); // Set the IR sensor pin as input
}
void loop() {
if (digitalRead(IRSENSOR_PIN) == LOW) { // Assuming LOW means detection
lastActivityTime = millis(); // Reset the activity timer on hand detection
lightUp(COLOR_HAND_DETECTED);
delay(500); // Delay for visual effect
passLightToRandomModule();
pixels.clear(); // Turn off LEDs of the current module
pixels.show();
}
if (millis() - lastActivityTime > ACTIVITY_TIMEOUT) { // Check for inactivity
pixels.clear(); // Turn off LEDs
pixels.show();
}
}
void lightUp(uint32_t color) {
for (int i = 0; i < RGBLEDNUM; i++) {
pixels.setPixelColor(i, color); // Set color
}
pixels.show();
}
void passLightToRandomModule() {
int selectedModuleIndex;
do {
selectedModuleIndex = random(0, sizeof(receiverAddresses) / 6); // Select a random module, excluding itself
} while ((selectedModuleIndex + 1) == MY_ECU);
Serial.print("Passing light to module: ");
Serial.println(selectedModuleIndex + 1);
esp_now_send(receiverAddresses[selectedModuleIndex], (uint8_t*)&packet, sizeof(packet));
}
void OnDataRecv(uint8_t* mac, uint8_t* incomingData, uint8_t len) {
memcpy(&packet, incomingData, sizeof(packet));
// Change LED color to indicate communication success
lightUp(COLOR_COMM_SUCCESS);
}
void OnDataSent(uint8_t* mac_addr, uint8_t sendStatus) {
Serial.print("Send status: ");
Serial.println(sendStatus);
}