diff --git a/src/fdrs_debug.h b/src/fdrs_debug.h index ef9f9a0..753beea 100644 --- a/src/fdrs_debug.h +++ b/src/fdrs_debug.h @@ -4,7 +4,7 @@ #ifdef FDRS_DEBUG #ifdef USE_OLED - #define DBG(a) (" "); Serial.println(a); debug_OLED(String(a)); + #define DBG(a) Serial.print(" "); Serial.println(a); debug_OLED(String(a)); #else #define DBG(a) Serial.print(" "); Serial.println(a); #endif // USE_OLED diff --git a/src/fdrs_gateway.h b/src/fdrs_gateway.h index f49157f..bcaf0c4 100644 --- a/src/fdrs_gateway.h +++ b/src/fdrs_gateway.h @@ -212,21 +212,7 @@ void handleCommands() #endif // USE_ESPNOW } - break; - - case cmd_time_req: -#ifdef USE_ESPNOW - // theCmd.param = theCmd.param & 0x000000FF; - DBG1("Received ESP-NOW time request from 0x" + String((uint8_t) theCmd.param << 24,HEX)); - sendTimeESPNow((uint8_t) theCmd.param << 24); -#endif // USE_ESPNOW -#ifdef USE_LORA - DBG1("Received LoRa time request from 0x" + String((uint16_t) theCmd.param << 16,HEX)); - sendTimeLoRa((uint16_t) theCmd.param << 16); -#endif // USE_LORA - - break; - + break; } theCmd.cmd = cmd_clear; theCmd.param = 0; @@ -290,8 +276,8 @@ void loopFDRS() void broadcastLoRa() {} void sendLoRaNbr(uint8_t address) {} void timeFDRSLoRa(uint8_t *address) {} // fdrs_gateway_lora.h - crcResult sendTimeLoRa() { return CRC_NULL; } // fdrs_gateway_time.h - crcResult handleLoRa() { return CRC_NULL; } // fdrs_gateway_lora.h + void sendTimeLoRa() { return; } // fdrs_gateway_time.h + void handleLoRa() { return; } // fdrs_gateway_lora.h bool pingLoRaTimeMaster() { return false; } //fdrs_gateway_lora.h #endif #ifndef USE_ESPNOW diff --git a/src/fdrs_gateway_serial.h b/src/fdrs_gateway_serial.h index 908bdf4..d4676f7 100644 --- a/src/fdrs_gateway_serial.h +++ b/src/fdrs_gateway_serial.h @@ -1,10 +1,13 @@ #include #if defined (ESP32) -#define UART_IF Serial1 -#define GPS_IF Serial2 + #define UART_IF Serial1 + #define GPS_IF Serial2 +#elif defined (ESP8266) + #define UART_IF Serial #else -#define UART_IF Serial + #define UART_IF Serial + #define GPS_IF Serial1 #endif #if defined(ESP32) @@ -127,6 +130,7 @@ void getSerial() { else if (Serial.available()){ incomingString = Serial.readStringUntil('\n'); } +#ifdef GPS_IF if (GPS_IF.available()){ // Data is coming in every second from the GPS, let's minimize the processing power @@ -143,6 +147,7 @@ void getSerial() { } return; } +#endif // GPS_IF JsonDocument doc; DeserializationError error = deserializeJson(doc, incomingString); if (error) { // Test if parsing succeeds. @@ -227,7 +232,11 @@ void sendSerial() { } void handleSerial(){ +#ifdef GPS_IF while (UART_IF.available() || Serial.available() || GPS_IF.available()) +#else + while (UART_IF.available() || Serial.available()) +#endif { getSerial(); } @@ -251,5 +260,11 @@ void sendTimeSerial() { } void begin_gps() { - GPS_IF.begin(9600, SERIAL_8N1, GPS_RXD, GPS_TXD); +#ifdef GPS_IF +#ifdef ARDUINO_ARCH_SAMD + GPS_IF.begin(9600); + #else + GPS_IF.begin(9600, SERIAL_8N1, GPS_RXD, GPS_TXD); + #endif +#endif } \ No newline at end of file diff --git a/src/fdrs_globals.h b/src/fdrs_globals.h index 44c1858..c6f8c31 100644 --- a/src/fdrs_globals.h +++ b/src/fdrs_globals.h @@ -46,4 +46,17 @@ #define USE_RTC #endif +#if defined(USE_GPS) && defined(ESP8266) + #error "For ESP8266 only one UART has both Tx and Rx capabilities. GPS not supported for ESP8266" #endif + +#if defined(USE_ETHERNET) && !defined(ESP32) + #error "Ethernet only supported for ESP32." +#endif + +#if defined(USE_OLED) && (!defined(ESP32) || !defined(ESP8266)) + #warning "OLED current supported for only ESP32 or ESP8266." + #undef USE_OLED +#endif + +#endif // __FDRS_GLOBALS_h__ diff --git a/src/fdrs_lora.h b/src/fdrs_lora.h index f8a2ea8..2e94fd5 100644 --- a/src/fdrs_lora.h +++ b/src/fdrs_lora.h @@ -786,7 +786,7 @@ void handleLoRa() static unsigned long txWindow = 0; // It's polite to Listen more than you talk - if(TDIFF(txWindow,TXWINDOWMS)) { + if(TDIFF(txWindow,(TXWINDOWMS + random(0,50)))) { // Start Transmit data from the SystemPacket queue if(!SPQUEUEEMPTY && (loraTxState == stReady)) { DBG2("SP Index: start: " + String(startIdxSP) + " end: " + String(endIdxSP) + " Address: 0x" + String(loraSPBuffTx[endIdxSP].dstAddress,HEX)); diff --git a/src/fdrs_node.h b/src/fdrs_node.h index db755e9..7fdbce9 100644 --- a/src/fdrs_node.h +++ b/src/fdrs_node.h @@ -8,39 +8,10 @@ #include #define FDRS_NODE -// CRC16 from https://github.com/4-20ma/ModbusMaster/blob/3a05ff87677a9bdd8e027d6906dc05ca15ca8ade/src/util/crc16.h#L71 - -/** @ingroup util_crc16 - Processor-independent CRC-16 calculation. - Polynomial: x^16 + x^15 + x^2 + 1 (0xA001)
- Initial value: 0xFFFF - This CRC is normally used in disk-drive controllers. - @param uint16_t crc (0x0000..0xFFFF) - @param uint8_t a (0x00..0xFF) - @return calculated CRC (0x0000..0xFFFF) -*/ - -static uint16_t crc16_update(uint16_t crc, uint8_t a) -{ - int i; - - crc ^= a; - for (i = 0; i < 8; ++i) - { - if (crc & 1) - crc = (crc >> 1) ^ 0xA001; - else - crc = (crc >> 1); - } - - return crc; -} - bool is_controller = false; -// SystemPacket theCmd; // does not seem to be used DataReading theData[256]; uint8_t ln; -bool newData; +uint8_t newData; = event_clear; uint8_t gatewayAddress[] = {MAC_PREFIX, GTWY_MAC}; const uint16_t espnow_size = 250 / sizeof(DataReading); crcResult crcReturned = CRC_NULL; @@ -165,10 +136,10 @@ void beginFDRS() void handleIncoming() { - if (newData) + if (newData != event_clear) { - newData = false; + newData = event_clear; for (int i = 0; i < ln; i++) { // Cycle through array of incoming DataReadings for any we are subbed to for (int j = 0; j < 255; j++) @@ -213,24 +184,10 @@ bool sendFDRS() } #endif #ifdef USE_LORA - crcReturned = transmitLoRa(>wyAddress, fdrsData, data_count); + transmitLoRaAsync(>wyAddress, fdrsData, data_count); // DBG(" LoRa sent."); -#ifdef LORA_ACK - if(crcReturned == CRC_OK) { data_count = 0; - return true; - } -#endif -#ifndef LORA_ACK - if(crcReturned == CRC_OK || crcReturned == CRC_NULL) { - data_count = 0; return true; -} -#endif - else { - data_count = 0; - return false; - } #endif } @@ -396,22 +353,31 @@ bool unsubscribeFDRS(uint16_t sub_id) -uint32_t pingFDRS(uint32_t timeout) +void pingFDRS(uint32_t timeout) { #ifdef USE_ESPNOW // pingFDRSEspNow is now asynchronous so cannot return a value directly pingFDRSEspNow(gatewayAddress, timeout); - return UINT32_MAX; #endif #ifdef USE_LORA - uint32_t pingResponseMs = pingFDRSLoRa(>wyAddress, timeout); - return pingResponseMs; + pingRequestLoRa(>wyAddress, timeout); +#endif + return; +} + +bool reqTimeFDRS() { +#ifdef USE_ESPNOW + return reqTimeEspNow(); +#endif +#ifdef USE_LORA + return reqTimeLoRa(); #endif } // Skeleton Functions related to function calls to files that are not included #ifndef USE_LORA void sendTimeLoRa() {} + bool reqTimeLoRa() { return false; } #endif #ifndef USE_ESPNOW esp_err_t sendTimeESPNow() { return ESP_OK; } // fdrs_gateway_time.h diff --git a/src/fdrs_node_espnow.h b/src/fdrs_node_espnow.h index 316187a..8727d38 100644 --- a/src/fdrs_node_espnow.h +++ b/src/fdrs_node_espnow.h @@ -30,15 +30,33 @@ bool pingFlag = false; uint32_t last_refresh = 0; uint32_t gtwy_timeout = 300000; +// Request time from gateway - Optionally used in sensors +bool reqTimeEspNow() { + unsigned long pingStart = millis(); + SystemPacket sys_packet = {.cmd = cmd_time, .param = 0}; + DBG1("Requesting time from gateway 0x" + String(gatewayAddress[5],HEX)); + esp_now_send(gatewayAddress, (uint8_t *)&sys_packet, sizeof(SystemPacket)); + while(timeSource.tmNetIf < TMIF_ESPNOW && (millis() - pingStart < 1000)) { + // wait for time to be set + // magic happens here :) + } + if(timeSource.tmNetIf == TMIF_ESPNOW) { + return true; + } + else { + return false; + } +} + void recvTimeEspNow(uint32_t t) { // Process time if there is no master set yet or if LoRa is the master or if we are already the time master if(timeSource.tmNetIf < TMIF_ESPNOW || (timeSource.tmNetIf == TMIF_ESPNOW && timeSource.tmAddress == (incMAC[4] << 8 | incMAC[5]))) { DBG("Received time via ESP-NOW from 0x" + String(incMAC[5], HEX)); if(timeSource.tmNetIf < TMIF_ESPNOW) { - timeSource.tmNetIf = TMIF_ESPNOW; -timeSource.tmSource = TMS_NET; - timeSource.tmAddress = incMAC[4] << 8 & incMAC[5]; - DBG("ESP-NOW time source is now 0x" + String(incMAC[5], HEX)); + timeSource.tmNetIf = TMIF_ESPNOW; + timeSource.tmSource = TMS_NET; + timeSource.tmAddress = incMAC[4] << 8 & incMAC[5]; + DBG("ESP-NOW time source is now 0x" + String(incMAC[5], HEX)); } setTime(t); timeSource.tmLastTimeSet = millis(); @@ -116,14 +134,18 @@ memcpy(&incMAC, mac, sizeof(incMAC)); switch (command.cmd) { case cmd_ping: - recvPingEspNow(incMAC); + if(command.param == ping_reply) { + recvPingEspNow(incMAC); + } break; case cmd_add: is_added = true; gtwy_timeout = command.param; break; case cmd_time: - recvTimeEspNow(command.param); + if(command.param > MIN_TS) { + recvTimeEspNow(command.param); + } break; } } @@ -132,7 +154,7 @@ memcpy(&incMAC, mac, sizeof(incMAC)); memcpy(&theData, incomingData, len); ln = len / sizeof(DataReading); DBG2("Incoming ESP-NOW Data Reading from 0x" + String(incMAC[5], HEX)); - newData = true; + newData = event_espnowg; // Processing done by handleIncoming() in fdrs_node.h } else { diff --git a/src/fdrs_time.h b/src/fdrs_time.h index c09d911..86f0dc8 100644 --- a/src/fdrs_time.h +++ b/src/fdrs_time.h @@ -41,7 +41,6 @@ struct tm timeinfo; // Structure containing time elements struct timeval tv; bool validTimeFlag = false; // Indicate whether we have reliable time bool validRtcFlag = false; // Is RTC date and time valid? -// time_t lastNTPFetchSuccess = 0; // Last time that a successful NTP fetch was made bool isDST; // Keeps track of Daylight Savings Time vs Standard Time long slewSecs = 0; // When time is set this is the number of seconds the time changes double stdOffset = (FDRS_STD_OFFSET * 60 * 60); // UTC -> Local time, in Seconds, offset from UTC in Standard Time