Fork of the espurna firmware for `mhsw` switches
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

144 lines
3.6 KiB

/*
POWER EMON MODULE
Copyright (C) 2016-2017 by Xose Pérez <xose dot perez at gmail dot com>
*/
#if (POWER_PROVIDER & POWER_PROVIDER_EMON == POWER_PROVIDER_EMON)
// -----------------------------------------------------------------------------
// MODULE GLOBALS AND CACHE
// -----------------------------------------------------------------------------
#include <EmonLiteESP.h>
EmonLiteESP _emon;
#if POWER_PROVIDER == POWER_PROVIDER_EMON_ADC121
#include "brzo_i2c.h"
// ADC121 Registers
#define ADC121_REG_RESULT 0x00
#define ADC121_REG_ALERT 0x01
#define ADC121_REG_CONFIG 0x02
#define ADC121_REG_LIMITL 0x03
#define ADC121_REG_LIMITH 0x04
#define ADC121_REG_HYST 0x05
#define ADC121_REG_CONVL 0x06
#define ADC121_REG_CONVH 0x07
#endif // POWER_PROVIDER == POWER_PROVIDER_EMON_ADC121
// -----------------------------------------------------------------------------
// HAL
// -----------------------------------------------------------------------------
unsigned int currentCallback() {
#if POWER_PROVIDER == POWER_PROVIDER_EMON_ANALOG
return analogRead(0);
#endif // POWER_PROVIDER == POWER_PROVIDER_EMON_ANALOG
#if POWER_PROVIDER == POWER_PROVIDER_EMON_ADC121
uint8_t buffer[2];
brzo_i2c_start_transaction(POWER_I2C_ADDRESS, I2C_SCL_FREQUENCY);
buffer[0] = ADC121_REG_RESULT;
brzo_i2c_write(buffer, 1, false);
brzo_i2c_read(buffer, 2, false);
brzo_i2c_end_transaction();
unsigned int value;
value = (buffer[0] & 0x0F) << 8;
value |= buffer[1];
return value;
#endif // POWER_PROVIDER == POWER_PROVIDER_EMON_ADC121
}
// -----------------------------------------------------------------------------
double _powerCurrent() {
static unsigned long last = 0;
static double current = 0;
if (millis() - last > 1000) {
last = millis();
current = _emon.getCurrent(POWER_SAMPLES);
current -= POWER_CURRENT_OFFSET;
if (current < 0) current = 0;
}
return current;
}
double _powerVoltage() {
return _power_voltage;
}
double _powerActivePower() {
return _powerApparentPower();
}
double _powerApparentPower() {
return _powerCurrent() * _powerVoltage();
}
double _powerReactivePower() {
return 0;
}
double _powerPowerFactor() {
return 1;
}
// -----------------------------------------------------------------------------
// PUBLIC API
// -----------------------------------------------------------------------------
void powerEnabledProvider() {
// Nothing to do
}
void powerConfigureProvider() {
_emon.setCurrentRatio(getSetting("powerRatioC", POWER_CURRENT_RATIO).toFloat());
_power_voltage = getSetting("powerVoltage", POWER_VOLTAGE).toFloat();
}
void powerSetupProvider() {
_emon.initCurrent(currentCallback, POWER_ADC_BITS, POWER_REFERENCE_VOLTAGE, POWER_CURRENT_RATIO);
#if POWER_PROVIDER == POWER_PROVIDER_EMON_ADC121
uint8_t buffer[2];
buffer[0] = ADC121_REG_CONFIG;
buffer[1] = 0x00;
brzo_i2c_start_transaction(POWER_I2C_ADDRESS, I2C_SCL_FREQUENCY);
brzo_i2c_write(buffer, 2, false);
brzo_i2c_end_transaction();
#endif
powerConfigureProvider();
_emon.warmup();
}
void powerLoopProvider(bool before) {
if (before) {
static unsigned long last = 0;
if (millis() - last > POWER_READ_INTERVAL) {
last = millis();
_power_newdata = true;
}
}
}
#endif // (POWER_PROVIDER & POWER_PROVIDER_EMON == POWER_PROVIDER_EMON)