Created
October 30, 2022 18:33
-
-
Save Xitee1/5ede55927c9a37c06dc6015e38e46d51 to your computer and use it in GitHub Desktop.
This is a modified version of https://tutorials-raspberrypi.de/esp8266-regensensor-selber-bauen-wie-viel-pro-qm/ . I made lots of changes and made the code a bit cleaner looking (at least for me it is). Some main features are WiFi sleep to reduce power consumption, INBUILT_LED blinking on detections and overall a few "improvements".
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <ESP8266WiFi.h> | |
#include <PubSubClient.h> | |
#include <ArduinoJson.h> | |
// WiFi | |
#define WIFI_AP "WiFi SSID" | |
#define WIFI_PASSWORD "Password" | |
// MQTT | |
#define MQTT_SERVER "192.168.x.x" // MQTT Server IP (e.g. the IP of HA) | |
#define MQTT_USER "mqtt" // MQTT username | |
#define MQTT_PASSWORD "password" | |
#define MQTT_CLIENT "Regensensor1" // Device name | |
#define MQTT_TOPIC "esp/sensor/regen" // Topic | |
int triggerPin = 16; // The stick reading about it tipped. | |
int totalCount = 0; // a simple calculator that adds how many tipping it has done since its start. | |
const char* mmPerSquareMeter = "0.094175";// 1.25 ml per dipper change, 94.175 ml per m^2 (=1.25*75.34), = 0.094175mm/m^2 | |
// diameter of raingauge is about 130mm, r = 65mm, surface = pi*r^2 = 132.73 cm^2 | |
// therefore per m^2 (=10000cm^2) we have a factor of about 75.34 | |
WiFiClient espClient; | |
PubSubClient client(espClient); | |
void setup() { | |
// Outcomment for debugging | |
Serial.begin(115200); | |
pinMode(LED_BUILTIN, OUTPUT); | |
pinMode(triggerPin, INPUT); | |
digitalWrite(LED_BUILTIN, LOW); | |
connectWiFi(); | |
connectMQTT(); | |
digitalWrite(LED_BUILTIN, HIGH); | |
} | |
int lastState = 0; // The last reading | |
// Timers | |
unsigned long wifiEnergySave = 0; | |
void loop() { | |
int currentState = digitalRead(triggerPin); | |
// Checks whether the previous loop has the same loop as the current loop. Will not go into this first loop. | |
if(currentState == 0) { | |
digitalWrite(LED_BUILTIN, LOW); | |
wifiEnergySave = millis(); // Reset WiFi energy save | |
totalCount++; // Count the detections | |
delay(50); // Little delay in case that WiFi was put in sleep in the last loop (insanely rare I think, but just in case) | |
// Wake WiFi from sleep (if not already connected) | |
if(WiFi.status() != WL_CONNECTED) { | |
WiFi.mode(WIFI_STA); | |
connectWiFi(); | |
connectMQTT(); | |
} | |
// Generate Json | |
StaticJsonDocument<128> doc; | |
doc["name"] = "Regensensor 1"; | |
doc["count_since_boot"] = totalCount; | |
// Check if state is not last state | |
// If it is, the "wipper?" likely hangs somewhere in the middle | |
if(currentState == lastState) { | |
doc["mm"] = 0.0; | |
doc["error"] = "1"; | |
} else { | |
doc["mm"] = mmPerSquareMeter; | |
doc["error"] = "0"; | |
} | |
char JSONmessageBuffer[128]; | |
serializeJson(doc, JSONmessageBuffer); | |
// Send data | |
if(client.publish(MQTT_TOPIC, JSONmessageBuffer)) { | |
Serial.println("Sent data!"); | |
}else{ | |
Serial.println("Failed to send data!"); | |
} | |
digitalWrite(LED_BUILTIN, HIGH); | |
delay(1000); // Only allow one change per second in case it changes 2 times really quickly | |
} | |
lastState = currentState; | |
/* | |
* Set WiFi to sleep after 30 minutes of no detections | |
* This reduces the power consumption nearly 4 times (700mA to 200mA) on the Wemos D1 mini | |
* | |
* Why only after 15 minutes? | |
* The WiFi takes a few seconds to reconnect. In a heavy rain, it would have to | |
* disconnect and reconnect really often (maybe even scipping a detection while connecting). | |
* With the delay, in a heavy rain it will not disconnect. | |
* | |
*/ | |
if((millis() - wifiEnergySave) > 1000 * 60 * 15) { | |
if(WiFi.status() == WL_CONNECTED) { | |
client.disconnect(); | |
WiFi.mode(WIFI_OFF); | |
WiFi.forceSleepBegin(); | |
Serial.println("Put WiFi to sleep"); | |
} | |
} | |
// Make sure that MQTT stays conencted | |
if(client.connected()) { | |
client.loop(); | |
} | |
} | |
// WiFi and MQTT stuff | |
void connectWiFi() { | |
delay(10); | |
Serial.println(); | |
Serial.print("Connecting to "); | |
Serial.println(WIFI_AP); | |
WiFi.begin(WIFI_AP, WIFI_PASSWORD); | |
while(WiFi.status() != WL_CONNECTED) { | |
delay(500); | |
Serial.print("."); | |
} | |
Serial.println(""); | |
Serial.println("WiFi connected"); | |
Serial.println("IP address: "); | |
Serial.println(WiFi.localIP()); | |
} | |
void connectMQTT() { | |
// Loop until we're reconnected | |
while (!client.connected()) { | |
Serial.print("Attempting MQTT connection..."); | |
client.setServer(MQTT_SERVER, 1883); | |
// Attempt to connect | |
// If you do not want to use a username and password, change next line to | |
//if (client.connect(MQTT_CLIENT_NAME)) { | |
if (client.connect(MQTT_CLIENT, MQTT_USER, MQTT_PASSWORD)) { | |
Serial.println("connected"); | |
} else { | |
Serial.print("failed, rc="); | |
Serial.print(client.state()); | |
Serial.println(" try again in 5 seconds"); | |
// Wait 5 seconds before retrying | |
delay(5000); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment