Merge pull request #31 from timmbogner/dev

Additions and subtractions
This commit is contained in:
Timm Bogner 2022-06-30 19:28:07 -05:00 committed by GitHub
commit d5f9b75e08
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
50 changed files with 3484 additions and 2653 deletions

View File

@ -1,178 +1,178 @@
// FARM DATA RELAY SYSTEM
//
// "fdrs_sensor.h"
//
// Developed by Timm Bogner (timmbogner@gmail.com) for Sola Gratia Farm in Urbana, Illinois, USA.
//
#include "sensor_setup.h"
#if defined(ESP8266)
#include <ESP8266WiFi.h>
#include <espnow.h>
#elif defined(ESP32)
#include <esp_now.h>
#include <WiFi.h>
#include <esp_wifi.h>
#endif
#ifdef USE_LORA
#include <LoRa.h>
#endif
#ifdef GLOBALS
#define FDRS_BAND GLOBAL_BAND
#define FDRS_SF GLOBAL_SF
#else
#define FDRS_BAND BAND
#define FDRS_SF SF
#endif
#ifdef DEBUG
#define DBG(a) (Serial.println(a))
#else
#define DBG(a)
#endif
#define STATUS_T 0 // Status
#define TEMP_T 1 // Temperature
#define TEMP2_T 2 // Temperature #2
#define HUMIDITY_T 3 // Relative Humidity
#define PRESSURE_T 4 // Atmospheric Pressure
#define LIGHT_T 5 // Light (lux)
#define SOIL_T 6 // Soil Moisture
#define SOIL2_T 7 // Soil Moisture #2
#define SOILR_T 8 // Soil Resistance
#define SOILR2_T 9 // Soil Resistance #2
#define OXYGEN_T 10 // Oxygen
#define CO2_T 11 // Carbon Dioxide
#define WINDSPD_T 12 // Wind Speed
#define WINDHDG_T 13 // Wind Direction
#define RAINFALL_T 14 // Rainfall
#define MOTION_T 15 // Motion
#define VOLTAGE_T 16 // Voltage
#define VOLTAGE2_T 17 // Voltage #2
#define CURRENT_T 18 // Current
#define CURRENT2_T 19 // Current #2
#define IT_T 20 // Iterations
#define MAC_PREFIX 0xAA, 0xBB, 0xCC, 0xDD, 0xEE // Should only be changed if implementing multiple FDRS systems.
typedef struct __attribute__((packed)) DataReading {
float d;
uint16_t id;
uint8_t t;
} DataReading;
const uint16_t espnow_size = 250 / sizeof(DataReading);
uint8_t gatewayAddress[] = {MAC_PREFIX, GTWY_MAC};
uint8_t gtwyAddress[] = {gatewayAddress[3], gatewayAddress[4], GTWY_MAC};
uint8_t LoRaAddress[] = {0x42, 0x00};
uint32_t wait_time = 0;
DataReading fdrsData[espnow_size];
uint8_t data_count = 0;
void beginFDRS() {
#ifdef DEBUG
Serial.begin(115200);
#endif
DBG("FDRS Sensor ID " + String(READING_ID) + " initializing...");
DBG(" Gateway: " + String (GTWY_MAC, HEX));
#ifdef POWER_CTRL
DBG("Powering up the sensor array!");
pinMode(POWER_CTRL, OUTPUT);
digitalWrite(POWER_CTRL, 1);
#endif
// Init ESP-NOW for either ESP8266 or ESP32 and set MAC address
#ifdef USE_ESPNOW
DBG("Initializing ESP-NOW!");
WiFi.mode(WIFI_STA);
WiFi.disconnect();
#if defined(ESP8266)
if (esp_now_init() != 0) {
return;
}
esp_now_set_self_role(ESP_NOW_ROLE_COMBO);
// Register peers
esp_now_add_peer(gatewayAddress, ESP_NOW_ROLE_COMBO, 0, NULL, 0);
#elif defined(ESP32)
if (esp_now_init() != ESP_OK) {
DBG("Error initializing ESP-NOW");
return;
}
esp_now_peer_info_t peerInfo;
peerInfo.ifidx = WIFI_IF_STA;
peerInfo.channel = 0;
peerInfo.encrypt = false;
// Register first peer
memcpy(peerInfo.peer_addr, gatewayAddress, 6);
if (esp_now_add_peer(&peerInfo) != ESP_OK) {
DBG("Failed to add peer");
return;
}
#endif
DBG(" ESP-NOW Initialized.");
#endif
#ifdef USE_LORA
DBG("Initializing LoRa!");
DBG(BAND);
DBG(SF);
#ifndef __AVR__
SPI.begin(SCK, MISO, MOSI, SS);
#endif
LoRa.setPins(SS, RST, DIO0);
if (!LoRa.begin(FDRS_BAND)) {
while (1);
}
LoRa.setSpreadingFactor(FDRS_SF);
DBG(" LoRa Initialized.");
#endif
}
void transmitLoRa(uint8_t* mac, DataReading * packet, uint8_t len) {
#ifdef USE_LORA
uint8_t pkt[5 + (len * sizeof(DataReading))];
memcpy(&pkt, mac, 3); //
memcpy(&pkt[3], &LoRaAddress, 2);
memcpy(&pkt[5], packet, len * sizeof(DataReading));
LoRa.beginPacket();
LoRa.write((uint8_t*)&pkt, sizeof(pkt));
LoRa.endPacket();
#endif
}
void sendFDRS() {
DBG("Sending FDRS Packet!");
#ifdef USE_ESPNOW
esp_now_send(gatewayAddress, (uint8_t *) &fdrsData, data_count * sizeof(DataReading));
delay(5);
DBG(" ESP-NOW sent.");
#endif
#ifdef USE_LORA
transmitLoRa(gtwyAddress, fdrsData, data_count);
DBG(" LoRa sent.");
#endif
data_count = 0;
}
void loadFDRS(float d, uint8_t t) {
DBG("Data loaded. Type: " + String(t));
if (data_count > espnow_size) sendFDRS();
DataReading dr;
dr.id = READING_ID;
dr.t = t;
dr.d = d;
fdrsData[data_count] = dr;
data_count++;
}
void sleepFDRS(int sleep_time) {
DBG("Sleepytime!");
#ifdef DEEP_SLEEP
DBG(" Deep sleeping.");
#ifdef ESP32
esp_sleep_enable_timer_wakeup(sleep_time * 1000000);
esp_deep_sleep_start();
#endif
#ifdef ESP8266
ESP.deepSleep(sleep_time * 1000000);
#endif
#endif
DBG(" Delaying.");
delay(sleep_time * 1000);
}
// FARM DATA RELAY SYSTEM
//
// "fdrs_sensor.h"
//
// Developed by Timm Bogner (timmbogner@gmail.com) for Sola Gratia Farm in Urbana, Illinois, USA.
//
#include "sensor_setup.h"
#if defined(ESP8266)
#include <ESP8266WiFi.h>
#include <espnow.h>
#elif defined(ESP32)
#include <esp_now.h>
#include <WiFi.h>
#include <esp_wifi.h>
#endif
#ifdef USE_LORA
#include <LoRa.h>
#endif
#ifdef GLOBALS
#define FDRS_BAND GLOBAL_BAND
#define FDRS_SF GLOBAL_SF
#else
#define FDRS_BAND BAND
#define FDRS_SF SF
#endif
#ifdef DEBUG
#define DBG(a) (Serial.println(a))
#else
#define DBG(a)
#endif
#define STATUS_T 0 // Status
#define TEMP_T 1 // Temperature
#define TEMP2_T 2 // Temperature #2
#define HUMIDITY_T 3 // Relative Humidity
#define PRESSURE_T 4 // Atmospheric Pressure
#define LIGHT_T 5 // Light (lux)
#define SOIL_T 6 // Soil Moisture
#define SOIL2_T 7 // Soil Moisture #2
#define SOILR_T 8 // Soil Resistance
#define SOILR2_T 9 // Soil Resistance #2
#define OXYGEN_T 10 // Oxygen
#define CO2_T 11 // Carbon Dioxide
#define WINDSPD_T 12 // Wind Speed
#define WINDHDG_T 13 // Wind Direction
#define RAINFALL_T 14 // Rainfall
#define MOTION_T 15 // Motion
#define VOLTAGE_T 16 // Voltage
#define VOLTAGE2_T 17 // Voltage #2
#define CURRENT_T 18 // Current
#define CURRENT2_T 19 // Current #2
#define IT_T 20 // Iterations
#define MAC_PREFIX 0xAA, 0xBB, 0xCC, 0xDD, 0xEE // Should only be changed if implementing multiple FDRS systems.
typedef struct __attribute__((packed)) DataReading {
float d;
uint16_t id;
uint8_t t;
} DataReading;
const uint16_t espnow_size = 250 / sizeof(DataReading);
uint8_t gatewayAddress[] = {MAC_PREFIX, GTWY_MAC};
uint8_t gtwyAddress[] = {gatewayAddress[3], gatewayAddress[4], GTWY_MAC};
uint8_t LoRaAddress[] = {0x42, 0x00};
uint32_t wait_time = 0;
DataReading fdrsData[espnow_size];
uint8_t data_count = 0;
void beginFDRS() {
#ifdef DEBUG
Serial.begin(115200);
#endif
DBG("FDRS Sensor ID " + String(READING_ID) + " initializing...");
DBG(" Gateway: " + String (GTWY_MAC, HEX));
#ifdef POWER_CTRL
DBG("Powering up the sensor array!");
pinMode(POWER_CTRL, OUTPUT);
digitalWrite(POWER_CTRL, 1);
#endif
// Init ESP-NOW for either ESP8266 or ESP32 and set MAC address
#ifdef USE_ESPNOW
DBG("Initializing ESP-NOW!");
WiFi.mode(WIFI_STA);
WiFi.disconnect();
#if defined(ESP8266)
if (esp_now_init() != 0) {
return;
}
esp_now_set_self_role(ESP_NOW_ROLE_COMBO);
// Register peers
esp_now_add_peer(gatewayAddress, ESP_NOW_ROLE_COMBO, 0, NULL, 0);
#elif defined(ESP32)
if (esp_now_init() != ESP_OK) {
DBG("Error initializing ESP-NOW");
return;
}
esp_now_peer_info_t peerInfo;
peerInfo.ifidx = WIFI_IF_STA;
peerInfo.channel = 0;
peerInfo.encrypt = false;
// Register first peer
memcpy(peerInfo.peer_addr, gatewayAddress, 6);
if (esp_now_add_peer(&peerInfo) != ESP_OK) {
DBG("Failed to add peer");
return;
}
#endif
DBG(" ESP-NOW Initialized.");
#endif
#ifdef USE_LORA
DBG("Initializing LoRa!");
DBG(BAND);
DBG(SF);
#ifdef ESP32
SPI.begin(SCK, MISO, MOSI, SS);
#endif
LoRa.setPins(SS, RST, DIO0);
if (!LoRa.begin(FDRS_BAND)) {
while (1);
}
LoRa.setSpreadingFactor(FDRS_SF);
DBG(" LoRa Initialized.");
#endif
}
void transmitLoRa(uint8_t* mac, DataReading * packet, uint8_t len) {
#ifdef USE_LORA
uint8_t pkt[5 + (len * sizeof(DataReading))];
memcpy(&pkt, mac, 3); //
memcpy(&pkt[3], &LoRaAddress, 2);
memcpy(&pkt[5], packet, len * sizeof(DataReading));
LoRa.beginPacket();
LoRa.write((uint8_t*)&pkt, sizeof(pkt));
LoRa.endPacket();
#endif
}
void sendFDRS() {
DBG("Sending FDRS Packet!");
#ifdef USE_ESPNOW
esp_now_send(gatewayAddress, (uint8_t *) &fdrsData, data_count * sizeof(DataReading));
delay(5);
DBG(" ESP-NOW sent.");
#endif
#ifdef USE_LORA
transmitLoRa(gtwyAddress, fdrsData, data_count);
DBG(" LoRa sent.");
#endif
data_count = 0;
}
void loadFDRS(float d, uint8_t t) {
DBG("Data loaded. Type: " + String(t));
if (data_count > espnow_size) sendFDRS();
DataReading dr;
dr.id = READING_ID;
dr.t = t;
dr.d = d;
fdrsData[data_count] = dr;
data_count++;
}
void sleepFDRS(int sleep_time) {
DBG("Sleepytime!");
#ifdef DEEP_SLEEP
DBG(" Deep sleeping.");
#ifdef ESP32
esp_sleep_enable_timer_wakeup(sleep_time * 1000000);
esp_deep_sleep_start();
#endif
#ifdef ESP8266
ESP.deepSleep(sleep_time * 1000000);
#endif
#endif
DBG(" Delaying.");
delay(sleep_time * 1000);
}

View File

@ -1,178 +1,178 @@
// FARM DATA RELAY SYSTEM
//
// "fdrs_sensor.h"
//
// Developed by Timm Bogner (timmbogner@gmail.com) for Sola Gratia Farm in Urbana, Illinois, USA.
//
#include "sensor_setup.h"
#if defined(ESP8266)
#include <ESP8266WiFi.h>
#include <espnow.h>
#elif defined(ESP32)
#include <esp_now.h>
#include <WiFi.h>
#include <esp_wifi.h>
#endif
#ifdef USE_LORA
#include <LoRa.h>
#endif
#ifdef GLOBALS
#define FDRS_BAND GLOBAL_BAND
#define FDRS_SF GLOBAL_SF
#else
#define FDRS_BAND BAND
#define FDRS_SF SF
#endif
#ifdef DEBUG
#define DBG(a) (Serial.println(a))
#else
#define DBG(a)
#endif
#define STATUS_T 0 // Status
#define TEMP_T 1 // Temperature
#define TEMP2_T 2 // Temperature #2
#define HUMIDITY_T 3 // Relative Humidity
#define PRESSURE_T 4 // Atmospheric Pressure
#define LIGHT_T 5 // Light (lux)
#define SOIL_T 6 // Soil Moisture
#define SOIL2_T 7 // Soil Moisture #2
#define SOILR_T 8 // Soil Resistance
#define SOILR2_T 9 // Soil Resistance #2
#define OXYGEN_T 10 // Oxygen
#define CO2_T 11 // Carbon Dioxide
#define WINDSPD_T 12 // Wind Speed
#define WINDHDG_T 13 // Wind Direction
#define RAINFALL_T 14 // Rainfall
#define MOTION_T 15 // Motion
#define VOLTAGE_T 16 // Voltage
#define VOLTAGE2_T 17 // Voltage #2
#define CURRENT_T 18 // Current
#define CURRENT2_T 19 // Current #2
#define IT_T 20 // Iterations
#define MAC_PREFIX 0xAA, 0xBB, 0xCC, 0xDD, 0xEE // Should only be changed if implementing multiple FDRS systems.
typedef struct __attribute__((packed)) DataReading {
float d;
uint16_t id;
uint8_t t;
} DataReading;
const uint16_t espnow_size = 250 / sizeof(DataReading);
uint8_t gatewayAddress[] = {MAC_PREFIX, GTWY_MAC};
uint8_t gtwyAddress[] = {gatewayAddress[3], gatewayAddress[4], GTWY_MAC};
uint8_t LoRaAddress[] = {0x42, 0x00};
uint32_t wait_time = 0;
DataReading fdrsData[espnow_size];
uint8_t data_count = 0;
void beginFDRS() {
#ifdef DEBUG
Serial.begin(115200);
#endif
DBG("FDRS Sensor ID " + String(READING_ID) + " initializing...");
DBG(" Gateway: " + String (GTWY_MAC, HEX));
#ifdef POWER_CTRL
DBG("Powering up the sensor array!");
pinMode(POWER_CTRL, OUTPUT);
digitalWrite(POWER_CTRL, 1);
#endif
// Init ESP-NOW for either ESP8266 or ESP32 and set MAC address
#ifdef USE_ESPNOW
DBG("Initializing ESP-NOW!");
WiFi.mode(WIFI_STA);
WiFi.disconnect();
#if defined(ESP8266)
if (esp_now_init() != 0) {
return;
}
esp_now_set_self_role(ESP_NOW_ROLE_COMBO);
// Register peers
esp_now_add_peer(gatewayAddress, ESP_NOW_ROLE_COMBO, 0, NULL, 0);
#elif defined(ESP32)
if (esp_now_init() != ESP_OK) {
DBG("Error initializing ESP-NOW");
return;
}
esp_now_peer_info_t peerInfo;
peerInfo.ifidx = WIFI_IF_STA;
peerInfo.channel = 0;
peerInfo.encrypt = false;
// Register first peer
memcpy(peerInfo.peer_addr, gatewayAddress, 6);
if (esp_now_add_peer(&peerInfo) != ESP_OK) {
DBG("Failed to add peer");
return;
}
#endif
DBG(" ESP-NOW Initialized.");
#endif
#ifdef USE_LORA
DBG("Initializing LoRa!");
DBG(BAND);
DBG(SF);
#ifndef __AVR__
SPI.begin(SCK, MISO, MOSI, SS);
#endif
LoRa.setPins(SS, RST, DIO0);
if (!LoRa.begin(FDRS_BAND)) {
while (1);
}
LoRa.setSpreadingFactor(FDRS_SF);
DBG(" LoRa Initialized.");
#endif
}
void transmitLoRa(uint8_t* mac, DataReading * packet, uint8_t len) {
#ifdef USE_LORA
uint8_t pkt[5 + (len * sizeof(DataReading))];
memcpy(&pkt, mac, 3); //
memcpy(&pkt[3], &LoRaAddress, 2);
memcpy(&pkt[5], packet, len * sizeof(DataReading));
LoRa.beginPacket();
LoRa.write((uint8_t*)&pkt, sizeof(pkt));
LoRa.endPacket();
#endif
}
void sendFDRS() {
DBG("Sending FDRS Packet!");
#ifdef USE_ESPNOW
esp_now_send(gatewayAddress, (uint8_t *) &fdrsData, data_count * sizeof(DataReading));
delay(5);
DBG(" ESP-NOW sent.");
#endif
#ifdef USE_LORA
transmitLoRa(gtwyAddress, fdrsData, data_count);
DBG(" LoRa sent.");
#endif
data_count = 0;
}
void loadFDRS(float d, uint8_t t) {
DBG("Data loaded. Type: " + String(t));
if (data_count > espnow_size) sendFDRS();
DataReading dr;
dr.id = READING_ID;
dr.t = t;
dr.d = d;
fdrsData[data_count] = dr;
data_count++;
}
void sleepFDRS(int sleep_time) {
DBG("Sleepytime!");
#ifdef DEEP_SLEEP
DBG(" Deep sleeping.");
#ifdef ESP32
esp_sleep_enable_timer_wakeup(sleep_time * 1000000);
esp_deep_sleep_start();
#endif
#ifdef ESP8266
ESP.deepSleep(sleep_time * 1000000);
#endif
#endif
DBG(" Delaying.");
delay(sleep_time * 1000);
}
// FARM DATA RELAY SYSTEM
//
// "fdrs_sensor.h"
//
// Developed by Timm Bogner (timmbogner@gmail.com) for Sola Gratia Farm in Urbana, Illinois, USA.
//
#include "sensor_setup.h"
#if defined(ESP8266)
#include <ESP8266WiFi.h>
#include <espnow.h>
#elif defined(ESP32)
#include <esp_now.h>
#include <WiFi.h>
#include <esp_wifi.h>
#endif
#ifdef USE_LORA
#include <LoRa.h>
#endif
#ifdef GLOBALS
#define FDRS_BAND GLOBAL_BAND
#define FDRS_SF GLOBAL_SF
#else
#define FDRS_BAND BAND
#define FDRS_SF SF
#endif
#ifdef DEBUG
#define DBG(a) (Serial.println(a))
#else
#define DBG(a)
#endif
#define STATUS_T 0 // Status
#define TEMP_T 1 // Temperature
#define TEMP2_T 2 // Temperature #2
#define HUMIDITY_T 3 // Relative Humidity
#define PRESSURE_T 4 // Atmospheric Pressure
#define LIGHT_T 5 // Light (lux)
#define SOIL_T 6 // Soil Moisture
#define SOIL2_T 7 // Soil Moisture #2
#define SOILR_T 8 // Soil Resistance
#define SOILR2_T 9 // Soil Resistance #2
#define OXYGEN_T 10 // Oxygen
#define CO2_T 11 // Carbon Dioxide
#define WINDSPD_T 12 // Wind Speed
#define WINDHDG_T 13 // Wind Direction
#define RAINFALL_T 14 // Rainfall
#define MOTION_T 15 // Motion
#define VOLTAGE_T 16 // Voltage
#define VOLTAGE2_T 17 // Voltage #2
#define CURRENT_T 18 // Current
#define CURRENT2_T 19 // Current #2
#define IT_T 20 // Iterations
#define MAC_PREFIX 0xAA, 0xBB, 0xCC, 0xDD, 0xEE // Should only be changed if implementing multiple FDRS systems.
typedef struct __attribute__((packed)) DataReading {
float d;
uint16_t id;
uint8_t t;
} DataReading;
const uint16_t espnow_size = 250 / sizeof(DataReading);
uint8_t gatewayAddress[] = {MAC_PREFIX, GTWY_MAC};
uint8_t gtwyAddress[] = {gatewayAddress[3], gatewayAddress[4], GTWY_MAC};
uint8_t LoRaAddress[] = {0x42, 0x00};
uint32_t wait_time = 0;
DataReading fdrsData[espnow_size];
uint8_t data_count = 0;
void beginFDRS() {
#ifdef DEBUG
Serial.begin(115200);
#endif
DBG("FDRS Sensor ID " + String(READING_ID) + " initializing...");
DBG(" Gateway: " + String (GTWY_MAC, HEX));
#ifdef POWER_CTRL
DBG("Powering up the sensor array!");
pinMode(POWER_CTRL, OUTPUT);
digitalWrite(POWER_CTRL, 1);
#endif
// Init ESP-NOW for either ESP8266 or ESP32 and set MAC address
#ifdef USE_ESPNOW
DBG("Initializing ESP-NOW!");
WiFi.mode(WIFI_STA);
WiFi.disconnect();
#if defined(ESP8266)
if (esp_now_init() != 0) {
return;
}
esp_now_set_self_role(ESP_NOW_ROLE_COMBO);
// Register peers
esp_now_add_peer(gatewayAddress, ESP_NOW_ROLE_COMBO, 0, NULL, 0);
#elif defined(ESP32)
if (esp_now_init() != ESP_OK) {
DBG("Error initializing ESP-NOW");
return;
}
esp_now_peer_info_t peerInfo;
peerInfo.ifidx = WIFI_IF_STA;
peerInfo.channel = 0;
peerInfo.encrypt = false;
// Register first peer
memcpy(peerInfo.peer_addr, gatewayAddress, 6);
if (esp_now_add_peer(&peerInfo) != ESP_OK) {
DBG("Failed to add peer");
return;
}
#endif
DBG(" ESP-NOW Initialized.");
#endif
#ifdef USE_LORA
DBG("Initializing LoRa!");
DBG(BAND);
DBG(SF);
#ifdef ESP32
SPI.begin(SCK, MISO, MOSI, SS);
#endif
LoRa.setPins(SS, RST, DIO0);
if (!LoRa.begin(FDRS_BAND)) {
while (1);
}
LoRa.setSpreadingFactor(FDRS_SF);
DBG(" LoRa Initialized.");
#endif
}
void transmitLoRa(uint8_t* mac, DataReading * packet, uint8_t len) {
#ifdef USE_LORA
uint8_t pkt[5 + (len * sizeof(DataReading))];
memcpy(&pkt, mac, 3); //
memcpy(&pkt[3], &LoRaAddress, 2);
memcpy(&pkt[5], packet, len * sizeof(DataReading));
LoRa.beginPacket();
LoRa.write((uint8_t*)&pkt, sizeof(pkt));
LoRa.endPacket();
#endif
}
void sendFDRS() {
DBG("Sending FDRS Packet!");
#ifdef USE_ESPNOW
esp_now_send(gatewayAddress, (uint8_t *) &fdrsData, data_count * sizeof(DataReading));
delay(5);
DBG(" ESP-NOW sent.");
#endif
#ifdef USE_LORA
transmitLoRa(gtwyAddress, fdrsData, data_count);
DBG(" LoRa sent.");
#endif
data_count = 0;
}
void loadFDRS(float d, uint8_t t) {
DBG("Data loaded. Type: " + String(t));
if (data_count > espnow_size) sendFDRS();
DataReading dr;
dr.id = READING_ID;
dr.t = t;
dr.d = d;
fdrsData[data_count] = dr;
data_count++;
}
void sleepFDRS(int sleep_time) {
DBG("Sleepytime!");
#ifdef DEEP_SLEEP
DBG(" Deep sleeping.");
#ifdef ESP32
esp_sleep_enable_timer_wakeup(sleep_time * 1000000);
esp_deep_sleep_start();
#endif
#ifdef ESP8266
ESP.deepSleep(sleep_time * 1000000);
#endif
#endif
DBG(" Delaying.");
delay(sleep_time * 1000);
}

View File

@ -49,7 +49,7 @@ void setup() {
delay(500);
}
DBG("WiFi Connected");
client.setServer(mqtt_server, 1883);
client.setServer(mqtt_server, mqtt_port);
if (!client.connected()) {
DBG("Connecting MQTT...");
reconnect();

View File

@ -34,6 +34,13 @@
#define WIFI_SSID "Your SSID"
#define WIFI_PASS "Your Password"
#define MQTT_ADDR "192.168.0.8"
#define MQTT_PORT 1883 // Default MQTT port is 1883
//MQTT Credentials -- Needed only if MQTT broker requires authentication
//#define MQTT_AUTH //uncomment to enable MQTT authentication
#define MQTT_USER "Your MQTT Username"
#define MQTT_PASS "Your MQTT Password"
// MQTT Topics
#define TOPIC_DATA "fdrs/data"
#define TOPIC_STATUS "fdrs/status"

File diff suppressed because it is too large Load Diff

View File

@ -49,7 +49,7 @@ void setup() {
delay(500);
}
DBG("WiFi Connected");
client.setServer(mqtt_server, 1883);
client.setServer(mqtt_server, mqtt_port);
if (!client.connected()) {
DBG("Connecting MQTT...");
reconnect();

View File

@ -34,6 +34,13 @@
#define WIFI_SSID "Your SSID"
#define WIFI_PASS "Your Password"
#define MQTT_ADDR "192.168.0.8"
#define MQTT_PORT 1883 // Default MQTT port is 1883
//MQTT Credentials -- Needed only if MQTT broker requires authentication
//#define MQTT_AUTH //uncomment to enable MQTT authentication
#define MQTT_USER "Your MQTT Username"
#define MQTT_PASS "Your MQTT Password"
// MQTT Topics
#define TOPIC_DATA "fdrs/data"
#define TOPIC_STATUS "fdrs/status"

View File

@ -14,16 +14,26 @@
#define FDRS_WIFI_SSID GLOBAL_SSID
#define FDRS_WIFI_PASS GLOBAL_PASS
#define FDRS_MQTT_ADDR GLOBAL_MQTT_ADDR
#define FDRS_MQTT_PORT GLOBAL_MQTT_PORT
#define FDRS_MQTT_USER GLOBAL_MQTT_USER
#define FDRS_MQTT_PASS GLOBAL_MQTT_PASS
#define FDRS_BAND GLOBAL_BAND
#define FDRS_SF GLOBAL_SF
#else
#define FDRS_WIFI_SSID WIFI_SSID
#define FDRS_WIFI_PASS WIFI_PASS
#define FDRS_MQTT_ADDR MQTT_ADDR
#define FDRS_MQTT_PORT MQTT_PORT
#define FDRS_MQTT_USER MQTT_USER
#define FDRS_MQTT_PASS MQTT_PASS
#define FDRS_BAND BAND
#define FDRS_SF SF
#endif
#if defined (MQTT_AUTH) || defined (GLOBAL_MQTT_AUTH)
#define FDRS_MQTT_AUTH
#endif
#define MAC_PREFIX 0xAA, 0xBB, 0xCC, 0xDD, 0xEE // Should only be changed if implementing multiple FDRS systems.
typedef struct __attribute__((packed)) DataReading {
@ -100,8 +110,15 @@ PubSubClient client(espClient);
const char* ssid = FDRS_WIFI_SSID;
const char* password = FDRS_WIFI_PASS;
const char* mqtt_server = FDRS_MQTT_ADDR;
const int mqtt_port = FDRS_MQTT_PORT;
#endif
#ifdef FDRS_MQTT_AUTH
const char* mqtt_user = FDRS_MQTT_USER;
const char* mqtt_pass = FDRS_MQTT_PASS;
#else
const char* mqtt_user = NULL;
const char* mqtt_pass = NULL;
#endif
// Set ESP-NOW send and receive callbacks for either ESP8266 or ESP32
#if defined(ESP8266)
@ -482,7 +499,7 @@ void reconnect() {
// Loop until reconnected
while (!client.connected()) {
// Attempt to connect
if (client.connect("FDRS_GATEWAY")) {
if (client.connect("FDRS_GATEWAY", mqtt_user, mqtt_pass)) {
// Subscribe
client.subscribe(TOPIC_COMMAND);
} else {

View File

@ -49,7 +49,7 @@ void setup() {
delay(500);
}
DBG("WiFi Connected");
client.setServer(mqtt_server, 1883);
client.setServer(mqtt_server, mqtt_port);
if (!client.connected()) {
DBG("Connecting MQTT...");
reconnect();

View File

@ -67,6 +67,13 @@
#define WIFI_SSID "Your SSID"
#define WIFI_PASS "Your Password"
#define MQTT_ADDR "192.168.0.8"
#define MQTT_PORT 1883 // Default MQTT port is 1883
//MQTT Credentials -- Needed only if MQTT broker requires authentication
//#define MQTT_AUTH //uncomment to enable MQTT authentication
#define MQTT_USER "Your MQTT Username"
#define MQTT_PASS "Your MQTT Password"
// MQTT Topics
#define TOPIC_DATA "fdrs/data"
#define TOPIC_STATUS "fdrs/status"

View File

@ -14,16 +14,26 @@
#define FDRS_WIFI_SSID GLOBAL_SSID
#define FDRS_WIFI_PASS GLOBAL_PASS
#define FDRS_MQTT_ADDR GLOBAL_MQTT_ADDR
#define FDRS_MQTT_PORT GLOBAL_MQTT_PORT
#define FDRS_MQTT_USER GLOBAL_MQTT_USER
#define FDRS_MQTT_PASS GLOBAL_MQTT_PASS
#define FDRS_BAND GLOBAL_BAND
#define FDRS_SF GLOBAL_SF
#else
#define FDRS_WIFI_SSID WIFI_SSID
#define FDRS_WIFI_PASS WIFI_PASS
#define FDRS_MQTT_ADDR MQTT_ADDR
#define FDRS_MQTT_PORT MQTT_PORT
#define FDRS_MQTT_USER MQTT_USER
#define FDRS_MQTT_PASS MQTT_PASS
#define FDRS_BAND BAND
#define FDRS_SF SF
#endif
#if defined (MQTT_AUTH) || defined (GLOBAL_MQTT_AUTH)
#define FDRS_MQTT_AUTH
#endif
#define MAC_PREFIX 0xAA, 0xBB, 0xCC, 0xDD, 0xEE // Should only be changed if implementing multiple FDRS systems.
typedef struct __attribute__((packed)) DataReading {
@ -100,8 +110,15 @@ PubSubClient client(espClient);
const char* ssid = FDRS_WIFI_SSID;
const char* password = FDRS_WIFI_PASS;
const char* mqtt_server = FDRS_MQTT_ADDR;
const int mqtt_port = FDRS_MQTT_PORT;
#endif
#ifdef FDRS_MQTT_AUTH
const char* mqtt_user = FDRS_MQTT_USER;
const char* mqtt_pass = FDRS_MQTT_PASS;
#else
const char* mqtt_user = NULL;
const char* mqtt_pass = NULL;
#endif
// Set ESP-NOW send and receive callbacks for either ESP8266 or ESP32
#if defined(ESP8266)
@ -482,7 +499,7 @@ void reconnect() {
// Loop until reconnected
while (!client.connected()) {
// Attempt to connect
if (client.connect("FDRS_GATEWAY")) {
if (client.connect("FDRS_GATEWAY", mqtt_user, mqtt_pass)) {
// Subscribe
client.subscribe(TOPIC_COMMAND);
} else {

View File

@ -1,3 +0,0 @@
Please copy this directory into your Arduino "libraries" directory.
Edit the files in your libraries folder according to your needs with your WiFi info, LoRa band, etc.
Never edit them here!!!

View File

@ -1,8 +0,0 @@
#define GLOBAL_SSID "Your SSID"
#define GLOBAL_PASS "Password"
#define GLOBAL_MQTT_ADDR "192.168.0.8"
#define GLOBAL_BAND 915E6 //LoRa Frequency Band
#define GLOBAL_SF 7 //LoRa Spreading Factor
#define GLOBALS

View File

@ -0,0 +1,234 @@
// FARM DATA RELAY SYSTEM
//
// Experimental Universal Gateway
//
// Under construction, feedback is appreciated!
//
#include "fdrs_config.h"
#ifdef USE_LED
#include <FastLED.h>
#endif
#include "fdrs_gateway.h"
#include "fdrs_config.h"
#ifdef USE_LED
CRGB leds[NUM_LEDS];
#endif
uint8_t selfAddress[6] = {MAC_PREFIX, UNIT_MAC};
#if defined(ESP_GET) || defined(ESP_SEND)
#ifdef ESPNOW_ALL
std::vector<DataReading_t> espnow_peer_unknown_data;
#endif
#ifdef ESPNOW_PEER_1
uint8_t ESPNOW1[] = {MAC_PREFIX, ESPNOW_PEER_1};
std::vector<DataReading_t> espnow_peer_1_data;
#endif
#ifdef ESPNOW_PEER_2
uint8_t ESPNOW2[] = {MAC_PREFIX, ESPNOW_PEER_2};
std::vector<DataReading_t> espnow_peer_2_data;
#endif
#endif
#if defined(LORA_GET) || defined(LORA_SEND)
#ifdef LORA_PEER_1
uint8_t LoRa1[6] = {MAC_PREFIX, LORA_PEER_1};
std::vector<DataReading_t> lora_peer_1_data;
#endif
#ifdef LORA_PEER_2
uint8_t LoRa2[6] = {MAC_PREFIX, LORA_PEER_2};
std::vector<DataReading_t> lora_peer_2_data;
#endif
#endif
#if defined(MQTT_GET) || defined(MQTT_SEND)
MQTT_FDRSGateWay MQTT(WIFI_SSID,WIFI_PASS,MQTT_ADDR,MQTT_PORT);
std::vector<DataReading_t> mqtt_data;
#endif
#if defined(ESP_GET) || defined(ESP_SEND)
ESP_FDRSGateWay ESPNow;
#endif
#if defined(SER_GET) || defined(SER_SEND)
#ifdef ESP32
Serial_FDRSGateWay SerialGW(&Serial1,115200);
#else
Serial_FDRSGateWay SerialGW(&Serial,115200);
#endif
std::vector<DataReading_t> serial_data;
#endif
#if defined(LORA_GET) || defined(LORA_SEND)
LoRa_FDRSGateWay LoRaGW(MISO,MOSI,SCK,SS,RST,DIO0,BAND,SF);
#endif
void setup() {
#ifdef USE_LED
FastLED.addLeds<WS2812B, LED_PIN, GRB>(leds, NUM_LEDS);
leds[0] = CRGB::Blue;
FastLED.show();
#endif
#if defined(MQTT_GET) || defined(MQTT_SEND)
MQTT.init();
#endif
#if defined(ESP_GET) || defined(ESP_SEND)
ESPNow.init(selfAddress);
#ifdef ESPNOW_PEER_1
ESPNow.add_peer(ESPNOW1);
#endif
#ifdef ESPNOW_PEER_2
ESPNow.add_peer(ESPNOW2);
#endif
#endif
#if defined(SER_GET) || defined(SER_SEND)
#ifdef ESP32
SerialGW.init(SERIAL_8N1,RXD2,TXD2);
#else
SerialGW.init();
#endif
#endif
#if defined(LORA_GET) || defined(LORA_SEND)
LoRaGW.init(selfAddress);
#endif
}
void loop() {
//collect data
#ifdef LORA_GET
LoRaGW.get();
#endif
#ifdef SER_GET
SerialGW.get();
#endif
//get the collected data
#ifdef ESP_GET
#ifdef ESPNOW_ALL
espnow_peer_unknown_data = ESPNow.get_unkown_peer_data();
#endif
#ifdef ESPNOW_PEER_1
espnow_peer_1_data = ESPNow.get_peer_data(ESPNOW1);
#endif
#ifdef ESPNOW_PEER_2
espnow_peer_2_data = ESPNow.get_peer_data(ESPNOW2);
#endif
#endif
#ifdef MQTT_GET
mqtt_data = MQTT.get_data();
#endif
#ifdef SER_GET
serial_data = SerialGW.get_data();
#endif
#ifdef LORA_GET
#ifdef LORA_PEER_1
lora_peer_1_data = LoRaGW.get_peer_data(LoRa1);
#endif
#ifdef LORA_PEER_1
lora_peer_2_data = LoRaGW.get_peer_data(LoRa2);
#endif
#endif
//send the collected data to where you want it
#ifdef ESP_SEND
#ifdef ESPNOW_ALL
// send ESPNOW_UNKNOWN_PEER data to ESPNOW_UNKNOWN_PEER
ESPNow.release(espnow_peer_unknown_data);
#endif
#ifdef ESPNOW_PEER_1
// send ESPNOW_PEER_2 data to ESPNOW_PEER_1
ESPNow.release(espnow_peer_2_data,ESPNOW1);
#endif
#ifdef ESPNOW_PEER_2
// send ESPNOW_PEER_1 data to ESPNOW_PEER_2
ESPNow.release(espnow_peer_1_data,ESPNOW2);
#endif
#endif
#ifdef MQTT_SEND
// send ESPNOW_PEER_1 data to MQTT
MQTT.release(espnow_peer_1_data);
#endif
#ifdef SER_SEND
// send ESPNOW_PEER_2 data to SERIAL
SerialGW.release(espnow_peer_2_data);
#endif
#ifdef LORA_SEND
// send SERIAL data to LoRa
LoRaGW.release(serial_data);
#endif
//clear out the buffers
#ifdef ESP_GET
#ifdef ESPNOW_ALL
ESPNow.flush();
#endif
#ifdef ESPNOW_PEER_1
ESPNow.flush(ESPNOW1);
#endif
#ifdef ESPNOW_PEER_2
ESPNow.flush(ESPNOW2);
#endif
#endif
#ifdef MQTT_GET
MQTT.flush();
#endif
#ifdef SER_GET
SerialGW.flush();
#endif
#ifdef LORA_GET
#ifdef LORA_PEER_1
LoRaGW.flush(LoRa1);
#endif
#ifdef LORA_PEER_1
LoRaGW.flush(LoRa2);
#endif
#endif
delay(1000);
}

View File

@ -0,0 +1,61 @@
// FARM DATA RELAY SYSTEM
//
// GATEWAY 2.000 Configuration
//#include <fdrs_globals.h> //Uncomment if you install the globals file
#define DEBUG
#define MAC_PREFIX 0xAA, 0xBB, 0xCC, 0xDD, 0xEE // Should only be changed if implementing multiple FDRS systems.
#define UNIT_MAC 0x03 // The address of this gateway
//Where we get the data from
#define LORA_GET
#define MQTT_GET
#define ESP_GET
#define SER_GET
//Where we send the data to
#define LORA_SEND
#define MQTT_SEND
#define ESP_SEND
#define SER_SEND
//#define USE_LORA
//#define USE_WIFI //Used only for MQTT gateway
// Peer addresses
#define LORA_PEER_1 0x0E // LoRa1 Address
#define LORA_PEER_2 0x0F // LoRa2 Address
#define ESPNOW_ALL //send to all know and unknow peers
#define ESPNOW_PEER_1 0x0C // ESPNOW1 Address
#define ESPNOW_PEER_2 0x0D // ESPNOW2 Address
//WiFi and MQTT Credentials -- Needed only for MQTT gateway
#define WIFI_SSID "Your SSID"
#define WIFI_PASS "Your Password"
#define MQTT_ADDR "192.168.0.8"
#define MQTT_PORT 1883
//Pins for UART data interface (ESP32 only)
#define RXD2 14
#define TXD2 15
//LoRa Configuration -- Needed only if using LoRa
#define SCK 5
#define MISO 19
#define MOSI 27
#define SS 18
#define RST 14
#define DIO0 26
//433E6 for Asia
//866E6 for Europe
//915E6 for North America
#define BAND 915E6
#define SF 7
//#define USE_LED //Not yet fully implemented
#define LED_PIN 32
#define NUM_LEDS 4

View File

@ -0,0 +1,685 @@
#include "fdrs_gateway.h"
// #define ESP8266
// #define ESP32
// #define USE_WIFI
bool ESP_FDRSGateWay::is_init = false;
std::vector<Peer_t> ESP_FDRSGateWay::_peer_list;
std::vector<Peer_t> ESP_FDRSGateWay::_unknow_peer;
std::vector<DataReading_t> MQTT_FDRSGateWay::_buffer;
std::vector<DataReading_t> Serial_FDRSGateWay::_buffer;
// Set ESP-NOW send and receive callbacks for either ESP8266 or ESP32
void ESP_FDRSGateWay::OnDataRecv(uint8_t * mac, const uint8_t *incomingData, int len){
DataReading_t data;
uint32_t i = 0;
uint32_t j = 0;
uint8_t d = len / sizeof(DataReading_t);
for(uint32_t i = 0; i < _peer_list.size();i++){
if(memcmp(_peer_list[i]._get_peer(),mac,6) == 0){
for(j = 0; j < d; j++){
memcpy(&data,&incomingData[j*sizeof(DataReading_t)],sizeof(DataReading_t));
_peer_list[i].buffer.push_back(data);
memset(&data,0,sizeof(DataReading_t));
}
return;
}
}
for(uint32_t i = 0; i < _unknow_peer.size();i++){
if(memcmp(_unknow_peer[i]._get_peer(),mac,6) == 0){
for(j = 0; j < d; j++){
memcpy(&data,&incomingData[j*sizeof(DataReading_t)],sizeof(DataReading_t));
_unknow_peer[i].buffer.push_back(data);
memset(&data,0,sizeof(DataReading_t));
}
return;
}
}
Peer_t peer;
peer._set_peer(mac);
_unknow_peer.push_back(peer);
for(j = 0; j < d; j++){
memcpy(&data,&incomingData[j*sizeof(DataReading_t)],sizeof(DataReading_t));
_unknow_peer.back().buffer.push_back(data);
memset(&data,0,sizeof(DataReading_t));
}
}
#if defined(ESP8266)
void ESP8266OnDataSent(uint8_t *mac_addr, uint8_t sendStatus) {
}
void ESP8266OnDataRecv(uint8_t* mac, uint8_t *incomingData, uint8_t len) {
ESP_FDRSGateWay::OnDataRecv((uint8_t*)mac,*(const uint8_t *)incomingData,len);
}
#endif
#if defined(ESP32)
void ESP32OnDataSent(const uint8_t *mac_addr, esp_now_send_status_t status) {
}
void ESP32OnDataRecv(const uint8_t * mac, const uint8_t *incomingData, int len) {
ESP_FDRSGateWay::OnDataRecv((uint8_t*)mac,incomingData,len);
}
#endif
FDRSGateWayBase::FDRSGateWayBase(){
}
FDRSGateWayBase::~FDRSGateWayBase(){
}
void FDRSGateWayBase::release(std::vector<DataReading_t> data,uint8_t *peer_mac){
if(peer_mac == NULL){
send(data);
}
forward(peer_mac ,data);
}
ESP_FDRSGateWay::ESP_FDRSGateWay(void)
{
memset(_broadcast_mac,0xFF,6);
memset(_inturnal_mac,0,6);
}
void ESP_FDRSGateWay::init(uint8_t inturnal_mac[5]){
memcpy(_inturnal_mac,inturnal_mac,6);
#if defined(ESP8266)
wifi_set_macaddr(STATION_IF, _inturnal_mac);
#endif
#if defined(ESP32)
esp_wifi_set_mac(WIFI_IF_STA, &_inturnal_mac[0]);
#endif
ESP_FDRSGateWay::setup();
#if defined(ESP32)
esp_now_peer_info_t peerInfo;
memset(&peerInfo, 0, sizeof(peerInfo));
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;
}
#endif
}
void ESP_FDRSGateWay::setup(void){
if(is_init){
return;
}
is_init = true;
WiFi.mode(WIFI_STA);
WiFi.disconnect();
#if defined(ESP8266)
if (esp_now_init() != 0) {
return;
}
esp_now_set_self_role(ESP_NOW_ROLE_COMBO);
esp_now_register_send_cb(ESP8266OnDataSent);
esp_now_register_recv_cb(ESP8266OnDataRecv);
#endif
#if defined(ESP32)
if(esp_now_init() != ESP_OK) {
DBG("Error initializing ESP-NOW");
return;
}
esp_now_register_send_cb(ESP32OnDataSent);
esp_now_register_recv_cb(ESP32OnDataRecv);
#endif
DBG("ESP-NOW Initialized.");
}
void ESP_FDRSGateWay::add_peer(uint8_t peer_mac[6]){
uint32_t i = 0;
for(uint32_t i = 0; i < _peer_list.size();i++){
if(memcmp(_peer_list[i]._get_peer(),peer_mac,6) == 0){
return;
}
}
list_peer(peer_mac);
Peer_t peer;
peer._set_peer(peer_mac);
//esp_now_del_peer(NEWPEER);
_peer_list.push_back(peer);
}
void ESP_FDRSGateWay::remove_peer(uint8_t peer_mac[6]){
unlist_peer(peer_mac);
if(_peer_list.size() == 0){
return;
}
Peer_t peer;
peer._set_peer(peer_mac);
_peer_list.erase(std::find(_peer_list.begin(),_peer_list.end(),peer));
}
void ESP_FDRSGateWay::list_peer(uint8_t peer_mac[6]){
#if defined(ESP8266)
esp_now_add_peer(peer_mac, ESP_NOW_ROLE_COMBO, 0, NULL, 0);
#endif
#if defined(ESP32)
esp_now_peer_info_t peerInfo;
memset(&peerInfo, 0, sizeof(peerInfo));
peerInfo.channel = 0;
peerInfo.encrypt = false;
memcpy(peerInfo.peer_addr, peer_mac, 6);
if (esp_now_add_peer(&peerInfo) != ESP_OK) {
DBG("Failed to add peer 1");
return;
}
#endif
}
void ESP_FDRSGateWay::unlist_peer(uint8_t peer_mac[6]){
esp_now_del_peer(peer_mac);
}
std::vector<DataReading_t> ESP_FDRSGateWay::get_peer_data(uint8_t *peer_mac){
for(uint32_t i = 0; i < _peer_list.size();i++){
if(memcmp(_peer_list[i]._get_peer(),peer_mac,6) == 0){
return _peer_list[i].buffer;
}
}
return std::vector<DataReading_t>();
}
std::vector<DataReading_t> ESP_FDRSGateWay::get_unkown_peer_data(void){
std::vector<DataReading_t> data;
for(uint32_t i = 0; i < _unknow_peer.size(); i++){
data.insert(data.end(),_unknow_peer[i].buffer.begin(),_unknow_peer[i].buffer.end());
}
return data;
}
void ESP_FDRSGateWay::flush(uint8_t *peer_mac){
if(peer_mac == NULL){
for(uint32_t i = 0; i < _unknow_peer.size(); i++){
_unknow_peer[i].buffer.clear();
return;
}
}
for(uint32_t i = 0; i < _peer_list.size();i++){
if(memcmp(_peer_list[i]._get_peer(),peer_mac,6) == 0){
_peer_list[i].buffer.clear();
return;
}
}
}
void ESP_FDRSGateWay::send(std::vector<DataReading_t> data){
const uint8_t espnow_size = 250 / sizeof(DataReading_t);
uint32_t i = 0;
for(i = 0; i < _unknow_peer.size(); i++){
list_peer(_unknow_peer[i]._get_peer());
}
uint8_t d = data.size() / espnow_size;
DataReading_t buffer1[d * sizeof(DataReading_t)];
memset(buffer1,0,d * sizeof(DataReading_t));
uint32_t j = 0;
for(i = 0; i < data.size(); i++){
buffer1[j++] = data[i];
if(j >= d){
esp_now_send(NULL, (uint8_t *) buffer1, d * sizeof(DataReading_t));
memset(buffer1,0,d * sizeof(DataReading_t));
j = 0;
delay(10);
}
}
if(j != 0){
esp_now_send(NULL, (uint8_t *) buffer1, j * sizeof(DataReading_t));
}
for(i = 0; i < _unknow_peer.size(); i++){
unlist_peer(_unknow_peer[i]._get_peer());
}
_unknow_peer.clear();
}
void ESP_FDRSGateWay::forward(uint8_t *peer_mac ,std::vector<DataReading_t> data){
const uint8_t espnow_size = 250 / sizeof(DataReading_t);
uint8_t d = data.size() / espnow_size;
uint32_t i = 0;
DataReading_t buffer1[d * sizeof(DataReading_t)];
memset(buffer1,0,d * sizeof(DataReading_t));
uint32_t j = 0;
for(i = 0; i < data.size(); i++){
buffer1[j++] = data[i];
if(j >= d){
esp_now_send(NULL, (uint8_t *) buffer1, d * sizeof(DataReading_t));
memset(buffer1,0,d * sizeof(DataReading_t));
j = 0;
delay(10);
}
}
if(j != 0){
esp_now_send(NULL, (uint8_t *) buffer1, j * sizeof(DataReading_t));
}
esp_now_send(peer_mac, (uint8_t *) buffer1, d * sizeof(DataReading_t));
}
MQTT_FDRSGateWay::MQTT_FDRSGateWay(const char *ssid, const char *password, const char *server,int port):
_ssid(ssid),
_password(password),
_server(server),
_port(port)
{
_client = new PubSubClient(espClient);
}
MQTT_FDRSGateWay::~MQTT_FDRSGateWay(void){
delete _client;
}
void MQTT_FDRSGateWay::mqtt_callback(char* topic, byte * message, unsigned int length){
//No point in reading topics that are not data.
if(strcmp(TOPIC_DATA,topic) != 0){
return;
}
String incomingString;
DBG(topic);
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;
}
int s = doc.size();
//UART_IF.println(s);
DataReading_t data;
memset(&data,0,sizeof(DataReading_t));
for (int i = 0; i < s; i++) {
data.id = doc[i]["id"];
data.type = doc[i]["type"];
data.data = doc[i]["data"];
_buffer.push_back(data);
memset(&data,0,sizeof(DataReading_t));
}
DBG("Incoming MQTT.");
}
void MQTT_FDRSGateWay::init(void){
delay(10);
WiFi.begin(_ssid, _password);
while (WiFi.status() != WL_CONNECTED) {
DBG("Connecting to WiFi... ");
DBG(_ssid);
delay(500);
}
DBG("WiFi Connected");
_client->setServer(_server, _port);
if (!_client->connected()) {
DBG("Connecting MQTT...");
reconnect();
}
DBG("MQTT Connected");
_client->setCallback(MQTT_FDRSGateWay::mqtt_callback);
_client->publish(TOPIC_STATUS, "FDRS initialized");
}
void MQTT_FDRSGateWay::reconnect() {
// Loop until reconnected
while (!_client->connected()) {
// Attempt to connect
if (_client->connect("FDRS_GATEWAY")) {
// Subscribe
_client->subscribe(TOPIC_COMMAND);
break;
}
DBG("Connecting MQTT.");
delay(5000);
}
}
void MQTT_FDRSGateWay::send(std::vector<DataReading_t> data) {
DBG("Releasing MQTT.");
DynamicJsonDocument doc(24576);
for (int i = 0; i < data.size(); i++) {
doc[i]["id"] = data[i].id;
doc[i]["type"] = data[i].type;
doc[i]["data"] = data[i].data;
}
String outgoingString;
serializeJson(doc, outgoingString);
_client->publish(TOPIC_DATA, (char*) outgoingString.c_str());
reconnect();
_client->loop();
}
void MQTT_FDRSGateWay::forward(uint8_t *peer_mac ,std::vector<DataReading_t> data){
//does nothing. just here implement the pure virtule from the base class.
send(data);
}
std::vector<DataReading_t> MQTT_FDRSGateWay::get_data(void){
return _buffer;
}
void MQTT_FDRSGateWay::flush(uint8_t *peer_mac){
_buffer.clear();
}
Serial_FDRSGateWay::Serial_FDRSGateWay(HardwareSerial *serial, uint32_t baud):
_serial(serial),
_baud(baud)
{
}
void Serial_FDRSGateWay::init(void){
_serial->begin(_baud);
}
#if defined(ESP32)
void Serial_FDRSGateWay::init(int mode, int rx_pin, int tx_pin){
_serial->begin(_baud,mode,rx_pin,tx_pin);
}
#endif
void Serial_FDRSGateWay::pull(void){
//TDDO: This is blocking. Some method of escaping is required.
// At the momment we are just hoping we get a \n
String incomingString = _serial->readStringUntil('\n');
DynamicJsonDocument doc(24576);
DeserializationError error = deserializeJson(doc, incomingString);
// Test if parsing succeeds.
if (error) {
// DBG("json parse err");
// DBG(incomingString);
return;
}
int s = doc.size();
//UART_IF.println(s);
DataReading_t data;
memset(&data,0,sizeof(DataReading_t));
for (int i = 0; i < s; i++) {
data.id = doc[i]["id"];
data.type = doc[i]["type"];
data.data = doc[i]["data"];
_buffer.push_back(data);
memset(&data,0,sizeof(DataReading_t));
}
DBG("Incoming Serial.");
}
std::vector<DataReading_t> Serial_FDRSGateWay::get_data(void){
return _buffer;
}
void Serial_FDRSGateWay::get(void){
while(_serial->available()){
pull();
}
}
void Serial_FDRSGateWay::send(std::vector<DataReading_t> data){
DBG("Releasing Serial.");
DynamicJsonDocument doc(24576);
for (int i = 0; i < data.size(); i++) {
doc[i]["id"] = data[i].id;
doc[i]["type"] = data[i].type;
doc[i]["data"] = data[i].data;
}
serializeJson(doc, *_serial);
_serial->println();
}
void Serial_FDRSGateWay::forward(uint8_t *peer_mac ,std::vector<DataReading_t> data){
//does nothing. just here implement the pure virtule from the base class.
}
void Serial_FDRSGateWay::flush(uint8_t *peer_mac){
_buffer.clear();
}
LoRa_FDRSGateWay::LoRa_FDRSGateWay(uint8_t miso,uint8_t mosi,uint8_t sck, uint8_t ss,uint8_t rst,uint8_t dio0,double band,uint8_t sf):
_miso(miso),
_mosi(mosi),
_sck(sck),
_ss(ss),
_rst(rst),
_dio0(dio0),
_band(band),
_sf(sf)
{
memset(_mac,0,6);
_peer_list.clear();
}
void LoRa_FDRSGateWay::init(uint8_t mac[6]){
memcpy(_mac,mac,6);
DBG("Initializing LoRa!");
SPI.begin(_sck, _miso, _mosi, _ss);
LoRa.setPins(_ss, _rst, _dio0);
if (!LoRa.begin(_band)) {
DBG(" LoRa initialize failed");
return;
}
LoRa.setSpreadingFactor(_sf);
DBG(" LoRa initialized.");
}
void LoRa_FDRSGateWay::add_peer(uint8_t peer_mac[6]){
uint32_t i = 0;
for(uint32_t i = 0; i < _peer_list.size();i++){
if(memcmp(_peer_list[i]._get_peer(),peer_mac,6) == 0){
return;
}
}
Peer_t peer;
peer._set_peer(peer_mac);
_peer_list.push_back(peer);
}
void LoRa_FDRSGateWay::remove_peer(uint8_t peer_mac[6]){
if(_peer_list.size() == 0){
return;
}
Peer_t peer;
peer._set_peer(peer_mac);
_peer_list.erase(std::find(_peer_list.begin(),_peer_list.end(),peer));
}
void LoRa_FDRSGateWay::get(void){
int packetSize = LoRa.parsePacket();
if (packetSize== 0) {
return;
}
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);
// }
//Check if addressed to this device
if (memcmp(&packet, &_mac[3], 3) != 0) {
return;
}
uint8_t theData[packetSize - 5];
memcpy(&incLORAMAC, &packet[3], 2); //Split off address portion of packet
memcpy(&theData, &packet[5], packetSize - 5); //Split off data portion of packet
//Check if it is from a registered sender
for(uint32_t i = 0; i < _peer_list.size();i++){
if(memcmp(&_peer_list[i].peer[3],incLORAMAC,2) == 0){
DataReading_t data;
uint32_t i = 0;
uint8_t d = packetSize / sizeof(DataReading_t);
memset(&data,0,sizeof(DataReading_t));
for(uint32_t j = 0; j < d; j++){
memcpy(&data,&theData[j*sizeof(DataReading_t)],sizeof(DataReading_t));
_peer_list[i].buffer.push_back(data);
memset(&data,0,sizeof(DataReading_t));
}
return;
}
}
DBG("Incoming LoRa.");
}
std::vector<DataReading_t> LoRa_FDRSGateWay::get_peer_data(uint8_t *peer_mac){
for(uint32_t i = 0; i < _peer_list.size();i++){
if(memcmp(_peer_list[i]._get_peer(),peer_mac,6) == 0){
return _peer_list[i].buffer;
}
}
return std::vector<DataReading_t>();
}
void LoRa_FDRSGateWay::send(std::vector<DataReading_t> data){
const uint8_t espnow_size = 250 / sizeof(DataReading_t);
uint32_t i = 0;
uint8_t d = data.size() / espnow_size;
DataReading_t buffer1[d];
for(i = 0; i < d; i++){
buffer1[i] = data[i];
}
transmit(buffer1, d * sizeof(DataReading_t));
}
void LoRa_FDRSGateWay::forward(uint8_t *peer_mac ,std::vector<DataReading_t> data){
//TODO: add peer forwading.
}
void LoRa_FDRSGateWay::transmit(DataReading_t *packet, uint8_t len) {
DBG("Transmitting LoRa.");
uint8_t pkt[5 + (len * sizeof(DataReading_t))];
memcpy(&pkt, _mac, 3);
memcpy(&pkt[3], &_mac[4], 2);
memcpy(&pkt[5], packet, len * sizeof(DataReading_t));
LoRa.beginPacket();
LoRa.write((uint8_t*)&pkt, sizeof(pkt));
LoRa.endPacket();
}
void LoRa_FDRSGateWay::flush(uint8_t *peer_mac){
if(peer_mac == NULL){
return;
}
for(uint32_t i = 0; i < _peer_list.size();i++){
if(memcmp(_peer_list[i]._get_peer(),peer_mac,6) == 0){
_peer_list[i].buffer.clear();
return;
}
}
}

View File

@ -0,0 +1,186 @@
/* FARM DATA RELAY SYSTEM
*
* "fdrs_sensor.h"
*
* Developed by Timm Bogner (timmbogner@gmail.com) for Sola Gratia Farm in Urbana, Illinois, USA.
* Condensed and refactored to a single file pair by Binder Tronics (info@bindertronics.com).
*/
#ifndef __FDRS_GATEWAY_H__
#define __FDRS_GATEWAY_H__
#include "HardwareSerial.h"
#include "fdrs_types.h"
#include <string.h>
#include <vector>
#include <memory>
#include <algorithm>
#include <esp_now.h>
#include <WiFi.h>
#include <esp_wifi.h>
#include "ArduinoJson.h"
#include "PubSubClient.h"
#include "LoRa.h"
#define USE_LORA
#define DEBUG
#ifdef DEBUG
#define DBG(a) (Serial.println(a))
#else
#define DBG(a)
#endif
class FDRSGateWayBase{
public:
FDRSGateWayBase();
~FDRSGateWayBase();
void release(std::vector<DataReading_t> data, uint8_t *peer_mac = NULL);
virtual void flush(uint8_t *peer_mac = NULL) = 0;
private:
static uint32_t peer_id;
virtual void send(std::vector<DataReading_t> data) = 0;
virtual void forward(uint8_t *peer_mac ,std::vector<DataReading_t> data) = 0;
};
class ESP_FDRSGateWay: public FDRSGateWayBase{
public:
ESP_FDRSGateWay(void);
static void OnDataRecv(uint8_t * mac, const uint8_t *incomingData, int len);
void init(uint8_t inturnal_mac[5]);
void add_peer(uint8_t peer_mac[6]);
void remove_peer(uint8_t peer_mac[6]);
std::vector<DataReading_t> get_peer_data(uint8_t peer_mac[6]);
std::vector<DataReading_t> get_unkown_peer_data(void);
void flush(uint8_t *peer_mac = NULL) override;
private:
static bool is_init;
uint8_t _broadcast_mac[6];
uint8_t _inturnal_mac[6];
static std::vector<Peer_t> _peer_list;
static std::vector<Peer_t> _unknow_peer;
static void setup(void);
void send(std::vector<DataReading_t> data) override;
void forward(uint8_t *peer_mac ,std::vector<DataReading_t> data) override;
void list_peer(uint8_t peer_mac[6]);
void unlist_peer(uint8_t peer_mac[6]);
};
class MQTT_FDRSGateWay: public FDRSGateWayBase{
public:
MQTT_FDRSGateWay(const char *ssid, const char *password, const char *server,int port = 1883);
~MQTT_FDRSGateWay(void);
void init(void);
std::vector<DataReading_t> get_data(void);
void flush(uint8_t *peer_mac = NULL) override;
private:
#define TOPIC_DATA "fdrs/data"
#define TOPIC_STATUS "fdrs/status"
#define TOPIC_COMMAND "fdrs/command"
static void mqtt_callback(char* topic, byte * message, unsigned int length);
const char *_ssid;
const char *_password;
const char *_server;
int _port;
WiFiClient espClient;
PubSubClient *_client;
static std::vector<DataReading_t> _buffer;
void reconnect();
void send(std::vector<DataReading_t> data) override;
void forward(uint8_t *peer_mac ,std::vector<DataReading_t> data) override;
};
class Serial_FDRSGateWay: public FDRSGateWayBase{
public:
Serial_FDRSGateWay(HardwareSerial *serial, uint32_t baud);
void init(void);
#if defined(ESP32)
void init(int mode, int rx_pin, int tx_pin);
#endif
void get(void);
std::vector<DataReading_t> get_data(void);
void flush(uint8_t *peer_mac = NULL) override;
private:
HardwareSerial *_serial;
uint32_t _baud;
static std::vector<DataReading_t> _buffer;
static void setup(void);
void pull(void);
void send(std::vector<DataReading_t> data) override;
void forward(uint8_t *peer_mac ,std::vector<DataReading_t> data) override;
};
class LoRa_FDRSGateWay: public FDRSGateWayBase{
public:
LoRa_FDRSGateWay(uint8_t miso,uint8_t mosi,uint8_t sck, uint8_t ss,uint8_t rst,uint8_t dio0,double band,uint8_t sf);
void init(uint8_t mac[6]);
void get(void);
void add_peer(uint8_t peer_mac[6]);
void remove_peer(uint8_t peer_mac[6]);
std::vector<DataReading_t> get_peer_data(uint8_t *peer_mac);
void flush(uint8_t *peer_mac = NULL) override;
private:
uint8_t _mac[6];
uint8_t _miso;
uint8_t _mosi;
uint8_t _sck;
uint8_t _ss;
uint8_t _rst;
uint8_t _dio0;
uint32_t _band;
uint8_t _sf;
std::vector<Peer_t> _peer_list;
void transmit(DataReading_t *packet, uint8_t len);
void send(std::vector<DataReading_t> data) override;
void forward(uint8_t *peer_mac ,std::vector<DataReading_t> data) override;
};
#endif

View File

@ -0,0 +1,39 @@
#ifndef __FDRS_TYPES_H__
#define __FDRS_TYPES_H__
#include <stdint.h>
#include <string.h>
#include <vector>
typedef struct __attribute__((packed)) DataReading_t {
float data;
uint16_t id;
uint8_t type;
DataReading_t(): data(0.0),id(0),type(0){
}
} DataReading_t;
typedef struct Peer_t{
uint8_t peer[6];
std::vector<DataReading_t> buffer;
Peer_t(){
memset(peer,0,6);
buffer.clear();
}
void _set_peer(uint8_t p[6]){
memcpy(peer,p,6);
}
uint8_t *_get_peer(void){
return peer;
}
bool operator==(Peer_t c){
return (memcmp(this->peer,c.peer,6) == 0);
}
}Peer_t;
#endif

View File

Before

Width:  |  Height:  |  Size: 228 KiB

After

Width:  |  Height:  |  Size: 228 KiB

View File

Before

Width:  |  Height:  |  Size: 238 KiB

After

Width:  |  Height:  |  Size: 238 KiB

View File

Before

Width:  |  Height:  |  Size: 241 KiB

After

Width:  |  Height:  |  Size: 241 KiB

View File

Before

Width:  |  Height:  |  Size: 221 KiB

After

Width:  |  Height:  |  Size: 221 KiB

View File

@ -1,169 +1,169 @@
// FARM DATA RELAY SYSTEM
//
// GATEWAY 2.000
//
// Developed by Timm Bogner (timmbogner@gmail.com) for Sola Gratia Farm in Urbana, Illinois, USA.
//
#include "fdrs_config.h"
#ifdef ESP8266
#include <ESP8266WiFi.h>
#include <espnow.h>
#elif defined(ESP32)
#include <esp_now.h>
#include <WiFi.h>
#include <esp_wifi.h>
#endif
#include <ArduinoJson.h>
#ifdef USE_WIFI
#include <PubSubClient.h>
#endif
#ifdef USE_LORA
#include <LoRa.h>
#endif
#ifdef USE_LED
#include <FastLED.h>
#endif
#include "fdrs_functions.h"
void setup() {
#if defined(ESP8266)
Serial.begin(115200);
#elif defined(ESP32)
Serial.begin(115200);
UART_IF.begin(115200, SERIAL_8N1, RXD2, TXD2);
#endif
DBG("Address:" + String (UNIT_MAC, HEX));
#ifdef USE_LED
FastLED.addLeds<WS2812B, LED_PIN, GRB>(leds, NUM_LEDS);
leds[0] = CRGB::Blue;
FastLED.show();
#endif
#ifdef USE_WIFI
delay(10);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
DBG("Connecting to WiFi...");
DBG(FDRS_WIFI_SSID);
delay(500);
}
DBG("WiFi Connected");
client.setServer(mqtt_server, 1883);
if (!client.connected()) {
DBG("Connecting MQTT...");
reconnect();
}
DBG("MQTT Connected");
client.setCallback(mqtt_callback);
#else
begin_espnow();
#endif
#ifdef USE_LORA
DBG("Initializing LoRa!");
SPI.begin(SCK, MISO, MOSI, SS);
LoRa.setPins(SS, RST, DIO0);
if (!LoRa.begin(FDRS_BAND)) {
while (1);
}
LoRa.setSpreadingFactor(FDRS_SF);
DBG(" LoRa initialized.");
#endif
//DBG(sizeof(DataReading));
#ifdef USE_WIFI
client.publish(TOPIC_STATUS, "FDRS initialized");
#endif
}
void loop() {
#ifdef ESPNOWG_DELAY
if (millis() > timeESPNOWG) {
timeESPNOWG += ESPNOWG_DELAY;
if (lenESPNOWG > 0) releaseESPNOW(0);
}
#endif
#ifdef ESPNOW1_DELAY
if (millis() > timeESPNOW1) {
timeESPNOW1 += ESPNOW1_DELAY;
if (lenESPNOW1 > 0) releaseESPNOW(1);
}
#endif
#ifdef ESPNOW2_DELAY
if (millis() > timeESPNOW2) {
timeESPNOW2 += ESPNOW2_DELAY;
if (lenESPNOW2 > 0) releaseESPNOW(2);
}
#endif
#ifdef SERIAL_DELAY
if (millis() > timeSERIAL) {
timeSERIAL += SERIAL_DELAY;
if (lenSERIAL > 0) releaseSerial();
}
#endif
#ifdef MQTT_DELAY
if (millis() > timeMQTT) {
timeMQTT += MQTT_DELAY;
if (lenMQTT > 0) releaseMQTT();
}
#endif
#ifdef LORAG_DELAY
if (millis() > timeLORAG) {
timeLORAG += LORAG_DELAY;
if (lenLORAG > 0) releaseLoRa(0);
}
#endif
#ifdef LORA1_DELAY
if (millis() > timeLORA1) {
timeLORA1 += LORA1_DELAY;
if (lenLORA1 > 0) releaseLoRa(1);
}
#endif
#ifdef LORA2_DELAY
if (millis() > timeLORA2) {
timeLORA2 += LORA2_DELAY;
if (lenLORA2 > 0) releaseLoRa(2);
}
#endif
while (UART_IF.available()) {
getSerial();
}
getLoRa();
#ifdef USE_WIFI
if (!client.connected()) {
DBG("Connecting MQTT...");
reconnect();
}
client.loop();
#endif
if (newData) {
switch (newData) {
case 1: //ESP-NOW #1
ESPNOW1_ACT
break;
case 2: //ESP-NOW #2
ESPNOW2_ACT
break;
case 3: //ESP-NOW General
ESPNOWG_ACT
break;
case 4: //Serial
SERIAL_ACT
break;
case 5: //MQTT
MQTT_ACT
break;
case 6: //LoRa General
LORAG_ACT
break;
case 7: //LoRa #1
LORA1_ACT
break;
case 8: //LoRa #2
LORA2_ACT
break;
}
newData = 0;
}
}
// FARM DATA RELAY SYSTEM
//
// GATEWAY 2.000
//
// Developed by Timm Bogner (timmbogner@gmail.com) for Sola Gratia Farm in Urbana, Illinois, USA.
//
#include "fdrs_config.h"
#ifdef ESP8266
#include <ESP8266WiFi.h>
#include <espnow.h>
#elif defined(ESP32)
#include <esp_now.h>
#include <WiFi.h>
#include <esp_wifi.h>
#endif
#include <ArduinoJson.h>
#ifdef USE_WIFI
#include <PubSubClient.h>
#endif
#ifdef USE_LORA
#include <LoRa.h>
#endif
#ifdef USE_LED
#include <FastLED.h>
#endif
#include "fdrs_functions.h"
void setup() {
#if defined(ESP8266)
Serial.begin(115200);
#elif defined(ESP32)
Serial.begin(115200);
UART_IF.begin(115200, SERIAL_8N1, RXD2, TXD2);
#endif
DBG("Address:" + String (UNIT_MAC, HEX));
#ifdef USE_LED
FastLED.addLeds<WS2812B, LED_PIN, GRB>(leds, NUM_LEDS);
leds[0] = CRGB::Blue;
FastLED.show();
#endif
#ifdef USE_WIFI
delay(10);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
DBG("Connecting to WiFi...");
DBG(FDRS_WIFI_SSID);
delay(500);
}
DBG("WiFi Connected");
client.setServer(mqtt_server, mqtt_port);
if (!client.connected()) {
DBG("Connecting MQTT...");
reconnect();
}
DBG("MQTT Connected");
client.setCallback(mqtt_callback);
#else
begin_espnow();
#endif
#ifdef USE_LORA
DBG("Initializing LoRa!");
SPI.begin(SCK, MISO, MOSI, SS);
LoRa.setPins(SS, RST, DIO0);
if (!LoRa.begin(FDRS_BAND)) {
while (1);
}
LoRa.setSpreadingFactor(FDRS_SF);
DBG(" LoRa initialized.");
#endif
//DBG(sizeof(DataReading));
#ifdef USE_WIFI
client.publish(TOPIC_STATUS, "FDRS initialized");
#endif
}
void loop() {
#ifdef ESPNOWG_DELAY
if (millis() > timeESPNOWG) {
timeESPNOWG += ESPNOWG_DELAY;
if (lenESPNOWG > 0) releaseESPNOW(0);
}
#endif
#ifdef ESPNOW1_DELAY
if (millis() > timeESPNOW1) {
timeESPNOW1 += ESPNOW1_DELAY;
if (lenESPNOW1 > 0) releaseESPNOW(1);
}
#endif
#ifdef ESPNOW2_DELAY
if (millis() > timeESPNOW2) {
timeESPNOW2 += ESPNOW2_DELAY;
if (lenESPNOW2 > 0) releaseESPNOW(2);
}
#endif
#ifdef SERIAL_DELAY
if (millis() > timeSERIAL) {
timeSERIAL += SERIAL_DELAY;
if (lenSERIAL > 0) releaseSerial();
}
#endif
#ifdef MQTT_DELAY
if (millis() > timeMQTT) {
timeMQTT += MQTT_DELAY;
if (lenMQTT > 0) releaseMQTT();
}
#endif
#ifdef LORAG_DELAY
if (millis() > timeLORAG) {
timeLORAG += LORAG_DELAY;
if (lenLORAG > 0) releaseLoRa(0);
}
#endif
#ifdef LORA1_DELAY
if (millis() > timeLORA1) {
timeLORA1 += LORA1_DELAY;
if (lenLORA1 > 0) releaseLoRa(1);
}
#endif
#ifdef LORA2_DELAY
if (millis() > timeLORA2) {
timeLORA2 += LORA2_DELAY;
if (lenLORA2 > 0) releaseLoRa(2);
}
#endif
while (UART_IF.available()) {
getSerial();
}
getLoRa();
#ifdef USE_WIFI
if (!client.connected()) {
DBG("Connecting MQTT...");
reconnect();
}
client.loop();
#endif
if (newData) {
switch (newData) {
case 1: //ESP-NOW #1
ESPNOW1_ACT
break;
case 2: //ESP-NOW #2
ESPNOW2_ACT
break;
case 3: //ESP-NOW General
ESPNOWG_ACT
break;
case 4: //Serial
SERIAL_ACT
break;
case 5: //MQTT
MQTT_ACT
break;
case 6: //LoRa General
LORAG_ACT
break;
case 7: //LoRa #1
LORA1_ACT
break;
case 8: //LoRa #2
LORA2_ACT
break;
}
newData = 0;
}
}

View File

@ -45,10 +45,10 @@ Buffers can hold a maximum of 256 DataReadings.
![Basic](/FDRS_Gateway2000/Basic_Setup.png)
![Basic](/FDRS_Gateway/Basic_Setup.png)
![Advanced](/FDRS_Gateway2000/Advanced_Setup.png)
![Advanced](/FDRS_Gateway/Advanced_Setup.png)
![Basic LoRa](/FDRS_Gateway2000/Basic_LoRa_Setup.png)
![Basic LoRa](/FDRS_Gateway/Basic_LoRa_Setup.png)
![Advanced LoRa](/FDRS_Gateway2000/Advanced_Setup_LoRa.png)
![Advanced LoRa](/FDRS_Gateway/Advanced_Setup_LoRa.png)

View File

@ -1,73 +1,80 @@
// FARM DATA RELAY SYSTEM
//
// GATEWAY 2.000 Configuration
//#include <fdrs_globals.h> //Uncomment if you install the globals file
#define DEBUG //Enable USB-Serial debugging
#define UNIT_MAC 0x01 // The address of this gateway
//Actions -- Define what happens when a packet arrives at each interface:
// Current function options are: sendESPNOW(MAC), sendSerial(), sendMQTT(),
// bufferLoRa(interface), bufferESPNOW(interface), bufferSerial(), and bufferMQTT().
#define ESPNOWG_ACT sendSerial();
#define SERIAL_ACT
#define MQTT_ACT
#define LORAG_ACT sendSerial();
//#define USE_LORA
//#define USE_WIFI //Used only for MQTT gateway
// Peer addresses
#define ESPNOW1_PEER 0x0E // ESPNOW1 Address
#define ESPNOW2_PEER 0x0F // ESPNOW2 Address
#define LORA1_PEER 0x0E // LoRa1 Address
#define LORA2_PEER 0x0F // LoRa2 Address
// Peer Actions
#define ESPNOW1_ACT
#define ESPNOW2_ACT
#define LORA1_ACT
#define LORA2_ACT
//Pins for UART data interface (ESP32 only)
#define RXD2 14
#define TXD2 15
//LoRa Configuration -- Needed only if using LoRa
#define SCK 5
#define MISO 19
#define MOSI 27
#define SS 18
#define RST 14
#define DIO0 26
//433E6 for Asia
//866E6 for Europe
//915E6 for North America
#define BAND 915E6
#define SF 7
// Buffer Delays - in milliseconds - Uncomment to enable any buffer
//#define ESPNOW1_DELAY 0
//#define ESPNOW2_DELAY 0
//#define ESPNOWG_DELAY 0
//#define SERIAL_DELAY 0
//#define MQTT_DELAY 0
//#define LORAG_DELAY 1000
//#define LORA1_DELAY 1000
//#define LORA2_DELAY 1000
//#define USE_LED //Not yet fully implemented
#define LED_PIN 32
#define NUM_LEDS 4
//WiFi and MQTT Credentials -- Needed only for MQTT gateway
#define WIFI_SSID "Your SSID"
#define WIFI_PASS "Your Password"
#define MQTT_ADDR "192.168.0.8"
// MQTT Topics
#define TOPIC_DATA "fdrs/data"
#define TOPIC_STATUS "fdrs/status"
#define TOPIC_COMMAND "fdrs/command"
// FARM DATA RELAY SYSTEM
//
// GATEWAY 2.000 Configuration
//#include <fdrs_globals.h> //Uncomment if you install the globals file
#define DEBUG //Enable USB-Serial debugging
#define UNIT_MAC 0x01 // The address of this gateway
//Actions -- Define what happens when a packet arrives at each interface:
// Current function options are: sendESPNOW(MAC), sendSerial(), sendMQTT(),
// bufferLoRa(interface), bufferESPNOW(interface), bufferSerial(), and bufferMQTT().
#define ESPNOWG_ACT sendSerial();
#define SERIAL_ACT
#define MQTT_ACT
#define LORAG_ACT sendSerial();
//#define USE_LORA
//#define USE_WIFI //Used only for MQTT gateway
// Peer addresses
#define ESPNOW1_PEER 0x0E // ESPNOW1 Address
#define ESPNOW2_PEER 0x0F // ESPNOW2 Address
#define LORA1_PEER 0x0E // LoRa1 Address
#define LORA2_PEER 0x0F // LoRa2 Address
// Peer Actions
#define ESPNOW1_ACT
#define ESPNOW2_ACT
#define LORA1_ACT
#define LORA2_ACT
//Pins for UART data interface (ESP32 only)
#define RXD2 14
#define TXD2 15
//LoRa Configuration -- Needed only if using LoRa
#define SCK 5
#define MISO 19
#define MOSI 27
#define SS 18
#define RST 14
#define DIO0 26
//433E6 for Asia
//866E6 for Europe
//915E6 for North America
#define BAND 915E6
#define SF 7
// Buffer Delays - in milliseconds - Uncomment to enable any buffer
//#define ESPNOW1_DELAY 0
//#define ESPNOW2_DELAY 0
//#define ESPNOWG_DELAY 0
//#define SERIAL_DELAY 0
//#define MQTT_DELAY 0
//#define LORAG_DELAY 1000
//#define LORA1_DELAY 1000
//#define LORA2_DELAY 1000
//#define USE_LED //Not yet fully implemented
#define LED_PIN 32
#define NUM_LEDS 4
//WiFi and MQTT Credentials -- Needed only for MQTT gateway
#define WIFI_SSID "Your SSID"
#define WIFI_PASS "Your Password"
#define MQTT_ADDR "192.168.0.8"
#define MQTT_PORT 1883 // Default MQTT port is 1883
//MQTT Credentials -- Needed only if MQTT broker requires authentication
//#define MQTT_AUTH //uncomment to enable MQTT authentication
#define MQTT_USER "Your MQTT Username"
#define MQTT_PASS "Your MQTT Password"
// MQTT Topics
#define TOPIC_DATA "fdrs/data"
#define TOPIC_STATUS "fdrs/status"
#define TOPIC_COMMAND "fdrs/command"

View File

@ -1,3 +1,3 @@
Please copy this directory into your Arduino "libraries" directory.
Edit the files in your libraries folder according to your needs with your WiFi info, LoRa band, etc.
Edit 'fdrs_globals.h' in your libraries folder according to your needs with your WiFi info, LoRa band, etc.
Never edit them here!!!

View File

@ -2,6 +2,10 @@
#define GLOBAL_PASS "Password"
#define GLOBAL_MQTT_ADDR "192.168.0.8"
//#define GLOBAL_MQTT_AUTH //uncomment to enable MQTT authentication
#define GLOBAL_MQTT_USER "Your MQTT Username"
#define GLOBAL_MQTT_PASS "Your MQTT Password"
#define GLOBAL_BAND 915E6 //LoRa Frequency Band
#define GLOBAL_SF 7 //LoRa Spreading Factor

View File

@ -1,33 +1,33 @@
// FARM DATA RELAY SYSTEM
//
// Basic Sensor Example
//
// Developed by Timm Bogner (bogner1@gmail.com) for Sola Gratia Farm in Urbana, Illinois, USA.
// An example of how to send data using "fdrs_sensor.h".
//
#include "fdrs_sensor.h"
float data1;
float data2;
void setup() {
beginFDRS();
}
void loop() {
data1 = readHum();
loadFDRS(data1, HUMIDITY_T);
data2 = readTemp();
loadFDRS(data2, TEMP_T);
sendFDRS();
sleepFDRS(10); //Sleep time in seconds
}
float readTemp() {
return 42.069;
}
float readHum() {
return 21.0345;
}
// FARM DATA RELAY SYSTEM
//
// Basic Sensor Example
//
// Developed by Timm Bogner (bogner1@gmail.com) for Sola Gratia Farm in Urbana, Illinois, USA.
// An example of how to send data using "fdrs_sensor.h".
//
#include "fdrs_sensor.h"
float data1;
float data2;
void setup() {
beginFDRS();
}
void loop() {
data1 = readHum();
loadFDRS(data1, HUMIDITY_T);
data2 = readTemp();
loadFDRS(data2, TEMP_T);
sendFDRS();
sleepFDRS(10); //Sleep time in seconds
}
float readTemp() {
return 42.069;
}
float readHum() {
return 21.0345;
}

View File

@ -116,7 +116,7 @@ void beginFDRS() {
DBG("Initializing LoRa!");
DBG(BAND);
DBG(SF);
#ifndef __AVR__
#ifdef ESP32
SPI.begin(SCK, MISO, MOSI, SS);
#endif
LoRa.setPins(SS, RST, DIO0);

View File

@ -1,178 +0,0 @@
// FARM DATA RELAY SYSTEM
//
// "fdrs_sensor.h"
//
// Developed by Timm Bogner (timmbogner@gmail.com) for Sola Gratia Farm in Urbana, Illinois, USA.
//
#include "sensor_setup.h"
#if defined(ESP8266)
#include <ESP8266WiFi.h>
#include <espnow.h>
#elif defined(ESP32)
#include <esp_now.h>
#include <WiFi.h>
#include <esp_wifi.h>
#endif
#ifdef USE_LORA
#include <LoRa.h>
#endif
#ifdef GLOBALS
#define FDRS_BAND GLOBAL_BAND
#define FDRS_SF GLOBAL_SF
#else
#define FDRS_BAND BAND
#define FDRS_SF SF
#endif
#ifdef DEBUG
#define DBG(a) (Serial.println(a))
#else
#define DBG(a)
#endif
#define STATUS_T 0 // Status
#define TEMP_T 1 // Temperature
#define TEMP2_T 2 // Temperature #2
#define HUMIDITY_T 3 // Relative Humidity
#define PRESSURE_T 4 // Atmospheric Pressure
#define LIGHT_T 5 // Light (lux)
#define SOIL_T 6 // Soil Moisture
#define SOIL2_T 7 // Soil Moisture #2
#define SOILR_T 8 // Soil Resistance
#define SOILR2_T 9 // Soil Resistance #2
#define OXYGEN_T 10 // Oxygen
#define CO2_T 11 // Carbon Dioxide
#define WINDSPD_T 12 // Wind Speed
#define WINDHDG_T 13 // Wind Direction
#define RAINFALL_T 14 // Rainfall
#define MOTION_T 15 // Motion
#define VOLTAGE_T 16 // Voltage
#define VOLTAGE2_T 17 // Voltage #2
#define CURRENT_T 18 // Current
#define CURRENT2_T 19 // Current #2
#define IT_T 20 // Iterations
#define MAC_PREFIX 0xAA, 0xBB, 0xCC, 0xDD, 0xEE // Should only be changed if implementing multiple FDRS systems.
typedef struct __attribute__((packed)) DataReading {
float d;
uint16_t id;
uint8_t t;
} DataReading;
const uint16_t espnow_size = 250 / sizeof(DataReading);
uint8_t gatewayAddress[] = {MAC_PREFIX, GTWY_MAC};
uint8_t gtwyAddress[] = {gatewayAddress[3], gatewayAddress[4], GTWY_MAC};
uint8_t LoRaAddress[] = {0x42, 0x00};
uint32_t wait_time = 0;
DataReading fdrsData[espnow_size];
uint8_t data_count = 0;
void beginFDRS() {
#ifdef DEBUG
Serial.begin(115200);
#endif
DBG("FDRS Sensor ID " + String(READING_ID) + " initializing...");
DBG(" Gateway: " + String (GTWY_MAC, HEX));
#ifdef POWER_CTRL
DBG("Powering up the sensor array!");
pinMode(POWER_CTRL, OUTPUT);
digitalWrite(POWER_CTRL, 1);
#endif
// Init ESP-NOW for either ESP8266 or ESP32 and set MAC address
#ifdef USE_ESPNOW
DBG("Initializing ESP-NOW!");
WiFi.mode(WIFI_STA);
WiFi.disconnect();
#if defined(ESP8266)
if (esp_now_init() != 0) {
return;
}
esp_now_set_self_role(ESP_NOW_ROLE_COMBO);
// Register peers
esp_now_add_peer(gatewayAddress, ESP_NOW_ROLE_COMBO, 0, NULL, 0);
#elif defined(ESP32)
if (esp_now_init() != ESP_OK) {
DBG("Error initializing ESP-NOW");
return;
}
esp_now_peer_info_t peerInfo;
peerInfo.ifidx = WIFI_IF_STA;
peerInfo.channel = 0;
peerInfo.encrypt = false;
// Register first peer
memcpy(peerInfo.peer_addr, gatewayAddress, 6);
if (esp_now_add_peer(&peerInfo) != ESP_OK) {
DBG("Failed to add peer");
return;
}
#endif
DBG(" ESP-NOW Initialized.");
#endif
#ifdef USE_LORA
DBG("Initializing LoRa!");
DBG(BAND);
DBG(SF);
#ifndef __AVR__
SPI.begin(SCK, MISO, MOSI, SS);
#endif
LoRa.setPins(SS, RST, DIO0);
if (!LoRa.begin(FDRS_BAND)) {
while (1);
}
LoRa.setSpreadingFactor(FDRS_SF);
DBG(" LoRa Initialized.");
#endif
}
void transmitLoRa(uint8_t* mac, DataReading * packet, uint8_t len) {
#ifdef USE_LORA
uint8_t pkt[5 + (len * sizeof(DataReading))];
memcpy(&pkt, mac, 3); //
memcpy(&pkt[3], &LoRaAddress, 2);
memcpy(&pkt[5], packet, len * sizeof(DataReading));
LoRa.beginPacket();
LoRa.write((uint8_t*)&pkt, sizeof(pkt));
LoRa.endPacket();
#endif
}
void sendFDRS() {
DBG("Sending FDRS Packet!");
#ifdef USE_ESPNOW
esp_now_send(gatewayAddress, (uint8_t *) &fdrsData, data_count * sizeof(DataReading));
delay(5);
DBG(" ESP-NOW sent.");
#endif
#ifdef USE_LORA
transmitLoRa(gtwyAddress, fdrsData, data_count);
DBG(" LoRa sent.");
#endif
data_count = 0;
}
void loadFDRS(float d, uint8_t t) {
DBG("Data loaded. Type: " + String(t));
if (data_count > espnow_size) sendFDRS();
DataReading dr;
dr.id = READING_ID;
dr.t = t;
dr.d = d;
fdrsData[data_count] = dr;
data_count++;
}
void sleepFDRS(int sleep_time) {
DBG("Sleepytime!");
#ifdef DEEP_SLEEP
DBG(" Deep sleeping.");
#ifdef ESP32
esp_sleep_enable_timer_wakeup(sleep_time * 1000000);
esp_deep_sleep_start();
#endif
#ifdef ESP8266
ESP.deepSleep(sleep_time * 1000000);
#endif
#endif
DBG(" Delaying.");
delay(sleep_time * 1000);
}

View File

@ -1,7 +0,0 @@
typedef struct DataReading {
float d;
uint16_t id;
uint8_t t;
} DataReading;

View File

@ -1,135 +0,0 @@
// FARM DATA RELAY SYSTEM
//
// GATEWAY MODULE
//
// Developed by Timm Bogner (bogner1@gmail.com) for Sola Gratia Farm in Urbana, Illinois, USA.
// Setup instructions located in the "fdrs_config.h" file.
#if defined(ESP8266)
#include <ESP8266WiFi.h>
#include <espnow.h>
#elif defined(ESP32)
#define RXD2 21
#define TXD2 22
#include <esp_now.h>
#include <WiFi.h>
#include <esp_wifi.h>
#endif
#include "fdrs_config.h"
#include <ArduinoJson.h>
#include "DataReading.h"
uint8_t broadcast_mac[] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
uint8_t prevAddress[] = {MAC_PREFIX, PREV_MAC};
uint8_t selfAddress[] = {MAC_PREFIX, UNIT_MAC};
DataReading incData[31];
bool newData = false;
int pkt_readings;
uint8_t incMAC[6];
#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(&incData, incomingData, len);
memcpy(&incMAC, mac, 6);
pkt_readings = len / sizeof(DataReading);
newData = true;
}
void setup() {
WiFi.mode(WIFI_STA);
WiFi.disconnect();
// Init ESP-NOW for either ESP8266 or ESP32 and set MAC address
#if defined(ESP8266)
Serial.begin(115200);
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 peer
esp_now_add_peer(prevAddress, ESP_NOW_ROLE_COMBO, 0, NULL, 0);
esp_now_add_peer(broadcast_mac, ESP_NOW_ROLE_COMBO, 0, NULL, 0);
#elif defined(ESP32)
Serial.begin(115200, SERIAL_8N1, RXD2, TXD2);
esp_wifi_set_mac(WIFI_IF_STA, &selfAddress[0]);
if (esp_now_init() != ESP_OK) {
Serial.println("Error initializing ESP-NOW");
return;
}
esp_now_register_send_cb(OnDataSent);
esp_now_register_recv_cb(OnDataRecv);
esp_now_peer_info_t peerInfo;
peerInfo.channel = 0;
peerInfo.encrypt = false;
memcpy(peerInfo.peer_addr, prevAddress, 6);
if (esp_now_add_peer(&peerInfo) != ESP_OK) {
Serial.println("Failed to add peer");
return;
}
memcpy(peerInfo.peer_addr, broadcast_mac, 6);
if (esp_now_add_peer(&peerInfo) != ESP_OK) {
Serial.println("Failed to add peer");
return;
}
#endif
}
//CMD example {"id":72,"type":201,"data":166}
void getSerial() {
DataReading theCommands[31];
String incomingString = Serial.readStringUntil('\n');
StaticJsonDocument<2048> doc;
DeserializationError error = deserializeJson(doc, incomingString);
if (error) { // Test if parsing succeeds.
Serial.println("parse err");
return;
} else {
int s = doc.size();
//Serial.println(s);
for (int i = 0; i < s; i++) {
if (i > 31) break;
theCommands[i].id = doc[i]["id"];
theCommands[i].t = doc[i]["type"];
theCommands[i].d = doc[i]["data"];
}
esp_now_send(broadcast_mac, (uint8_t *) &theCommands, s * sizeof(DataReading));
}
}
void encodeJSON() {
StaticJsonDocument<2048> doc;
for (int i = 0; i < pkt_readings; i++) {
doc[i]["id"] = incData[i].id;
doc[i]["type"] = incData[i].t;
doc[i]["data"] = incData[i].d;
incData[i].id = 0;
incData[i].t = 0;
incData[i].d = 0;
}
serializeJson(doc, Serial);
Serial.println();
}
void loop() {
while (Serial.available()) {
getSerial();
}
if (newData) {
newData = false;
encodeJSON();
}
}

View File

@ -1,20 +0,0 @@
// To configure your FDRS Gateway:
// Each device in the system has a unique, one-byte address which
// is assigned to the last digit of its MAC address at startup.
// Each device is configured to know what the previous and/or next
// device in the line of communication is.
// The gateway should usually be assigned the address 0x00.
// The PREV_MAC is currently not used, as the gateway responds
// to all packets in the same manner.
// THIS UNIT
#define UNIT_MAC 0x00
#define PREV_MAC 0x01
//MAC prefix:
#define MAC_PREFIX 0xAA, 0xBB, 0xCC, 0xDD, 0xEE

View File

@ -1,141 +0,0 @@
// FARM DATA RELAY SYSTEM
//
// RELAY MODULE
//
// Developed by Timm Bogner (bogner1@gmail.com) for Sola Gratia Farm in Urbana, Illinois, USA.
// Setup instructions located in the "fdrs_config.h" file.
#if defined(ESP8266)
#include <ESP8266WiFi.h>
#include <espnow.h>
#elif defined(ESP32)
#include <esp_now.h>
#include <WiFi.h>
#include <esp_wifi.h>
#endif
#include "fdrs_config.h"
uint8_t prevAddress[] = {0xAA, 0xBB, 0xCC, 0xDD, 0xEE, PREV_MAC};
uint8_t selfAddress[] = {0xAA, 0xBB, 0xCC, 0xDD, 0xEE, UNIT_MAC};
uint8_t nextAddress[] = {0xAA, 0xBB, 0xCC, 0xDD, 0xEE, NEXT_MAC};
uint8_t outMAC[] = {0xAA, 0xBB, 0xCC, 0xDD, 0xEE, DEFT_MAC};
uint8_t incMAC[6];
uint8_t theData[250];
uint8_t ln;
bool newData = false;
bool isLocal = false;
void passOn() {
switch (incMAC[5]) {
case PREV_MAC:
outMAC[5] = NEXT_MAC;
break;
case NEXT_MAC:
outMAC[5] = PREV_MAC;
break;
default:
outMAC[5] = DEFT_MAC;
break;
}
if (!isLocal) outMAC[5] = DEFT_MAC;
Serial.print("Packet Received from device: ");
Serial.println(incMAC[5]);
Serial.print("and sending to: ");
Serial.println(outMAC[5]);
esp_now_send(outMAC, (uint8_t *) &theData, ln);
}
// Set ESP-NOW send and receive callbacks for either ESP8266 or ESP32
#if defined(ESP8266)
void OnDataSent(uint8_t *mac_addr, uint8_t sendStatus) {
Serial.print("Last Packet Send Status: ");
if (sendStatus == 0) {
Serial.println("Delivery success");
}
else {
Serial.println("Delivery fail");
}
}
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) {
Serial.print("Last Packet Send Status:");
Serial.println(status == ESP_NOW_SEND_SUCCESS ? "Delivery Success" : "Delivery Fail");
}
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, &selfAddress, 5) != 0) {
isLocal = false;
} else {
isLocal = true;
}
Serial.print("Data received: ");
Serial.println(len);
ln = len;
newData = true;
}
void setup() {
// Init Serial Monitor
Serial.begin(115200);
// Init WiFi
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(prevAddress, ESP_NOW_ROLE_COMBO, 0, NULL, 0);
esp_now_add_peer(nextAddress, 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) {
Serial.println("Error initializing ESP-NOW");
return;
}
esp_now_register_send_cb(OnDataSent);
esp_now_register_recv_cb(OnDataRecv);
esp_now_peer_info_t peerInfo;
peerInfo.channel = 0;
peerInfo.encrypt = false;
// Register first peer
memcpy(peerInfo.peer_addr, prevAddress, 6);
if (esp_now_add_peer(&peerInfo) != ESP_OK) {
Serial.println("Failed to add peer");
return;
}
// Register second peer
memcpy(peerInfo.peer_addr, nextAddress, 6);
if (esp_now_add_peer(&peerInfo) != ESP_OK) {
Serial.println("Failed to add peer");
return;
}
#endif
Serial.println();
Serial.println("FARM DATA RELAY SYSTEM :: Relay Module");
Serial.println("MAC:" + WiFi.macAddress());
Serial.print("Previous device: ");
Serial.println(PREV_MAC);
Serial.print("Next device: ");
Serial.println(NEXT_MAC);
Serial.print("Default device: ");
Serial.println(DEFT_MAC);
Serial.println(" ");
}
void loop() {
if (newData) {
newData = false;
passOn();
}
}

View File

@ -1,22 +0,0 @@
// To configure FDRS:
// Each device in the system has a unique, one-byte address which
// is assigned to the last digit of its MAC address at startup.
// Each relay receives data from its pre-programmed "PREV_MAC" device and
// sends the packet verbatim to the address corresponding to "NEXT_MAC".
// The gateway receives the data and outputs it as a json string over the serial port.
// THIS UNIT
#define UNIT_MAC 0x01
// NEXT UNIT
#define NEXT_MAC 0x00
// PREVIOUS UNIT
#define PREV_MAC 0x02
//Packets from unknown MACs are sent here.
#define DEFT_MAC NEXT_MAC

View File

@ -1,7 +0,0 @@
typedef struct DataReading {
float d;
uint16_t id;
uint8_t t;
} DataReading;

View File

@ -1,151 +0,0 @@
// FARM DATA RELAY SYSTEM
//
// TERMINAL MODULE
//
// Developed by Timm Bogner (bogner1@gmail.com) for Sola Gratia Farm in Urbana, Illinois, USA.
// Setup instructions located in the "fdrs_config.h" file.
#if defined(ESP8266)
#include <ESP8266WiFi.h>
#include <espnow.h>
#elif defined(ESP32)
#include <esp_now.h>
#include <WiFi.h>
#include <esp_wifi.h>
#endif
#include "fdrs_config.h"
#include "DataReading.h"
uint8_t selfAddress[] = {0xAA, 0xBB, 0xCC, 0xDD, 0xEE, UNIT_MAC};
uint8_t nextAddress[] = {0xAA, 0xBB, 0xCC, 0xDD, 0xEE, NEXT_MAC};
uint8_t broadcast_mac[] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
DataReading incData[31];
DataReading theData[31];
DataReading theCommands[31];
bool newCMD = false;
int wait_time = 0;
int tot_readings = 0;
int tot_commands = 0;
#if defined(ESP8266)
void OnDataSent(uint8_t *mac_addr, uint8_t sendStatus) {
Serial.print("Last Packet Send Status: ");
if (sendStatus == 0) {
Serial.println("Delivery success");
}
else {
Serial.println("Delivery fail");
}
}
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) {
Serial.print("Last Packet Send Status:");
Serial.println(status == ESP_NOW_SEND_SUCCESS ? "Delivery Success" : "Delivery Fail");
}
void OnDataRecv(const uint8_t * mac, const uint8_t *incomingData, int len) {
#endif
uint8_t incMAC[6];
memcpy(&incData, incomingData, len);
memcpy(&mac, incMAC, 6);
//if (memcmp(&incMAC, &nextAddress, 6) == 0)
int pkt_readings = len / sizeof(DataReading);
Serial.println(":Packet:");
for (byte i = 0; i < pkt_readings; i++) {
Serial.println("SENSOR ID: " + String(incData[i].id) + " TYPE " + String(incData[i].t) + " DATA " + String(incData[i].d));
if (incData[i].t < 200) {
if (tot_readings >= 250 / sizeof(DataReading)) {
Serial.println("ERROR::Too many sensor readings sent within delay period.");
break;
}
theData[tot_readings] = incData[i]; //Save the current incoming reading to the next open packet slot
++tot_readings;
} else {
theCommands[tot_commands] = incData[i]; //Save the current incoming reading to the next open packet slot
++tot_commands;
newCMD = true;
}
}
}
void setup() {
// Init Serial
Serial.begin(115200);
// Init WiFi
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 peer
esp_now_add_peer(nextAddress, ESP_NOW_ROLE_COMBO, 0, NULL, 0);
esp_now_add_peer(broadcast_mac, 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) {
Serial.println("Error initializing ESP-NOW");
return;
}
esp_now_register_send_cb(OnDataSent);
esp_now_register_recv_cb(OnDataRecv);
esp_now_peer_info_t peerInfo;
peerInfo.channel = 0;
peerInfo.encrypt = false;
// Register peer
memcpy(peerInfo.peer_addr, nextAddress, 6);
if (esp_now_add_peer(&peerInfo) != ESP_OK) {
Serial.println("Failed to add peer");
return;
}
memcpy(peerInfo.peer_addr, broadcast_mac, 6);
if (esp_now_add_peer(&peerInfo) != ESP_OK) {
Serial.println("Failed to add peer");
return;
}
#endif
Serial.println();
Serial.println("FARM DATA RELAY SYSTEM :: Terminal Module");
Serial.println("MAC:" + WiFi.macAddress());
Serial.print("Next device: ");
Serial.println(NEXT_MAC);
// Serial.println(250 / sizeof(DataReading), DEC);
// Serial.println(sizeof(DataReading), DEC);
}
void loop() {
if (newCMD) sendCmd();
if (millis() > wait_time) {
wait_time = wait_time + DELAY;
if (tot_readings != 0) passForward();
}
}
void passForward() {
Serial.println("Passing Forward");
esp_now_send(nextAddress, (uint8_t *) &theData, sizeof(DataReading)*tot_readings);
tot_readings = 0;
for (int i = 0; i < 250 / sizeof(DataReading); i++) {
theData[i].d = 0;
theData[i].id = 0;
theData[i].t = 0;
}
}
void sendCmd() {
newCMD = false;
esp_now_send(broadcast_mac, (uint8_t *) &theCommands, tot_commands* sizeof(DataReading));
tot_commands = 0;
}

View File

@ -1,27 +0,0 @@
// To configure FDRS:
// Uncomment the code corresponding to the unit you are configuring,
// then uncomment the code corresponding to the unit you would like
// to be previous and/or next in the line of communication.
// Each device in the system has a unique, one-byte address which
// is assigned to the last digit of its MAC address at startup.
// Each device is configured to know what the previous and/or next
// device in the line of communication is.
// The terminal is considered the "first" device, which can be addressed
// to a relay or the gateway.
// Each relay receives data from its pre-programmed "PREV_MAC" device and
// sends the packet verbatim to the address corresponding to "NEXT_MAC".
// The gateway receives the data and outputs it as a json string over the serial port.
#define DELAY 15000
// THIS UNIT
#define UNIT_MAC 0x01
// NEXT UNIT
#define NEXT_MAC 0x00

View File

@ -1,7 +0,0 @@
typedef struct DataReading {
float d;
uint16_t id;
uint8_t t;
} DataReading;

View File

@ -1,151 +0,0 @@
// FARM DATA RELAY SYSTEM
//
// BLYNK FRONT-END MODULE
// Uses JSON data from the serial port to set Blynk variables.
//
// Developed by Timm Bogner (bogner1@gmail.com) for Sola Gratia Farm in Urbana, Illinois, USA.
// This code was written for the now-outdated version of Blynk, and is mostly here for reference.
//
#define STASSID "" //Your SSID
#define STAPSK "" //Your Password
#define BLKAUTH "" //Your Blynk auth code
#define DELAY 30000
#if defined(ESP8266)
#include <BlynkSimpleEsp8266.h>
#include <ESP8266WiFi.h>
#elif defined(ESP32)
#include <BlynkSimpleEsp32.h>
#include <WiFi.h>
#endif
#include <ArduinoJson.h>
#include "DataReading.h"
BlynkTimer timer;
WidgetTerminal terminal(V69);
DataReading allData[256];
int wait_time = DELAY;
char auth[] = BLKAUTH;
const char* ssid = STASSID;
const char* password = STAPSK;
bool is_new[255];
int new_readings;
bool term_flag;
String the_command;
BLYNK_WRITE(V69)
{
Serial.println("blynkwrite");
the_command = param.asStr();
term_flag = true;
}
void setup() {
Serial.begin(115200);
WiFi.mode(WIFI_STA);
Serial.println();
Serial.println("FDRS Blynk Module");
Serial.println("Connect to WiFi please?");
Blynk.begin(auth, ssid, password);
// Blynk.config(auth);
// Blynk.connectWiFi(ssid, password);
Serial.println("Thanks!");
//terminal.clear();
timer.setInterval(30000L, updateBlynk);
Blynk.run();
terminal.println("Hello, world!");
terminal.flush();
}
void loop() {
while (Serial.available()) {
Serial.println("waiting for tilda");
if (Serial.read() == '~') { //Waits for '~', then parses following data
getSerial();
Serial.println("getSerial done");
break;
}
}
// if (millis() > wait_time) {
// wait_time = wait_time + DELAY;
// if (Blynk.connected()) {
// updateBlynk();
// Serial.println("blynk updated");
// }
// }
if (term_flag) {
parseBlynkTerm(the_command);
term_flag = false;
}
Blynk.run();
timer.run();
}
void getSerial() {
String incomingString = Serial.readString();
StaticJsonDocument<3072> doc;
Serial.println("Received: " + incomingString);
DeserializationError error = deserializeJson(doc, incomingString);
if (error) { // Test if parsing succeeds.
Serial.print(F("deserializeJson() failed: "));
Serial.println(error.f_str());
return;
} else {
for (int i = 0; i < doc.size(); i++) {
Serial.println(doc.size());
DataReading newData;
newData.id = doc[i]["id"];
newData.t = doc[i]["type"];
newData.d = doc[i]["data"];
allData[newData.id] = newData;
is_new[newData.id] = true;
Serial.println("SENSOR ID: " + String(newData.id) + " TYPE " + String(newData.t) + " DATA " + String(newData.d));
yield();
}
}
}
void updateBlynk() {
Serial.println("Updateblynk");
for (int i = 0; i < 127; i++) {
if (is_new[i] == true) {
Serial.println("abt to write");
Blynk.virtualWrite(i, allData[i].d);
is_new[i] = false;
yield();
}
}
}
void parseBlynkTerm(String command) {
int ind1 = command.indexOf(" ");
String arg1 = command.substring(0, ind1);
if (arg1.equalsIgnoreCase(String("SET"))) {
int ind2 = command.indexOf(" ", ind1 + 1);
String arg2 = command.substring(ind1 + 1, ind2);
String arg3 = command.substring(ind2 + 1, command.length());
terminal.println("ARG1:" + arg1);
terminal.println("ARG2:" + arg2);
terminal.println("ARG3:" + arg3);
terminal.flush();
DataReading newCMD;
newCMD.id = arg2.toInt();
newCMD.t = 201;
newCMD.d = arg3.toFloat();
allData[newCMD.id] = newCMD;
StaticJsonDocument<2048> doc;
doc[0]["id"] = newCMD.id;
doc[0]["type"] = newCMD.t;
doc[0]["data"] = newCMD.d;
Serial.write('~');
serializeJson(doc, Serial);
Serial.println();
} else if (arg1.equalsIgnoreCase(String("GET"))) {
String arg2 = command.substring(ind1 + 1, command.length());
terminal.println("DataReading " + arg2 + " :: " + String(allData[arg2.toInt()].d));
terminal.flush();
}
}

View File

@ -1,44 +0,0 @@
# <p align="center">Ye Olde Farm Data Relay System
##### <p align="center">[***In loving memory of Gay Holman, an extraordinary woman.***](https://www.facebook.com/CFECI/posts/2967989419953119) #####
### This is the first version of my project, and is left here only for reference.
The Farm Data Relay System is an easy way to link remote sensors to the internet without the need for WiFi. It uses the ESP-NOW protocol on widely availabe ESP32 and ESP8266 microcontroller boards, and can be used to collect and transmit sensor data in situations where it would be too difficult or energy-consuming to provide full WiFi coverage.
A major consideration has been to make the system straight-forward and easy to set up, since the primary user may not be very familiar with Arduino. Using an assigned MAC address scheme allows for the whole system to be configured by setting just a handful of values in code.
Other than the nodes, each device in the system has a one-byte address. At boot, each device changes its MAC address to "AA:BB:CC:DD:EE:xx" where xx is the device's address identifier. Nodes can send their data to a terminal, a relay, or directly to a gateway. Each of these devices can be connected as needed in a chain that leads to a gateway, where the data is handed off to another system.
## Getting Started
To get started using FDRS with Node-Red, you'll first need to flash an ESP32 or 8266 device with the FDRS_Gateway sketch. Next, connect the device via serial port to a computer running Node-Red. You can then use the serialport node connected to a JSON node, and finally a split node to get your data ready to use. You can find the basic flow examples in the 'NodeRed-Basic.json' file. If you are using a usb-serial port, keep in mind that you may have to change the selected port after plugging in your device, or de-select the port when trying to flash the device from another program.
As you flash each sensor, you'll need to change the UNIT_ID to a unique integer (0-65535). For some sensors, you'll also need to adjust pin assignments and install libraries.
By default, all sensors have GTWY_MAC set to 0x00. You'll only need to change this if you are going to use a relay to extend the system's range.
If you need to get data from sensors that are out of reach of the gateway, place an FDRS_Relay device near the edge of the gateway's range. Flash this device with the default parameters, and then flash the sensors with GTWY_MAC set to 0x01. They will now send their data to the relay, which in turn sends it to the gateway.
## Sensors
```
typedef struct DataReading {
float d;
uint16_t id;
uint8_t t;
} DataReading;
```
Each sensor in the system sends its data over ESP-NOW as a float 'd' inside of a structure called a DataReading. Its global sensor address is represented by an integer 'id', and each type is represented by a single byte 't'. If sensors need to send multiple types of readings (ex: temp and humidity), then they are sent in an array of DataReadings. In this case each reading will share an id, but be differentiated by its type.
## Terminal
A terminal is a device that recieves data from the nodes and aggregates it into a larger array. The larger array is then periodically sent forward through the system to the gateway. The time between sends must be short enough so as not to exceed the maximum legnth of an ESP-NOW packet with DataReadings, which is 31.
## Relays
Relays are absolute ESP-NOW repeaters. They are programmed with the address of the previous and next device, and when data is received from one, it delivers it to the other. The "DEFT_MAC" setting defines where a relay will send an incoming packet with an unknown address. This can be used to direct sensor packets either to the terminal or the gateway.
In the FDRS, one can place as many relays as needed to span the distance to the gateway, which is the final device in the system.
## Gateway
The gateway takes the packet of DataReadings and interprets it into json format, then outputs it over the serial port. From here it can be collected by another microcontroller or a Raspberry Pi front-end to be sent to the cloud for further processing and storage.

View File

@ -7,10 +7,10 @@ Using an assigned MAC address scheme allows for the whole system to be configure
## Getting Started
### [Sensors](https://github.com/timmbogner/Farm-Data-Relay-System/tree/main/FDRS_Sensor2000)
### [Sensors](https://github.com/timmbogner/Farm-Data-Relay-System/tree/main/FDRS_Sensor)
Sensors gather data and send it to a gateway via ESP-NOW or LoRa.
### [Gateways](https://github.com/timmbogner/Farm-Data-Relay-System/tree/main/FDRS_Gateway2000)
### [Gateways](https://github.com/timmbogner/Farm-Data-Relay-System/tree/main/FDRS_Gateway)
Gateways listen for packets over ESP-NOW, LoRa, UART, and/or MQTT, then re-transmit the packets using one or more of the same interfaces.
### Front-end
@ -19,7 +19,9 @@ The Node-RED front-end can be set up with these nodes to format and send the dat
[{"id":"66d36c0f.cedf94","type":"influxdb out","z":"d7346a99.716ef8","influxdb":"905dd357.34717","name":"","measurement":"DataReading","precision":"","retentionPolicy":"","database":"database","precisionV18FluxV20":"ms","retentionPolicyV18Flux":"","org":"the_organization","bucket":"bkt","x":760,"y":240,"wires":[]},{"id":"93e9822a.3ad59","type":"mqtt in","z":"d7346a99.716ef8","name":"","topic":"esp/fdrs","qos":"2","datatype":"auto","broker":"c513f7e9.760658","nl":false,"rap":true,"rh":0,"x":170,"y":220,"wires":[["d377f9e0.faef98"]]},{"id":"d377f9e0.faef98","type":"json","z":"d7346a99.716ef8","name":"","property":"payload","action":"obj","pretty":false,"x":290,"y":220,"wires":[["ca383562.4014e8"]]},{"id":"ca383562.4014e8","type":"split","z":"d7346a99.716ef8","name":"","splt":"\\n","spltType":"str","arraySplt":1,"arraySpltType":"len","stream":false,"addname":"","x":410,"y":220,"wires":[["6eaba8dd.429e38"]]},{"id":"6eaba8dd.429e38","type":"function","z":"d7346a99.716ef8","name":"Fields","func":"msg.payload = [{\n data: msg.payload.data\n},{\n id: msg.payload.id,\n type: msg.payload.type\n}]\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":530,"y":220,"wires":[["296d0f4b.37a46","66d36c0f.cedf94"]]},{"id":"296d0f4b.37a46","type":"debug","z":"d7346a99.716ef8","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":670,"y":200,"wires":[]},{"id":"905dd357.34717","type":"influxdb","hostname":"127.0.0.1","port":"8086","protocol":"http","database":"database","name":"","usetls":false,"tls":"d50d0c9f.31e858","influxdbVersion":"2.0","url":"http://localhost:8086","rejectUnauthorized":true},{"id":"c513f7e9.760658","type":"mqtt-broker","name":"","broker":"localhost","port":"1883","clientid":"","usetls":false,"protocolVersion":"4","keepalive":"60","cleansession":true,"birthTopic":"","birthQos":"0","birthPayload":"","birthMsg":{},"closeTopic":"","closeQos":"0","closePayload":"","closeMsg":{},"willTopic":"","willQos":"0","willPayload":"","willMsg":{},"sessionExpiry":""},{"id":"d50d0c9f.31e858","type":"tls-config","name":"","cert":"","key":"","ca":"","certname":"","keyname":"","caname":"","servername":"","verifyservercert":false}]
```
## Dependencies
[LoRa library](https://github.com/sandeepmistry/arduino-LoRa)
[ArduinoJson](https://arduinojson.org/)
## Future Plans
A few things that I intend to add are:
@ -41,5 +43,5 @@ Development of this project would not have been possible without the support of
![Basic](/FDRS_Gateway2000/Basic_Setup.png)
![Advanced](/FDRS_Gateway2000/Advanced_Setup.png)
![Basic](/FDRS_Gateway/Basic_Setup.png)
![Advanced](/FDRS_Gateway/Advanced_Setup.png)

View File

@ -0,0 +1,37 @@
// FARM DATA RELAY SYSTEM
//
// Basic Sensor Example
//
// Developed by Timm Bogner (bogner1@gmail.com) for Sola Gratia Farm in Urbana, Illinois, USA.
// An example of how to send data using "fdrs_sensor.h".
//
#include "fdrs_sensor.h"
#include "sensor_setup.h"
FDRSLoRa FDRS(GTWY_MAC,READING_ID,MISO,MOSI,SCK,SS,RST,DIO0,BAND,SF);
float data1;
float data2;
void setup() {
FDRS.begin();
}
void loop() {
data1 = readHum();
FDRS.load(data1, HUMIDITY_T);
data2 = readTemp();
FDRS.load(data2, TEMP_T);
FDRS.send();
FDRS.sleep(10); //Sleep time in seconds
}
float readTemp() {
return 42.069;
}
float readHum() {
return 21.0345;
}

View File

@ -0,0 +1,181 @@
#include "fdrs_sensor.h"
const uint8_t prefix[] = {0xAA, 0xBB, 0xCC, 0xDD, 0xEE}; // Should only be changed if implementing multiple FDRS systems.
uint8_t LoRaAddress[] = {0x42, 0x00};
uint32_t wait_time = 0;
FDRSBase::FDRSBase(uint8_t gtwy_mac,uint8_t reading_id):
_gtwy_mac(gtwy_mac),
_espnow_size(250 / sizeof(DataReading_t)),
_reading_id(reading_id),
_data_count(0)
{
fdrsData = new DataReading_t[_espnow_size];
}
FDRSBase::~FDRSBase(){
delete[] fdrsData;
}
void FDRSBase::begin() {
#ifdef DEBUG
Serial.begin(115200);
#endif
DBG("FDRS Sensor ID " + String(_reading_id) + " initializing...");
DBG(" Gateway: " + String (_gtwy_mac, HEX));
#ifdef POWER_CTRL
DBG("Powering up the sensor array!");
pinMode(POWER_CTRL, OUTPUT);
digitalWrite(POWER_CTRL, 1);
#endif
init();
}
void FDRSBase::send(void) {
DBG("Sending FDRS Packet!");
if(_data_count == 0){
return;
}
transmit(fdrsData,_data_count);
_data_count = 0;
}
void FDRSBase::load(float data, uint8_t type) {
DBG("Data loaded. Type: " + String(type));
if (_data_count > _espnow_size){
send();
}
DataReading_t dr;
dr.id = _reading_id;
dr.type = type;
dr.data = data;
fdrsData[_data_count] = dr;
_data_count++;
}
void FDRSBase::sleep(int seconds){
DBG("Sleepytime!");
#ifdef DEEP_SLEEP
DBG(" Deep sleeping.");
#ifdef ESP32
esp_sleep_enable_timer_wakeup(sleep_time * 1000000);
esp_deep_sleep_start();
#endif
#ifdef ESP8266
ESP.deepSleep(sleep_time * 1000000);
#endif
#endif
DBG(" Delaying.");
delay(seconds * 1000);
}
FDRS_EspNow::FDRS_EspNow(uint8_t gtwy_mac,uint8_t reading_id):
FDRSBase(gtwy_mac,reading_id)
{
memcpy(_gatewayAddress,MAC_PREFIX,5);
_gatewayAddress[5] = gtwy_mac;
}
void FDRS_EspNow::init(void){
// Init ESP-NOW for either ESP8266 or ESP32 and set MAC address
DBG("Initializing ESP-NOW!");
WiFi.mode(WIFI_STA);
WiFi.disconnect();
#if defined(ESP8266)
if (esp_now_init() != 0) {
return;
}
esp_now_set_self_role(ESP_NOW_ROLE_COMBO);
// Register peers
esp_now_add_peer(_gatewayAddress, ESP_NOW_ROLE_COMBO, 0, NULL, 0);
#elif defined(ESP32)
if(esp_now_init() != ESP_OK){
DBG("Error initializing ESP-NOW");
return;
}
esp_now_peer_info_t peerInfo;
peerInfo.ifidx = WIFI_IF_STA;
peerInfo.channel = 0;
peerInfo.encrypt = false;
// Register first peer
memcpy(peerInfo.peer_addr, _gatewayAddress, 6);
if(esp_now_add_peer(&peerInfo) != ESP_OK) {
DBG("Failed to add peer");
return;
}
#endif
DBG(" ESP-NOW Initialized.");
}
void FDRS_EspNow::transmit(DataReading_t *fdrsData, uint8_t _data_count){
esp_now_send(_gatewayAddress, (uint8_t *) fdrsData, _data_count * sizeof(DataReading_t));
delay(5);
DBG(" ESP-NOW sent.");
}
#ifdef USE_LORA
FDRSLoRa::FDRSLoRa(uint8_t gtwy_mac,
uint8_t reading_id,uint8_t miso,uint8_t mosi,uint8_t sck,
uint8_t ss,uint8_t rst,uint8_t dio0,uint32_t band,uint8_t sf):
FDRSBase(gtwy_mac,reading_id),
_miso(miso),
_mosi(mosi),
_sck(sck),
_ss(ss),
_rst(rst),
_dio0(dio0),
_band(band),
_sf(sf)
{
_gatewayAddress[0] = prefix[3];
_gatewayAddress[1] = prefix[4];
_gatewayAddress[2] = gtwy_mac;
}
void FDRSLoRa::init(void){
DBG("Initializing LoRa!");
DBG(_band);
DBG(_sf);
#ifdef ESP32
SPI.begin(_sck, _miso, _mosi, _ss);
#endif
LoRa.setPins(_ss, _rst, _dio0);
if (!LoRa.begin(_band)) {
DBG("LoRa Initialize Failed.");
while (1);
}
LoRa.setSpreadingFactor(_sf);
DBG("LoRa Initialized.");
}
void FDRSLoRa::buildPacket(uint8_t* mac, DataReading_t * packet, uint8_t len) {
uint8_t pkt[5 + (len * sizeof(DataReading_t))];
memcpy(&pkt, mac, 3); //
memcpy(&pkt[3], &LoRaAddress, 2);
memcpy(&pkt[5], packet, len * sizeof(DataReading_t));
LoRa.beginPacket();
LoRa.write((uint8_t*)&pkt, sizeof(pkt));
LoRa.endPacket();
}
void FDRSLoRa::transmit(DataReading_t *fdrsData, uint8_t _data_count){
buildPacket(_gatewayAddress, fdrsData, _data_count);
DBG(" LoRa sent.");
}
#endif

View File

@ -0,0 +1,141 @@
/* FARM DATA RELAY SYSTEM
*
* "fdrs_sensor.h"
*
* Developed by Timm Bogner (timmbogner@gmail.com) for Sola Gratia Farm in Urbana, Illinois, USA.
* Condensed and refactored to a single file pair by Binder Tronics (info@bindertronics.com).
*/
#ifndef __FDRS_SENSOR__H__
#define __FDRS_SENSOR__H__
#include "fdrs_types.h"
//1 to enable debugging prints. 0 disables the debugging prints
#define ENABLE_DEBUG 1
#if ENABLE_DEBUG == 1
#ifndef DEBUG
#define DEBUG
#endif
#endif
#define USE_LORA
#if defined(ESP8266)
#include <ESP8266WiFi.h>
#include <espnow.h>
#elif defined(ESP32)
#include <esp_now.h>
#include <WiFi.h>
#include <esp_wifi.h>
#endif
#ifdef USE_LORA
#include "LoRa.h"
#endif
#ifdef GLOBALS
#define FDRS_BAND GLOBAL_BAND
#define FDRS_SF GLOBAL_SF
#else
#define FDRS_BAND BAND
#define FDRS_SF SF
#endif
#ifdef DEBUG
#define DBG(a) (Serial.println(a))
#else
#define DBG(a)
#endif
#define STATUS_T 0 // Status
#define TEMP_T 1 // Temperature
#define TEMP2_T 2 // Temperature #2
#define HUMIDITY_T 3 // Relative Humidity
#define PRESSURE_T 4 // Atmospheric Pressure
#define LIGHT_T 5 // Light (lux)
#define SOIL_T 6 // Soil Moisture
#define SOIL2_T 7 // Soil Moisture #2
#define SOILR_T 8 // Soil Resistance
#define SOILR2_T 9 // Soil Resistance #2
#define OXYGEN_T 10 // Oxygen
#define CO2_T 11 // Carbon Dioxide
#define WINDSPD_T 12 // Wind Speed
#define WINDHDG_T 13 // Wind Direction
#define RAINFALL_T 14 // Rainfall
#define MOTION_T 15 // Motion
#define VOLTAGE_T 16 // Voltage
#define VOLTAGE2_T 17 // Voltage #2
#define CURRENT_T 18 // Current
#define CURRENT2_T 19 // Current #2
#define IT_T 20 // Iterations
extern const uint8_t prefix[5];
#define MAC_PREFIX prefix // Should only be changed if implementing multiple FDRS systems.
#define ESP_GATEWAY_ADDRESS_SIZE 6
#define LORA_GATEWAY_ADDRESS_SIZE 3
class FDRSBase{
public:
FDRSBase(uint8_t gtwy_mac,uint8_t reading_id);
~FDRSBase();
void begin(void);
void load(float data, uint8_t type);
void sleep(int seconds);
void send();
private:
uint8_t _gtwy_mac;
const uint16_t _espnow_size;
uint8_t _reading_id;
uint8_t _data_count;
DataReading_t *fdrsData;
virtual void init(void) = 0;
virtual void transmit(DataReading_t *fdrsData, uint8_t _data_count) = 0;
};
class FDRS_EspNow: public FDRSBase{
public:
FDRS_EspNow(uint8_t gtwy_mac, uint8_t reading_id);
private:
uint8_t _gatewayAddress[ESP_GATEWAY_ADDRESS_SIZE];
void transmit(DataReading_t *fdrsData, uint8_t _data_count) override;
void init(void) override;
};
class FDRSLoRa: public FDRSBase{
public:
FDRSLoRa(uint8_t gtwy_mac, uint8_t reading_id,uint8_t miso,uint8_t mosi,uint8_t sck, uint8_t ss,uint8_t rst,uint8_t dio0,uint32_t band,uint8_t sf);
private:
uint8_t _gatewayAddress[LORA_GATEWAY_ADDRESS_SIZE];
uint8_t _miso;
uint8_t _mosi;
uint8_t _sck;
uint8_t _ss;
uint8_t _rst;
uint8_t _dio0;
uint32_t _band;
uint8_t _sf;
void buildPacket(uint8_t* mac, DataReading_t * packet, uint8_t len);
void transmit(DataReading_t *fdrsData, uint8_t _data_count) override;
void init(void) override;
};
#endif

View File

@ -0,0 +1,39 @@
#ifndef __FDRS_TYPES_H__
#define __FDRS_TYPES_H__
#include <stdint.h>
#include <string.h>
#include <vector>
typedef struct __attribute__((packed)) DataReading_t {
float data;
uint16_t id;
uint8_t type;
DataReading_t(): data(0.0),id(0),type(0){
}
} DataReading_t;
typedef struct Peer_t{
uint8_t peer[6];
std::vector<DataReading_t> buffer;
Peer_t(){
memset(peer,0,6);
buffer.clear();
}
void _set_peer(uint8_t p[6]){
memcpy(peer,p,6);
}
uint8_t *_get_peer(void){
return peer;
}
bool operator==(Peer_t c){
return (memcmp(this->peer,c.peer,6) == 0);
}
}Peer_t;
#endif

View File

@ -0,0 +1,27 @@
// FARM DATA RELAY SYSTEM
//
// Sensor Configuration
// (This file will soon be known as 'sensor_config.h')
//
//#include <fdrs_globals.h> //Uncomment when you install the globals file
#define READING_ID 1 //Unique ID for this sensor
#define GTWY_MAC 0x04 //Address of the nearest gateway
#define DEEP_SLEEP
//#define POWER_CTRL 14
#define DEBUG
//LoRa Configuration
#define SCK 5
#define MISO 19
#define MOSI 27
#define SS 18
#define RST 14
#define DIO0 26
//433E6 for Asia
//866E6 for Europe
//915E6 for North America
#define BAND 915E6
#define SF 7