Browse Source

sns/hlw8012: default ratios at compile time

mcspr-patch-1
Maxim Prokhorov 4 years ago
parent
commit
12ae9d15be
1 changed files with 75 additions and 34 deletions
  1. +75
    -34
      code/espurna/sensors/HLW8012Sensor.h

+ 75
- 34
code/espurna/sensors/HLW8012Sensor.h View File

@ -14,6 +14,53 @@
#include "BaseEmonSensor.h" #include "BaseEmonSensor.h"
// ref. HLW8012/src/HLW8012.h
//
// These values are used to calculate current, voltage and power factors as per datasheet formula
// These are the nominal values for the Sonoff POW resistors:
// * The CURRENT_RESISTOR is the 1milliOhm copper-manganese resistor in series with the main line
// * The VOLTAGE_RESISTOR_UPSTREAM are the 5 470kOhm resistors in the voltage divider that feeds the V2P pin in the HLW8012
// * The VOLTAGE_RESISTOR_DOWNSTREAM is the 1kOhm resistor in the voltage divider that feeds the V2P pin in the HLW8012
//
// (note: V_REF & F_OSC come from HLW8012.h)
namespace {
constexpr double _hlw8012_voltage_resistor(double voltage_upstream, double voltage_downstream) {
return (voltage_upstream + voltage_downstream) / voltage_downstream;
}
constexpr double _hlw8012_default_voltage_resistor() {
return _hlw8012_voltage_resistor(HLW8012_VOLTAGE_R_UP, HLW8012_VOLTAGE_R_DOWN);
}
constexpr double _hlw8012_default_current_resistor() {
return HLW8012_CURRENT_R;
}
// TODO: ..._RATIO flags are 0, but would it not make a better case for 1.0 as default aka make this a 'multiplier'?
// TODO: Also note that HLW8012 lib will happily accept 0.0 as multiplier, with no way to recover back through the WebUI as we only adjust 'expected' value
constexpr double _hlw8012_default_current_multiplier() {
return (HLW8012_CURRENT_RATIO != 0.0)
? (HLW8012_CURRENT_RATIO)
: ( 1000000.0 * 512 * V_REF / _hlw8012_default_current_resistor() / 24.0 / F_OSC );
}
constexpr double _hlw8012_default_voltage_multiplier() {
return (HLW8012_VOLTAGE_RATIO != 0.0)
? (HLW8012_VOLTAGE_RATIO)
: ( 1000000.0 * 512 * V_REF * _hlw8012_default_voltage_resistor() / 2.0 / F_OSC );
}
constexpr double _hlw8012_default_power_multiplier() {
return (HLW8012_POWER_RATIO != 0.0)
? (HLW8012_POWER_RATIO)
: ( 1000000.0 * 128 * V_REF * V_REF * _hlw8012_default_voltage_resistor() / _hlw8012_default_current_resistor() / 48.0 / F_OSC );
}
} //namespace
class HLW8012Sensor : public BaseEmonSensor { class HLW8012Sensor : public BaseEmonSensor {
public: public:
@ -72,46 +119,50 @@ class HLW8012Sensor : public BaseEmonSensor {
} }
double defaultCurrentRatio() const override { double defaultCurrentRatio() const override {
return HLW8012_CURRENT_RATIO;
return _hlw8012_default_current_multiplier();
} }
double defaultVoltageRatio() const override { double defaultVoltageRatio() const override {
return HLW8012_VOLTAGE_RATIO;
return _hlw8012_default_voltage_multiplier();
} }
double defaultPowerRatio() const override { double defaultPowerRatio() const override {
return HLW8012_POWER_RATIO;
return _hlw8012_default_power_multiplier();
} }
void resetRatios() override { void resetRatios() override {
_hlw8012->setCurrentMultiplier(_initialRatioC);
_hlw8012->setVoltageMultiplier(_initialRatioV);
_hlw8012->setPowerMultiplier(_initialRatioP);
_defaultRatios();
} }
void setCurrentRatio(double value) override { void setCurrentRatio(double value) override {
_hlw8012->setCurrentMultiplier(value);
};
if (value > 0.0) {
_hlw8012->setCurrentMultiplier(value);
}
}
void setVoltageRatio(double value) override { void setVoltageRatio(double value) override {
_hlw8012->setVoltageMultiplier(value);
};
if (value > 0.0) {
_hlw8012->setVoltageMultiplier(value);
}
}
void setPowerRatio(double value) override { void setPowerRatio(double value) override {
_hlw8012->setPowerMultiplier(value);
};
if (value > 0.0) {
_hlw8012->setPowerMultiplier(value);
}
}
double getCurrentRatio() override { double getCurrentRatio() override {
return _hlw8012->getCurrentMultiplier(); return _hlw8012->getCurrentMultiplier();
};
}
double getVoltageRatio() override { double getVoltageRatio() override {
return _hlw8012->getVoltageMultiplier(); return _hlw8012->getVoltageMultiplier();
};
}
double getPowerRatio() override { double getPowerRatio() override {
return _hlw8012->getPowerMultiplier(); return _hlw8012->getPowerMultiplier();
};
}
// --------------------------------------------------------------------- // ---------------------------------------------------------------------
@ -151,10 +202,13 @@ class HLW8012Sensor : public BaseEmonSensor {
_hlw8012->begin(_cf, _cf1, _sel, _sel_current, false, 1000000); _hlw8012->begin(_cf, _cf1, _sel, _sel_current, false, 1000000);
#endif #endif
// Adjust with ratio values that could be set in the hardware profile
// Note that HLW8012 does not initialize the multipliers (aka ratios) after begin(),
// we need to manually set those based on either resistor values or RATIO flags
// (see the defaults block at the top)
_defaultRatios(); _defaultRatios();
// Handle interrupts
// While we expect begin() to be called only once, try to detach before attaching again
// (might be no-op on esp8266, since attachInterrupt will replace the existing func)
#if HLW8012_USE_INTERRUPTS && (!HLW8012_WAIT_FOR_WIFI) #if HLW8012_USE_INTERRUPTS && (!HLW8012_WAIT_FOR_WIFI)
_enableInterrupts(false); _enableInterrupts(false);
_enableInterrupts(true); _enableInterrupts(true);
@ -174,7 +228,7 @@ class HLW8012Sensor : public BaseEmonSensor {
// Descriptive name of the slot # index // Descriptive name of the slot # index
String description(unsigned char index) { String description(unsigned char index) {
return description(); return description();
};
}
// Address of the sensor (it could be the GPIO or I2C address) // Address of the sensor (it could be the GPIO or I2C address)
String address(unsigned char index) { String address(unsigned char index) {
@ -240,22 +294,9 @@ class HLW8012Sensor : public BaseEmonSensor {
protected: protected:
void _defaultRatios() { void _defaultRatios() {
// These values are used to calculate current, voltage and power factors as per datasheet formula
// These are the nominal values for the Sonoff POW resistors:
// * The CURRENT_RESISTOR is the 1milliOhm copper-manganese resistor in series with the main line
// * The VOLTAGE_RESISTOR_UPSTREAM are the 5 470kOhm resistors in the voltage divider that feeds the V2P pin in the HLW8012
// * The VOLTAGE_RESISTOR_DOWNSTREAM is the 1kOhm resistor in the voltage divider that feeds the V2P pin in the HLW8012
_hlw8012->setResistors(HLW8012_CURRENT_R, HLW8012_VOLTAGE_R_UP, HLW8012_VOLTAGE_R_DOWN);
// Multipliers are already set, but we might have changed default values via the hardware profile
if (defaultCurrentRatio() > 0.0) _hlw8012->setCurrentMultiplier(defaultCurrentRatio());
if (defaultVoltageRatio() > 0.0) _hlw8012->setVoltageMultiplier(defaultVoltageRatio());
if (defaultPowerRatio() > 0.0) _hlw8012->setPowerMultiplier(defaultPowerRatio());
// Preserve ratios as a fallback
_initialRatioC = getCurrentRatio();
_initialRatioV = getVoltageRatio();
_initialRatioP = getPowerRatio();
_hlw8012->setCurrentMultiplier(defaultCurrentRatio());
_hlw8012->setVoltageMultiplier(defaultVoltageRatio());
_hlw8012->setPowerMultiplier(defaultPowerRatio());
} }
// --------------------------------------------------------------------- // ---------------------------------------------------------------------


Loading…
Cancel
Save