1
0
mirror of https://github.com/esphome/esphome.git synced 2025-03-14 14:48:18 +00:00

Add CT Clamp component

This commit is contained in:
Jesse Hills 2019-05-27 07:16:57 +12:00
parent 510e53de70
commit fffa342048
No known key found for this signature in database
GPG Key ID: F7ECB64F6269DC28
4 changed files with 143 additions and 0 deletions

View File

View File

@ -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

View File

@ -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<<ADC_BITS)
};
} // namespace ct_clamp
} // namespace esphome

View File

@ -0,0 +1,31 @@
import esphome.codegen as cg
import esphome.config_validation as cv
from esphome import pins
from esphome.components import sensor
from esphome.const import CONF_ID, CONF_PIN, ICON_FLASH, UNIT_AMPERE
CONF_CALIBRATION = 'calibration'
CONF_SAMPLE_SIZE = 'sample_size'
CONF_SUPPLY_VOLTAGE = 'supply_voltage'
ct_clamp_ns = cg.esphome_ns.namespace('ct_clamp')
CTClampSensor = ct_clamp_ns.class_('CTClampSensor', sensor.Sensor, cg.PollingComponent)
CONFIG_SCHEMA = sensor.sensor_schema(UNIT_AMPERE, ICON_FLASH, 2).extend({
cv.GenerateID(): cv.declare_id(CTClampSensor),
cv.Required(CONF_PIN): pins.analog_pin,
cv.Required(CONF_CALIBRATION): cv.positive_int,
cv.Optional(CONF_SAMPLE_SIZE, default=1480): cv.positive_int,
cv.Optional(CONF_SUPPLY_VOLTAGE, default='1V'): cv.voltage,
}).extend(cv.polling_component_schema('60s'))
def to_code(config):
var = cg.new_Pvariable(config[CONF_ID])
yield cg.register_component(var, config)
yield sensor.register_sensor(var, config)
cg.add(var.set_pin(config[CONF_PIN]))
cg.add(var.set_calibration(config[CONF_CALIBRATION]))
cg.add(var.set_sample_size(config[CONF_SAMPLE_SIZE]))
cg.add(var.set_supply_voltage(config[CONF_SUPPLY_VOLTAGE]))