ESPHome  2024.5.0
ade7953_base.cpp
Go to the documentation of this file.
1 #include "ade7953_base.h"
2 #include "esphome/core/log.h"
3 
4 namespace esphome {
5 namespace ade7953_base {
6 
7 static const char *const TAG = "ade7953";
8 
9 static const float ADE_POWER_FACTOR = 154.0f;
10 static const float ADE_WATTSEC_POWER_FACTOR = ADE_POWER_FACTOR * ADE_POWER_FACTOR / 3600;
11 
13  if (this->irq_pin_ != nullptr) {
14  this->irq_pin_->setup();
15  }
16 
17  // The chip might take up to 100ms to initialise
18  this->set_timeout(100, [this]() {
19  // this->ade_write_8(0x0010, 0x04);
20  this->ade_write_8(0x00FE, 0xAD);
21  this->ade_write_16(0x0120, 0x0030);
22  // Set gains
23  this->ade_write_8(PGA_V_8, pga_v_);
24  this->ade_write_8(PGA_IA_8, pga_ia_);
25  this->ade_write_8(PGA_IB_8, pga_ib_);
26  this->ade_write_32(AVGAIN_32, vgain_);
27  this->ade_write_32(AIGAIN_32, aigain_);
28  this->ade_write_32(BIGAIN_32, bigain_);
29  this->ade_write_32(AWGAIN_32, awgain_);
30  this->ade_write_32(BWGAIN_32, bwgain_);
31  // Read back gains for debugging
32  this->ade_read_8(PGA_V_8, &pga_v_);
33  this->ade_read_8(PGA_IA_8, &pga_ia_);
34  this->ade_read_8(PGA_IB_8, &pga_ib_);
35  this->ade_read_32(AVGAIN_32, &vgain_);
36  this->ade_read_32(AIGAIN_32, &aigain_);
37  this->ade_read_32(BIGAIN_32, &bigain_);
38  this->ade_read_32(AWGAIN_32, &awgain_);
39  this->ade_read_32(BWGAIN_32, &bwgain_);
40  this->last_update_ = millis();
41  this->is_setup_ = true;
42  });
43 }
44 
46  LOG_PIN(" IRQ Pin: ", irq_pin_);
47  LOG_UPDATE_INTERVAL(this);
48  LOG_SENSOR(" ", "Voltage Sensor", this->voltage_sensor_);
49  LOG_SENSOR(" ", "Current A Sensor", this->current_a_sensor_);
50  LOG_SENSOR(" ", "Current B Sensor", this->current_b_sensor_);
51  LOG_SENSOR(" ", "Power Factor A Sensor", this->power_factor_a_sensor_);
52  LOG_SENSOR(" ", "Power Factor B Sensor", this->power_factor_b_sensor_);
53  LOG_SENSOR(" ", "Apparent Power A Sensor", this->apparent_power_a_sensor_);
54  LOG_SENSOR(" ", "Apparent Power B Sensor", this->apparent_power_b_sensor_);
55  LOG_SENSOR(" ", "Active Power A Sensor", this->active_power_a_sensor_);
56  LOG_SENSOR(" ", "Active Power B Sensor", this->active_power_b_sensor_);
57  LOG_SENSOR(" ", "Rective Power A Sensor", this->reactive_power_a_sensor_);
58  LOG_SENSOR(" ", "Reactive Power B Sensor", this->reactive_power_b_sensor_);
59  ESP_LOGCONFIG(TAG, " USE_ACC_ENERGY_REGS: %d", this->use_acc_energy_regs_);
60  ESP_LOGCONFIG(TAG, " PGA_V_8: 0x%X", pga_v_);
61  ESP_LOGCONFIG(TAG, " PGA_IA_8: 0x%X", pga_ia_);
62  ESP_LOGCONFIG(TAG, " PGA_IB_8: 0x%X", pga_ib_);
63  ESP_LOGCONFIG(TAG, " VGAIN_32: 0x%08jX", (uintmax_t) vgain_);
64  ESP_LOGCONFIG(TAG, " AIGAIN_32: 0x%08jX", (uintmax_t) aigain_);
65  ESP_LOGCONFIG(TAG, " BIGAIN_32: 0x%08jX", (uintmax_t) bigain_);
66  ESP_LOGCONFIG(TAG, " AWGAIN_32: 0x%08jX", (uintmax_t) awgain_);
67  ESP_LOGCONFIG(TAG, " BWGAIN_32: 0x%08jX", (uintmax_t) bwgain_);
68 }
69 
70 #define ADE_PUBLISH_(name, val, factor) \
71  if (err == 0 && this->name##_sensor_) { \
72  float value = (val) / (factor); \
73  this->name##_sensor_->publish_state(value); \
74  }
75 #define ADE_PUBLISH(name, val, factor) ADE_PUBLISH_(name, val, factor)
76 
78  if (!this->is_setup_)
79  return;
80 
81  bool err;
82 
83  uint32_t interrupts_a = 0;
84  uint32_t interrupts_b = 0;
85  if (this->irq_pin_ != nullptr) {
86  // Read and reset interrupts
87  this->ade_read_32(0x032E, &interrupts_a);
88  this->ade_read_32(0x0331, &interrupts_b);
89  }
90 
91  uint32_t val;
92  uint16_t val_16;
93  uint16_t reg;
94 
95  // Power factor
96  err = this->ade_read_16(0x010A, &val_16);
97  ADE_PUBLISH(power_factor_a, (int16_t) val_16, (0x7FFF / 100.0f));
98  err = this->ade_read_16(0x010B, &val_16);
99  ADE_PUBLISH(power_factor_b, (int16_t) val_16, (0x7FFF / 100.0f));
100 
101  float pf = ADE_POWER_FACTOR;
102  if (this->use_acc_energy_regs_) {
103  const uint32_t now = millis();
104  const auto diff = now - this->last_update_;
105  this->last_update_ = now;
106  // prevent DIV/0
107  pf = ADE_WATTSEC_POWER_FACTOR * (diff < 10 ? 10 : diff) / 1000;
108  ESP_LOGVV(TAG, "ADE7953::update() diff=%d pf=%f", diff, pf);
109  }
110 
111  // Apparent power
112  reg = this->use_acc_energy_regs_ ? 0x0322 : 0x0310;
113  err = this->ade_read_32(reg, &val);
114  ADE_PUBLISH(apparent_power_a, (int32_t) val, pf);
115  err = this->ade_read_32(reg + 1, &val);
116  ADE_PUBLISH(apparent_power_b, (int32_t) val, pf);
117 
118  // Active power
119  reg = this->use_acc_energy_regs_ ? 0x031E : 0x0312;
120  err = this->ade_read_32(reg, &val);
121  ADE_PUBLISH(active_power_a, (int32_t) val, pf);
122  err = this->ade_read_32(reg + 1, &val);
123  ADE_PUBLISH(active_power_b, (int32_t) val, pf);
124 
125  // Reactive power
126  reg = this->use_acc_energy_regs_ ? 0x0320 : 0x0314;
127  err = this->ade_read_32(reg, &val);
128  ADE_PUBLISH(reactive_power_a, (int32_t) val, pf);
129  err = this->ade_read_32(reg + 1, &val);
130  ADE_PUBLISH(reactive_power_b, (int32_t) val, pf);
131 
132  // Current
133  err = this->ade_read_32(0x031A, &val);
134  ADE_PUBLISH(current_a, (uint32_t) val, 100000.0f);
135  err = this->ade_read_32(0x031B, &val);
136  ADE_PUBLISH(current_b, (uint32_t) val, 100000.0f);
137 
138  // Voltage
139  err = this->ade_read_32(0x031C, &val);
140  ADE_PUBLISH(voltage, (uint32_t) val, 26000.0f);
141 
142  // Frequency
143  err = this->ade_read_16(0x010E, &val_16);
144  ADE_PUBLISH(frequency, 223750.0f, 1 + val_16);
145 }
146 
147 } // namespace ade7953_base
148 } // namespace esphome
sensor::Sensor * apparent_power_b_sensor_
Definition: ade7953_base.h:93
sensor::Sensor * voltage_sensor_
Definition: ade7953_base.h:88
virtual bool ade_read_32(uint16_t reg, uint32_t *value)=0
sensor::Sensor * reactive_power_a_sensor_
Definition: ade7953_base.h:96
sensor::Sensor * power_factor_b_sensor_
Definition: ade7953_base.h:99
void set_timeout(const std::string &name, uint32_t timeout, std::function< void()> &&f)
Set a timeout function with a unique name.
Definition: component.cpp:69
mopeka_std_values val[4]
virtual void setup()=0
virtual bool ade_write_32(uint16_t reg, uint32_t value)=0
uint32_t IRAM_ATTR HOT millis()
Definition: core.cpp:25
sensor::Sensor * active_power_b_sensor_
Definition: ade7953_base.h:95
virtual bool ade_read_8(uint16_t reg, uint8_t *value)=0
sensor::Sensor * power_factor_a_sensor_
Definition: ade7953_base.h:98
uint16_le_t frequency
Definition: bl0942.h:21
InternalGPIOPin * irq_pin_
Definition: ade7953_base.h:86
virtual bool ade_write_16(uint16_t reg, uint16_t value)=0
sensor::Sensor * reactive_power_b_sensor_
Definition: ade7953_base.h:97
sensor::Sensor * current_b_sensor_
Definition: ade7953_base.h:91
sensor::Sensor * active_power_a_sensor_
Definition: ade7953_base.h:94
This is a workaround until we can figure out a way to get the tflite-micro idf component code availab...
Definition: a01nyub.cpp:7
virtual bool ade_read_16(uint16_t reg, uint16_t *value)=0
sensor::Sensor * apparent_power_a_sensor_
Definition: ade7953_base.h:92
sensor::Sensor * current_a_sensor_
Definition: ade7953_base.h:90
virtual bool ade_write_8(uint16_t reg, uint8_t value)=0