ESPHome 2025.5.0
Loading...
Searching...
No Matches
bl0939.h
Go to the documentation of this file.
1#pragma once
7namespace esphome {
8namespace bl0939 {
10// https://datasheet.lcsc.com/lcsc/2108071830_BL-Shanghai-Belling-BL0939_C2841044.pdf
11// (unfortunately chinese, but the formulas can be easily understood)
12// Sonoff Dual R3 V2 has the exact same resistor values for the current shunts (RL=1miliOhm)
13// and for the voltage divider (R1=0.51kOhm, R2=5*390kOhm)
14// as in the manufacturer's reference circuit, so the same formulas were used here (Vref=1.218V)
15static const float BL0939_IREF = 324004 * 1 / 1.218;
16static const float BL0939_UREF = 79931 * 0.51 * 1000 / (1.218 * (5 * 390 + 0.51));
17static const float BL0939_PREF = 4046 * 1 * 0.51 * 1000 / (1.218 * 1.218 * (5 * 390 + 0.51));
18static const float BL0939_EREF = 3.6e6 * 4046 * 1 * 0.51 * 1000 / (1638.4 * 256 * 1.218 * 1.218 * (5 * 390 + 0.51));
19
20struct ube24_t { // NOLINT(readability-identifier-naming,altera-struct-pack-align)
21 uint8_t l;
22 uint8_t m;
23 uint8_t h;
24} __attribute__((packed));
25
26struct ube16_t { // NOLINT(readability-identifier-naming,altera-struct-pack-align)
27 uint8_t l;
28 uint8_t h;
29} __attribute__((packed));
30
31struct sbe24_t { // NOLINT(readability-identifier-naming,altera-struct-pack-align)
32 uint8_t l;
33 uint8_t m;
34 int8_t h;
35} __attribute__((packed));
36
37// Caveat: All these values are big endian (low - middle - high)
38
39union DataPacket { // NOLINT(altera-struct-pack-align)
40 uint8_t raw[35];
41 struct {
42 uint8_t frame_header; // 0x55 according to docs
53 uint8_t RESERVED1; // value of 0x00
55 uint8_t RESERVED2; // value of 0x00
56 uint8_t checksum; // checksum
57 };
58} __attribute__((packed));
59
61 public:
62 void set_voltage_sensor(sensor::Sensor *voltage_sensor) { voltage_sensor_ = voltage_sensor; }
63 void set_current_sensor_1(sensor::Sensor *current_sensor_1) { current_sensor_1_ = current_sensor_1; }
64 void set_current_sensor_2(sensor::Sensor *current_sensor_2) { current_sensor_2_ = current_sensor_2; }
65 void set_power_sensor_1(sensor::Sensor *power_sensor_1) { power_sensor_1_ = power_sensor_1; }
66 void set_power_sensor_2(sensor::Sensor *power_sensor_2) { power_sensor_2_ = power_sensor_2; }
67 void set_energy_sensor_1(sensor::Sensor *energy_sensor_1) { energy_sensor_1_ = energy_sensor_1; }
68 void set_energy_sensor_2(sensor::Sensor *energy_sensor_2) { energy_sensor_2_ = energy_sensor_2; }
69 void set_energy_sensor_sum(sensor::Sensor *energy_sensor_sum) { energy_sensor_sum_ = energy_sensor_sum; }
70
71 void loop() override;
72
73 void update() override;
74 void setup() override;
75 void dump_config() override;
76
77 protected:
81 // NB This may be negative as the circuits is seemingly able to measure
82 // power in both directions
88
89 // Divide by this to turn into Watt
90 float power_reference_ = BL0939_PREF;
91 // Divide by this to turn into Volt
92 float voltage_reference_ = BL0939_UREF;
93 // Divide by this to turn into Ampere
94 float current_reference_ = BL0939_IREF;
95 // Divide by this to turn into kWh
96 float energy_reference_ = BL0939_EREF;
97
98 static uint32_t to_uint32_t(ube24_t input);
99
100 static int32_t to_int32_t(sbe24_t input);
101
102 static bool validate_checksum(const DataPacket *data);
103
104 void received_package_(const DataPacket *data) const;
106} // namespace bl0939
107} // namespace esphome
This class simplifies creating components that periodically check a state.
Definition component.h:301
void update() override
Definition bl0939.cpp:67
void set_power_sensor_2(sensor::Sensor *power_sensor_2)
Definition bl0939.h:66
void set_current_sensor_2(sensor::Sensor *current_sensor_2)
Definition bl0939.h:64
void set_energy_sensor_1(sensor::Sensor *energy_sensor_1)
Definition bl0939.h:67
static int32_t to_int32_t(sbe24_t input)
Definition bl0939.cpp:143
void setup() override
Definition bl0939.cpp:73
void loop() override
Definition bl0939.cpp:38
void set_power_sensor_1(sensor::Sensor *power_sensor_1)
Definition bl0939.h:65
void set_energy_sensor_2(sensor::Sensor *energy_sensor_2)
Definition bl0939.h:68
sensor::Sensor * energy_sensor_sum_
Definition bl0939.h:87
sensor::Sensor * voltage_sensor_
Definition bl0939.h:78
static bool validate_checksum(const DataPacket *data)
Definition bl0939.cpp:54
sensor::Sensor * current_sensor_2_
Definition bl0939.h:80
sensor::Sensor * energy_sensor_2_
Definition bl0939.h:86
void set_voltage_sensor(sensor::Sensor *voltage_sensor)
Definition bl0939.h:62
sensor::Sensor * power_sensor_1_
Definition bl0939.h:83
static uint32_t to_uint32_t(ube24_t input)
Definition bl0939.cpp:141
void received_package_(const DataPacket *data) const
Definition bl0939.cpp:81
void set_energy_sensor_sum(sensor::Sensor *energy_sensor_sum)
Definition bl0939.h:69
sensor::Sensor * energy_sensor_1_
Definition bl0939.h:85
void dump_config() override
Definition bl0939.cpp:129
void set_current_sensor_1(sensor::Sensor *current_sensor_1)
Definition bl0939.h:63
sensor::Sensor * power_sensor_2_
Definition bl0939.h:84
sensor::Sensor * current_sensor_1_
Definition bl0939.h:79
Base-class for all sensors.
Definition sensor.h:57
esphome::bl0939::BL0939 __attribute__
Providing packet encoding functions for exchanging data with a remote host.
Definition a01nyub.cpp:7