Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

hlw8012: fix constants for BL0937 #1973

Merged
merged 4 commits into from Jul 4, 2021
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
34 changes: 22 additions & 12 deletions esphome/components/hlw8012/hlw8012.cpp
Expand Up @@ -6,15 +6,32 @@ namespace hlw8012 {

static const char *const TAG = "hlw8012";

// valid for HLW8012 and CSE7759
static const uint32_t HLW8012_CLOCK_FREQUENCY = 3579000;
static const float HLW8012_REFERENCE_VOLTAGE = 2.43f;

void HLW8012Component::setup() {
float reference_voltage = 0;
ESP_LOGCONFIG(TAG, "Setting up HLW8012...");
this->sel_pin_->setup();
this->sel_pin_->digital_write(this->current_mode_);
this->cf_store_.pulse_counter_setup(this->cf_pin_);
this->cf1_store_.pulse_counter_setup(this->cf1_pin_);

// Initialize multipliers
if (this->sensor_model_ == HLW8012_SENSOR_MODEL_BL0937) {
reference_voltage = 1.218f;
this->power_multiplier_ =
reference_voltage * reference_voltage * this->voltage_divider_ / this->current_resistor_ / 1721506.0f;
this->current_multiplier_ = reference_voltage / this->current_resistor_ / 94638.0f;
this->voltage_multiplier_ = reference_voltage * this->voltage_divider_ / 15397.0f;
} else {
// HLW8012 and CSE7759 have same reference specs
reference_voltage = 2.43f;
this->power_multiplier_ = reference_voltage * reference_voltage * this->voltage_divider_ / this->current_resistor_ *
64.0f / 24.0f / HLW8012_CLOCK_FREQUENCY;
this->current_multiplier_ = reference_voltage / this->current_resistor_ * 512.0f / 24.0f / HLW8012_CLOCK_FREQUENCY;
this->voltage_multiplier_ = reference_voltage * this->voltage_divider_ * 256.0f / HLW8012_CLOCK_FREQUENCY;
}
}
void HLW8012Component::dump_config() {
ESP_LOGCONFIG(TAG, "HLW8012:");
Expand Down Expand Up @@ -49,25 +66,18 @@ void HLW8012Component::update() {
return;
}

const float v_ref_squared = HLW8012_REFERENCE_VOLTAGE * HLW8012_REFERENCE_VOLTAGE;
const float power_multiplier_micros =
64000000.0f * v_ref_squared * this->voltage_divider_ / this->current_resistor_ / 24.0f / HLW8012_CLOCK_FREQUENCY;
float power = cf_hz * power_multiplier_micros / 1000000.0f;
float power = cf_hz * this->power_multiplier_;

if (this->change_mode_at_ != 0) {
// Only read cf1 after one cycle. Apparently it's quite unstable after being changed.
if (this->current_mode_) {
const float current_multiplier_micros =
512000000.0f * HLW8012_REFERENCE_VOLTAGE / this->current_resistor_ / 24.0f / HLW8012_CLOCK_FREQUENCY;
float current = cf1_hz * current_multiplier_micros / 1000000.0f;
float current = cf1_hz * this->current_multiplier_;
ESP_LOGD(TAG, "Got power=%.1fW, current=%.1fA", power, current);
if (this->current_sensor_ != nullptr) {
this->current_sensor_->publish_state(current);
}
} else {
const float voltage_multiplier_micros =
256000000.0f * HLW8012_REFERENCE_VOLTAGE * this->voltage_divider_ / HLW8012_CLOCK_FREQUENCY;
float voltage = cf1_hz * voltage_multiplier_micros / 1000000.0f;
float voltage = cf1_hz * this->voltage_multiplier_;
ESP_LOGD(TAG, "Got power=%.1fW, voltage=%.1fV", power, voltage);
if (this->voltage_sensor_ != nullptr) {
this->voltage_sensor_->publish_state(voltage);
Expand All @@ -81,7 +91,7 @@ void HLW8012Component::update() {

if (this->energy_sensor_ != nullptr) {
cf_total_pulses_ += raw_cf;
float energy = cf_total_pulses_ * power_multiplier_micros / 3600 / 1000000.0f;
float energy = cf_total_pulses_ * this->power_multiplier_ / 3600;
this->energy_sensor_->publish_state(energy);
}

Expand Down
12 changes: 12 additions & 0 deletions esphome/components/hlw8012/hlw8012.h
Expand Up @@ -10,6 +10,12 @@ namespace hlw8012 {

enum HLW8012InitialMode { HLW8012_INITIAL_MODE_CURRENT = 0, HLW8012_INITIAL_MODE_VOLTAGE };

enum HLW8012SensorModels {
HLW8012_SENSOR_MODEL_HLW8012 = 0,
HLW8012_SENSOR_MODEL_CSE7759,
HLW8012_SENSOR_MODEL_BL0937
};

class HLW8012Component : public PollingComponent {
public:
void setup() override;
Expand All @@ -20,6 +26,7 @@ class HLW8012Component : public PollingComponent {
void set_initial_mode(HLW8012InitialMode initial_mode) {
current_mode_ = initial_mode == HLW8012_INITIAL_MODE_CURRENT;
}
void set_sensor_model(HLW8012SensorModels sensor_model) { sensor_model_ = sensor_model; }
void set_change_mode_every(uint32_t change_mode_every) { change_mode_every_ = change_mode_every; }
void set_current_resistor(float current_resistor) { current_resistor_ = current_resistor; }
void set_voltage_divider(float voltage_divider) { voltage_divider_ = voltage_divider; }
Expand All @@ -38,6 +45,7 @@ class HLW8012Component : public PollingComponent {
uint32_t change_mode_every_{8};
float current_resistor_{0.001};
float voltage_divider_{2351};
HLW8012SensorModels sensor_model_{HLW8012_SENSOR_MODEL_HLW8012};
uint64_t cf_total_pulses_{0};
GPIOPin *sel_pin_;
GPIOPin *cf_pin_;
Expand All @@ -48,6 +56,10 @@ class HLW8012Component : public PollingComponent {
sensor::Sensor *current_sensor_{nullptr};
sensor::Sensor *power_sensor_{nullptr};
sensor::Sensor *energy_sensor_{nullptr};

float voltage_multiplier_{0.0f};
float current_multiplier_{0.0f};
float power_multiplier_{0.0f};
};

} // namespace hlw8012
Expand Down
11 changes: 11 additions & 0 deletions esphome/components/hlw8012/sensor.py
Expand Up @@ -11,6 +11,7 @@
CONF_POWER,
CONF_ENERGY,
CONF_SEL_PIN,
CONF_MODEL,
CONF_VOLTAGE,
CONF_VOLTAGE_DIVIDER,
DEVICE_CLASS_CURRENT,
Expand All @@ -31,11 +32,19 @@
hlw8012_ns = cg.esphome_ns.namespace("hlw8012")
HLW8012Component = hlw8012_ns.class_("HLW8012Component", cg.PollingComponent)
HLW8012InitialMode = hlw8012_ns.enum("HLW8012InitialMode")
HLW8012SensorModels = hlw8012_ns.enum("HLW8012SensorModels")

INITIAL_MODES = {
CONF_CURRENT: HLW8012InitialMode.HLW8012_INITIAL_MODE_CURRENT,
CONF_VOLTAGE: HLW8012InitialMode.HLW8012_INITIAL_MODE_VOLTAGE,
}

MODELS = {
"HLW8012": HLW8012SensorModels.HLW8012_SENSOR_MODEL_HLW8012,
"CSE7759": HLW8012SensorModels.HLW8012_SENSOR_MODEL_CSE7759,
"BL0937": HLW8012SensorModels.HLW8012_SENSOR_MODEL_BL0937,
}

CONF_CF1_PIN = "cf1_pin"
CONF_CF_PIN = "cf_pin"
CONFIG_SCHEMA = cv.Schema(
Expand All @@ -62,6 +71,7 @@
),
cv.Optional(CONF_CURRENT_RESISTOR, default=0.001): cv.resistance,
cv.Optional(CONF_VOLTAGE_DIVIDER, default=2351): cv.positive_float,
cv.Optional(CONF_MODEL, default="HLW8012"): cv.enum(MODELS, upper=True),
cv.Optional(CONF_CHANGE_MODE_EVERY, default=8): cv.All(
cv.uint32_t, cv.Range(min=1)
),
Expand Down Expand Up @@ -99,3 +109,4 @@ async def to_code(config):
cg.add(var.set_voltage_divider(config[CONF_VOLTAGE_DIVIDER]))
cg.add(var.set_change_mode_every(config[CONF_CHANGE_MODE_EVERY]))
cg.add(var.set_initial_mode(INITIAL_MODES[config[CONF_INITIAL_MODE]]))
cg.add(var.set_sensor_model(config[CONF_MODEL]))
1 change: 1 addition & 0 deletions esphome/const.py
Expand Up @@ -522,6 +522,7 @@
CONF_SENSING_PIN = "sensing_pin"
CONF_SENSOR = "sensor"
CONF_SENSOR_ID = "sensor_id"
CONF_SENSOR_MODEL = "sensor_model"
jesserockz marked this conversation as resolved.
Show resolved Hide resolved
CONF_SENSORS = "sensors"
CONF_SEQUENCE = "sequence"
CONF_SERVERS = "servers"
Expand Down