From 5757e93b57d58a64df202849397f03127763ee30 Mon Sep 17 00:00:00 2001 From: Siwat Sirichai Date: Fri, 13 Oct 2023 22:57:19 +0700 Subject: [PATCH 1/2] initial energy monitoring implementation --- src/espmega_iot_emon.cpp | 39 +++++++++++++++++++++++++++++++++++++++ src/espmega_iot_emon.hpp | 18 ++++++++++++++++++ 2 files changed, 57 insertions(+) create mode 100644 src/espmega_iot_emon.cpp create mode 100644 src/espmega_iot_emon.hpp diff --git a/src/espmega_iot_emon.cpp b/src/espmega_iot_emon.cpp new file mode 100644 index 0000000..2cb6054 --- /dev/null +++ b/src/espmega_iot_emon.cpp @@ -0,0 +1,39 @@ +#include "espmega_iot_emon.hpp" + +ESPMega_CT::ESPMega_CT(uint8_t analog_pin, float (*adc_to_watts)(uint16_t adc_value), uint32_t fram_address) +{ + this->analog_pin = analog_pin; + this->adc_to_watts = adc_to_watts; + this->fram_address = fram_address; +} + +void ESPMega_CT::begin() +{ + this->last_conversion_timestamp = millis(); + ESPMega_FRAM.read(fram_address, (uint8_t *)&this->energy, 16); + this->power = adc_to_watts(ESPMega_analogRead(this->analog_pin)); +} + +void ESPMega_CT::loop() +{ + this->energy += (millis() - this->last_conversion_timestamp) / 3600000 * this->power; + this->power = adc_to_watts(ESPMega_analogRead(this->analog_pin)); + this->last_conversion_timestamp = millis(); + ESPMega_FRAM.write(fram_address, (uint8_t *)&this->energy, 16); +} + +void ESPMega_CT::reset_energy() +{ + this->energy = 0; + ESPMega_FRAM.write16(fram_address, 0); +} + +long double ESPMega_CT::get_energy() +{ + return this->energy; +} + +float ESPMega_CT::get_power() +{ + return this->power; +} \ No newline at end of file diff --git a/src/espmega_iot_emon.hpp b/src/espmega_iot_emon.hpp new file mode 100644 index 0000000..e4993b8 --- /dev/null +++ b/src/espmega_iot_emon.hpp @@ -0,0 +1,18 @@ +#pragma once +#include +class ESPMega_CT { + public: + ESPMega_CT(uint8_t analog_pin,float(*adc_to_watts)(uint16_t adc_value), uint32_t fram_address); + void begin(); + void loop(); + float get_power(); + long double get_energy(); + void reset_energy(); + private: + uint8_t analog_pin; + uint32_t fram_address; + unsigned long last_conversion_timestamp; + float power; + long double energy; + float (*adc_to_watts)(uint16_t adc_value); +}; \ No newline at end of file From 10b55e5aa575154f9946e2e0805b444aba36c21f Mon Sep 17 00:00:00 2001 From: Siwat Sirichai Date: Fri, 13 Oct 2023 23:10:41 +0700 Subject: [PATCH 2/2] build in adc reference table --- src/espmega_iot_emon.cpp | 16 +++++++++++++++- src/espmega_iot_emon.hpp | 1 + 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/src/espmega_iot_emon.cpp b/src/espmega_iot_emon.cpp index 2cb6054..863de9f 100644 --- a/src/espmega_iot_emon.cpp +++ b/src/espmega_iot_emon.cpp @@ -3,8 +3,8 @@ ESPMega_CT::ESPMega_CT(uint8_t analog_pin, float (*adc_to_watts)(uint16_t adc_value), uint32_t fram_address) { this->analog_pin = analog_pin; - this->adc_to_watts = adc_to_watts; this->fram_address = fram_address; + this->adc_to_watts = adc_to_watts; } void ESPMega_CT::begin() @@ -36,4 +36,18 @@ long double ESPMega_CT::get_energy() float ESPMega_CT::get_power() { return this->power; +} + +float ESPMega_CT::adc_to_watts_builtin(uint16_t adc_value) +{ + const float RATIO = 0.1; + const float BURDEN_RESISTANCE = 20; + const float VOLTAGE = 220; + const uint16_t ADC_RANGE_START = 500; + const uint16_t ADC_RANGE_END = 16000; + const float ADC_RANGE = 12; + float burden_voltage = (adc_value - ADC_RANGE_START) / (ADC_RANGE_END - ADC_RANGE_START) * ADC_RANGE; + float secondary_current = burden_voltage / BURDEN_RESISTANCE; + float primary_current = secondary_current / RATIO; + return primary_current * VOLTAGE; } \ No newline at end of file diff --git a/src/espmega_iot_emon.hpp b/src/espmega_iot_emon.hpp index e4993b8..818ce36 100644 --- a/src/espmega_iot_emon.hpp +++ b/src/espmega_iot_emon.hpp @@ -15,4 +15,5 @@ class ESPMega_CT { float power; long double energy; float (*adc_to_watts)(uint16_t adc_value); + float adc_to_watts_builtin(uint16_t adc_value); }; \ No newline at end of file