diff --git a/code/lib/EmonLiteESP/EmonLiteESP.cpp b/code/lib/EmonLiteESP/EmonLiteESP.cpp
new file mode 100644
index 00000000..afc075f1
--- /dev/null
+++ b/code/lib/EmonLiteESP/EmonLiteESP.cpp
@@ -0,0 +1,65 @@
+/*
+ EmonLiteESP
+
+ Energy Monitor Library for ESP8266 based on EmonLib
+ Currently only support current sensing
+*/
+
+#include "Arduino.h"
+#include "EmonLiteESP.h"
+
+void EnergyMonitor::initCurrent(unsigned int pin, double ref, double ratio) {
+ _currentPin = pin;
+ _referenceVoltage = ref;
+ _currentRatio = ratio;
+ _currentMidPoint = (ADC_COUNTS>>1);
+
+ // Calculate default precision
+ _currentFactor = _currentRatio * _referenceVoltage / ADC_COUNTS;
+ _precision = 0;
+ _multiplier = 1;
+ while (_multiplier * _currentFactor < 1) {
+ _multiplier *= 10;
+ ++_precision;
+ }
+ --_precision;
+ _multiplier /= 10;
+
+};
+
+byte EnergyMonitor::getPrecision() {
+ return _precision;
+}
+
+void EnergyMonitor::setPrecision(byte precision) {
+ _precision = precision;
+ _multiplier = 1;
+ for (byte i=0; i<_precision; i++) _multiplier *= 10;
+}
+
+double EnergyMonitor::getCurrent(unsigned int samples) {
+
+ int sample;
+ double filtered;
+ double sum;
+
+ for (unsigned int n = 0; n < samples; n++) {
+
+ // Read analog value
+ sample = analogRead(_currentPin);
+
+ // Digital low pass filter extracts the VDC offset
+ _currentMidPoint = (_currentMidPoint + (sample - _currentMidPoint) / 1024.0);
+ filtered = sample - _currentMidPoint;
+
+ // Root-mean-square method
+ sum += (filtered * filtered);
+
+ }
+
+ double rms = int(sqrt(sum / samples) - 0.5);
+ double current = _currentFactor * rms;
+ current = round(current * _multiplier) / _multiplier;
+ return current;
+
+};
diff --git a/code/lib/EmonLiteESP/EmonLiteESP.h b/code/lib/EmonLiteESP/EmonLiteESP.h
new file mode 100644
index 00000000..f8d17ac8
--- /dev/null
+++ b/code/lib/EmonLiteESP/EmonLiteESP.h
@@ -0,0 +1,35 @@
+/*
+ EmonLiteESP
+
+ Energy Monitor Library for ESP8266 based on EmonLib
+ Currently only support current sensing
+*/
+
+#ifndef EmonLiteESP_h
+#define EmonLiteESP_h
+
+#define ADC_BITS 10
+#define ADC_COUNTS (1<.
#include
#include "FS.h"
#include
+#include
// -----------------------------------------------------------------------------
// ConfiguraciĆ³
@@ -40,6 +41,7 @@ along with this program. If not, see .
#define ENABLE_OTA 1
#define ENABLE_MQTT 1
#define ENABLE_WEBSERVER 1
+#define ENABLE_ENERGYMONITOR 1
#define APP_NAME "Espurna 0.9"
#define APP_AUTHOR "xose.perez@gmail.com"
@@ -64,6 +66,17 @@ along with this program. If not, see .
#define RF_DEVICE 1
#define MQTT_RETAIN true
+#define MQTT_TOPIC "/test/switch/{identifier}"
+#define MQTT_PORT 1883
+
+#define CURRENT_PIN A0
+#define REFERENCE_VOLTAGE 1.0
+#define MAINS_VOLTAGE 230.0
+#define CURRENT_RATIO 156
+#define CURRENT_PRECISION 1
+#define SAMPLES_X_MEASUREMENT 1500
+#define MEASUREMENT_INTERVAL 10000
+#define MEASUREMENTS_X_MESSAGE 6
// -----------------------------------------------------------------------------
// Globals
@@ -85,12 +98,15 @@ DebounceEvent button1 = false;
WiFiClient client;
PubSubClient mqtt(client);
String mqttServer = "";
- String mqttTopic = "/test/switch/{identifier}";
- String mqttPort = "1883";
+ String mqttTopic = MQTT_TOPIC;
+ String mqttPort = String(MQTT_PORT);
String mqttUser = "";
String mqttPassword = "";
char mqttStatusTopic[30];
char mqttIPTopic[30];
+ #if ENABLE_ENERGYMONITOR
+ char mqttPowerTopic[30];
+ #endif
bool isMQTTMessage = false;
#endif
@@ -102,6 +118,10 @@ DebounceEvent button1 = false;
String rfDevice = String(RF_DEVICE);
#endif
+#if ENABLE_ENERGYMONITOR
+ EnergyMonitor monitor;
+#endif
+
// -----------------------------------------------------------------------------
// Utils
// -----------------------------------------------------------------------------
@@ -533,6 +553,13 @@ void wifiLoop() {
tmp.toCharArray(mqttIPTopic, tmp.length()+1);
mqttIPTopic[tmp.length()+1] = 0;
+ // Get publish current topic
+ #if ENABLE_ENERGYMONITOR
+ tmp = base + "/power";
+ tmp.toCharArray(mqttPowerTopic, tmp.length()+1);
+ mqttPowerTopic[tmp.length()+1] = 0;
+ #endif
+
}
void mqttCallback(char* topic, byte* payload, unsigned int length) {
@@ -573,16 +600,25 @@ void wifiLoop() {
mqtt.setServer(buffer, mqttPort.toInt());
#ifdef DEBUG
- Serial.print("Connecting to MQTT broker: ");
+ Serial.print("Connecting to MQTT broker at ");
+ Serial.print(mqttServer);
#endif
if (mqttUser.length() > 0) {
+ #ifdef DEBUG
+ Serial.print(" as user ");
+ Serial.print(mqttUser);
+ Serial.print(": ");
+ #endif
char user[mqttUser.length() + 1];
mqttUser.toCharArray(user, mqttUser.length() + 1);
char password[mqttPassword.length() + 1];
mqttPassword.toCharArray(password, mqttPassword.length() + 1);
mqtt.connect(getIdentifier(), user, password);
} else {
+ #ifdef DEBUG
+ Serial.print(" anonymously: ");
+ #endif
mqtt.connect(getIdentifier());
}
@@ -798,7 +834,7 @@ bool loadConfig() {
ArduinoOTA.setPassword((const char *) ADMIN_PASS);
ArduinoOTA.onStart([]() {
- #ifdef ENABLE_RF
+ #if ENABLE_RF
RemoteReceiver::disable();
#endif
#ifdef DEBUG
@@ -810,7 +846,7 @@ bool loadConfig() {
#ifdef DEBUG
Serial.println("OTA - End");
#endif
- #ifdef ENABLE_RF
+ #if ENABLE_RF
RemoteReceiver::enable();
#endif
});
@@ -842,6 +878,56 @@ bool loadConfig() {
#endif
+// -----------------------------------------------------------------------------
+// Energy Monitor
+// -----------------------------------------------------------------------------
+
+#if ENABLE_ENERGYMONITOR
+
+ void energyMonitorSetup() {
+ monitor.initCurrent(CURRENT_PIN, REFERENCE_VOLTAGE, CURRENT_RATIO);
+ monitor.setPrecision(CURRENT_PRECISION);
+ }
+
+ void energyMonitorLoop() {
+
+ static unsigned long next_measurement = millis();
+ static byte measurements = 0;
+ static double sum = 0;
+
+ if (millis() > next_measurement) {
+
+ double current = monitor.getCurrent(SAMPLES_X_MEASUREMENT);
+ sum += current;
+ ++measurements;
+
+ #ifdef DEBUG
+ Serial.print("Power reading: ");
+ Serial.println(current * MAINS_VOLTAGE);
+ #endif
+
+ if (measurements == MEASUREMENTS_X_MESSAGE) {
+ char buffer[8];
+ sprintf(buffer, "%d", int(sum * MAINS_VOLTAGE / measurements));
+ #ifdef DEBUG
+ Serial.print("Power sending: ");
+ Serial.println(buffer);
+ #endif
+ #if ENABLE_MQTT
+ mqtt.publish(mqttPowerTopic, buffer, MQTT_RETAIN);
+ #endif
+ sum = 0;
+ measurements = 0;
+ }
+
+ next_measurement += MEASUREMENT_INTERVAL;
+
+ }
+
+ }
+
+#endif
+
// -----------------------------------------------------------------------------
// Hardware (buttons, LEDs,...)
// -----------------------------------------------------------------------------
@@ -918,6 +1004,9 @@ void setup() {
#if ENABLE_RF
rfSetup();
#endif
+ #if ENABLE_ENERGYMONITOR
+ energyMonitorSetup();
+ #endif
}
@@ -936,6 +1025,9 @@ void loop() {
#if ENABLE_WEBSERVER
webServerLoop();
#endif
+ #if ENABLE_ENERGYMONITOR
+ energyMonitorLoop();
+ #endif
hardwareLoop();
delay(1);