readme and sensor examples

moved readmes, added back sensor examples
This commit is contained in:
Timm Bogner 2022-08-07 00:30:48 -05:00
parent 2f2129dd6d
commit deabf20a3d
26 changed files with 904 additions and 2 deletions

View File

@ -15,10 +15,10 @@ Install the libraries that you need:
- [PubSubClient](https://github.com/knolleary/pubsubclient/) (required for MQTT Gateways) - [PubSubClient](https://github.com/knolleary/pubsubclient/) (required for MQTT Gateways)
### [Sensors](https://github.com/timmbogner/Farm-Data-Relay-System/tree/main/FDRS_Sensor) ### [Sensors](https://github.com/timmbogner/Farm-Data-Relay-System/tree/main/extras/SENSORS.md)
Sensors gather data and send it to a gateway via ESP-NOW or LoRa. 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_Gateway) ### [Gateways](https://github.com/timmbogner/Farm-Data-Relay-System/tree/main/extras/GATEWAYS.md)
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. 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 ### Front-end

View File

@ -0,0 +1,29 @@
// FARM DATA RELAY SYSTEM
//
// AHT20 SENSOR MODULE
//
// Developed by Timm Bogner (timmbogner@gmail.com) in Urbana, Illinois, USA.
#include "fdrs_sensor_config.h"
#include <Adafruit_AHTX0.h>
#include <fdrs_sensor.h>
Adafruit_AHTX0 aht;
void setup() {
Serial.begin(115200);
beginFDRS();
if (! aht.begin()) {
Serial.println("Could not find AHT? Check wiring");
while (1) delay(10);
}
}
void loop() {
sensors_event_t humidity, temp;
aht.getEvent(&humidity, &temp);// populate temp and humidity objects with fresh data
loadFDRS(temp.temperature, TEMP_T);
loadFDRS(humidity.relative_humidity, HUMIDITY_T);
sendFDRS();
sleepFDRS(60); //Sleep time in seconds
}

View File

@ -0,0 +1,33 @@
// FARM DATA RELAY SYSTEM
//
// Sensor Configuration
#include <fdrs_globals.h>
#define READING_ID 1 //Unique ID for this sensor
#define GTWY_MAC 0x01 //Address of the nearest gateway
#define USE_ESPNOW
//#define USE_LORA
#define DEEP_SLEEP
//#define POWER_CTRL 14
#define FDRS_DEBUG
//SPI Configuration -- Needed only on chipsets with multiple SPI interfaces (ESP32)
#define SPI_SCK 5
#define SPI_MISO 19
#define SPI_MOSI 27
//LoRa Configuration
#define LORA_SS 18
#define LORA_RST 14
#define LORA_DIO0 26
//433E6 for Asia
//866E6 for Europe
//915E6 for North America
//#define LORA_BAND 915E6 // LoRa Frequency Band
//#define LORA_SF 7 // LoRa Spreading Factor
//#define LORA_TXPWR 17 // LoRa TX power in dBm (+2dBm - +20dBm), default is +17dBm. Lower power = less battery use
//#define LORA_ACK // Uncomment to enable request for LoRa ACKs at cost of increased battery usage
//#define LORA_ACK_TIMEOUT 400 // ms timeout waiting for LoRa ACKs (if enabled). Wouldn't go less than 200ms
//#define LORA_RETRIES 2 // [0 - 3] When ACK enabled, number of sensor node tx retries when ACK not received or invalid CRC

View File

@ -0,0 +1,28 @@
// FARM DATA RELAY SYSTEM
//
// BME280 SENSOR MODULE
//
// Developed by Timm Bogner (bogner1@gmail.com) for Sola Gratia Farm in Urbana, Illinois, USA.
#include "fdrs_sensor_config.h"
#include <Adafruit_BME280.h>
#include <fdrs_sensor.h>
Adafruit_BME280 bme;
void setup() {
//Serial.begin(115200);
beginFDRS();
while (!bme.begin(0x76)) {
//Serial.println("BME not initializing!");
delay(10);
}
}
void loop() {
loadFDRS(bme.readTemperature(), TEMP_T);
loadFDRS(bme.readHumidity(), HUMIDITY_T);
loadFDRS(bme.readPressure() / 100.0F, PRESSURE_T);
sendFDRS();
sleepFDRS(60); //Sleep time in seconds
}

View File

@ -0,0 +1,33 @@
// FARM DATA RELAY SYSTEM
//
// Sensor Configuration
#include <fdrs_globals.h>
#define READING_ID 1 //Unique ID for this sensor
#define GTWY_MAC 0x01 //Address of the nearest gateway
#define USE_ESPNOW
//#define USE_LORA
#define DEEP_SLEEP
//#define POWER_CTRL 14
#define FDRS_DEBUG
//SPI Configuration -- Needed only on chipsets with multiple SPI interfaces (ESP32)
#define SPI_SCK 5
#define SPI_MISO 19
#define SPI_MOSI 27
//LoRa Configuration
#define LORA_SS 18
#define LORA_RST 14
#define LORA_DIO0 26
//433E6 for Asia
//866E6 for Europe
//915E6 for North America
//#define LORA_BAND 915E6 // LoRa Frequency Band
//#define LORA_SF 7 // LoRa Spreading Factor
//#define LORA_TXPWR 17 // LoRa TX power in dBm (+2dBm - +20dBm), default is +17dBm. Lower power = less battery use
//#define LORA_ACK // Uncomment to enable request for LoRa ACKs at cost of increased battery usage
//#define LORA_ACK_TIMEOUT 400 // ms timeout waiting for LoRa ACKs (if enabled). Wouldn't go less than 200ms
//#define LORA_RETRIES 2 // [0 - 3] When ACK enabled, number of sensor node tx retries when ACK not received or invalid CRC

View File

@ -0,0 +1,28 @@
// FARM DATA RELAY SYSTEM
//
// BMP280 SENSOR MODULE
//
// Developed by Timm Bogner (timmbogner@gmail.com) in Urbana, Illinois, USA.
// Connect sensor SDA and SCL pins to those of the ESP.
#include "fdrs_sensor_config.h"
#include <Adafruit_BMP280.h>
#include <fdrs_sensor.h>
Adafruit_BMP280 bmp;
void setup() {
//Serial.begin(115200);
beginFDRS();
while (!bmp.begin(0x76)) {
//Serial.println("BMP not initializing!");
delay(10);
}
}
void loop() {
loadFDRS(bmp.readTemperature(), TEMP_T);
loadFDRS(bmp.readPressure() / 100.0F, PRESSURE_T);
sendFDRS();
sleepFDRS(60); //Sleep time in seconds
}

View File

@ -0,0 +1,33 @@
// FARM DATA RELAY SYSTEM
//
// Sensor Configuration
#include <fdrs_globals.h>
#define READING_ID 1 //Unique ID for this sensor
#define GTWY_MAC 0x01 //Address of the nearest gateway
#define USE_ESPNOW
//#define USE_LORA
#define DEEP_SLEEP
//#define POWER_CTRL 14
#define FDRS_DEBUG
//SPI Configuration -- Needed only on chipsets with multiple SPI interfaces (ESP32)
#define SPI_SCK 5
#define SPI_MISO 19
#define SPI_MOSI 27
//LoRa Configuration
#define LORA_SS 18
#define LORA_RST 14
#define LORA_DIO0 26
//433E6 for Asia
//866E6 for Europe
//915E6 for North America
//#define LORA_BAND 915E6 // LoRa Frequency Band
//#define LORA_SF 7 // LoRa Spreading Factor
//#define LORA_TXPWR 17 // LoRa TX power in dBm (+2dBm - +20dBm), default is +17dBm. Lower power = less battery use
//#define LORA_ACK // Uncomment to enable request for LoRa ACKs at cost of increased battery usage
//#define LORA_ACK_TIMEOUT 400 // ms timeout waiting for LoRa ACKs (if enabled). Wouldn't go less than 200ms
//#define LORA_RETRIES 2 // [0 - 3] When ACK enabled, number of sensor node tx retries when ACK not received or invalid CRC

View File

@ -0,0 +1,42 @@
// Example testing sketch for various DHT humidity/temperature sensors
// Written by ladyada, public domain
// Modified by Timm Bogner for Farm Data Relay System -- Untested because I don't have a DHT sensor onhand.
#include "fdrs_sensor_config.h"
#include <fdrs_sensor.h>
#include "DHT.h"
#define DHTPIN 2 // Digital pin connected to the DHT sensor
// Uncomment whatever type you're using!
//#define DHTTYPE DHT11 // DHT 11
#define DHTTYPE DHT22 // DHT 22 (AM2302), AM2321
//#define DHTTYPE DHT21 // DHT 21 (AM2301)
DHT dht(DHTPIN, DHTTYPE);
void setup() {
beginFDRS();
DBG("DHTxx Sketch!");
dht.begin();
}
void loop() {
// Wait a few seconds between measurements.
// Reading temperature or humidity takes about 250 milliseconds!
// Sensor readings may also be up to 2 seconds 'old' (its a very slow sensor)
float h = dht.readHumidity();
// Read temperature as Celsius (the default)
float t = dht.readTemperature();
// Check if any reads failed and exit early (to try again).
if (isnan(h) || isnan(t)) {
DBG("Failed to read from DHT sensor!");
return;
}
loadFDRS(h, HUMIDITY_T);
loadFDRS(t, TEMP_T);
sendFDRS();
sleepFDRS(10); //Sleep time in seconds
}

View File

@ -0,0 +1,33 @@
// FARM DATA RELAY SYSTEM
//
// Sensor Configuration
#include <fdrs_globals.h>
#define READING_ID 1 //Unique ID for this sensor
#define GTWY_MAC 0x01 //Address of the nearest gateway
#define USE_ESPNOW
//#define USE_LORA
#define DEEP_SLEEP
//#define POWER_CTRL 14
#define FDRS_DEBUG
//SPI Configuration -- Needed only on chipsets with multiple SPI interfaces (ESP32)
#define SPI_SCK 5
#define SPI_MISO 19
#define SPI_MOSI 27
//LoRa Configuration
#define LORA_SS 18
#define LORA_RST 14
#define LORA_DIO0 26
//433E6 for Asia
//866E6 for Europe
//915E6 for North America
//#define LORA_BAND 915E6 // LoRa Frequency Band
//#define LORA_SF 7 // LoRa Spreading Factor
//#define LORA_TXPWR 17 // LoRa TX power in dBm (+2dBm - +20dBm), default is +17dBm. Lower power = less battery use
//#define LORA_ACK // Uncomment to enable request for LoRa ACKs at cost of increased battery usage
//#define LORA_ACK_TIMEOUT 400 // ms timeout waiting for LoRa ACKs (if enabled). Wouldn't go less than 200ms
//#define LORA_RETRIES 2 // [0 - 3] When ACK enabled, number of sensor node tx retries when ACK not received or invalid CRC

View File

@ -0,0 +1,27 @@
// FARM DATA RELAY SYSTEM
//
// DS18B20 SENSOR MODULE
//
#define ONE_WIRE_BUS 13 //Pin that the DS18B20 is connected to
#include "fdrs_sensor_config.h"
#include <fdrs_sensor.h>
#include <OneWire.h>
#include <DallasTemperature.h>
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);
void setup() {
beginFDRS();
sensors.begin();
}
void loop() {
sensors.requestTemperatures(); // Send the command to get temperatures
float tempC = sensors.getTempCByIndex(0);
loadFDRS(tempC, TEMP_T);
sendFDRS();
sleepFDRS(60);
}

View File

@ -0,0 +1,33 @@
// FARM DATA RELAY SYSTEM
//
// Sensor Configuration
#include <fdrs_globals.h>
#define READING_ID 1 //Unique ID for this sensor
#define GTWY_MAC 0x01 //Address of the nearest gateway
#define USE_ESPNOW
//#define USE_LORA
#define DEEP_SLEEP
//#define POWER_CTRL 14
#define FDRS_DEBUG
//SPI Configuration -- Needed only on chipsets with multiple SPI interfaces (ESP32)
#define SPI_SCK 5
#define SPI_MISO 19
#define SPI_MOSI 27
//LoRa Configuration
#define LORA_SS 18
#define LORA_RST 14
#define LORA_DIO0 26
//433E6 for Asia
//866E6 for Europe
//915E6 for North America
//#define LORA_BAND 915E6 // LoRa Frequency Band
//#define LORA_SF 7 // LoRa Spreading Factor
//#define LORA_TXPWR 17 // LoRa TX power in dBm (+2dBm - +20dBm), default is +17dBm. Lower power = less battery use
//#define LORA_ACK // Uncomment to enable request for LoRa ACKs at cost of increased battery usage
//#define LORA_ACK_TIMEOUT 400 // ms timeout waiting for LoRa ACKs (if enabled). Wouldn't go less than 200ms
//#define LORA_RETRIES 2 // [0 - 3] When ACK enabled, number of sensor node tx retries when ACK not received or invalid CRC

View File

@ -0,0 +1,169 @@
// FARM DATA RELAY SYSTEM
//
// Generic GPS Sensor
//
// Developed by Sascha Juch (sascha.juch@gmail.com).
// Reads in GPS data from serial and sends latitude, longitude and altitude to a gateway.
//
#include "fdrs_sensor_config.h"
#include <fdrs_sensor.h>
#define SERIAL1_RX 34 // TX pin of GPS sensor
#define SERIAL1_TX 12 // RX pin of GPS sensor
#define MAX_NMEA_LENGTH 82 //maximum allowed length of a NMEA 0183 sentences.
char currentNMEALine[MAX_NMEA_LENGTH];
void setup() {
// ToDo: This works well on a board with a second hardware serial port like the ESP32. But what if there is no hardware serial on the device?
// Unfortunately I do not have a GPS (standalone) sensor atm with which I could test. Help and advice appreciated.
Serial1.begin(9600, SERIAL_8N1, SERIAL1_RX, SERIAL1_TX);
beginFDRS();
}
void loop() {
// read in line by line of the NMEA input and get rid of trailing whitespaces
Serial1.readBytesUntil('\n', currentNMEALine, MAX_NMEA_LENGTH);
trimwhitespace(currentNMEALine);
// we are only interested in GPGGA (U-Blox M6N) or GNGGA (U-Blox M8N)lines.
if (startsWith(currentNMEALine, "$GNGGA") || startsWith(currentNMEALine, "$GPGGA")) {
DBG(currentNMEALine);
// just in case someone needs UTC, quality or #satelites, just uncomment and do what you have to do with them. :)
//char * gpsUTC = getNthValueOf(currentNMEALine, ',', 1);
char * gpsLatitude = getNthValueOf(currentNMEALine, ',', 2);
char * gpsLatitudeOrientation = getNthValueOf(currentNMEALine, ',', 3);
char * gpsLongitude = getNthValueOf(currentNMEALine, ',', 4);
char * gpsLongitudeOrientation = getNthValueOf(currentNMEALine, ',', 5);
//char * gpsQuality = getNthValueOf(currentNMEALine, ',', 6);
char * gpsAltitude = getNthValueOf(currentNMEALine, ',', 7);
//char * gpsNoOfSatelites = getNthValueOf(currentNMEALine, ',', 9);
// convert latitude and altitude to decimal degree values (as used in most maps programs)
// negative values mean "S" or "W", positive values mean "N" and "E"
float latitude = convertGpsCoordinates(atof(gpsLatitude), gpsLatitudeOrientation);
float longitude = convertGpsCoordinates(atof(gpsLongitude), gpsLongitudeOrientation);
float altitude = atof(gpsAltitude);
/*
loadFDRS(latitude, HUMIDITY_T);
loadFDRS(longitude, TEMP_T);
loadFDRS(altitude, TEMP2_T);
*/
// extended sensor types - not officially atm!
loadFDRS(latitude, LATITUDE_T);
loadFDRS(longitude, LONGITUDE_T);
loadFDRS(altitude, ALTITUDE_T);
sendFDRS();
sleepFDRS(10); //Sleep time in seconds
}
}
// cudos for the trimming function go to: https://stackoverflow.com/questions/122616/how-do-i-trim-leading-trailing-whitespace-in-a-standard-way
// Thanks! That was a time saver. :)
// Note: This function returns a pointer to a substring of the original string.
// If the given string was allocated dynamically, the caller must not overwrite
// that pointer with the returned value, since the original pointer must be
// deallocated using the same allocator with which it was allocated. The return
// value must NOT be deallocated using free() etc.
char *trimwhitespace(char *str)
{
char *end;
// Trim leading space
while(isspace((unsigned char)*str)) str++;
if(*str == 0) // All spaces?
return str;
// Trim trailing space
end = str + strlen(str) - 1;
while(end > str && isspace((unsigned char)*end)) end--;
// Write new null terminator character
end[1] = '\0';
return str;
}
// check, if a given char* fullString starts with a given char* startString.
// If that's the case, return true, false otherwise
bool startsWith(const char *fullString, const char *startString)
{
if (strncmp(fullString, startString, strlen(startString)) == 0) return 1;
return 0;
}
// Cudos for the substr function go to: https://www.techiedelight.com/implement-substr-function-c/
// Thanks! That helped a lot :)
// Following function extracts characters present in `src`
// between `m` and `n` (excluding `n`)
char* substr(const char *src, int m, int n)
{
// get the length of the destination string
int len = n - m;
// allocate (len + 1) chars for destination (+1 for extra null character)
char *dest = (char*)malloc(sizeof(char) * (len + 1));
// extracts characters between m'th and n'th index from source string
// and copy them into the destination string
for (int i = m; i < n && (*(src + i) != '\0'); i++)
{
*dest = *(src + i);
dest++;
}
// null-terminate the destination string
*dest = '\0';
// return the destination string
return dest - len;
}
// returns the value of the n-th occurance within a delimiter-separated string
char * getNthValueOf (char *inputString, const char delimiter, uint8_t index) {
uint8_t i = 0;
uint8_t currentIndex = 0;
uint8_t startOfValue = 0;
uint8_t endOfValue = 0;
while (i < strlen(inputString) && inputString[i] && currentIndex < index) {
if (inputString[i] == delimiter) {
currentIndex++;
}
i++;
}
startOfValue = i;
while (i < strlen(inputString) && inputString[i] && currentIndex <= index) {
if (inputString[i] == delimiter) {
currentIndex++;
}
i++;
}
endOfValue = i;
char* valueAtIndex = substr(inputString, startOfValue, endOfValue-1);
return valueAtIndex;
}
// convert NMEA0183 degrees minutes coordinates to decimal degrees
float convertGpsCoordinates(float degreesMinutes, char* orientation) {
double gpsMinutes = fmod((double)degreesMinutes, 100.0);
uint8_t gpsDegrees = degreesMinutes / 100;
double decimalDegrees = gpsDegrees + ( gpsMinutes / 60 );
if (orientation == "W" || orientation == "S") {
decimalDegrees = 0 - decimalDegrees;
}
return decimalDegrees;
}

View File

@ -0,0 +1,33 @@
// FARM DATA RELAY SYSTEM
//
// Sensor Configuration
#include <fdrs_globals.h>
#define READING_ID 1 //Unique ID for this sensor
#define GTWY_MAC 0x01 //Address of the nearest gateway
#define USE_ESPNOW
//#define USE_LORA
#define DEEP_SLEEP
//#define POWER_CTRL 14
#define FDRS_DEBUG
//SPI Configuration -- Needed only on chipsets with multiple SPI interfaces (ESP32)
#define SPI_SCK 5
#define SPI_MISO 19
#define SPI_MOSI 27
//LoRa Configuration
#define LORA_SS 18
#define LORA_RST 14
#define LORA_DIO0 26
//433E6 for Asia
//866E6 for Europe
//915E6 for North America
//#define LORA_BAND 915E6 // LoRa Frequency Band
//#define LORA_SF 7 // LoRa Spreading Factor
//#define LORA_TXPWR 17 // LoRa TX power in dBm (+2dBm - +20dBm), default is +17dBm. Lower power = less battery use
//#define LORA_ACK // Uncomment to enable request for LoRa ACKs at cost of increased battery usage
//#define LORA_ACK_TIMEOUT 400 // ms timeout waiting for LoRa ACKs (if enabled). Wouldn't go less than 200ms
//#define LORA_RETRIES 2 // [0 - 3] When ACK enabled, number of sensor node tx retries when ACK not received or invalid CRC

View File

@ -0,0 +1,113 @@
// FARM DATA RELAY SYSTEM
//
// LILYGO HIGROW SENSOR MODULE
//
#define I2C_SDA 25
#define I2C_SCL 26
#define DHT12_PIN 16
#define BAT_ADC 33
#define SALT_PIN 34
#define SOIL_PIN 32
#define BOOT_PIN 0
#define USER_BUTTON 35
#define DS18B20_PIN 21
#include "fdrs_sensor_config.h"
#include <fdrs_sensor.h>
#include <BH1750.h>
#include <Adafruit_BME280.h>
BH1750 lightMeter(0x23); //0x23
Adafruit_BME280 bmp; //0x77
RTC_DATA_ATTR int the_count = 0;
void setup() {
//Init Sensors
Wire.begin(I2C_SDA, I2C_SCL);
while (!bmp.begin()) {
//Serial.println("bmp");
delay(10);
}
if (lightMeter.begin(BH1750::CONTINUOUS_HIGH_RES_MODE)) {
Serial.println(F("BH1750 Advanced begin"));
} else {
Serial.println(F("Error initialising BH1750"));
}
}
void loadData() {
float s_battery = readBattery();
float bme_temp = bmp.readTemperature();
float bme_pressure = (bmp.readPressure() / 100.0F);
//float bme_altitude = bmp.readAltitude(1013.25);
float bme_humidity = bmp.readHumidity();
float s_soil = readSoil();
float s_salt = readSalt();
while (! lightMeter.measurementReady()) {
delay(10);
}
float lux = lightMeter.readLightLevel();
the_count++;
Serial.println();
Serial.println("Temp: " + String(bme_temp));
Serial.println("Humidity: " + String(bme_humidity));
Serial.println("Light: " + String(lux));
Serial.println("Pressure: " + String(bme_pressure));
Serial.println("Salt: " + String(s_salt));
Serial.println("Soil: " + String(s_soil));
Serial.println("Voltage: " + String(s_battery));
Serial.println("Count: " + String(the_count));
loadFDRS(bme_temp, TEMP_T);
loadFDRS(bme_humidity, HUMIDITY_T);
loadFDRS(lux, LIGHT_T);
loadFDRS(bme_pressure, PRESSURE_T);
loadFDRS(s_salt, SOILR_T);
loadFDRS(s_soil, SOIL_T);
loadFDRS(s_battery, VOLTAGE_T);
loadFDRS(float(the_count), IT_T);
}
uint32_t readSalt() //Soil Electrodes: This code came from the LilyGo documentation.
{
uint8_t samples = 120;
uint32_t humi = 0;
uint16_t array[120];
for (int i = 0; i < samples; i++) {
array[i] = analogRead(SALT_PIN);
delay(2);
}
std::sort(array, array + samples);
for (int i = 0; i < samples; i++) {
if (i == 0 || i == samples - 1)continue;
humi += array[i];
}
humi /= samples - 2;
return humi;
}
uint16_t readSoil() //Soil Capacitance: This code came from the LilyGo documentation.
{
uint16_t soil = analogRead(SOIL_PIN);
return map(soil, 0, 4095, 100, 0);
}
float readBattery() //Battery Voltage: This code came from the LilyGo documentation.
{
int vref = 1100;
uint16_t volt = analogRead(BAT_ADC);
float battery_voltage = ((float)volt / 4095.0) * 2.0 * 3.3 * (vref);
return battery_voltage;
}
void loop() {
}

View File

@ -0,0 +1,33 @@
// FARM DATA RELAY SYSTEM
//
// Sensor Configuration
#include <fdrs_globals.h>
#define READING_ID 1 //Unique ID for this sensor
#define GTWY_MAC 0x01 //Address of the nearest gateway
#define USE_ESPNOW
//#define USE_LORA
#define DEEP_SLEEP
//#define POWER_CTRL 14
#define FDRS_DEBUG
//SPI Configuration -- Needed only on chipsets with multiple SPI interfaces (ESP32)
#define SPI_SCK 5
#define SPI_MISO 19
#define SPI_MOSI 27
//LoRa Configuration
#define LORA_SS 18
#define LORA_RST 14
#define LORA_DIO0 26
//433E6 for Asia
//866E6 for Europe
//915E6 for North America
//#define LORA_BAND 915E6 // LoRa Frequency Band
//#define LORA_SF 7 // LoRa Spreading Factor
//#define LORA_TXPWR 17 // LoRa TX power in dBm (+2dBm - +20dBm), default is +17dBm. Lower power = less battery use
//#define LORA_ACK // Uncomment to enable request for LoRa ACKs at cost of increased battery usage
//#define LORA_ACK_TIMEOUT 400 // ms timeout waiting for LoRa ACKs (if enabled). Wouldn't go less than 200ms
//#define LORA_RETRIES 2 // [0 - 3] When ACK enabled, number of sensor node tx retries when ACK not received or invalid CRC

View File

@ -0,0 +1,45 @@
// FARM DATA RELAY SYSTEM
//
// Multifunction ESP8266 Sensor Board by Phil Grant
//
// https://github.com/gadjet/Multifunction-ESP8266-Sensor-board
//
#include "fdrs_sensor_config.h"
#include <Adafruit_AHT10.h>
#include <fdrs_sensor.h>
Adafruit_AHT10 aht;
const int reedSwitch = 13;
void setup() {
aht.begin();
// Init Serial Monitor
//Serial.begin(115200);
// initialize the reed switch pin as an input:
pinMode(reedSwitch, INPUT);
// initialize the wakeup pin as an input:
pinMode(16, WAKEUP_PULLUP);
beginFDRS();
}
void loop() {
sensors_event_t humidity, temp;
aht.getEvent(&humidity, &temp);// populate temp and humidity objects with fresh data
// Read the state of the reed switch and send open or closed
if (digitalRead(reedSwitch) == HIGH) {
loadFDRS(1.0, MOTION_T);
}
else {
loadFDRS(0.0, MOTION_T);
}
loadFDRS((analogRead(A0) * 4.2 * 10 / 1023), VOLTAGE_T);
loadFDRS(humidity.relative_humidity, HUMIDITY_T);
loadFDRS(temp.temperature, TEMP_T);
// Send message via FDRS
sendFDRS();
sleepFDRS(15); //15 Min's sleep
}

View File

@ -0,0 +1,33 @@
// FARM DATA RELAY SYSTEM
//
// Sensor Configuration
#include <fdrs_globals.h>
#define READING_ID 1 //Unique ID for this sensor
#define GTWY_MAC 0x01 //Address of the nearest gateway
#define USE_ESPNOW
//#define USE_LORA
#define DEEP_SLEEP
//#define POWER_CTRL 14
#define FDRS_DEBUG
//SPI Configuration -- Needed only on chipsets with multiple SPI interfaces (ESP32)
#define SPI_SCK 5
#define SPI_MISO 19
#define SPI_MOSI 27
//LoRa Configuration
#define LORA_SS 18
#define LORA_RST 14
#define LORA_DIO0 26
//433E6 for Asia
//866E6 for Europe
//915E6 for North America
//#define LORA_BAND 915E6 // LoRa Frequency Band
//#define LORA_SF 7 // LoRa Spreading Factor
//#define LORA_TXPWR 17 // LoRa TX power in dBm (+2dBm - +20dBm), default is +17dBm. Lower power = less battery use
//#define LORA_ACK // Uncomment to enable request for LoRa ACKs at cost of increased battery usage
//#define LORA_ACK_TIMEOUT 400 // ms timeout waiting for LoRa ACKs (if enabled). Wouldn't go less than 200ms
//#define LORA_RETRIES 2 // [0 - 3] When ACK enabled, number of sensor node tx retries when ACK not received or invalid CRC

View File

@ -0,0 +1,19 @@
# FDRS Sensors
| Sensor Name | Maker/Datasheet | Library |
| --- | --- | --- |
| AHT20 | [ASAIR](http://www.aosong.com/userfiles/files/media/Data%20Sheet%20AHT20.pdf) | [Adafruit](https://github.com/adafruit/Adafruit_AHTX0) |
| BME280 | [Bosch](https://www.bosch-sensortec.com/media/boschsensortec/downloads/datasheets/bst-bme280-ds002.pdf) | [Adafruit](https://github.com/adafruit/Adafruit_BME280_Library) |
| BMP280 | [Bosch](https://www.bosch-sensortec.com/media/boschsensortec/downloads/datasheets/bst-bmp280-ds001.pdf) | [Adafruit](https://github.com/adafruit/Adafruit_BMP280_Library) |
| DHT22 | [Aosong](https://www.sparkfun.com/datasheets/Sensors/Temperature/DHT22.pdf) |[adafruit](https://github.com/adafruit/DHT-sensor-library) |
| DS18B20 | [Dallas](https://datasheets.maximintegrated.com/en/ds/DS18B20.pdf) | [milesburton](https://github.com/adafruit/Adafruit_AHTX0) |
| LilyGo HiGrow | [TTGO](http://www.lilygo.cn/prod_view.aspx?TypeId=50033&Id=1172) |
| Multifunction ESP8266 Sensor Board | [Phil Grant](https://github.com/gadjet/Multifunction-ESP8266-Sensor-board) |
I would like to use this spot as a showcase for open source PCB designs. If **you** have designed a sensor module that runs on either ESP8266 or ESP32, please contact me at timmbogner@gmail.com. I will make a custom sensor sketch, along with a link and description available here.

View File

@ -0,0 +1,37 @@
// FARM DATA RELAY SYSTEM
//
// TIPPING BUCKET RAINFALL SENSOR MODULE
//
// Developed by Timm Bogner (timmbogner@gmail.com) in Urbana, Illinois, USA.
#define REED_PIN 2
#include "fdrs_sensor_config.h"
#include <fdrs_sensor.h>
unsigned int theCount = 0;
unsigned long lastTrigger = 0;
boolean clicked = false;
ICACHE_RAM_ATTR void detectsMovement() {
clicked = true;
lastTrigger = millis();
}
void setup() {
beginFDRS();
pinMode(REED_PIN, INPUT_PULLUP);
attachInterrupt(digitalPinToInterrupt(REED_PIN), detectsMovement, FALLING);
}
void loop() {
if (clicked && millis() - lastTrigger > 100) {
theCount++;
Serial.print("DINK.");
Serial.println(theCount);
clicked = false;
loadFDRS(theCount, RAINFALL_T);
sendFDRS();
}
}

View File

@ -0,0 +1,33 @@
// FARM DATA RELAY SYSTEM
//
// Sensor Configuration
#include <fdrs_globals.h>
#define READING_ID 1 //Unique ID for this sensor
#define GTWY_MAC 0x01 //Address of the nearest gateway
#define USE_ESPNOW
//#define USE_LORA
#define DEEP_SLEEP
//#define POWER_CTRL 14
#define FDRS_DEBUG
//SPI Configuration -- Needed only on chipsets with multiple SPI interfaces (ESP32)
#define SPI_SCK 5
#define SPI_MISO 19
#define SPI_MOSI 27
//LoRa Configuration
#define LORA_SS 18
#define LORA_RST 14
#define LORA_DIO0 26
//433E6 for Asia
//866E6 for Europe
//915E6 for North America
//#define LORA_BAND 915E6 // LoRa Frequency Band
//#define LORA_SF 7 // LoRa Spreading Factor
//#define LORA_TXPWR 17 // LoRa TX power in dBm (+2dBm - +20dBm), default is +17dBm. Lower power = less battery use
//#define LORA_ACK // Uncomment to enable request for LoRa ACKs at cost of increased battery usage
//#define LORA_ACK_TIMEOUT 400 // ms timeout waiting for LoRa ACKs (if enabled). Wouldn't go less than 200ms
//#define LORA_RETRIES 2 // [0 - 3] When ACK enabled, number of sensor node tx retries when ACK not received or invalid CRC

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

68
extras/SENSORS.md Normal file
View File

@ -0,0 +1,68 @@
# Sensor 2.000
This file is an example of how to set up a sensor using FDRS.
## Commands
### ``` beginFDRS();```
Initializes FDRS, powers up the sensor array, and begins ESP-NOW and/or LoRa.
### ```loadFDRS(float d, uint8_t t);```
Loads some data into the current packet. 'd' is a float and 't' is a byte used to represent the sensor type. Type definitions can be found below. Please feel free to contact me if you'd like to add a new sensor type.
### ```sendFDRS();```
Sends the current packet using ESP-NOW and/or LoRa.
### ``` sleepFDRS(int sleep_time)```
If available and enabled, the device enters deep-sleep. If ```#DEEP_SLEEP``` is disabled, the device will use a delay instead. ```int sleep_time``` is entered in seconds.
## Options
### ```#define READING_ID n```
The identifier of this individual device. Should be a 16 bit integer value (0 - 65535).
### ```#define GTWY_MAC 0xnn```
The UNIT_MAC of the gateway that this device will send its data to.
### ```#define FDRS_DEBUG```
This definition enables debug messages to be sent over the serial port. If disabled, no serial interface will be initialized.
### ```#define USE_ESPNOW```
Enables/disables ESP-NOW.
### ```#define USE_LORA```
Enables/disables LoRa.
### ```#define DEEP_SLEEP```
If enabled, device will enter deep-sleep when the sleepFDRS() command is used. If using ESP8266, be sure that you connect the WAKE pin (GPIO 16) to RST or your device will not wake up.
### ```#define POWER_CTRL (pin)```
IF defined, power control will bring a GPIO pin high within beginFDRS(). This is useful for powering sensors while running on battery.
## Type Definitions
For the moment, my thought is to reserve the first two bits of the type. I might use them in the future to indicate the data size or type (bool, char, int, float, etc?). This leaves us with 64 possible type definitions. If you have more types to add, please get in touch!
```
#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 LATITUDE_T 21 // GPS Latitude
#define LONGITUDE_T 22 // GPS Longitude
#define ALTITUDE_T 23 // GPS Altitude
```
## Under the hood
```
typedef struct __attribute__((packed)) DataReading {
float d;
uint16_t id;
uint8_t t;
} DataReading;
```
Each sensor in the system sends its data over ESP-NOW or LoRa as a float 'd' inside of a structure called a DataReading. Its global sensor address is represented by an integer 'id', and each type of reading is represented by a single byte 't'. If a sensor or gateway needs to send multiple DataReadings, then they are sent in an array. A single DataReading.id may have readings of multiple types ('t') associated with it.