From 97bb091ae5bcf0951a817debb7a4f03a4f52eeb5 Mon Sep 17 00:00:00 2001 From: Stefan Ostermann Date: Sun, 11 Apr 2021 00:05:40 +0200 Subject: [PATCH] esp8266 only, mqtt added --- esp-receiver/platformio.ini | 11 +- esp-receiver/src/main.cpp | 295 +++++++++++++++++++++++++++++------- 2 files changed, 243 insertions(+), 63 deletions(-) diff --git a/esp-receiver/platformio.ini b/esp-receiver/platformio.ini index d9b39dd..380e7a5 100644 --- a/esp-receiver/platformio.ini +++ b/esp-receiver/platformio.ini @@ -15,13 +15,8 @@ framework = arduino monitor_speed = 9600 lib_deps = mikem/RadioHead@^1.113 - ;tzapu/WiFiManager@^0.16.0 + tzapu/WiFiManager@^0.16.0 + knolleary/PubSubClient@^2.8 + bblanchon/ArduinoJson@^6.17.3 build_flags = -D USE_ESPRESSIF -[env:nanoatmega328] -platform = atmelavr -board = nanoatmega328 -framework = arduino -monitor_speed = 9600 -lib_deps = mikem/RadioHead@^1.113 -build_flags = -D USE_ARDUINO \ No newline at end of file diff --git a/esp-receiver/src/main.cpp b/esp-receiver/src/main.cpp index d5d05be..623daad 100644 --- a/esp-receiver/src/main.cpp +++ b/esp-receiver/src/main.cpp @@ -1,13 +1,20 @@ #include #include +#include //https://github.com/esp8266/Arduino +#include +#include +#include "WiFiManager.h" //https://github.com/tzapu/WiFiManager + +#include //MQTT +#include + /** * Baud Rate for the 433 Mhz connection. * Caution: Must be the same for sender & receiver! **/ #define RH_SPEED 1000 - /** * Pin for the receiver **/ @@ -25,15 +32,16 @@ uint8_t rh_buf[RH_BUF_LEN]; const int AirValue = 800; //replace the value with value when placed in air const int WaterValue = 345; //replace the value with value when placed in water +const char *MQTT_BROKER = "192.168.178.74"; +const char *MQTT_SENSOR_TOPIC = "living/sensor2"; +const char *MQTT_CLIENT_ID = "living_mobile_sensor"; +ESP8266WebServer server(80); +WiFiClient espClient; +PubSubClient mqttClient(MQTT_BROKER, 1883, espClient); RH_ASK driver(RH_SPEED, RH_RX_PIN); -float t = 0; -float h = 0; -long bat = 0; -int soil = 0; - /** * Message identifier constants: * */ @@ -44,61 +52,238 @@ int soil = 0; #define MSG_SOIL 0x04 #define MSG_ERR 0xee -void setup() { +char buff[20]; + +float Temperature = 0; +float Humidity = 0; +int soil = 0; +float SoilHumidity = 0; +long battery = 0; + +long lastMillis = 0; + +void handleRoot(); // function prototypes for HTTP handlers +void handleNotFound(); +void reconnect(); +String SendHTML(float Temperaturestat, float Humiditystat); +void publishData(float temp, float humid, float soil); +void callback(char *inTopic, byte *payload, unsigned int length); + +void configModeCallback(WiFiManager *myWiFiManager) +{ + Serial.println("Entered config mode"); + Serial.println(WiFi.softAPIP()); + //if you used auto generated SSID, print it + Serial.println(myWiFiManager->getConfigPortalSSID()); +} + +void setup() +{ Serial.begin(9600); - if (!driver.init()) { + if (!driver.init()) + { Serial.println("init failed"); - } else { + } + else + { Serial.println("init done"); } + + //WiFiManager + //Local intialization. Once its business is done, there is no need to keep it around + WiFiManager wifiManager; + //reset settings - for testing + //wifiManager.resetSettings(); + + //set callback that gets called when connecting to previous WiFi fails, and enters Access Point mode + wifiManager.setAPCallback(configModeCallback); + + //fetches ssid and pass and tries to connect + //if it does not connect it starts an access point with the specified name + //here "AutoConnectAP" + //and goes into a blocking loop awaiting configuration + if (!wifiManager.autoConnect()) + { + Serial.println("failed to connect and hit timeout"); + //reset and try again, or maybe put it to deep sleep + ESP.reset(); + delay(1000); + } + + //if you get here you have connected to the WiFi + Serial.println("connected...yeey :)"); + + mqttClient.setCallback(callback); + + server.on("/", handleRoot); + server.onNotFound(handleNotFound); + + server.begin(); + Serial.println("HTTP server started"); +} + +void loop() +{ + + uint8_t len = sizeof(rh_buf); + + long ms = millis(); + + if (driver.recv(rh_buf, &len)) + { + switch (rh_buf[0]) + { + case MSG_START: + // start message + Serial.println("0x00 start byte"); + break; + case MSG_TEMP: + // DHT Temperature + Serial.println("0x01 DHT Temp"); + memcpy(&Temperature, &rh_buf[1], 4); + Serial.print(Temperature); + Serial.println(" °C"); + break; + case MSG_HUMID: + // DHT Humidity: + Serial.println("0x02 DHT Humidity"); + memcpy(&Humidity, &rh_buf[1], 4); + Serial.print(Humidity); + Serial.println(" %"); + break; + case MSG_SOIL: + // Soil Humidity: + Serial.println("0x04 Soil Humidity"); + + memcpy(&soil, &rh_buf[1], 2); + Serial.println(soil); + SoilHumidity = (float)(map(soil, AirValue, WaterValue, 0, 100)); + Serial.println(SoilHumidity); + break; + case MSG_BAT: + // battery data + Serial.println("0x03 Battery"); + memcpy(&battery, &rh_buf[1], 4); + Serial.print(battery); + Serial.println(" mV"); + break; + case MSG_ERR: + // error + Serial.println("0xEE error"); + break; + default: + // should never happen + break; + } + } + + server.handleClient(); + if (!mqttClient.connected()) + { + reconnect(); + } + + if (ms - lastMillis > 5000 && Temperature != 0.0 && Humidity != 0.0 && SoilHumidity != 0.0) + { + publishData(Temperature, Humidity,SoilHumidity); + lastMillis = ms; + } + + mqttClient.loop(); +} + +void reconnect() +{ + // Loop until we're reconnected + while (!mqttClient.connected()) + { + Serial.println("INFO: Attempting MQTT connection..."); + // Attempt to connect + if (mqttClient.connect(MQTT_CLIENT_ID)) + { + Serial.println("INFO: connected"); + } + else + { + Serial.print("ERROR: failed, rc="); + Serial.print(mqttClient.state()); + Serial.println("DEBUG: try again in 5 seconds"); + // Wait 5 seconds before retrying + //delay(5000); + return; + } + } } -void loop() { +void callback(char *inTopic, byte *payload, unsigned int length) +{ + Serial.println("Got RF data"); + Serial.write(payload, length); + Serial.println(); - uint8_t len = sizeof(rh_buf); - if (driver.recv(rh_buf, &len)) { - switch (rh_buf[0]) { - case MSG_START: - // start message - Serial.println("0x00 start byte"); - break; - case MSG_TEMP: - // DHT Temperature - Serial.println("0x01 DHT Temp"); - memcpy(&t, &rh_buf[1], 4); - Serial.print(t); - Serial.println(" °C"); - break; - case MSG_HUMID: - // DHT Humidity: - Serial.println("0x02 DHT Humidity"); - memcpy(&t, &rh_buf[1], 4); - Serial.print(t); - Serial.println(" %"); - break; - case MSG_SOIL: - // Soil Humidity: - Serial.println("0x04 Soil Humidity"); - - memcpy(&soil, &rh_buf[1], 2); - Serial.println(soil); - Serial.println(map(soil, AirValue, WaterValue, 0, 100)); - break; - case MSG_BAT: - // battery data - Serial.println("0x03 Battery"); - memcpy(&bat, &rh_buf[1], 4); - Serial.print(bat); - Serial.println(" mV"); - break; - case MSG_ERR: - // error - Serial.println("0xEE error"); - break; - default: - // should never happen - break; - } - } + // convert the byte non terminated payload to string: + char pltext[length + 1]; + strncpy(pltext, (char *)payload, length); + pltext[length] = '\0'; + // convert payload string to int: + int num = atoi(pltext); + Serial.println(pltext); + Serial.println("RF data sent"); +} + +void handleRoot() +{ + server.send(200, "text/html", SendHTML(Temperature, Humidity)); +} + +void handleNotFound() +{ + server.send(404, "text/plain", "Not found"); +} + +// function called to publish the temperature and the humidity +void publishData(float temp, float humid, float soil) +{ + // create a JSON object + // doc : https://github.com/bblanchon/ArduinoJson/wiki/API%20Reference + DynamicJsonDocument doc(1024); + + doc["temperature"] = (String)temp; + doc["humidity"] = (String)humid; + doc["soilhumidity"] = (String)soil; + serializeJson(doc, Serial); + Serial.println(""); + char data[200]; + serializeJson(doc, data); + mqttClient.publish(MQTT_SENSOR_TOPIC, data, true); + yield(); +} + +String SendHTML(float Temperaturestat, float Humiditystat) +{ + String ptr = " \n"; + ptr += "\n"; + ptr += "Wiesendamm Wetter Report\n"; + ptr += ""; + ptr += "\n"; + ptr += "\n"; + ptr += "\n"; + ptr += "
\n"; + ptr += "

Wiesendamm Wetter Report

\n"; + + ptr += "

Temperature: "; + ptr += (float)Temperaturestat; + ptr += " C

"; + ptr += "

Humidity: "; + ptr += (float)Humiditystat; + ptr += " %

"; + + ptr += "
\n"; + ptr += "\n"; + ptr += "\n"; + return ptr; } \ No newline at end of file