From 68e0aac374d13c0c34b9762b5cbc80a4475e5865 Mon Sep 17 00:00:00 2001 From: Jeff Lehman Date: Thu, 13 Jun 2024 14:13:34 -0500 Subject: [PATCH 1/3] Remove unnecessary gateway registration code --- .../Irrigation/Irrigation.ino | 34 ++++--------------- 1 file changed, 7 insertions(+), 27 deletions(-) diff --git a/examples/Controller_examples/Irrigation/Irrigation.ino b/examples/Controller_examples/Irrigation/Irrigation.ino index 25eb1b7e..01dfe82d 100644 --- a/examples/Controller_examples/Irrigation/Irrigation.ino +++ b/examples/Controller_examples/Irrigation/Irrigation.ino @@ -74,11 +74,8 @@ irrigController cont[] = { }; unsigned long statusCheck = 0; -unsigned long checkGatewayStatus = 0; - bool isData = false; bool newStatus = false; -bool connectedToGateway = false; uint numcontrollers; // Callback function in the controller that receives data to get or set coils @@ -133,7 +130,6 @@ void checkCoils() { // Sends back a status report for each coil pin. } } - // Sets coil value according to data received in callback function void updateCoils() { for(int i = 0; i < numcontrollers; i++) { @@ -155,21 +151,6 @@ void updateCoils() { } } -// Attempts to inform gateway that we are alive and waiting to receive data -// Returns true if we have successfully registered with gateway otherwise return false -bool registerWithGateway() { - if (addFDRS(1000, fdrs_recv_cb)) { - for(int i = 0; i < numcontrollers; i++) { - subscribeFDRS(cont[i].address); - } - return true; - } else { - DBG("Not Connected"); - // If we can't connect to gateway then we won't receive data should we delay and retry or delay and reboot? - } - return false; -} - void setup() { beginFDRS(); DBG("FARM DATA RELAY SYSTEM :: Irrigation Module"); @@ -181,7 +162,13 @@ void setup() { pinMode(cont[i].coilPin, OUTPUT); digitalWrite(cont[i].coilPin, OFF); } - connectedToGateway = registerWithGateway(); + + // Register the callback function for received data + addFDRS(fdrs_recv_cb); + // Subscribe to Data Readings + for(int i = 0; i < numcontrollers; i++) { + subscribeFDRS(cont[i].address); + } } void loop() { @@ -212,11 +199,4 @@ void loop() { } statusCheck = millis(); } - // Periodically test and try to reestablish gateway connection if not connected - if(millis() - checkGatewayStatus > 20000) { - if(connectedToGateway == false){ - connectedToGateway = registerWithGateway(); - } - checkGatewayStatus = millis(); - } } \ No newline at end of file From c82e9dcda6bb25195b1c1a397aa654a6727b37f5 Mon Sep 17 00:00:00 2001 From: Jeff Lehman Date: Fri, 28 Jun 2024 20:56:06 -0500 Subject: [PATCH 2/3] Updated irrigation sketch with pin feedback and TB updates --- .../Irrigation/Irrigation.ino | 234 ++++++++++-------- 1 file changed, 126 insertions(+), 108 deletions(-) diff --git a/examples/Controller_examples/Irrigation/Irrigation.ino b/examples/Controller_examples/Irrigation/Irrigation.ino index 810def3c..2f5fb4fb 100644 --- a/examples/Controller_examples/Irrigation/Irrigation.ino +++ b/examples/Controller_examples/Irrigation/Irrigation.ino @@ -8,6 +8,39 @@ #include "fdrs_node_config.h" #include +#define CMD_GET 1 +#define CMD_SET 0 + +typedef struct irrigController +{ + uint address; + int coilPin; + bool updatePending = false; + unsigned long status = 0; +} irrigController; + +/* + +Format of loadFDRS.... +loadFDRS(data, type, address); + +Get Coil status of address 102 (data value is ignored) +loadFDRS(1, 1, 102); + +Turn off (set) Coil at address 102 for an indefinite amount of time +loadFDRS(0, 0, 102); + +Turn on (set) Coil at address 102 for an indefinite amount of time +loadFDRS(1, 0, 102); + +Turn on (set) Coil at address 102 for 300 seconds +loadFDRS(300, 0, 102); + +When turning on coil for certain amount of time the data value +must be 10 or greater and is in units of seconds. + +*/ + #define CONTROL_1 101 //Address for controller 1 #define CONTROL_2 102 //Address for controller 2 #define CONTROL_3 103 //Address for controller 3 @@ -18,20 +51,25 @@ #define COIL_3 13 //Coil Pin 3 #define COIL_4 14 //Coil Pin 4 -irrigController cont[] = { - [0] = { .address = CONTROL_1, .coilPin = COIL_1, .updatePending = false, .status = 0 }, - [1] = { .address = CONTROL_2, .coilPin = COIL_2, .updatePending = false, .status = 0 }, - [2] = { .address = CONTROL_3, .coilPin = COIL_3, .updatePending = false, .status = 0 }, - [3] = { .address = CONTROL_4, .coilPin = COIL_4, .updatePending = false, .status = 0 }, - // [4] = { .address = CONTROL_5, .coilPin = COIL_5, .updatePending = false, .status = 0 }, - // [5] = { .address = CONTROL_6, .coilPin = COIL_6, .updatePending = false, .status = 0 }, - // [6] = { .address = CONTROL_7, .coilPin = COIL_7, .updatePending = false, .status = 0 }, - // [7] = { .address = CONTROL_8, .coilPin = COIL_8, .updatePending = false, .status = 0 }, - // [8] = { .address = CONTROL_9, .coilPin = COIL_9, .updatePending = false, .status = 0 }, - // [9] = { .address = CONTROL_10, .coilPin = COIL_10, .updatePending = false, .status = 0 }, - // [10] = { .address = CONTROL_11, .coilPin = COIL_11, .updatePending = false, .status = 0 }, - // [11] = { .address = CONTROL_12, .coilPin = COIL_12, .updatePending = false, .status = 0 }, - // [12] = { .address = CONTROL_13, .coilPin = COIL_13, .updatePending = false, .status = 0 }, +// These are set up for relay module which are active-LOW. +// Swap 'HIGH'and 'LOW' to use the inverse. +#define ON LOW +#define OFF HIGH + +irrigController coil[] = { + [0] = { .address = CONTROL_1, .coilPin = COIL_1 }, + [1] = { .address = CONTROL_2, .coilPin = COIL_2 }, + [2] = { .address = CONTROL_3, .coilPin = COIL_3 }, + [3] = { .address = CONTROL_4, .coilPin = COIL_4 }, + // [4] = { .address = CONTROL_5, .coilPin = COIL_5 }, + // [5] = { .address = CONTROL_6, .coilPin = COIL_6 }, + // [6] = { .address = CONTROL_7, .coilPin = COIL_7 }, + // [7] = { .address = CONTROL_8, .coilPin = COIL_8 }, + // [8] = { .address = CONTROL_9, .coilPin = COIL_9 }, + // [9] = { .address = CONTROL_10, .coilPin = COIL_10 }, + // [10] = { .address = CONTROL_11, .coilPin = COIL_11 }, + // [11] = { .address = CONTROL_12, .coilPin = COIL_12 }, + // [12] = { .address = CONTROL_13, .coilPin = COIL_13 }, }; unsigned long statusCheck = 0; @@ -39,87 +77,50 @@ bool isData = false; bool newStatus = false; uint numcontrollers; +// Callback function in the controller that receives data to get or set coils void fdrs_recv_cb(DataReading theData) { - DBG(String(theData.id)); - switch (theData.t) { - case 0: // Incoming command is to SET a value - switch (theData.id) { - case CONTROL_1: - status_1 = (int)theData.d; - isData = true; - break; - case CONTROL_2: - status_2 = (int)theData.d; - isData = true; - break; - case CONTROL_3: - status_3 = (int)theData.d; - isData = true; - break; - case CONTROL_4: - status_4 = (int)theData.d; + switch (theData.t) { + case CMD_SET: // Incoming command is to SET a value + for(int i = 0; i < numcontrollers; i++) { + if(coil[i].address == (uint) theData.id) { + coil[i].status = (unsigned long) theData.d; + coil[i].updatePending = true; isData = true; + DBG1("Received SET cmd. Address: " + String(theData.id) + " value: " + String(theData.d)); break; + } } break; - case 1: // Incoming command is to GET a value - switch (theData.id) { - case CONTROL_1: - if (digitalRead(COIL_1) == HIGH) { - loadFDRS(1, STATUS_T, CONTROL_1); + case CMD_GET: // Incoming command is to GET a value + for(int i = 0; i < numcontrollers; i++) { + if(coil[i].address == theData.id) { + if (digitalRead(coil[i].coilPin) == HIGH) { + loadFDRS(1, STATUS_T, coil[i].address); } else { - loadFDRS(0, STATUS_T, CONTROL_1); + loadFDRS(0, STATUS_T, coil[i].address); } - break; - case CONTROL_2: - if (digitalRead(COIL_2) == HIGH) { - loadFDRS(1, STATUS_T, CONTROL_2); - } else { - loadFDRS(0, STATUS_T, CONTROL_2); - } - break; - case CONTROL_3: - if (digitalRead(COIL_3) == HIGH) { - loadFDRS(1, STATUS_T, CONTROL_3); - } else { - loadFDRS(0, STATUS_T, CONTROL_3); - } - break; - case CONTROL_4: - if (digitalRead(COIL_4) == HIGH) { - loadFDRS(1, STATUS_T, CONTROL_4); - } else { - loadFDRS(0, STATUS_T, CONTROL_4); - } - break; + DBG1("Received GET cmd for address: " + String(theData.id)); + newStatus = true; + } } - newStatus = true; break; + + default: + DBG1("Unknown command: " + String(theData.t) + " address: " + String(theData.id) + " value: " + String(theData.d)); + break; + } } void checkCoils() { // Sends back a status report for each coil pin. - if (digitalRead(COIL_1) == HIGH) { - loadFDRS(1, STATUS_T, CONTROL_1); - } else { - loadFDRS(0, STATUS_T, CONTROL_1); - } - if (digitalRead(COIL_2) == HIGH) { - loadFDRS(1, STATUS_T, CONTROL_2); - } else { - loadFDRS(0, STATUS_T, CONTROL_2); - } - if (digitalRead(COIL_3) == HIGH) { - loadFDRS(1, STATUS_T, CONTROL_3); - } else { - loadFDRS(0, STATUS_T, CONTROL_3); - } - if (digitalRead(COIL_4) == HIGH) { - loadFDRS(1, STATUS_T, CONTROL_4); - } else { - loadFDRS(0, STATUS_T, CONTROL_4); + for(int i = 0; i < numcontrollers; i++) { + if (digitalRead(coil[i].coilPin) == HIGH) { + loadFDRS(1, STATUS_T, coil[i].address); + } else { + loadFDRS(0, STATUS_T, coil[i].address); + } } if (sendFDRS()) { DBG("Packet received by gateway"); @@ -131,41 +132,54 @@ void checkCoils() { // Sends back a status report for each coil pin. // Sets coil value according to data received in callback function void updateCoils() { for(int i = 0; i < numcontrollers; i++) { - if(cont[i].updatePending == true) { - if(cont[i].status == 0) { - digitalWrite(cont[i].coilPin, OFF); - DBG1("Address " + String(cont[i].address) + " coil pin " + String(cont[i].coilPin) + " off."); + if(coil[i].updatePending == true) { + if(coil[i].status == 0) { + digitalWrite(coil[i].coilPin, OFF); + delay(10); + bool outVal = digitalRead(coil[i].coilPin); + DBG1("Address " + String(coil[i].address) + " coil pin " + String(coil[i].coilPin) + " commanded off. Status: " + (outVal?"HIGH":"LOW")); + if(outVal != OFF) { + DBG("Alert! Address " + String(coil[i].address) + " coil pin " + String(coil[i].coilPin) + " commanded off but remains on!"); + } } else { - digitalWrite(cont[i].coilPin, ON); - DBG1("Address " + String(cont[i].address) + " coil pin " + String(cont[i].coilPin) + " on."); + digitalWrite(coil[i].coilPin, ON); + delay(10); + bool outVal = digitalRead(coil[i].coilPin); + DBG1("Address " + String(coil[i].address) + " coil pin " + String(coil[i].coilPin) + " commanded off. Status: " + (outVal?"HIGH":"LOW")); + if(outVal != ON) { + DBG("Alert! Address " + String(coil[i].address) + " coil pin " + String(coil[i].coilPin) + " commanded on but remains off!"); + } } - if(cont[i].status >= 10) { - DBG1("Address " + String(cont[i].address) + " coil pin " + String(cont[i].coilPin) + " on for " + String(cont[i].status) + " seconds."); - cont[i].status = millis() + (cont[i].status * 1000); // this is the time when the coil will be commanded off + if(coil[i].status >= 10) { + DBG1("Address " + String(coil[i].address) + " coil pin " + String(coil[i].coilPin) + " on for " + String(coil[i].status) + " seconds."); + coil[i].status = millis() + (coil[i].status * 1000); // this is the time when the coil will be commanded off } - cont[i].updatePending = false; + coil[i].updatePending = false; } } } void setup() { beginFDRS(); + DBG("FARM DATA RELAY SYSTEM :: Irrigation Module"); pingFDRS(1000); - if (addFDRS(1000, fdrs_recv_cb)) { - subscribeFDRS(CONTROL_1); - subscribeFDRS(CONTROL_2); - subscribeFDRS(CONTROL_3); - subscribeFDRS(CONTROL_4); - } else { - DBG("Not Connected"); + + numcontrollers = (uint) sizeof(coil)/sizeof(irrigController); + // set up the physical outputs + for(int i = 0; i < numcontrollers; i++) { + pinMode(coil[i].coilPin, OUTPUT); + digitalWrite(coil[i].coilPin, OFF); } - + // Register the callback function for received data - addFDRS(fdrs_recv_cb); - // Subscribe to Data Readings - for(int i = 0; i < numcontrollers; i++) { - subscribeFDRS(cont[i].address); + if(addFDRS(fdrs_recv_cb)) { + // Subscribe to Data Readings + for(int i = 0; i < numcontrollers; i++) { + subscribeFDRS(coil[i].address); + } + } else { + DBG("Not Connected"); } } @@ -189,15 +203,19 @@ void loop() { // periodically check for timer expiration on coils if(millis() - statusCheck > 500) { for(int i = 0; i < numcontrollers; i++) { - if(cont[i].status >= 10 && (millis() > cont[i].status)) { - cont[i].status = 0; - digitalWrite(cont[i].coilPin, OFF); - loadFDRS(OFF, STATUS_T, cont[i].address); - DBG1("Address " + String(cont[i].address) + " coil pin " + String(cont[i].coilPin) + " turned off."); + if(coil[i].status >= 10 && (millis() > coil[i].status)) { + coil[i].status = 0; + digitalWrite(coil[i].coilPin, OFF); + loadFDRS(OFF, STATUS_T, coil[i].address); + delay(10); + bool outVal = digitalRead(coil[i].coilPin); + DBG1("Address " + String(coil[i].address) + " coil pin " + String(coil[i].coilPin) + " commanded off. Status: " + (outVal?"HIGH":"LOW")); + if(outVal != OFF) { + DBG("Alert! Address " + String(coil[i].address) + " coil pin " + String(coil[i].coilPin) + " commanded off but remains on!"); + } newStatus = true; } } statusCheck = millis(); } - } \ No newline at end of file From d741a52ed5a0f39a0a7ad62b375bd8fd9447842f Mon Sep 17 00:00:00 2001 From: Jeff Lehman Date: Fri, 28 Jun 2024 20:57:09 -0500 Subject: [PATCH 3/3] Allow multiple DRs for ESP-NOW Node --- src/fdrs_node_espnow.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/fdrs_node_espnow.h b/src/fdrs_node_espnow.h index 2f39a5b4..760468fc 100644 --- a/src/fdrs_node_espnow.h +++ b/src/fdrs_node_espnow.h @@ -108,7 +108,7 @@ void OnDataRecv(const esp_now_recv_info *pkt_info, const uint8_t *incomingData, break; } } - else if((len == sizeof(DataReading))) + else if((len % sizeof(DataReading) == 0)) { memcpy(&theData, incomingData, len); ln = len / sizeof(DataReading);