ESPHome 2026.5.0-dev
Loading...
Searching...
No Matches
ade7953_base.cpp
Go to the documentation of this file.
1#include "ade7953_base.h"
2#include "esphome/core/log.h"
3
4#include <cinttypes>
5
6namespace esphome {
7namespace ade7953_base {
8
9static const char *const TAG = "ade7953";
10
11constexpr uint16_t CONFIG_DEFAULT = 0x8004u;
12constexpr uint16_t CONFIG_LOCK_BIT = 0x8000u;
13
14static const float ADE_POWER_FACTOR = 154.0f;
15static const float ADE_WATTSEC_POWER_FACTOR = ADE_POWER_FACTOR * ADE_POWER_FACTOR / 3600;
16
18 if (this->irq_pin_ != nullptr) {
19 this->irq_pin_->setup();
20 }
21
22 // The chip might take up to 100ms to initialise
23 this->set_timeout(100, [this]() {
24 // Lock communication interface (SPI or I2C)
25 uint16_t config_v = CONFIG_DEFAULT;
26 this->ade_read_16(CONFIG_16, &config_v);
27 config_v &= static_cast<uint16_t>(~CONFIG_LOCK_BIT); // Clear the lock bit
28 this->ade_write_16(CONFIG_16, config_v);
29 // Configure optimum settings according to datasheet
30 this->ade_write_8(0x00FE, 0xAD);
31 this->ade_write_16(0x0120, 0x0030);
32 // Set gains
33 this->ade_write_8(PGA_V_8, pga_v_);
34 this->ade_write_8(PGA_IA_8, pga_ia_);
35 this->ade_write_8(PGA_IB_8, pga_ib_);
36 this->ade_write_32(AVGAIN_32, avgain_);
37 this->ade_write_32(BVGAIN_32, bvgain_);
38 this->ade_write_32(AIGAIN_32, aigain_);
39 this->ade_write_32(BIGAIN_32, bigain_);
40 this->ade_write_32(AWGAIN_32, awgain_);
41 this->ade_write_32(BWGAIN_32, bwgain_);
42 // Read back gains for debugging
43 this->ade_read_8(PGA_V_8, &pga_v_);
44 this->ade_read_8(PGA_IA_8, &pga_ia_);
45 this->ade_read_8(PGA_IB_8, &pga_ib_);
46 this->ade_read_32(AVGAIN_32, &avgain_);
47 this->ade_read_32(BVGAIN_32, &bvgain_);
48 this->ade_read_32(AIGAIN_32, &aigain_);
49 this->ade_read_32(BIGAIN_32, &bigain_);
50 this->ade_read_32(AWGAIN_32, &awgain_);
51 this->ade_read_32(BWGAIN_32, &bwgain_);
52 this->last_update_ = millis();
53 this->is_setup_ = true;
54 });
55}
56
58 LOG_PIN(" IRQ Pin: ", irq_pin_);
59 LOG_UPDATE_INTERVAL(this);
60 LOG_SENSOR(" ", "Voltage Sensor", this->voltage_sensor_);
61 LOG_SENSOR(" ", "Current A Sensor", this->current_a_sensor_);
62 LOG_SENSOR(" ", "Current B Sensor", this->current_b_sensor_);
63 LOG_SENSOR(" ", "Power Factor A Sensor", this->power_factor_a_sensor_);
64 LOG_SENSOR(" ", "Power Factor B Sensor", this->power_factor_b_sensor_);
65 LOG_SENSOR(" ", "Apparent Power A Sensor", this->apparent_power_a_sensor_);
66 LOG_SENSOR(" ", "Apparent Power B Sensor", this->apparent_power_b_sensor_);
67 LOG_SENSOR(" ", "Active Power A Sensor", this->active_power_a_sensor_);
68 LOG_SENSOR(" ", "Active Power B Sensor", this->active_power_b_sensor_);
69 LOG_SENSOR(" ", "Rective Power A Sensor", this->reactive_power_a_sensor_);
70 LOG_SENSOR(" ", "Reactive Power B Sensor", this->reactive_power_b_sensor_);
71 ESP_LOGCONFIG(TAG,
72 " USE_ACC_ENERGY_REGS: %d\n"
73 " PGA_V_8: 0x%X\n"
74 " PGA_IA_8: 0x%X\n"
75 " PGA_IB_8: 0x%X\n"
76 " AVGAIN_32: 0x%08jX\n"
77 " BVGAIN_32: 0x%08jX\n"
78 " AIGAIN_32: 0x%08jX\n"
79 " BIGAIN_32: 0x%08jX\n"
80 " AWGAIN_32: 0x%08jX\n"
81 " BWGAIN_32: 0x%08jX",
82 this->use_acc_energy_regs_, pga_v_, pga_ia_, pga_ib_, (uintmax_t) avgain_, (uintmax_t) bvgain_,
83 (uintmax_t) aigain_, (uintmax_t) bigain_, (uintmax_t) awgain_, (uintmax_t) bwgain_);
84}
85
86#define ADE_PUBLISH_(name, val, factor) \
87 if (err == 0 && this->name##_sensor_) { \
88 float value = (val) / (factor); \
89 this->name##_sensor_->publish_state(value); \
90 }
91#define ADE_PUBLISH(name, val, factor) ADE_PUBLISH_(name, val, factor)
92
94 if (!this->is_setup_)
95 return;
96
97 bool err;
98
99 uint32_t interrupts_a = 0;
100 uint32_t interrupts_b = 0;
101 if (this->irq_pin_ != nullptr) {
102 // Read and reset interrupts
103 this->ade_read_32(0x032E, &interrupts_a);
104 this->ade_read_32(0x0331, &interrupts_b);
105 }
106
108 uint16_t val_16;
109 uint16_t reg;
110
111 // Power factor
112 err = this->ade_read_16(0x010A, &val_16);
113 ADE_PUBLISH(power_factor_a, (int16_t) val_16, (0x7FFF / 100.0f));
114 err = this->ade_read_16(0x010B, &val_16);
115 ADE_PUBLISH(power_factor_b, (int16_t) val_16, (0x7FFF / 100.0f));
116
117 float pf = ADE_POWER_FACTOR;
118 if (this->use_acc_energy_regs_) {
119 const uint32_t now = millis();
120 const auto diff = now - this->last_update_;
121 this->last_update_ = now;
122 // prevent DIV/0
123 pf = ADE_WATTSEC_POWER_FACTOR * (diff < 10 ? 10 : diff) / 1000;
124 ESP_LOGVV(TAG, "ADE7953::update() diff=%" PRIu32 " pf=%f", diff, pf);
125 }
126
127 // Apparent power
128 reg = this->use_acc_energy_regs_ ? 0x0322 : 0x0310;
129 err = this->ade_read_32(reg, &val);
130 ADE_PUBLISH(apparent_power_a, (int32_t) val, pf);
131 err = this->ade_read_32(reg + 1, &val);
132 ADE_PUBLISH(apparent_power_b, (int32_t) val, pf);
133
134 // Active power
135 reg = this->use_acc_energy_regs_ ? 0x031E : 0x0312;
136 err = this->ade_read_32(reg, &val);
137 ADE_PUBLISH(active_power_a, (int32_t) val, pf);
138 err = this->ade_read_32(reg + 1, &val);
139 ADE_PUBLISH(active_power_b, (int32_t) val, pf);
140
141 // Reactive power
142 reg = this->use_acc_energy_regs_ ? 0x0320 : 0x0314;
143 err = this->ade_read_32(reg, &val);
144 ADE_PUBLISH(reactive_power_a, (int32_t) val, pf);
145 err = this->ade_read_32(reg + 1, &val);
146 ADE_PUBLISH(reactive_power_b, (int32_t) val, pf);
147
148 // Current
149 err = this->ade_read_32(0x031A, &val);
150 ADE_PUBLISH(current_a, (uint32_t) val, 100000.0f);
151 err = this->ade_read_32(0x031B, &val);
152 ADE_PUBLISH(current_b, (uint32_t) val, 100000.0f);
153
154 // Voltage
155 err = this->ade_read_32(0x031C, &val);
156 ADE_PUBLISH(voltage, (uint32_t) val, 26000.0f);
157
158 // Frequency
159 err = this->ade_read_16(0x010E, &val_16);
160 ADE_PUBLISH(frequency, 223750.0f, 1 + val_16);
161}
162
163} // namespace ade7953_base
164} // namespace esphome
uint16_le_t frequency
Definition bl0942.h:6
ESPDEPRECATED("Use const char* or uint32_t overload instead. Removed in 2026.7.0", "2026.1.0") void set_timeout(const std voi set_timeout)(const char *name, uint32_t timeout, std::function< void()> &&f)
Set a timeout function with a unique name.
Definition component.h:510
virtual void setup()=0
virtual bool ade_write_32(uint16_t reg, uint32_t value)=0
virtual bool ade_read_16(uint16_t reg, uint16_t *value)=0
sensor::Sensor * reactive_power_b_sensor_
sensor::Sensor * reactive_power_a_sensor_
sensor::Sensor * current_a_sensor_
sensor::Sensor * power_factor_b_sensor_
sensor::Sensor * power_factor_a_sensor_
virtual bool ade_read_8(uint16_t reg, uint8_t *value)=0
sensor::Sensor * active_power_a_sensor_
virtual bool ade_read_32(uint16_t reg, uint32_t *value)=0
sensor::Sensor * apparent_power_b_sensor_
virtual bool ade_write_16(uint16_t reg, uint16_t value)=0
sensor::Sensor * apparent_power_a_sensor_
sensor::Sensor * current_b_sensor_
virtual bool ade_write_8(uint16_t reg, uint8_t value)=0
sensor::Sensor * active_power_b_sensor_
sensor::Sensor * voltage_sensor_
mopeka_std_values val[3]
constexpr uint16_t CONFIG_LOCK_BIT
constexpr uint16_t CONFIG_DEFAULT
Providing packet encoding functions for exchanging data with a remote host.
Definition a01nyub.cpp:7
uint32_t IRAM_ATTR HOT millis()
Definition core.cpp:26
static void uint32_t