From 8244ad1c8a75d259bd6d9a8c67b21cbea6391f92 Mon Sep 17 00:00:00 2001 From: Siwat Sirichai Date: Sat, 10 Feb 2024 16:20:36 +0700 Subject: [PATCH] beta current transformer card --- .../lib/ESPMegaPRO/CurrentTransformer.cpp | 93 +++++++++++++++++++ .../lib/ESPMegaPRO/CurrentTransformer.hpp | 46 +++++++++ 2 files changed, 139 insertions(+) create mode 100644 ESPMegaPRO-OS-SDK/lib/ESPMegaPRO/CurrentTransformer.cpp create mode 100644 ESPMegaPRO-OS-SDK/lib/ESPMegaPRO/CurrentTransformer.hpp diff --git a/ESPMegaPRO-OS-SDK/lib/ESPMegaPRO/CurrentTransformer.cpp b/ESPMegaPRO-OS-SDK/lib/ESPMegaPRO/CurrentTransformer.cpp new file mode 100644 index 0000000..ce5c835 --- /dev/null +++ b/ESPMegaPRO-OS-SDK/lib/ESPMegaPRO/CurrentTransformer.cpp @@ -0,0 +1,93 @@ +#include + +CurrentTransformer::CurrentTransformer(AnalogCard* analogCard, uint8_t pin, float *voltage, std::function adcToCurrent, uint32_t conversionInterval) +{ + this->analogCard = analogCard; + this->pin = pin; + this->voltage = voltage; + this->adcToCurrent = adcToCurrent; +} + +void CurrentTransformer::bindFRAM(FRAM *fram, uint8_t framAddress) +{ + this->fram = fram; + this->framAddress = framAddress; +} + +void CurrentTransformer::begin() +{ + this->beginConversion(); +} + +void CurrentTransformer::loop() +{ + if (this->lastConversionTime == 0) { + this->lastConversionTime = millis(); + } + static uint32_t lastConversionLoopTime = 0; + if (millis() - lastConversionLoopTime > this->conversionInterval) { + this->beginConversion(); + lastConversionLoopTime = millis(); + } +} + +void CurrentTransformer::beginConversion() +{ + uint16_t adcValue = this->analogCard->analogRead(this->pin); + this->current = this->adcToCurrent(adcValue); + this->setEnergy(this->energy + this->current * *this->voltage * (millis() - this->lastConversionTime) / 3600000); // in Wh + this->lastConversionTime = millis(); + for (auto const& callback : this->callbacks) { + callback.second(this->current, this->energy); + } +} + +void CurrentTransformer::setEnergy(float energy) +{ + this->energy = energy; + if (this->autoSave) { + this->saveEnergy(); + } +} + +void CurrentTransformer::resetEnergy() +{ + this->setEnergy(0); +} + +float CurrentTransformer::getCurrent() +{ + return this->current; +} + +long double CurrentTransformer::getEnergy() +{ + return this->energy; +} + +uint8_t CurrentTransformer::registerCallback(std::function callback) { + this->callbacks[this->handler_count] = callback; + return this->handler_count++; +} +void CurrentTransformer::unregisterCallback(uint8_t handler) { + this->callbacks.erase(handler); +} + +void CurrentTransformer::saveEnergy(){ + this->fram->write(this->framAddress, (uint8_t*)&this->energy, 16); +} +void CurrentTransformer::loadEnergy(){ + this->fram->read(this->framAddress, (uint8_t*)&this->energy, 16); +} + +void CurrentTransformer::setEnergyAutoSave(bool autoSave){ + this->autoSave = autoSave; +} + +float CurrentTransformer::getVoltage(){ + return *this->voltage; +} + +float CurrentTransformer::getPower(){ + return this->current * *this->voltage; +} \ No newline at end of file diff --git a/ESPMegaPRO-OS-SDK/lib/ESPMegaPRO/CurrentTransformer.hpp b/ESPMegaPRO-OS-SDK/lib/ESPMegaPRO/CurrentTransformer.hpp new file mode 100644 index 0000000..daf0e9f --- /dev/null +++ b/ESPMegaPRO-OS-SDK/lib/ESPMegaPRO/CurrentTransformer.hpp @@ -0,0 +1,46 @@ +#pragma once +#include +#include +#include + +/** + * @brief The CurrentTransformer class is a class for reading the current and energy from a current transformer that's connected to the AnalogCard. + * Also supports storing energy to FRAM. + */ + +class CurrentTransformer +{ + public: + CurrentTransformer(AnalogCard* analogCard, uint8_t pin, float *voltage, std::function adcToCurrent, uint32_t conversionInterval); + void bindFRAM(FRAM *fram, uint8_t framAddress); // Takes 16 bytes of FRAM (long double energy) + void begin(); + void loop(); + void beginConversion(); + void setEnergy(float energy); + void resetEnergy(); + float getCurrent(); + long double getEnergy(); + float getPower(); + void saveEnergy(); + void loadEnergy(); + void setEnergyAutoSave(bool autoSave); + float getVoltage(); + uint8_t registerCallback(std::function callback); + void unregisterCallback(uint8_t handler); + private: + AnalogCard* analogCard; + uint8_t pin; + uint8_t framAddress; + FRAM *fram; + uint32_t conversionInterval; + bool autoSave; + float calibration; + long double energy; + float current; + float *voltage; + uint32_t lastConversionTime; + std::function adcToCurrent; // std::function that convert adc value to current in amps + uint8_t handler_count = 0; + std::map> callbacks; +}; +