diff --git a/espsens/espsens.ino b/espsens/espsens.ino index 10aa0c8..6096e95 100644 --- a/espsens/espsens.ino +++ b/espsens/espsens.ino @@ -13,39 +13,18 @@ #include #include "DHT.h" #include "configuration.h" +#include "sensing.h" -#define TOPIC_BASE "sensor/" SENSOR_ID "/" -#define TOPIC_TEMP TOPIC_BASE "temperature" -#define TOPIC_HMID TOPIC_BASE "humidity" -#define TOPIC_ABHU TOPIC_BASE "abs_humidity" -#define TOPIC_HEAT TOPIC_BASE "heat_index" +WiFiClient espClient; +PubSubClient client(espClient); -#define DIFF_TEMP 0.3 // sensor has only 0.5°C accuracy, triggering on less is ludicrous -#define DIFF_HMID 1.5 // humidity doesn't change that much anyways -#define DIFF_ABHU 0.4 // small changes mean quite something -#define DIFF_HEAT 0.4 // this one's actually quite active - -struct Sensor { - String desc; // sensor description - char* topic; // sensor topic - float diff; // value difference for an update - float value; // current values - float lastValue; // value at last update - int lastUpdate; // number of samples since last update -}; +DHT dht(DHTPIN, DHTTYPE); Sensor temp = {"temperature (°C)", TOPIC_TEMP, DIFF_TEMP, 0.0, 0.0, -1}; // temperature Sensor hmid = {"humidity (%)", TOPIC_HMID, DIFF_HMID, 0.0, 0.0, -1}; // humidity Sensor abhu = {"absolute humidity (gr/m³)", TOPIC_ABHU, DIFF_ABHU, 0.0, 0.0, -1}; // absolute humidity Sensor heat = {"heat index (°C)", TOPIC_HEAT, DIFF_HEAT, 0.0, 0.0, -1}; // heat index -#define DHTPIN 4 // Digital pin connected to the DHT sensor -#define DHTTYPE DHT22 // DHT 22 (AM2302), AM2321 -DHT dht(DHTPIN, DHTTYPE); - -WiFiClient espClient; -PubSubClient client(espClient); - void setup() { Serial.begin(SERIAL_BAUDRATE); pinMode(LED_BUILTIN, OUTPUT); @@ -55,106 +34,11 @@ void setup() { dht.begin(); } -void setup_wifi() { - delay(10); - // Connect to a WiFi network - Serial.println(); - Serial.print("Connecting to "); - Serial.println(WIFI_SSID); - - WiFi.begin(WIFI_SSID, WIFI_PW); - WiFi.mode(WIFI_STA); - - // blink LED fast until WiFi is connected - while (WiFi.status() != WL_CONNECTED) { - delay(200); - digitalWrite(LED_BUILTIN, HIGH); - Serial.print("."); - delay(200); - digitalWrite(LED_BUILTIN, LOW); - } - - // WiFi connected - Serial.println(""); - Serial.println("WiFi connected"); - Serial.println("IP address: "); - Serial.println(WiFi.localIP()); -} - -void reconnect() { - // Loop until reconnected - while (!client.connected()) { - Serial.print("Attempting MQTT connection..."); - // Attempt to connect - if (client.connect(MQTT_CLIENT, MQTT_USER, MQTT_PW)) { - Serial.println("connected"); - } else { - Serial.print("failed, rc="); - Serial.print(client.state()); - Serial.println(" try again in 5 seconds"); - digitalWrite(LED_BUILTIN, HIGH); - // Wait 5 seconds before retrying - delay(4000); - digitalWrite(LED_BUILTIN, LOW); - delay(1000); - } - } -} - -bool checkVariation(float newValue, float prevValue, float maxDiff) { - return !isnan(newValue) && - (newValue < prevValue - maxDiff || newValue > prevValue + maxDiff); -} - -bool checkPlausibility(float newValue, float prevValue, float maxDiff) { - return (newValue < prevValue + (maxDiff * 10) || newValue > prevValue - (maxDiff * 10)); -} - long lastMsg = 0; -void publish (Sensor &sensor){ - bool force = false; - Serial.print("Sample " + sensor.desc + " : "); - Serial.print(String(sensor.value).c_str()); - Serial.print(" last : "); - Serial.print(String(sensor.lastValue).c_str()); - Serial.print(" samples since last update : "); - Serial.println(String(sensor.lastUpdate).c_str()); - - // check if first sample, set lastValue and return - if (sensor.lastUpdate == -1){ - sensor.lastValue = sensor.value; - sensor.lastUpdate = 0; - return; - } - - // force an update if the number of samples without update is exceeded - force = sensor.lastUpdate >= FORCE_PERIOD; - if (force) { - Serial.println(" * Forcing publication if sensor value is plausible"); - } - - // update the sample counter, will be reset if sample is published - sensor.lastUpdate += 1; - - // check if there was sufficient variation on the signal and if the value is plausible - if (checkVariation(sensor.value, sensor.lastValue, sensor.diff) or force) { - Serial.println(" Sufficient variation on " + sensor.desc + ": " + String(sensor.value).c_str()); - if (checkPlausibility(sensor.value, sensor.lastValue, sensor.diff)) { - Serial.println(" Value published"); - client.publish(sensor.topic, String(sensor.value).c_str(), true); - sensor.lastUpdate = 0; - } else { - Serial.print(" ** ERROR: Value out of bounds, not published. Last value :"); - Serial.println(String(sensor.lastValue).c_str()); - } - sensor.lastValue = sensor.value; - } -} - void loop() { if (!client.connected()) { - reconnect(); + reconnect(client); } client.loop(); digitalWrite(LED_BUILTIN, HIGH); @@ -175,10 +59,10 @@ void loop() { heat.value = dht.computeHeatIndex(temp.value, hmid.value, false); } - publish(temp); - publish(hmid); - publish(heat); - publish(abhu); + publishSensor(client, temp); + publishSensor(client, hmid); + publishSensor(client, heat); + publishSensor(client, abhu); } } diff --git a/espsens/sensing.cpp b/espsens/sensing.cpp new file mode 100644 index 0000000..066c926 --- /dev/null +++ b/espsens/sensing.cpp @@ -0,0 +1,110 @@ +/* ESP8266 environmental sensor project + + This file provides functions for all the sensor publication used in espsens and envisens. + + (C) 2019 Macrocell - Environmental sensing solutions + proudly presented by Macrocell - FPGA Innovators +*/ + +#include +#include "Arduino.h" +#include +#include + +#include "configuration.h" +#include "sensing.h" + +void setup_wifi() { + delay(10); + // Connect to a WiFi network + Serial.println(); + Serial.print("Connecting to "); + Serial.println(WIFI_SSID); + + WiFi.begin(WIFI_SSID, WIFI_PW); + WiFi.mode(WIFI_STA); + + // blink LED fast until WiFi is connected + while (WiFi.status() != WL_CONNECTED) { + delay(200); + digitalWrite(LED_BUILTIN, HIGH); + Serial.print("."); + delay(200); + digitalWrite(LED_BUILTIN, LOW); + } + + // WiFi connected + Serial.println(""); + Serial.println("WiFi connected"); + Serial.println("IP address: "); + Serial.println(WiFi.localIP()); +} + +void reconnect(PubSubClient client) { + // Loop until reconnected + while (!client.connected()) { + Serial.print("Attempting MQTT connection..."); + // Attempt to connect + if (client.connect(MQTT_CLIENT, MQTT_USER, MQTT_PW)) { + Serial.println("connected"); + } else { + Serial.print("failed, rc="); + Serial.print(client.state()); + Serial.println(" try again in 5 seconds"); + digitalWrite(LED_BUILTIN, HIGH); + // Wait 5 seconds before retrying + delay(4000); + digitalWrite(LED_BUILTIN, LOW); + delay(1000); + } + } +} + +bool checkVariation(float newValue, float prevValue, float maxDiff) { + return !isnan(newValue) && + (newValue < prevValue - maxDiff || newValue > prevValue + maxDiff); +} + +bool checkPlausibility(float newValue, float prevValue, float maxDiff) { + return (newValue < prevValue + (maxDiff * 10) || newValue > prevValue - (maxDiff * 10)); +} + +void publishSensor (PubSubClient &client, Sensor &sensor){ + bool force = false; + Serial.print("Sample " + sensor.desc + " : "); + Serial.print(String(sensor.value).c_str()); + Serial.print(" last : "); + Serial.print(String(sensor.lastValue).c_str()); + Serial.print(" samples since last update : "); + Serial.println(String(sensor.lastUpdate).c_str()); + + // check if first sample, set lastValue and return + if (sensor.lastUpdate == -1){ + sensor.lastValue = sensor.value; + sensor.lastUpdate = 0; + return; + } + + // force an update if the number of samples without update is exceeded + force = sensor.lastUpdate >= FORCE_PERIOD; + if (force) { + Serial.println(" * Forcing publication if sensor value is plausible"); + } + + // update the sample counter, will be reset if sample is published + sensor.lastUpdate += 1; + + // check if there was sufficient variation on the signal and if the value is plausible + if (checkVariation(sensor.value, sensor.lastValue, sensor.diff) or force) { + Serial.println(" Sufficient variation on " + sensor.desc + ": " + String(sensor.value).c_str()); + if (checkPlausibility(sensor.value, sensor.lastValue, sensor.diff)) { + Serial.println(" Value published"); + client.publish(sensor.topic, String(sensor.value).c_str(), true); + sensor.lastUpdate = 0; + } else { + Serial.print(" ** ERROR: Value out of bounds, not published. Last value :"); + Serial.println(String(sensor.lastValue).c_str()); + } + sensor.lastValue = sensor.value; + } +} diff --git a/espsens/sensing.h b/espsens/sensing.h new file mode 100644 index 0000000..9e56069 --- /dev/null +++ b/espsens/sensing.h @@ -0,0 +1,33 @@ +/* ESP8266 environmental sensor project + + This file provides functions for all the sensor publication used in espsens and envisens. + + (C) 2019 Macrocell - Environmental sensing solutions + proudly presented by Macrocell - FPGA Innovators +*/ +#define TOPIC_BASE "sensor/" SENSOR_ID "/" +#define TOPIC_TEMP TOPIC_BASE "temperature" +#define TOPIC_HMID TOPIC_BASE "humidity" +#define TOPIC_ABHU TOPIC_BASE "abs_humidity" +#define TOPIC_HEAT TOPIC_BASE "heat_index" + +#define DIFF_TEMP 0.3 // sensor has only 0.5°C accuracy, triggering on less is ludicrous +#define DIFF_HMID 1.5 // humidity doesn't change that much anyways +#define DIFF_ABHU 0.4 // small changes mean quite something +#define DIFF_HEAT 0.4 // this one's actually quite active + +#define DHTPIN 4 // Digital pin connected to the DHT sensor +#define DHTTYPE DHT22 // DHT 22 (AM2302), AM2321 + +struct Sensor { + String desc; // sensor description + char* topic; // sensor topic + float diff; // value difference for an update + float value; // current values + float lastValue; // value at last update + int lastUpdate; // number of samples since last update +}; + +void setup_wifi(); +void reconnect(PubSubClient client); +void publishSensor (PubSubClient &client, Sensor &sensor);