ESP-NOW node request time, test compilation in PlatformIO

This commit is contained in:
Jeff Lehman 2024-02-26 12:09:00 -06:00
parent 9a00eab8af
commit c958e003ef
8 changed files with 83 additions and 82 deletions

View File

@ -4,7 +4,7 @@
#ifdef FDRS_DEBUG #ifdef FDRS_DEBUG
#ifdef USE_OLED #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 #else
#define DBG(a) Serial.print(" "); Serial.println(a); #define DBG(a) Serial.print(" "); Serial.println(a);
#endif // USE_OLED #endif // USE_OLED

View File

@ -212,21 +212,7 @@ void handleCommands()
#endif // USE_ESPNOW #endif // USE_ESPNOW
} }
break; 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;
} }
theCmd.cmd = cmd_clear; theCmd.cmd = cmd_clear;
theCmd.param = 0; theCmd.param = 0;
@ -290,8 +276,8 @@ void loopFDRS()
void broadcastLoRa() {} void broadcastLoRa() {}
void sendLoRaNbr(uint8_t address) {} void sendLoRaNbr(uint8_t address) {}
void timeFDRSLoRa(uint8_t *address) {} // fdrs_gateway_lora.h void timeFDRSLoRa(uint8_t *address) {} // fdrs_gateway_lora.h
crcResult sendTimeLoRa() { return CRC_NULL; } // fdrs_gateway_time.h void sendTimeLoRa() { return; } // fdrs_gateway_time.h
crcResult handleLoRa() { return CRC_NULL; } // fdrs_gateway_lora.h void handleLoRa() { return; } // fdrs_gateway_lora.h
bool pingLoRaTimeMaster() { return false; } //fdrs_gateway_lora.h bool pingLoRaTimeMaster() { return false; } //fdrs_gateway_lora.h
#endif #endif
#ifndef USE_ESPNOW #ifndef USE_ESPNOW

View File

@ -1,10 +1,13 @@
#include <ArduinoJson.h> #include <ArduinoJson.h>
#if defined (ESP32) #if defined (ESP32)
#define UART_IF Serial1 #define UART_IF Serial1
#define GPS_IF Serial2 #define GPS_IF Serial2
#elif defined (ESP8266)
#define UART_IF Serial
#else #else
#define UART_IF Serial #define UART_IF Serial
#define GPS_IF Serial1
#endif #endif
#if defined(ESP32) #if defined(ESP32)
@ -127,6 +130,7 @@ void getSerial() {
else if (Serial.available()){ else if (Serial.available()){
incomingString = Serial.readStringUntil('\n'); incomingString = Serial.readStringUntil('\n');
} }
#ifdef GPS_IF
if (GPS_IF.available()){ if (GPS_IF.available()){
// Data is coming in every second from the GPS, let's minimize the processing power // Data is coming in every second from the GPS, let's minimize the processing power
@ -143,6 +147,7 @@ void getSerial() {
} }
return; return;
} }
#endif // GPS_IF
JsonDocument doc; JsonDocument doc;
DeserializationError error = deserializeJson(doc, incomingString); DeserializationError error = deserializeJson(doc, incomingString);
if (error) { // Test if parsing succeeds. if (error) { // Test if parsing succeeds.
@ -227,7 +232,11 @@ void sendSerial() {
} }
void handleSerial(){ void handleSerial(){
#ifdef GPS_IF
while (UART_IF.available() || Serial.available() || GPS_IF.available()) while (UART_IF.available() || Serial.available() || GPS_IF.available())
#else
while (UART_IF.available() || Serial.available())
#endif
{ {
getSerial(); getSerial();
} }
@ -251,5 +260,11 @@ void sendTimeSerial() {
} }
void begin_gps() { 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
} }

View File

@ -46,4 +46,17 @@
#define USE_RTC #define USE_RTC
#endif #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 #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__

View File

@ -786,7 +786,7 @@ void handleLoRa()
static unsigned long txWindow = 0; static unsigned long txWindow = 0;
// It's polite to Listen more than you talk // 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 // Start Transmit data from the SystemPacket queue
if(!SPQUEUEEMPTY && (loraTxState == stReady)) { if(!SPQUEUEEMPTY && (loraTxState == stReady)) {
DBG2("SP Index: start: " + String(startIdxSP) + " end: " + String(endIdxSP) + " Address: 0x" + String(loraSPBuffTx[endIdxSP].dstAddress,HEX)); DBG2("SP Index: start: " + String(startIdxSP) + " end: " + String(endIdxSP) + " Address: 0x" + String(loraSPBuffTx[endIdxSP].dstAddress,HEX));

View File

@ -8,39 +8,10 @@
#include <fdrs_globals.h> #include <fdrs_globals.h>
#define FDRS_NODE #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)<br>
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; bool is_controller = false;
// SystemPacket theCmd; // does not seem to be used
DataReading theData[256]; DataReading theData[256];
uint8_t ln; uint8_t ln;
bool newData; uint8_t newData; = event_clear;
uint8_t gatewayAddress[] = {MAC_PREFIX, GTWY_MAC}; uint8_t gatewayAddress[] = {MAC_PREFIX, GTWY_MAC};
const uint16_t espnow_size = 250 / sizeof(DataReading); const uint16_t espnow_size = 250 / sizeof(DataReading);
crcResult crcReturned = CRC_NULL; crcResult crcReturned = CRC_NULL;
@ -165,10 +136,10 @@ void beginFDRS()
void handleIncoming() void handleIncoming()
{ {
if (newData) if (newData != event_clear)
{ {
newData = false; newData = event_clear;
for (int i = 0; i < ln; i++) for (int i = 0; i < ln; i++)
{ // Cycle through array of incoming DataReadings for any we are subbed to { // Cycle through array of incoming DataReadings for any we are subbed to
for (int j = 0; j < 255; j++) for (int j = 0; j < 255; j++)
@ -213,24 +184,10 @@ bool sendFDRS()
} }
#endif #endif
#ifdef USE_LORA #ifdef USE_LORA
crcReturned = transmitLoRa(&gtwyAddress, fdrsData, data_count); transmitLoRaAsync(&gtwyAddress, fdrsData, data_count);
// DBG(" LoRa sent."); // DBG(" LoRa sent.");
#ifdef LORA_ACK
if(crcReturned == CRC_OK) {
data_count = 0; data_count = 0;
return true;
}
#endif
#ifndef LORA_ACK
if(crcReturned == CRC_OK || crcReturned == CRC_NULL) {
data_count = 0;
return true; return true;
}
#endif
else {
data_count = 0;
return false;
}
#endif #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 #ifdef USE_ESPNOW
// pingFDRSEspNow is now asynchronous so cannot return a value directly // pingFDRSEspNow is now asynchronous so cannot return a value directly
pingFDRSEspNow(gatewayAddress, timeout); pingFDRSEspNow(gatewayAddress, timeout);
return UINT32_MAX;
#endif #endif
#ifdef USE_LORA #ifdef USE_LORA
uint32_t pingResponseMs = pingFDRSLoRa(&gtwyAddress, timeout); pingRequestLoRa(&gtwyAddress, timeout);
return pingResponseMs; #endif
return;
}
bool reqTimeFDRS() {
#ifdef USE_ESPNOW
return reqTimeEspNow();
#endif
#ifdef USE_LORA
return reqTimeLoRa();
#endif #endif
} }
// Skeleton Functions related to function calls to files that are not included // Skeleton Functions related to function calls to files that are not included
#ifndef USE_LORA #ifndef USE_LORA
void sendTimeLoRa() {} void sendTimeLoRa() {}
bool reqTimeLoRa() { return false; }
#endif #endif
#ifndef USE_ESPNOW #ifndef USE_ESPNOW
esp_err_t sendTimeESPNow() { return ESP_OK; } // fdrs_gateway_time.h esp_err_t sendTimeESPNow() { return ESP_OK; } // fdrs_gateway_time.h

View File

@ -30,15 +30,33 @@ bool pingFlag = false;
uint32_t last_refresh = 0; uint32_t last_refresh = 0;
uint32_t gtwy_timeout = 300000; 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) { 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 // 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]))) { 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)); DBG("Received time via ESP-NOW from 0x" + String(incMAC[5], HEX));
if(timeSource.tmNetIf < TMIF_ESPNOW) { if(timeSource.tmNetIf < TMIF_ESPNOW) {
timeSource.tmNetIf = TMIF_ESPNOW; timeSource.tmNetIf = TMIF_ESPNOW;
timeSource.tmSource = TMS_NET; timeSource.tmSource = TMS_NET;
timeSource.tmAddress = incMAC[4] << 8 & incMAC[5]; timeSource.tmAddress = incMAC[4] << 8 & incMAC[5];
DBG("ESP-NOW time source is now 0x" + String(incMAC[5], HEX)); DBG("ESP-NOW time source is now 0x" + String(incMAC[5], HEX));
} }
setTime(t); setTime(t);
timeSource.tmLastTimeSet = millis(); timeSource.tmLastTimeSet = millis();
@ -116,14 +134,18 @@ memcpy(&incMAC, mac, sizeof(incMAC));
switch (command.cmd) switch (command.cmd)
{ {
case cmd_ping: case cmd_ping:
recvPingEspNow(incMAC); if(command.param == ping_reply) {
recvPingEspNow(incMAC);
}
break; break;
case cmd_add: case cmd_add:
is_added = true; is_added = true;
gtwy_timeout = command.param; gtwy_timeout = command.param;
break; break;
case cmd_time: case cmd_time:
recvTimeEspNow(command.param); if(command.param > MIN_TS) {
recvTimeEspNow(command.param);
}
break; break;
} }
} }
@ -132,7 +154,7 @@ memcpy(&incMAC, mac, sizeof(incMAC));
memcpy(&theData, incomingData, len); memcpy(&theData, incomingData, len);
ln = len / sizeof(DataReading); ln = len / sizeof(DataReading);
DBG2("Incoming ESP-NOW Data Reading from 0x" + String(incMAC[5], HEX)); 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 // Processing done by handleIncoming() in fdrs_node.h
} }
else { else {

View File

@ -41,7 +41,6 @@ struct tm timeinfo; // Structure containing time elements
struct timeval tv; struct timeval tv;
bool validTimeFlag = false; // Indicate whether we have reliable time bool validTimeFlag = false; // Indicate whether we have reliable time
bool validRtcFlag = false; // Is RTC date and time valid? 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 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 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 double stdOffset = (FDRS_STD_OFFSET * 60 * 60); // UTC -> Local time, in Seconds, offset from UTC in Standard Time