From 5cf3b542712c253532741b0f51435232849354b9 Mon Sep 17 00:00:00 2001 From: Ronald Schaten Date: Tue, 23 Feb 2016 11:12:04 +0100 Subject: [PATCH] initial commit, basic functionality --- thing.ino | 283 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 283 insertions(+) create mode 100644 thing.ino diff --git a/thing.ino b/thing.ino new file mode 100644 index 0000000..69322aa --- /dev/null +++ b/thing.ino @@ -0,0 +1,283 @@ +// based on example code from the used libraries + +extern "C" { + #include +} +#include // https://github.com/esp8266/Arduino +#include +#include // https://github.com/tzapu/WiFiManager +#include +#include +#include // https://github.com/knolleary/pubsubclient +#include // https://github.com/adafruit/DHT-sensor-library + +// configure DHT sensor +#define DHTPIN D4 // what pin the DHT is connected to +//#define DHTTYPE DHT11 // DHT11 +//#define DHTTYPE DHT21 // DHT21 (AM2301) +#define DHTTYPE DHT22 // DHT22 (AM2302) + +const char* mqtt_server = "192.168.0.66"; + +// initialize modules +ESP8266WebServer server(80); // webserver +DHT dht(DHTPIN, DHTTYPE); // DHT sensor +Ticker ticker; // LED status + +WiFiClient wifiClient; +PubSubClient client(wifiClient); + +float humidity, temperature; // raw values from the sensor +float heatindex; // computed value from the sensor +char str_humidity[10], str_temperature[10]; // rounded values as strings +char str_heatindex[10]; // rounded value as string +unsigned long previousMillis = 0; // last sensor read +const long interval = 2000; // interval between readings + +long lastMsg = 0; + +// toggle LED state +void toggle_led() { + int state = digitalRead(BUILTIN_LED); // get the current state LED + digitalWrite(BUILTIN_LED, !state); // set the opposite state +} + +// gets called when WiFiManager enters configuration mode +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()); + //entered config mode, make led toggle faster + ticker.attach(0.1, toggle_led); +} + +void read_sensor() { + // wait at least 2 seconds seconds between measurements + unsigned long currentMillis = millis(); + + if (currentMillis - previousMillis >= interval) { + previousMillis = currentMillis; + float previousHumidity = humidity; + float previousTemperature = temperature; + float previousHeatindex = heatindex; + humidity = dht.readHumidity(); // read humidity as a percent + temperature = dht.readTemperature(); // read temperature as Celsius + + // compute heat index + heatindex = dht.computeHeatIndex(temperature, humidity, false); + + // check if any reads failed and exit early (to try again) + if (isnan(humidity) || isnan(temperature)) { + Serial.println("Failed to read from DHT sensor!"); + return; + } + + // convert the floats to strings and round to 2 decimal places + dtostrf(humidity, 1, 2, str_humidity); + dtostrf(temperature, 1, 2, str_temperature); + dtostrf(heatindex, 1, 2, str_heatindex); + + if (humidity != previousHumidity) { + client.publish("nodemcu/humidity", str_humidity); + } + if (temperature != previousTemperature) { + client.publish("nodemcu/temperature", str_temperature); + } + if (heatindex != previousHeatindex) { + client.publish("nodemcu/heatindex", str_heatindex); + } + + Serial.print("Humidity: "); + Serial.print(str_humidity); + Serial.print(" %\t"); + Serial.print("Temperature: "); + Serial.print(str_temperature); + Serial.print(" °C\t"); + Serial.print("Heat Index: "); + Serial.print(str_heatindex); + Serial.println(" °C"); + } +} + +void callback(char* topic, byte* payload, unsigned int length) { + Serial.print("Message arrived ["); + Serial.print(topic); + Serial.print("] "); + for (int i = 0; i < length; i++) { + Serial.print((char)payload[i]); + } + Serial.println(); + + // Switch on the LED if an 1 was received as first character + if ((char)payload[0] == '1') { + Serial.println("setting LED to low"); + digitalWrite(BUILTIN_LED, LOW); // Turn the LED on (Note that LOW is the voltage level + // but actually the LED is on; this is because + // it is acive low on the ESP-01) + } else { + Serial.println("setting LED to high"); + digitalWrite(BUILTIN_LED, HIGH); // Turn the LED off by making the voltage HIGH + } +} + +void reconnect() { + // Loop until we're reconnected + while (!client.connected()) { + Serial.print("Attempting MQTT connection..."); + // Attempt to connect + if (client.connect(wifi_station_get_hostname(), "nodemcu/online", MQTTQOS1, true, "0")) { + Serial.println("connected"); + // Once connected, publish an announcement... + client.publish("nodemcu/online", "1"); + // ... and resubscribe: + client.subscribe("inTopic"); + } else { + Serial.print("failed, rc="); + Serial.print(client.state()); + Serial.println(" try again in 5 seconds"); + // Wait 5 seconds before retrying + delay(5000); + } + } +} + +void setup() { + // put your setup code here, to run once: + Serial.begin(9600); + + //set led pin as output + pinMode(BUILTIN_LED, OUTPUT); + // start ticker with 0.5 because we start in AP mode and try to connect + ticker.attach(0.6, toggle_led); + + //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 :)"); + ticker.detach(); + //keep LED on + digitalWrite(BUILTIN_LED, LOW); + + client.setServer(mqtt_server, 1883); + client.setCallback(callback); + + dht.begin(); + + // Initial read + read_sensor(); + client.publish("nodemcu/humidity", str_humidity); + client.publish("nodemcu/temperature", str_temperature); + client.publish("nodemcu/heatindex", str_heatindex); + + // Handle http requests + server.on("/", [](){ + read_sensor(); + String response = "\r\n"; + response += "\r\n"; + response += "\r\n"; + response += "\r\n"; + response += "\r\n"; + response += "Status\r\n"; + response += "\r\n"; + response += "\r\n"; + response += "\r\n"; + response += "
\r\n"; + response += "

"; + response += wifi_station_get_hostname(); + response += "

\r\n"; + response += "

Sensor Status

\r\n"; + response += "\r\n"; + response += "\r\n"; + response += "\r\n"; + response += "\r\n"; + response += "
Temperature"; + response += str_temperature; + response += "°C
Humidity"; + response += str_humidity; + response += "%RH
Heat Index"; + response += str_heatindex; + response += "°C
\r\n"; + response += "
\r\n"; + response += "
\r\n"; + response += "\r\n"; + response += "\n"; + server.send(200, "text/html", response); + delay(100); + }); + + server.on("/values", [](){ + read_sensor(); + String response = "updatetime\t"; + response += previousMillis; + response += "\n"; + response += "temperature\t"; + response += str_temperature; + response += "\n"; + response += "humidity\t"; + response += str_humidity; + response += "\n"; + response += "heatindex\t"; + response += str_heatindex; + response += "\n"; + server.send(200, "text/plain", response); + delay(100); + }); + + server.on("/temp", [](){ + read_sensor(); + char response[50]; + snprintf(response, 50, "Temperature: %s °C", str_temperature); + server.send(200, "text/plain", response); + }); + + server.on("/humidity", [](){ + read_sensor(); + char response[50]; + snprintf(response, 50, "Humidity: %s %", str_humidity); + server.send(200, "text/plain", response); + }); + + // Start the web server + server.begin(); + Serial.println("HTTP server started"); +} + +void loop() { + // Listen for http requests + server.handleClient(); + + if (!client.connected()) { + reconnect(); + } + client.loop(); + + long now = millis(); + if (now - lastMsg > 10000) { + lastMsg = now; + read_sensor(); + } +}