9 static const char *
const TAG =
"atm90e32";
13 for (uint8_t phase = 0; phase < 3; phase++) {
14 if (this->
phase_[phase].voltage_sensor_ !=
nullptr) {
18 for (uint8_t phase = 0; phase < 3; phase++) {
19 if (this->
phase_[phase].current_sensor_ !=
nullptr) {
23 for (uint8_t phase = 0; phase < 3; phase++) {
24 if (this->
phase_[phase].power_sensor_ !=
nullptr) {
28 for (uint8_t phase = 0; phase < 3; phase++) {
29 if (this->
phase_[phase].power_factor_sensor_ !=
nullptr) {
33 for (uint8_t phase = 0; phase < 3; phase++) {
34 if (this->
phase_[phase].reactive_power_sensor_ !=
nullptr) {
38 for (uint8_t phase = 0; phase < 3; phase++) {
39 if (this->
phase_[phase].forward_active_energy_sensor_ !=
nullptr) {
43 for (uint8_t phase = 0; phase < 3; phase++) {
44 if (this->
phase_[phase].reverse_active_energy_sensor_ !=
nullptr) {
48 for (uint8_t phase = 0; phase < 3; phase++) {
49 if (this->
phase_[phase].phase_angle_sensor_ !=
nullptr) {
53 for (uint8_t phase = 0; phase < 3; phase++) {
54 if (this->
phase_[phase].harmonic_active_power_sensor_ !=
nullptr) {
58 for (uint8_t phase = 0; phase < 3; phase++) {
59 if (this->
phase_[phase].peak_current_sensor_ !=
nullptr) {
64 for (uint8_t phase = 0; phase < 3; phase++) {
65 if (this->
phase_[phase].voltage_sensor_ !=
nullptr) {
69 for (uint8_t phase = 0; phase < 3; phase++) {
70 if (this->
phase_[phase].current_sensor_ !=
nullptr) {
74 for (uint8_t phase = 0; phase < 3; phase++) {
75 if (this->
phase_[phase].power_sensor_ !=
nullptr) {
79 for (uint8_t phase = 0; phase < 3; phase++) {
80 if (this->
phase_[phase].power_factor_sensor_ !=
nullptr) {
84 for (uint8_t phase = 0; phase < 3; phase++) {
85 if (this->
phase_[phase].reactive_power_sensor_ !=
nullptr) {
89 for (uint8_t phase = 0; phase < 3; phase++) {
90 if (this->
phase_[phase].forward_active_energy_sensor_ !=
nullptr) {
95 for (uint8_t phase = 0; phase < 3; phase++) {
96 if (this->
phase_[phase].reverse_active_energy_sensor_ !=
nullptr) {
101 for (uint8_t phase = 0; phase < 3; phase++) {
102 if (this->
phase_[phase].phase_angle_sensor_ !=
nullptr) {
106 for (uint8_t phase = 0; phase < 3; phase++) {
107 if (this->
phase_[phase].harmonic_active_power_sensor_ !=
nullptr) {
112 for (uint8_t phase = 0; phase < 3; phase++) {
113 if (this->
phase_[phase].peak_current_sensor_ !=
nullptr) {
127 if (this->
read16_(ATM90E32_REGISTER_METEREN) != 1) {
165 ESP_LOGI(TAG,
"PhaseA Vo=%5d PhaseB Vo=%5d PhaseC Vo=%5d", this->
offset_phase_[
PHASEA].voltage_offset_,
167 ESP_LOGI(TAG,
"PhaseA Io=%5d PhaseB Io=%5d PhaseC Io=%5d", this->
offset_phase_[
PHASEA].current_offset_,
192 ESP_LOGI(TAG,
"PhaseA Vo=%5d PhaseB Vo=%5d PhaseC Vo=%5d", this->
offset_phase_[
PHASEA].voltage_offset_,
194 ESP_LOGI(TAG,
"PhaseA Io=%5d PhaseB Io=%5d PhaseC Io=%5d", this->
offset_phase_[
PHASEA].current_offset_,
199 ESP_LOGCONFIG(TAG,
"Setting up ATM90E32 Component...");
206 uint16_t mmode0 = 0x87;
216 this->
write16_(ATM90E32_REGISTER_SOFTRESET, 0x789A);
218 this->
write16_(ATM90E32_REGISTER_CFGREGACCEN, 0x55AA);
219 if (this->
read16_(ATM90E32_REGISTER_LASTSPIDATA) != 0x55AA) {
220 ESP_LOGW(TAG,
"Could not initialize ATM90E32 IC, check SPI settings");
225 this->
write16_(ATM90E32_REGISTER_METEREN, 0x0001);
226 this->
write16_(ATM90E32_REGISTER_SAGPEAKDETCFG, 0xFF3F);
227 this->
write16_(ATM90E32_REGISTER_PLCONSTH, 0x0861);
228 this->
write16_(ATM90E32_REGISTER_PLCONSTL, 0xC468);
229 this->
write16_(ATM90E32_REGISTER_ZXCONFIG, 0xD654);
230 this->
write16_(ATM90E32_REGISTER_MMODE0, mmode0);
232 this->
write16_(ATM90E32_REGISTER_PSTARTTH, 0x1D4C);
233 this->
write16_(ATM90E32_REGISTER_QSTARTTH, 0x1D4C);
234 this->
write16_(ATM90E32_REGISTER_SSTARTTH, 0x1D4C);
235 this->
write16_(ATM90E32_REGISTER_PPHASETH, 0x02EE);
236 this->
write16_(ATM90E32_REGISTER_QPHASETH, 0x02EE);
246 this->
write16_(ATM90E32_REGISTER_CFGREGACCEN, 0x0000);
250 ESP_LOGCONFIG(
"",
"ATM90E32:");
251 LOG_PIN(
" CS Pin: ", this->
cs_);
253 ESP_LOGE(TAG,
"Communication with ATM90E32 failed!");
255 LOG_UPDATE_INTERVAL(
this);
256 LOG_SENSOR(
" ",
"Voltage A", this->
phase_[
PHASEA].voltage_sensor_);
257 LOG_SENSOR(
" ",
"Current A", this->
phase_[
PHASEA].current_sensor_);
258 LOG_SENSOR(
" ",
"Power A", this->
phase_[
PHASEA].power_sensor_);
259 LOG_SENSOR(
" ",
"Reactive Power A", this->
phase_[
PHASEA].reactive_power_sensor_);
260 LOG_SENSOR(
" ",
"PF A", this->
phase_[
PHASEA].power_factor_sensor_);
261 LOG_SENSOR(
" ",
"Active Forward Energy A", this->
phase_[
PHASEA].forward_active_energy_sensor_);
262 LOG_SENSOR(
" ",
"Active Reverse Energy A", this->
phase_[
PHASEA].reverse_active_energy_sensor_);
263 LOG_SENSOR(
" ",
"Harmonic Power A", this->
phase_[
PHASEA].harmonic_active_power_sensor_);
264 LOG_SENSOR(
" ",
"Phase Angle A", this->
phase_[
PHASEA].phase_angle_sensor_);
265 LOG_SENSOR(
" ",
"Peak Current A", this->
phase_[
PHASEA].peak_current_sensor_);
266 LOG_SENSOR(
" ",
"Voltage B", this->
phase_[
PHASEB].voltage_sensor_);
267 LOG_SENSOR(
" ",
"Current B", this->
phase_[
PHASEB].current_sensor_);
268 LOG_SENSOR(
" ",
"Power B", this->
phase_[
PHASEB].power_sensor_);
269 LOG_SENSOR(
" ",
"Reactive Power B", this->
phase_[
PHASEB].reactive_power_sensor_);
270 LOG_SENSOR(
" ",
"PF B", this->
phase_[
PHASEB].power_factor_sensor_);
271 LOG_SENSOR(
" ",
"Active Forward Energy B", this->
phase_[
PHASEB].forward_active_energy_sensor_);
272 LOG_SENSOR(
" ",
"Active Reverse Energy B", this->
phase_[
PHASEB].reverse_active_energy_sensor_);
273 LOG_SENSOR(
" ",
"Harmonic Power A", this->
phase_[
PHASEB].harmonic_active_power_sensor_);
274 LOG_SENSOR(
" ",
"Phase Angle A", this->
phase_[
PHASEB].phase_angle_sensor_);
275 LOG_SENSOR(
" ",
"Peak Current A", this->
phase_[
PHASEB].peak_current_sensor_);
276 LOG_SENSOR(
" ",
"Voltage C", this->
phase_[
PHASEC].voltage_sensor_);
277 LOG_SENSOR(
" ",
"Current C", this->
phase_[
PHASEC].current_sensor_);
278 LOG_SENSOR(
" ",
"Power C", this->
phase_[
PHASEC].power_sensor_);
279 LOG_SENSOR(
" ",
"Reactive Power C", this->
phase_[
PHASEC].reactive_power_sensor_);
280 LOG_SENSOR(
" ",
"PF C", this->
phase_[
PHASEC].power_factor_sensor_);
281 LOG_SENSOR(
" ",
"Active Forward Energy C", this->
phase_[
PHASEC].forward_active_energy_sensor_);
282 LOG_SENSOR(
" ",
"Active Reverse Energy C", this->
phase_[
PHASEC].reverse_active_energy_sensor_);
283 LOG_SENSOR(
" ",
"Harmonic Power A", this->
phase_[
PHASEC].harmonic_active_power_sensor_);
284 LOG_SENSOR(
" ",
"Phase Angle A", this->
phase_[
PHASEC].phase_angle_sensor_);
285 LOG_SENSOR(
" ",
"Peak Current A", this->
phase_[
PHASEC].peak_current_sensor_);
296 uint8_t addrh = (1 << 7) | ((a_register >> 8) & 0x03);
297 uint8_t addrl = (a_register & 0xFF);
307 output = (uint16_t(data[0] & 0xFF) << 8) | (data[1] & 0xFF);
308 ESP_LOGVV(TAG,
"read16_ 0x%04" PRIX16
" output 0x%04" PRIX16, a_register, output);
313 const uint16_t val_h = this->
read16_(addr_h);
314 const uint16_t val_l = this->
read16_(addr_l);
315 const int32_t
val = (val_h << 16) | val_l;
318 "read32_ addr_h 0x%04" PRIX16
" val_h 0x%04" PRIX16
" addr_l 0x%04" PRIX16
" val_l 0x%04" PRIX16
320 addr_h, val_h, addr_l, val_l, val);
326 ESP_LOGVV(TAG,
"write16_ 0x%04" PRIX16
" val 0x%04" PRIX16, a_register, val);
331 if (this->
read16_(ATM90E32_REGISTER_LASTSPIDATA) != val)
332 ESP_LOGW(TAG,
"SPI write error 0x%04X val 0x%04X", a_register, val);
362 const uint16_t voltage = this->
read16_(ATM90E32_REGISTER_URMS + phase);
363 if (this->
read16_(ATM90E32_REGISTER_LASTSPIDATA) != voltage)
364 ESP_LOGW(TAG,
"SPI URMS voltage register read error.");
365 return (
float) voltage / 100;
369 const uint8_t reads = 10;
370 uint32_t accumulation = 0;
371 uint16_t voltage = 0;
372 for (uint8_t i = 0; i < reads; i++) {
373 voltage = this->
read16_(ATM90E32_REGISTER_URMS + phase);
374 if (this->
read16_(ATM90E32_REGISTER_LASTSPIDATA) != voltage)
375 ESP_LOGW(TAG,
"SPI URMS voltage register read error.");
376 accumulation += voltage;
378 voltage = accumulation / reads;
384 const uint8_t reads = 10;
385 uint32_t accumulation = 0;
386 uint16_t current = 0;
387 for (uint8_t i = 0; i < reads; i++) {
388 current = this->
read16_(ATM90E32_REGISTER_IRMS + phase);
389 if (this->
read16_(ATM90E32_REGISTER_LASTSPIDATA) != current)
390 ESP_LOGW(TAG,
"SPI IRMS current register read error.");
391 accumulation += current;
393 current = accumulation / reads;
399 const uint16_t current = this->
read16_(ATM90E32_REGISTER_IRMS + phase);
400 if (this->
read16_(ATM90E32_REGISTER_LASTSPIDATA) != current)
401 ESP_LOGW(TAG,
"SPI IRMS current register read error.");
402 return (
float) current / 1000;
406 const int val = this->
read32_(ATM90E32_REGISTER_PMEAN + phase, ATM90E32_REGISTER_PMEANLSB + phase);
407 return val * 0.00032f;
411 const int val = this->
read32_(ATM90E32_REGISTER_QMEAN + phase, ATM90E32_REGISTER_QMEANLSB + phase);
412 return val * 0.00032f;
416 const int16_t powerfactor = this->
read16_(ATM90E32_REGISTER_PFMEAN + phase);
417 if (this->
read16_(ATM90E32_REGISTER_LASTSPIDATA) != powerfactor)
418 ESP_LOGW(TAG,
"SPI power factor read error.");
419 return (
float) powerfactor / 1000;
423 const uint16_t
val = this->
read16_(ATM90E32_REGISTER_APENERGY + phase);
424 if ((UINT32_MAX - this->
phase_[phase].cumulative_forward_active_energy_) > val) {
429 return ((
float) this->
phase_[phase].cumulative_forward_active_energy_ * 10 / 3200);
433 const uint16_t
val = this->
read16_(ATM90E32_REGISTER_ANENERGY);
434 if (UINT32_MAX - this->
phase_[phase].cumulative_reverse_active_energy_ > val) {
439 return ((
float) this->
phase_[phase].cumulative_reverse_active_energy_ * 10 / 3200);
443 int val = this->
read32_(ATM90E32_REGISTER_PMEANH + phase, ATM90E32_REGISTER_PMEANHLSB + phase);
444 return val * 0.00032f;
448 uint16_t
val = this->
read16_(ATM90E32_REGISTER_PANGLE + phase) / 10.0;
449 return (
float) (val > 180) ? val - 360.0 : val;
453 int16_t
val = (float) this->
read16_(ATM90E32_REGISTER_IPEAK + phase);
461 const uint16_t freq = this->
read16_(ATM90E32_REGISTER_FREQ);
462 return (
float) freq / 100;
466 const uint16_t ctemp = this->
read16_(ATM90E32_REGISTER_TEMP);
467 return (
float) ctemp;
471 const uint8_t num_reads = 5;
472 uint64_t total_value = 0;
473 for (
int i = 0; i < num_reads; ++i) {
474 const uint32_t measurement_value =
read32_(ATM90E32_REGISTER_URMS + phase, ATM90E32_REGISTER_URMSLSB + phase);
475 total_value += measurement_value;
477 const uint32_t average_value = total_value / num_reads;
478 const uint32_t shifted_value = average_value >> 7;
479 const uint32_t voltage_offset = ~shifted_value + 1;
480 return voltage_offset & 0xFFFF;
484 const uint8_t num_reads = 5;
485 uint64_t total_value = 0;
486 for (
int i = 0; i < num_reads; ++i) {
487 const uint32_t measurement_value =
read32_(ATM90E32_REGISTER_IRMS + phase, ATM90E32_REGISTER_IRMSLSB + phase);
488 total_value += measurement_value;
490 const uint32_t average_value = total_value / num_reads;
491 const uint32_t current_offset = ~average_value + 1;
492 return current_offset & 0xFFFF;
float get_local_phase_active_power_(uint8_t)
sensor::Sensor * voltage_sensor_
float reverse_active_energy_
sensor::Sensor * forward_active_energy_sensor_
float get_phase_power_factor_(uint8_t)
float get_setup_priority() const override
float get_local_phase_current_(uint8_t)
void write16_(uint16_t a_register, uint16_t val)
void status_set_warning(const char *message="unspecified")
ESPPreferenceObject pref_
void clear_offset_calibrations()
float get_phase_reactive_power_(uint8_t)
uint32_t cumulative_reverse_active_energy_
void spi_setup() override
int read32_(uint16_t addr_h, uint16_t addr_l)
struct esphome::atm90e32::ATM90E32Component::Calibration offset_phase_[3]
sensor::Sensor * current_sensor_
const std::string & get_friendly_name() const
Get the friendly name of this Application set by pre_setup().
void write_byte(uint8_t data)
void IRAM_ATTR HOT delay_microseconds_safe(uint32_t us)
Delay for the given amount of microseconds, possibly yielding to other processes during the wait...
static const uint8_t PHASEC
static const uint8_t PHASEB
float get_chip_temperature_()
bool peak_current_signed_
bool enable_offset_calibration_
float get_phase_forward_active_energy_(uint8_t)
sensor::Sensor * harmonic_active_power_sensor_
void dump_config() override
void read_array(uint8_t *data, size_t length)
static const uint8_t PHASEA
float get_phase_peak_current_(uint8_t)
ESPPreferences * global_preferences
float get_phase_current_avg_(uint8_t)
sensor::Sensor * phase_angle_sensor_
void status_clear_warning()
float forward_active_energy_
void publish_state(float state)
Publish a new state to the front-end.
float get_local_phase_voltage_(uint8_t)
struct esphome::atm90e32::ATM90E32Component::ATM90E32Phase phase_[3]
float get_local_phase_forward_active_energy_(uint8_t)
uint16_t calibrate_voltage_offset_phase(uint8_t)
Application App
Global storage of Application pointer - only one Application can exist.
sensor::Sensor * peak_current_sensor_
uint32_t cumulative_forward_active_energy_
float get_phase_current_(uint8_t)
sensor::Sensor * reverse_active_energy_sensor_
float get_phase_reverse_active_energy_(uint8_t)
float get_local_phase_peak_current_(uint8_t)
float get_phase_voltage_avg_(uint8_t)
float get_phase_active_power_(uint8_t)
float get_phase_voltage_(uint8_t)
void run_offset_calibrations()
bool get_publish_interval_flag_()
float get_phase_harmonic_active_power_(uint8_t)
float harmonic_active_power_
void restore_calibrations_()
virtual ESPPreferenceObject make_preference(size_t length, uint32_t type, bool in_flash)=0
uint32_t fnv1_hash(const std::string &str)
Calculate a FNV-1 hash of str.
uint16_t read16_(uint16_t a_register)
virtual void mark_failed()
Mark this component as failed.
const float IO
For components that represent GPIO pins like PCF8573.
sensor::Sensor * chip_temperature_sensor_
float get_phase_angle_(uint8_t)
float get_local_phase_reverse_active_energy_(uint8_t)
Implementation of SPI Controller mode.
uint16_t calibrate_current_offset_phase(uint8_t)
sensor::Sensor * power_sensor_
void write_byte16(uint16_t data)
Write 16 bit data.
sensor::Sensor * freq_sensor_
sensor::Sensor * reactive_power_sensor_
float get_local_phase_harmonic_active_power_(uint8_t)
float get_local_phase_power_factor_(uint8_t)
void set_publish_interval_flag_(bool flag)
float get_local_phase_angle_(uint8_t)
float get_local_phase_reactive_power_(uint8_t)
void IRAM_ATTR HOT delay(uint32_t ms)
sensor::Sensor * power_factor_sensor_