Browse Source

Added suport or energy monitoring

fastled
Xose Pérez 7 years ago
parent
commit
22ae72c520
3 changed files with 197 additions and 5 deletions
  1. +65
    -0
      code/lib/EmonLiteESP/EmonLiteESP.cpp
  2. +35
    -0
      code/lib/EmonLiteESP/EmonLiteESP.h
  3. +97
    -5
      code/src/code.ino

+ 65
- 0
code/lib/EmonLiteESP/EmonLiteESP.cpp View File

@ -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;
};

+ 35
- 0
code/lib/EmonLiteESP/EmonLiteESP.h View File

@ -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<<ADC_BITS)
class EnergyMonitor {
public:
void initCurrent(unsigned int pin, double ref, double ratio);
double getCurrent(unsigned int samples);
byte getPrecision();
void setPrecision(byte precision);
private:
unsigned int _currentPin;
double _referenceVoltage;
double _currentRatio;
double _currentMidPoint;
double _currentFactor;
byte _precision;
double _multiplier;
};
#endif

+ 97
- 5
code/src/code.ino View File

@ -29,6 +29,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include <EEPROM.h>
#include "FS.h"
#include <stdio.h>
#include <EmonLiteESP.h>
// -----------------------------------------------------------------------------
// Configuració
@ -40,6 +41,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#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 <http://www.gnu.org/licenses/>.
#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);


Loading…
Cancel
Save