From 008cd645cce715bff9ac8ffba2a664d21182dec5 Mon Sep 17 00:00:00 2001 From: Joe Tretter Date: Wed, 1 Nov 2023 11:57:02 -0500 Subject: [PATCH] Implement handling for Power LED and big LED --- src/main.cpp | 127 ++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 91 insertions(+), 36 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index a80973c..954bcb7 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -3,14 +3,20 @@ #include // GPIOs -#define GPIO_EMERGENCY_LED 5 +#define GPIO_EMERGENCY_LED_SMALL 5 +#define GPIO_EMERGENCY_LED_RED 13 +#define GPIO_EMERGENCY_LED_GREEN 12 +#define GPIO_EMERGENCY_LED_BLUE 14 + +#define GPIO_POWER_LED 18 #define GPIO_SYNC_LED 19 #define GPIO_REQUESTED_STATE_LED 2 + #define GPIO_EMERGENCY_BUTTON 16 // Software Parameters #define LOOP_DELAY 1 -#define PING_TIMEOUT_NUM_LOOPS 2 +#define PING_TIMEOUT_NUM_LOOPS 3 #define EMERGENCY_BUTTON_SCAN_RATE_SECONDS 1 String macList[2] = {"24:6F:28:B1:EE:74", "24:6F:28:B2:40:8C"}; @@ -19,8 +25,9 @@ uint8_t macRemoteIntArr[6]; esp_now_peer_info_t peerInfo={}; int64_t lastPingUptimeInSeconds; volatile int64_t lastButtonPushUptimeInSeconds; -boolean isReceiverEmergencyLedOn; +volatile boolean isReceiverEmergencyLedOn; volatile boolean isSenderEmergency; +TaskHandle_t BigLEDTask; typedef struct struct_info { boolean isEmergency; @@ -29,7 +36,6 @@ typedef struct struct_info { } struct_info; struct_info myData; - int64_t getUptimeInSeconds(){ return esp_timer_get_time()/1000000; } @@ -53,10 +59,10 @@ void OnDataRecv(const uint8_t * mac, const uint8_t *incomingData, int len) { } if(myData.isEmergency) { - digitalWrite(GPIO_EMERGENCY_LED,HIGH); + digitalWrite(GPIO_EMERGENCY_LED_SMALL,HIGH); isReceiverEmergencyLedOn=true; } else { - digitalWrite(GPIO_EMERGENCY_LED,LOW); + digitalWrite(GPIO_EMERGENCY_LED_SMALL,LOW); isReceiverEmergencyLedOn=false; } } @@ -71,6 +77,7 @@ void OnButtonPushed(){ } } +// Convert single hex char to integer int char2int(char input) { if(input >= '0' && input <= '9') @@ -93,9 +100,79 @@ void hex2bin(const char* src, uint8_t* target) } } +// the big LED should flash when we are in emergency state. +void BigLEDTaskCode(void * parameter){ + // Test the channels of the big LED + digitalWrite(GPIO_EMERGENCY_LED_GREEN,LOW); + digitalWrite(GPIO_EMERGENCY_LED_BLUE,LOW); + digitalWrite(GPIO_EMERGENCY_LED_RED,HIGH); + sleep(1); + digitalWrite(GPIO_EMERGENCY_LED_RED,LOW); + digitalWrite(GPIO_EMERGENCY_LED_GREEN,HIGH); + sleep(1); + digitalWrite(GPIO_EMERGENCY_LED_GREEN,LOW); + digitalWrite(GPIO_EMERGENCY_LED_BLUE,HIGH); + sleep(1); + digitalWrite(GPIO_EMERGENCY_LED_BLUE,LOW); + + // Blink in emergecy mode. + for(;;){ + if (isReceiverEmergencyLedOn){ + digitalWrite(GPIO_EMERGENCY_LED_BLUE,HIGH); + delay(100); + digitalWrite(GPIO_EMERGENCY_LED_BLUE,LOW); + + delay(250); + digitalWrite(GPIO_EMERGENCY_LED_RED,HIGH); + delay(100); + digitalWrite(GPIO_EMERGENCY_LED_RED,LOW); + + delay(500); + } + } +} + +void setPowerLEDBrightness(int brightnessValue){ + // setting PWM properties + const int freq = 5000; + const int ledChannel = 0; + const int resolution = 8; + + ledcSetup(ledChannel, freq, resolution); + ledcAttachPin(GPIO_POWER_LED, ledChannel); + ledcWrite(ledChannel, brightnessValue); +} + void setup(){ + // GPIO Setup + pinMode(GPIO_POWER_LED,OUTPUT); + pinMode(GPIO_EMERGENCY_LED_RED,OUTPUT); + pinMode(GPIO_EMERGENCY_LED_GREEN,OUTPUT); + pinMode(GPIO_EMERGENCY_LED_BLUE,OUTPUT); + pinMode(GPIO_EMERGENCY_LED_SMALL, OUTPUT); + pinMode(GPIO_REQUESTED_STATE_LED, OUTPUT); + pinMode(GPIO_SYNC_LED,OUTPUT); + pinMode(GPIO_EMERGENCY_BUTTON,INPUT_PULLDOWN); + + // Initialize state + digitalWrite(GPIO_POWER_LED,HIGH); //Power LED ON + digitalWrite(GPIO_REQUESTED_STATE_LED,LOW); + digitalWrite(GPIO_EMERGENCY_LED_SMALL,LOW); + digitalWrite(GPIO_SYNC_LED,LOW); + + myData.isPing=1; + myData.macOfSender=""; + isReceiverEmergencyLedOn=false; + myData.isEmergency=false; + isSenderEmergency=false; + lastButtonPushUptimeInSeconds=getUptimeInSeconds(); + + // The button triggers an interrupt, attach callback function + attachInterrupt(GPIO_EMERGENCY_BUTTON, OnButtonPushed, RISING); + sleep(LOOP_DELAY); // give the serial monitor a moment to connect. Serial.begin(115200); + WiFi.mode(WIFI_MODE_STA); macLocal=WiFi.macAddress(); macRemote=macList[macList[0]==macLocal?1:0]; @@ -116,18 +193,7 @@ void setup(){ macRemoteNoColon.replace(":",""); char macRemoteNoColonCharArr[13]; macRemoteNoColon.toCharArray(macRemoteNoColonCharArr,sizeof(macRemoteNoColonCharArr)); - - for (int i=0;i<12;i++){ - Serial.print( macRemoteNoColonCharArr[i]); - Serial.print("."); - } - Serial.println("<--- HEX CA"); - hex2bin(macRemoteNoColonCharArr,macRemoteIntArr); - for (int i=0;i<6;i++){ - Serial.printf( "%d|%X - ",macRemoteIntArr[i],macRemoteIntArr[i]); - } - Serial.println("<--- DEC REM"); memcpy(peerInfo.peer_addr, macRemoteIntArr, 6); peerInfo.channel = 0; peerInfo.encrypt = false; @@ -142,23 +208,8 @@ void setup(){ // Register for a callback function that will be called when data is received esp_now_register_recv_cb(OnDataRecv); - pinMode(GPIO_EMERGENCY_LED, OUTPUT); - pinMode(GPIO_REQUESTED_STATE_LED, OUTPUT); - - digitalWrite(GPIO_REQUESTED_STATE_LED,LOW); - digitalWrite(GPIO_EMERGENCY_LED,LOW); - pinMode(GPIO_SYNC_LED,OUTPUT); - digitalWrite(GPIO_SYNC_LED,LOW); - - pinMode(GPIO_EMERGENCY_BUTTON,INPUT_PULLDOWN); - attachInterrupt(GPIO_EMERGENCY_BUTTON, OnButtonPushed, RISING); - - myData.isPing=1; - myData.macOfSender=""; - isReceiverEmergencyLedOn=false; - myData.isEmergency=false; - isSenderEmergency=false; - lastButtonPushUptimeInSeconds=getUptimeInSeconds(); + // The BIG LED blinking is running in it's own task + xTaskCreatePinnedToCore(BigLEDTaskCode,"BigLEDHandler",10000,NULL,0,&BigLEDTask,0); } void loop(){ @@ -184,12 +235,16 @@ void loop(){ Serial.println(myData.isEmergency?"EMERGENGY ON":"EMERGENCY OFF"); Serial.println((isSenderEmergency==1)?"SEN EMERG ON":"SEN EMERG OFF"); - digitalWrite(GPIO_SYNC_LED,LOW); + // Control the SYNC-LED, if we didn't receive a ping for too long, the LED is switched off if ((getUptimeInSeconds()-lastPingUptimeInSeconds) < (LOOP_DELAY*PING_TIMEOUT_NUM_LOOPS)) { - delay(3); digitalWrite(GPIO_SYNC_LED,HIGH); + } else { + digitalWrite(GPIO_SYNC_LED,LOW); } + // To indicate the device hasn't crashed we vary the brightess of the power LED + setPowerLEDBrightness((getUptimeInSeconds()%5*20)+50); + switch (result) { case ESP_OK: Serial.println("[" +macLocal+ "] Sent with success");