Farm-Data-Relay-System/Examples/4_UART_Gateway/fdrs_functions.h
sensorsiot aee0ada35e Debugging enhanced
Definition of DEBUG in the main sketch (easy to change)
DBG definition
Use Serial2 instead of Serial1 for the ESP32
Changed the concept of UART.IF in the -5 sketch: Debug is always Serial and the ESP32 gets an additional Serial2 for communication

esp_now_peer_info_t peerInfo; seems not needed anymore

added a ROLE definition. With this definition it should be possible to have the same directory for all roles. We can discuss this in Skype if you want
2022-05-21 23:50:45 +02:00

496 lines
13 KiB
C

#ifdef DEBUG
#define DBG(a) (Serial.println(a))
#else
#define DBG(a)
#endif
const uint8_t espnow_size = 250 / sizeof(DataReading);
const uint8_t lora_size = 256 / sizeof(DataReading);
const uint8_t mac_prefix[] = {MAC_PREFIX};
esp_now_peer_info_t peerInfo;
uint8_t broadcast_mac[] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
uint8_t selfAddress[] = {MAC_PREFIX, UNIT_MAC};
uint8_t ESPNOW1[] = {MAC_PREFIX, ESPNOW1_PEER};
uint8_t ESPNOW2[] = {MAC_PREFIX, ESPNOW2_PEER};
uint8_t incMAC[6];
uint8_t LoRa1[] = {mac_prefix[3], mac_prefix[4], LORA1_PEER};
uint8_t LoRa2[] = {mac_prefix[3], mac_prefix[4], LORA2_PEER};
DataReading theData[256];
uint8_t ln;
uint8_t newData = 0;
DataReading ESPNOW1buffer[256];
uint8_t lenESPNOW1 = 0;
uint32_t timeESPNOW1 = 0;
DataReading ESPNOW2buffer[256];
uint8_t lenESPNOW2 = 0;
uint32_t timeESPNOW2 = 0;
DataReading ESPNOWGbuffer[256];
uint8_t lenESPNOWG = 0;
uint32_t timeESPNOWG = 0;
DataReading SERIALbuffer[256];
uint8_t lenSERIAL = 0;
uint32_t timeSERIAL = 0;
DataReading MQTTbuffer[256];
uint8_t lenMQTT = 0;
uint32_t timeMQTT = 0;
DataReading LORAGbuffer[256];
uint8_t lenLORAG = 0;
uint32_t timeLORAG = 0;
DataReading LORA1buffer[256];
uint8_t lenLORA1 = 0;
uint32_t timeLORA1 = 0;
DataReading LORA2buffer[256];
uint8_t lenLORA2 = 0;
uint32_t timeLORA2 = 0;
WiFiClient espClient;
#ifdef USE_LED
CRGB leds[NUM_LEDS];
#endif
#ifdef USE_WIFI
PubSubClient client(espClient);
const char* ssid = WIFI_NET;
const char* password = WIFI_PASS;
const char* mqtt_server = MQTT_ADDR;
#endif
// Set ESP-NOW send and receive callbacks for either ESP8266 or ESP32
#if defined(ESP8266)
void OnDataSent(uint8_t *mac_addr, uint8_t sendStatus) {
}
void OnDataRecv(uint8_t* mac, uint8_t *incomingData, uint8_t len) {
#elif defined(ESP32)
void OnDataSent(const uint8_t *mac_addr, esp_now_send_status_t status) {
}
void OnDataRecv(const uint8_t * mac, const uint8_t *incomingData, int len) {
#endif
memcpy(&theData, incomingData, sizeof(theData));
memcpy(&incMAC, mac, sizeof(incMAC));
if (memcmp(&incMAC, &ESPNOW1, 6) == 0) newData = 1;
else if (memcmp(&incMAC, &ESPNOW2, 6) == 0) newData = 2;
else newData = 3;
ln = len / sizeof(DataReading);
DBG("Incoming ESP-NOW.");
}
void getSerial() {
String incomingString = UART_IF.readStringUntil('\n');
DynamicJsonDocument doc(24576);
DeserializationError error = deserializeJson(doc, incomingString);
if (error) { // Test if parsing succeeds.
// DBG("json parse err");
// DBG(incomingString);
return;
} else {
int s = doc.size();
//UART_IF.println(s);
for (int i = 0; i < s; i++) {
theData[i].id = doc[i]["id"];
theData[i].t = doc[i]["type"];
theData[i].d = doc[i]["data"];
}
ln = s;
newData = 4;
DBG("Incoming Serial.");
}
}
void mqtt_callback(char* topic, byte * message, unsigned int length) {
String incomingString;
for (int i = 0; i < length; i++) {
incomingString += (char)message[i];
}
StaticJsonDocument<2048> doc;
DeserializationError error = deserializeJson(doc, incomingString);
if (error) { // Test if parsing succeeds.
DBG("json parse err");
DBG(incomingString);
return;
} else {
int s = doc.size();
//UART_IF.println(s);
for (int i = 0; i < s; i++) {
theData[i].id = doc[i]["id"];
theData[i].t = doc[i]["type"];
theData[i].d = doc[i]["data"];
}
ln = s;
newData = 5;
DBG("Incoming MQTT.");
}
}
void getLoRa() {
#ifdef USE_LORA
int packetSize = LoRa.parsePacket();
if (packetSize) {
uint8_t packet[packetSize];
uint8_t incLORAMAC[2];
LoRa.readBytes((uint8_t *)&packet, packetSize);
// for (int i = 0; i < packetSize; i++) {
// UART_IF.println(packet[i], HEX);
// }
if (memcmp(&packet, &selfAddress[3], 3) == 0) { //Check if addressed to this device
memcpy(&incLORAMAC, &packet[3], 2); //Split off address portion of packet
memcpy(&theData, &packet[5], packetSize - 5); //Split off data portion of packet
if (memcmp(&incLORAMAC, &LoRa1, 2) == 0) newData = 7; //Check if it is from a registered sender
else if (memcmp(&incLORAMAC, &LoRa2, 2) == 0) newData = 8;
else newData = 6;
ln = (packetSize - 5) / sizeof(DataReading);
newData = 6;
DBG("Incoming LoRa.");
}
}
#endif
}
void sendESPNOW(uint8_t address) {
DBG("Sending ESP-NOW.");
uint8_t NEWPEER[] = {MAC_PREFIX, address};
#if defined(ESP32)
esp_now_peer_info_t peerInfo;
peerInfo.ifidx = WIFI_IF_STA;
peerInfo.channel = 0;
peerInfo.encrypt = false;
memcpy(peerInfo.peer_addr, NEWPEER, 6);
if (esp_now_add_peer(&peerInfo) != ESP_OK) {
DBG("Failed to add peer");
return;
}
#endif
DataReading thePacket[ln];
int j = 0;
for (int i = 0; i < ln; i++) {
if ( j > espnow_size) {
j = 0;
esp_now_send(NEWPEER, (uint8_t *) &thePacket, sizeof(thePacket));
}
thePacket[j] = theData[i];
j++;
}
esp_now_send(NEWPEER, (uint8_t *) &thePacket, j * sizeof(DataReading));
esp_now_del_peer(NEWPEER);
}
void sendSerial() {
DBG("Sending Serial.");
DynamicJsonDocument doc(24576);
for (int i = 0; i < ln; i++) {
doc[i]["id"] = theData[i].id;
doc[i]["type"] = theData[i].t;
doc[i]["data"] = theData[i].d;
}
serializeJson(doc, UART_IF);
UART_IF.println();
#ifndef ESP8266
serializeJson(doc, Serial);
Serial.println();
#endif
}
void sendMQTT() {
#ifdef USE_WIFI
DBG("Sending MQTT.");
DynamicJsonDocument doc(24576);
for (int i = 0; i < ln; i++) {
doc[i]["id"] = theData[i].id;
doc[i]["type"] = theData[i].t;
doc[i]["data"] = theData[i].d;
}
String outgoingString;
serializeJson(doc, outgoingString);
client.publish("esp/fdrs", (char*) outgoingString.c_str());
#endif
}
void bufferESPNOW(uint8_t interface) {
DBG("Buffering ESP-NOW.");
switch (interface) {
case 0:
for (int i = 0; i < ln; i++) {
ESPNOWGbuffer[lenESPNOWG + i] = theData[i];
}
lenESPNOWG += ln;
break;
case 1:
for (int i = 0; i < ln; i++) {
ESPNOW1buffer[lenESPNOW1 + i] = theData[i];
}
lenESPNOW1 += ln;
break;
case 2:
for (int i = 0; i < ln; i++) {
ESPNOW2buffer[lenESPNOW2 + i] = theData[i];
}
lenESPNOW2 += ln;
break;
}
}
void bufferSerial() {
DBG("Buffering Serial.");
for (int i = 0; i < ln; i++) {
SERIALbuffer[lenSERIAL + i] = theData[i];
}
lenSERIAL += ln;
//UART_IF.println("SENDSERIAL:" + String(lenSERIAL) + " ");
}
void bufferMQTT() {
DBG("Buffering MQTT.");
for (int i = 0; i < ln; i++) {
MQTTbuffer[lenMQTT + i] = theData[i];
}
lenMQTT += ln;
}
//void bufferLoRa() {
// for (int i = 0; i < ln; i++) {
// LORAbuffer[lenLORA + i] = theData[i];
// }
// lenLORA += ln;
//}
void bufferLoRa(uint8_t interface) {
DBG("Buffering LoRa.");
switch (interface) {
case 0:
for (int i = 0; i < ln; i++) {
LORAGbuffer[lenLORAG + i] = theData[i];
}
lenLORAG += ln;
break;
case 1:
for (int i = 0; i < ln; i++) {
LORA1buffer[lenLORA1 + i] = theData[i];
}
lenLORA1 += ln;
break;
case 2:
for (int i = 0; i < ln; i++) {
LORA2buffer[lenLORA2 + i] = theData[i];
}
lenLORA2 += ln;
break;
}
}
void releaseESPNOW(uint8_t interface) {
DBG("Releasing ESP-NOW.");
switch (interface) {
case 0:
{
DataReading thePacket[espnow_size];
int j = 0;
for (int i = 0; i < lenESPNOWG; i++) {
if ( j > espnow_size) {
j = 0;
esp_now_send(broadcast_mac, (uint8_t *) &thePacket, sizeof(thePacket));
}
thePacket[j] = ESPNOWGbuffer[i];
j++;
}
esp_now_send(broadcast_mac, (uint8_t *) &thePacket, j * sizeof(DataReading));
lenESPNOWG = 0;
break;
}
case 1:
{
DataReading thePacket[espnow_size];
int j = 0;
for (int i = 0; i < lenESPNOW1; i++) {
if ( j > espnow_size) {
j = 0;
esp_now_send(ESPNOW1, (uint8_t *) &thePacket, sizeof(thePacket));
}
thePacket[j] = ESPNOW1buffer[i];
j++;
}
esp_now_send(ESPNOW1, (uint8_t *) &thePacket, j * sizeof(DataReading));
lenESPNOW1 = 0;
break;
}
case 2:
{
DataReading thePacket[espnow_size];
int j = 0;
for (int i = 0; i < lenESPNOW2; i++) {
if ( j > espnow_size) {
j = 0;
esp_now_send(ESPNOW2, (uint8_t *) &thePacket, sizeof(thePacket));
}
thePacket[j] = ESPNOW2buffer[i];
j++;
}
esp_now_send(ESPNOW2, (uint8_t *) &thePacket, j * sizeof(DataReading));
lenESPNOW2 = 0;
break;
}
}
}
#ifdef USE_LORA
void transmitLoRa(uint8_t* mac, DataReading * packet, uint8_t len) {
DBG("Transmitting LoRa.");
uint8_t pkt[5 + (len * sizeof(DataReading))];
memcpy(&pkt, mac, 3);
memcpy(&pkt[3], &selfAddress[4], 2);
memcpy(&pkt[5], packet, len * sizeof(DataReading));
LoRa.beginPacket();
LoRa.write((uint8_t*)&pkt, sizeof(pkt));
LoRa.endPacket();
}
#endif
void releaseLoRa(uint8_t interface) {
#ifdef USE_LORA
DBG("Releasing LoRa.");
switch (interface) {
case 0:
{
DataReading thePacket[lora_size];
int j = 0;
for (int i = 0; i < lenLORAG; i++) {
if ( j > lora_size) {
j = 0;
transmitLoRa(broadcast_mac, thePacket, j);
}
thePacket[j] = LORAGbuffer[i];
j++;
}
transmitLoRa(broadcast_mac, thePacket, j);
lenLORAG = 0;
break;
}
case 1:
{
DataReading thePacket[lora_size];
int j = 0;
for (int i = 0; i < lenLORA1; i++) {
if ( j > lora_size) {
j = 0;
transmitLoRa(LoRa1, thePacket, j);
}
thePacket[j] = LORA1buffer[i];
j++;
}
transmitLoRa(LoRa1, thePacket, j);
lenLORA1 = 0;
break;
}
case 2:
{
DataReading thePacket[lora_size];
int j = 0;
for (int i = 0; i < lenLORA2; i++) {
if ( j > lora_size) {
j = 0;
transmitLoRa(LoRa2, thePacket, j);
}
thePacket[j] = LORA2buffer[i];
j++;
}
transmitLoRa(LoRa2, thePacket, j);
lenLORA2 = 0;
break;
}
}
#endif
}
void releaseSerial() {
DBG("Releasing Serial.");
DynamicJsonDocument doc(24576);
for (int i = 0; i < lenSERIAL; i++) {
doc[i]["id"] = SERIALbuffer[i].id;
doc[i]["type"] = SERIALbuffer[i].t;
doc[i]["data"] = SERIALbuffer[i].d;
}
serializeJson(doc, UART_IF);
UART_IF.println();
lenSERIAL = 0;
}
void releaseMQTT() {
#ifdef USE_WIFI
DBG("Releasing MQTT.");
DynamicJsonDocument doc(24576);
for (int i = 0; i < lenMQTT; i++) {
doc[i]["id"] = MQTTbuffer[i].id;
doc[i]["type"] = MQTTbuffer[i].t;
doc[i]["data"] = MQTTbuffer[i].d;
}
String outgoingString;
serializeJson(doc, outgoingString);
client.publish("esp/fdrs", (char*) outgoingString.c_str());
lenMQTT = 0;
#endif
}
void reconnect() {
#ifdef USE_WIFI
// Loop until reconnected
while (!client.connected()) {
// Attempt to connect
if (client.connect("FDRS_GATEWAY")) {
// Subscribe
client.subscribe("esp/fdrs");
} else {
DBG("Connecting MQTT.");
delay(5000);
}
}
#endif
}
void begin_espnow() {
DBG("Initializing ESP-NOW!");
WiFi.mode(WIFI_STA);
WiFi.disconnect();
// Init ESP-NOW for either ESP8266 or ESP32 and set MAC address
#if defined(ESP8266)
wifi_set_macaddr(STATION_IF, selfAddress);
if (esp_now_init() != 0) {
return;
}
esp_now_set_self_role(ESP_NOW_ROLE_COMBO);
esp_now_register_send_cb(OnDataSent);
esp_now_register_recv_cb(OnDataRecv);
// Register peers
esp_now_add_peer(ESPNOW1, ESP_NOW_ROLE_COMBO, 0, NULL, 0);
esp_now_add_peer(ESPNOW2, ESP_NOW_ROLE_COMBO, 0, NULL, 0);
#elif defined(ESP32)
esp_wifi_set_mac(WIFI_IF_STA, &selfAddress[0]);
if (esp_now_init() != ESP_OK) {
DBG("Error initializing ESP-NOW");
return;
}
esp_now_register_send_cb(OnDataSent);
esp_now_register_recv_cb(OnDataRecv);
peerInfo.channel = 0;
peerInfo.encrypt = false;
// Register first peer
memcpy(peerInfo.peer_addr, broadcast_mac, 6);
if (esp_now_add_peer(&peerInfo) != ESP_OK) {
DBG("Failed to add peer bcast");
return;
}
memcpy(peerInfo.peer_addr, ESPNOW1, 6);
if (esp_now_add_peer(&peerInfo) != ESP_OK) {
DBG("Failed to add peer 1");
return;
}
memcpy(peerInfo.peer_addr, ESPNOW2, 6);
if (esp_now_add_peer(&peerInfo) != ESP_OK) {
DBG("Failed to add peer 2");
return;
}
#endif
DBG(" ESP-NOW Initialized.");
DBG(WIFI_NET);
}