From fffa34204836a9efabe2841024147d75959d9956 Mon Sep 17 00:00:00 2001 From: Jesse Hills Date: Mon, 27 May 2019 07:16:57 +1200 Subject: [PATCH] Add CT Clamp component --- esphome/components/ct_clamp/__init__.py | 0 .../components/ct_clamp/ct_clamp_sensor.cpp | 64 +++++++++++++++++++ esphome/components/ct_clamp/ct_clamp_sensor.h | 48 ++++++++++++++ esphome/components/ct_clamp/sensor.py | 31 +++++++++ 4 files changed, 143 insertions(+) create mode 100644 esphome/components/ct_clamp/__init__.py create mode 100644 esphome/components/ct_clamp/ct_clamp_sensor.cpp create mode 100644 esphome/components/ct_clamp/ct_clamp_sensor.h create mode 100644 esphome/components/ct_clamp/sensor.py diff --git a/esphome/components/ct_clamp/__init__.py b/esphome/components/ct_clamp/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/esphome/components/ct_clamp/ct_clamp_sensor.cpp b/esphome/components/ct_clamp/ct_clamp_sensor.cpp new file mode 100644 index 0000000000..c4a856f214 --- /dev/null +++ b/esphome/components/ct_clamp/ct_clamp_sensor.cpp @@ -0,0 +1,64 @@ +#include "esphome/components/ct_clamp/ct_clamp_sensor.h" +#include "esphome/core/log.h" + +namespace esphome { +namespace ct_clamp { + +static const char *TAG = "ct_clamp"; + +void CTClampSensor::setup() { + ESP_LOGCONFIG(TAG, "Setting up CT Clamp '%s'...", this->get_name().c_str()); + GPIOPin(this->pin_, INPUT).setup(); + + offsetI = ADC_COUNTS>>1; + +} + +void CTClampSensor::dump_config() { + LOG_SENSOR("", "CT Clamp Sensor", this); + ESP_LOGCONFIG(TAG, " Pin: %u", this->pin_); + ESP_LOGCONFIG(TAG, " Calibration: %u", this->calibration_); + ESP_LOGCONFIG(TAG, " Sample Size: %u", this->sample_size_); + ESP_LOGCONFIG(TAG, " Supply Voltage: %0.2fV", this->supply_voltage_); + LOG_UPDATE_INTERVAL(this); +} + +float CTClampSensor::get_setup_priority() const { return setup_priority::DATA; } + +void CTClampSensor::update() { + + for (unsigned int n = 0; n < this->sample_size_; n++) + { + sampleI = analogRead(this->pin_); + + // Digital low pass filter extracts the 1.65 V dc offset, + // then subtract this - signal is now centered on 0 counts. + offsetI = (offsetI + (sampleI-offsetI)/(ADC_COUNTS)); + filteredI = sampleI - offsetI; + + // Root-mean-square method current + // 1) square current values + sqI = filteredI * filteredI; + // 2) sum + sumI += sqI; + } + + double I_RATIO = this->calibration_ * ((supply_voltage_) / (ADC_COUNTS)); + Irms = I_RATIO * sqrt(sumI / this->sample_size_); + + //Reset accumulators + sumI = 0; + + ESP_LOGD(TAG, "'%s'", this->get_name().c_str(), Irms); + ESP_LOGD(TAG, " Amps=%.2fA", Irms); + ESP_LOGD(TAG, " Watts=%.0fW", Irms * 230.0); + + this->publish_state(Irms); +} + +#ifdef ARDUINO_ARCH_ESP8266 +std::string CTClampSensor::unique_id() { return get_mac_address() + "-ct_clamp"; } +#endif + +} // namespace ct_clamp +} // namespace esphome diff --git a/esphome/components/ct_clamp/ct_clamp_sensor.h b/esphome/components/ct_clamp/ct_clamp_sensor.h new file mode 100644 index 0000000000..a3d444f60c --- /dev/null +++ b/esphome/components/ct_clamp/ct_clamp_sensor.h @@ -0,0 +1,48 @@ +#pragma once + +#include "esphome/core/component.h" +#include "esphome/core/esphal.h" +#include "esphome/components/sensor/sensor.h" + +namespace esphome { +namespace ct_clamp { + +class CTClampSensor : public sensor::Sensor, public PollingComponent { + public: + /// Update CT Clamp sensor values. + void update() override; + /// Setup CT Sensor + void setup() override; + void dump_config() override; + /// `HARDWARE_LATE` setup priority. + float get_setup_priority() const override; + + void set_pin(uint8_t pin) { this->pin_ = pin; } + void set_calibration(uint32_t calibration) { this->calibration_ = calibration; } + void set_sample_size(uint32_t sample_size) { this->sample_size_ = sample_size; } + void set_supply_voltage(double supply_voltage) { this->supply_voltage_ = supply_voltage; } + +#ifdef ARDUINO_ARCH_ESP8266 + std::string unique_id() override; +#endif + + protected: + uint8_t pin_; + uint32_t calibration_; + uint32_t sample_size_; + double supply_voltage_; + + int sampleI; + double Irms,filteredI,offsetI,sumI,sqI; + +#ifdef ARDUINO_ARCH_ESP32 +#define ADC_BITS 12 +#endif +#ifdef ARDUINO_ARCH_ESP8266 +#define ADC_BITS 10 +#endif +#define ADC_COUNTS (1<