Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <Arduino.h>
- #include <ESP8266WiFi.h>
- #include <ESP8266mDNS.h>
- #include "Adafruit_MQTT.h"
- #include "Adafruit_MQTT_Client.h"
- #include <ArduinoOTA.h>
- #include "/Users/hanpa/Dropbox/Hem/Arduino/common/credentials.h"
- const char* version = "WashingMachineMonitor 1.0";
- const char* date_name = "2017-08-01 Hans Palm";
- // Hans Palm 2017
- // http://www.hobbyelektronik.nu/
- //
- // This code monitors the washing machine using a SCT-013-030 current transformer
- // on one of the electrical phases. SCT-013-030 returns AC of 1V for 30A so a small
- // circuit is needed to transform this to a voltage suitable for the analogue A0 input
- // on a Wemos D1 mini that has a rage from 0 - 3.3V.
- // A circuit and description of the projekt is available here:
- // http://www.hobbyelektronik.nu/forum/viewtopic.php?f=13&t=42
- //
- // Max and min values of the current is logged during 1 second, the difference
- // of max - min is the maximum current span (max current amplitude) during that period.
- // This value is then used by a state machine to determine the status of
- // the washing machine. The logic will need to be adapted to a certain washing machine.
- // Use mqtt values for current span for checking your current levels during a washing cycle
- // and adapt the logic accordingly.
- //
- // The current state of washing machine is sent using mqtt each second and also using a separate
- // mqtt message on the event of that the washing machine is finished
- /************************* WiFi Access Point *********************************/
- #define WLAN_SSID ssid
- #define WLAN_PASS password
- /***************************** MQTT settings *********************************/
- #define SERVER mqtt_server
- #define SERVERPORT mqtt_port // use 8883 for SSL
- #define USERNAME "" // Not used, from Adafruit.io Setup
- #define KEY "" // Not used, from Adafruit.io Setup
- /************************* OTA *********************************/
- #define OTA_HOST_NAME "WashingMachineM" // No _ in host names!
- const char* host = OTA_HOST_NAME;
- // The follwing parameters are only required for fixed IP, otherwise uncomment, also uncomment WiFi.config(ip, gateway, subnet)
- //IPAddress ip(192, 168, 0, TBD);
- IPAddress gateway(192, 168, 0, 1);
- IPAddress subnet(255, 255, 255, 0);
- /******************** Types and values for monitoring ************************/
- enum washingMachineStates {
- Off,
- Inactive,
- Running
- };
- washingMachineStates washingMachineState = Off;
- // A measured current span above this value indicates a running machine
- #define TO_RUNNING_THRESHOLD 30
- // Require some seconds above threshold before considered running to filter out power transients
- #define TIME_ABOVE_TO_RUNNING_THRESHOLD_BEFORE_RUNNING 3
- // A measured current span below this value indicates an inactive machine, can be temporarily, e.g. filling up water
- #define TO_INACTIVE_THRESHOLD 20
- // Time in seconds of Inactive before considered Not_Running
- #define TIME_IN_INACTIVE_BEFORE_NOT_RUNNING 180
- // For keeping track of how long the current span has been above TO_RUNNING_THRESHOLD when in Off, to filter out transients
- int secondsInOffAboveToRunningThreshold = 0;
- // For keeping track of how long the state has been Inactive. Stored value of millis() when Inactive was assigned.
- unsigned int startTimeInInactive = 0;
- // Create an ESP8266 WiFiClient class to connect to the MQTT server.
- WiFiClient client;
- // or... use WiFiFlientSecure for SSL
- //WiFiClientSecure client;
- // Setup the MQTT client class by passing in the WiFi client and MQTT server and login details.
- Adafruit_MQTT_Client mqtt(&client, SERVER, SERVERPORT, USERNAME, KEY);
- /****************************** Feeds ***************************************/
- // Setup feeds for publishing.
- Adafruit_MQTT_Publish mqttWashingMachineCurrentSpan1s = Adafruit_MQTT_Publish(&mqtt, USERNAME "WashingMachineCurrentSpan1s");
- Adafruit_MQTT_Publish mqttWashingMachineState = Adafruit_MQTT_Publish(&mqtt, USERNAME "WashingMachineState");
- Adafruit_MQTT_Publish mqttWashingMachineFinishedEvent = Adafruit_MQTT_Publish(&mqtt, USERNAME "WashingMachineFinishedEvent");
- void MQTT_connect();
- void OTA_setup() {
- ArduinoOTA.setHostname(host);
- ArduinoOTA.onStart([]() {
- String type;
- // if (ArduinoOTA.getCommand() == U_FLASH)
- type = "sketch";
- // else // U_SPIFFS
- // type = "filesystem";
- // NOTE: if updating SPIFFS this would be the place to unmount SPIFFS using SPIFFS.end()
- Serial.println("Start updating " + type);
- });
- ArduinoOTA.onEnd([]() {
- Serial.println("\nEnd");
- });
- ArduinoOTA.onProgress([](unsigned int progress, unsigned int total) {
- Serial.printf("Progress: %u%%\r", (progress / (total / 100)));
- });
- ArduinoOTA.onError([](ota_error_t error) {
- Serial.printf("Error[%u]: ", error);
- if (error == OTA_AUTH_ERROR) Serial.println("Auth Failed");
- else if (error == OTA_BEGIN_ERROR) Serial.println("Begin Failed");
- else if (error == OTA_CONNECT_ERROR) Serial.println("Connect Failed");
- else if (error == OTA_RECEIVE_ERROR) Serial.println("Receive Failed");
- else if (error == OTA_END_ERROR) Serial.println("End Failed");
- });
- ArduinoOTA.begin();
- }
- void setup() {
- Serial.begin(115200);
- delay(10);
- // Connect to WiFi access point.
- Serial.println(); Serial.println();
- Serial.print("Connecting to ");
- Serial.println(WLAN_SSID);
- //WiFi.config(ip, gateway, subnet); // Only required for fixed IP
- WiFi.begin(WLAN_SSID, WLAN_PASS);
- while (WiFi.status() != WL_CONNECTED) {
- delay(500);
- Serial.print(".");
- }
- Serial.println();
- Serial.println("WiFi connected");
- Serial.println("IP address: "); Serial.println(WiFi.localIP());
- OTA_setup();
- }
- void loop() {
- ArduinoOTA.handle();
- // Ensure the connection to the MQTT server is alive (this will make the first
- // connection and automatically reconnect when disconnected). See the MQTT_connect
- // function definition further below.
- MQTT_connect();
- // Process mqtt data
- mqtt.processPackets(50);
- // ping the server to keep the mqtt connection alive
- // NOT required if you are publishing once every KEEPALIVE seconds
- /*
- if(! mqtt.ping()) {
- mqtt.disconnect();
- }
- */
- // Read current levels from analogue (A0) input during 1 second to determine min, max and current span (amplitude)
- int max = 0;
- int min = 1023;
- unsigned int startTimeOfMeasuring = millis();
- while (true) {
- int v = analogRead(A0);
- if (v > max) {
- max = v;
- }
- if (v < min) {
- min = v;
- }
- if ( (millis() - startTimeOfMeasuring) > 1000) {
- break; // 1 second of reading A0 completed
- }
- // Free some time for network tasks and check request for OTA update
- delay(10);
- ArduinoOTA.handle();
- }
- int currentSpan = max - min;
- // Publish current span value on MQTT
- mqttWashingMachineCurrentSpan1s.publish(currentSpan);
- // Evaluate state
- switch (washingMachineState) {
- case Off:
- if (currentSpan > TO_RUNNING_THRESHOLD) {
- // Filter out power transients, require vurrent span above threshold for some seconds before considered running
- if (secondsInOffAboveToRunningThreshold >= TIME_ABOVE_TO_RUNNING_THRESHOLD_BEFORE_RUNNING ) {
- washingMachineState = Running;
- secondsInOffAboveToRunningThreshold = 0;
- } else {
- secondsInOffAboveToRunningThreshold++;
- }
- } else {
- secondsInOffAboveToRunningThreshold = 0;
- }
- break;
- case Running:
- if (currentSpan < TO_INACTIVE_THRESHOLD) {
- startTimeInInactive = millis();
- washingMachineState = Inactive;
- }
- break;
- case Inactive:
- if ( (millis() - startTimeInInactive) > TIME_IN_INACTIVE_BEFORE_NOT_RUNNING*1000) {
- // The washing machine has completed a washing cycle
- washingMachineState = Off;
- // Publish the event of completion on MQTT
- mqttWashingMachineFinishedEvent.publish(1);
- } else if (currentSpan > TO_RUNNING_THRESHOLD) {
- washingMachineState = Running;
- }
- break;
- }
- // Publish current state on MQTT
- switch (washingMachineState) {
- case Off:
- mqttWashingMachineState.publish("Off");
- break;
- case Running:
- mqttWashingMachineState.publish("Running");
- break;
- case Inactive:
- mqttWashingMachineState.publish("Inactive");
- break;
- }
- } // end of loop()
- // Function to connect and reconnect as necessary to the MQTT server.
- // Should be called in the loop function and it will take care if connecting.
- void MQTT_connect() {
- int8_t ret;
- // Stop if already connected.
- if (mqtt.connected()) {
- return;
- }
- Serial.print("Connecting to MQTT... ");
- while ((ret = mqtt.connect()) != 0) { // connect will return 0 for connected
- Serial.println(mqtt.connectErrorString(ret));
- Serial.println("Retrying MQTT connection in 5 seconds...");
- mqtt.disconnect();
- delay(5000); // wait 5 seconds
- }
- Serial.println("MQTT Connected!");
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement