trying out polling ads131m08 sensor
This commit is contained in:
parent
799407c6be
commit
de74905436
@ -312,6 +312,15 @@ void ADS131M08Hub::isr_handler(ADS131M08Hub *arg) {
|
||||
}
|
||||
}
|
||||
|
||||
float ADS131M08Hub::get_sample(int32_t& raw_value, uint8_t channel, uint8_t gain, ADC_INPUT_CHANNEL_MUX input, uint32_t phase_calibration, uint32_t offset_calibration, uint32_t gain_calibration, bool dc_block)
|
||||
{
|
||||
if(channel < ADC_CHANNELS) {
|
||||
raw_value = raw_sampled_values_[channel];
|
||||
return sampled_values_[channel];
|
||||
}
|
||||
return NAN;
|
||||
}
|
||||
|
||||
void ADS131M08Hub::loop()
|
||||
{
|
||||
// Check the semaphore (0 timeout means non-blocking)
|
||||
@ -335,7 +344,7 @@ void ADS131M08Hub::loop()
|
||||
// }
|
||||
// ESP_LOGD(TAG, "spi_freq: %u", freq);
|
||||
//}
|
||||
if (rms_calc_req_) {
|
||||
if (false /*rms_calc_req_*/) {
|
||||
float_str result = read_multi();
|
||||
num_samples = result[0];
|
||||
crc_errors = result[1];
|
||||
@ -375,13 +384,29 @@ void ADS131M08Hub::loop()
|
||||
}
|
||||
if (crc_errors > 30) {
|
||||
ESP_LOGW(TAG, "High CRC error rate.");
|
||||
int i = 4;
|
||||
while(i-- > 0 && !adc_set_word_length(DEFAULT_WORD_LENGTH)); // for some reason the adc occasionally reverts to 24bits; this will
|
||||
// reset the word length to what it should be
|
||||
// update_adc_word_length();
|
||||
// spiframe recoverframe(40, 0);
|
||||
// read_array(recoverframe);
|
||||
// ESP_LOGI(TAG, "WL: %u Frame: %s", this->adc_word_length_, frame_to_string(recoverframe).c_str());
|
||||
if (!this->adc_initialize(DEFAULT_WORD_LENGTH)) {
|
||||
ESP_LOGE(TAG, "ADC reset failed!");
|
||||
this->mark_failed(LOG_STR("Initialisation failed."));
|
||||
this->adc_init_ = 0;
|
||||
return;
|
||||
}
|
||||
set_reg_osr();
|
||||
if (!adc_lock(true)) {
|
||||
ESP_LOGE(TAG, "ADC lock failed!");
|
||||
this->mark_failed(LOG_STR("ADC lock failed."));
|
||||
this->adc_init_ = 0;
|
||||
return;
|
||||
}
|
||||
if (!adc_lock(false)) {
|
||||
ESP_LOGE(TAG, "ADC unlock failed!");
|
||||
this->mark_failed(LOG_STR("ADC unlock failed."));
|
||||
this->adc_init_ = 0;
|
||||
return;
|
||||
}
|
||||
//int i = 4;
|
||||
//while(i-- > 0 && !adc_set_word_length(DEFAULT_WORD_LENGTH)); // for some reason the adc occasionally reverts to 24bits; this will
|
||||
// // reset the word length to what it should be
|
||||
|
||||
}
|
||||
// ESP_LOGW(TAG, "%llu ms (%llu us), max samples: %u", (end - start)/1000, (end - start), num_samples);
|
||||
}
|
||||
@ -629,7 +654,7 @@ bool ADS131M08Hub::adc_soft_reset() {
|
||||
for (; index < framelength; index++) {
|
||||
rx_frame[index] = 0;
|
||||
}
|
||||
ESP_LOGVV(TAG, "Sent Frame: %s", frame_to_string(rx_frame).c_str());
|
||||
ESP_LOGW(TAG, "Sent Frame: %s", frame_to_string(rx_frame).c_str());
|
||||
transfer_array(rx_frame);
|
||||
}
|
||||
delay_microseconds_safe(T_REGACQ);
|
||||
@ -723,6 +748,11 @@ uint16_t ADS131M08Hub::crc(uint16_t crc_register, uint8_t data) {
|
||||
|
||||
void ADS131M08Hub::transfer_array(spiframe &frame) {
|
||||
CHIP_SELECT
|
||||
//uint16_t cmd = get_unsigned_frame_word(rx_frame, 0, true);
|
||||
//if(cmd == CMD_RESET) {
|
||||
// ESP_LOGW(TAG, "Reset cmd sent : %s", command_to_string(cmd).c_str());
|
||||
// ESP_LOGW(TAG, "reset cmd frame:%s", frame_to_string(rx_frame).c_str());
|
||||
//}
|
||||
Base::transfer_array(frame.data(), (size_t)frame.size());
|
||||
}
|
||||
|
||||
@ -759,14 +789,17 @@ void ADS131M08Hub::read_single() {
|
||||
int32_t raw = get_sign_ext_frame_word(rx_frame, i + 1);
|
||||
float value = this->conversion_factor_ * raw;
|
||||
this->sampled_values_[i] = value;
|
||||
bool ac_sensor_exist = this->sensors_ac[i] != nullptr;
|
||||
bool dc_sensor_exist = this->sensors_dc[i] != nullptr;
|
||||
if (ac_sensor_exist || dc_sensor_exist) {
|
||||
if (ac_sensor_exist)
|
||||
this->sensors_ac[i]->publish_state(value);
|
||||
if (dc_sensor_exist)
|
||||
this->sensors_dc[i]->publish_state(value);
|
||||
}
|
||||
this->raw_sampled_values_[i] = raw;
|
||||
//bool ac_sensor_exist = this->sensors_ac[i] != nullptr;
|
||||
//bool dc_sensor_exist = this->sensors_dc[i] != nullptr;
|
||||
//if (ac_sensor_exist || dc_sensor_exist) {
|
||||
// if (ac_sensor_exist) {
|
||||
// this->sensors_ac[i]->publish_state(value);
|
||||
// }
|
||||
// if (dc_sensor_exist) {
|
||||
// this->sensors_dc[i]->publish_state(value);
|
||||
// }
|
||||
//}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -810,13 +843,36 @@ float_str ADS131M08Hub::read_multi() {
|
||||
//ESP_LOGD(TAG, "frame_word%d: %s", 0, frame_words_to_string(rx_frame, 0, 1).c_str());
|
||||
status = get_unsigned_frame_word(rx_frame, 0, true);
|
||||
update_adc_word_length(status);
|
||||
if(status & MASK_STATUS_RESET) {
|
||||
if(status == CMD_RESET) {
|
||||
ESP_LOGI(TAG,"Reset frame: %s", frame_to_string(rx_frame).c_str());
|
||||
ESP_LOGW(TAG, "ADC reset detected. Trying recover");
|
||||
if (!adc_register_write(REG_MODE, MODE_MASK_RESET_HAPPENED & reg_mode_cfg32, __LINE__)) {
|
||||
ESP_LOGE(TAG, "MODE register write / read to set word size to 32bits failed");
|
||||
return result;
|
||||
}
|
||||
if (!this->adc_initialize(DEFAULT_WORD_LENGTH)) {
|
||||
ESP_LOGE(TAG, "ADC reset failed!");
|
||||
this->mark_failed(LOG_STR("Initialisation failed."));
|
||||
this->adc_init_ = 0;
|
||||
return result;
|
||||
}
|
||||
set_reg_osr();
|
||||
if (!adc_lock(true)) {
|
||||
ESP_LOGE(TAG, "ADC lock failed!");
|
||||
this->mark_failed(LOG_STR("ADC lock failed."));
|
||||
this->adc_init_ = 0;
|
||||
return result;
|
||||
}
|
||||
if (!adc_lock(false)) {
|
||||
ESP_LOGE(TAG, "ADC unlock failed!");
|
||||
this->mark_failed(LOG_STR("ADC unlock failed."));
|
||||
this->adc_init_ = 0;
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
this->set_timeout("reset detected", 250, [this, result]() {
|
||||
ESP_LOGE(TAG, "ADC reset detected. Trying to restore registers");
|
||||
if(this->adc_restore_registers()) {
|
||||
@ -1147,7 +1203,7 @@ bool ADS131M08Hub::adc_register_write(uint16_t start_address, const uint16_str &
|
||||
set_frame_word(rx_frame, i + 1, data[i]);
|
||||
}
|
||||
add_crc(rx_frame);
|
||||
ESP_LOGD(TAG, "%s\n", rwreg_command_frame_to_string(rx_frame).c_str());
|
||||
//ESP_LOGD(TAG, "%s\n", rwreg_command_frame_to_string(rx_frame).c_str());
|
||||
//ESP_LOGD(TAG, "Send Frame: %s", frame_to_string(rx_frame).c_str());
|
||||
transfer_array(rx_frame); // WREG
|
||||
}
|
||||
|
||||
@ -122,6 +122,8 @@ class ADS131M08Hub : public Component,
|
||||
bool set_channel_gain(uint8_t channel, uint8_t gain);
|
||||
bool set_measure_rms(uint8_t channel, bool enable);
|
||||
float get_sampled_value(uint8_t channel) { return sampled_values_[channel]; }
|
||||
float get_sample(int32_t& raw_value, uint8_t channel_, uint8_t gain_, ADC_INPUT_CHANNEL_MUX input,
|
||||
uint32_t phase_calibration, uint32_t offset_calibration, uint32_t gain_calibration, bool dc_block);
|
||||
uint32_t get_filter_settling_time();
|
||||
//float get_average(uint8_t channel, bool read_ac);
|
||||
bool set_reg_osr();
|
||||
@ -138,6 +140,7 @@ class ADS131M08Hub : public Component,
|
||||
InternalGPIOPin *sync_reset_pin_ = {nullptr};
|
||||
sensor::Sensor *sensors_ac[MAX_CHANNELS] = {nullptr};
|
||||
sensor::Sensor *sensors_dc[MAX_CHANNELS] = {nullptr};
|
||||
uint32_t raw_sampled_values_[ADC_CHANNELS];
|
||||
float sampled_values_[ADC_CHANNELS];
|
||||
bool rms_enabled_[MAX_CHANNELS];
|
||||
bool rms_calc_req_{false};
|
||||
|
||||
@ -1,7 +1,17 @@
|
||||
import esphome.codegen as cg
|
||||
import esphome.config_validation as cv
|
||||
from esphome.components import sensor, voltage_sampler
|
||||
from esphome.const import CONF_ID, CONF_GAIN, CONF_CHANNEL
|
||||
from esphome.const import (
|
||||
CONF_ID,
|
||||
CONF_GAIN,
|
||||
CONF_CHANNEL,
|
||||
CONF_NAME,
|
||||
DEVICE_CLASS_VOLTAGE,
|
||||
STATE_CLASS_MEASUREMENT,
|
||||
ICON_CURRENT_AC,
|
||||
UNIT_VOLT,
|
||||
)
|
||||
|
||||
from .. import CONF_ADS131M08_ID, ADS131M08Hub, ads131m08_ns
|
||||
from ..sensor_rms import CONFIG_SCHEMA_RMS_SENSORS, to_code_ac, to_code_dc
|
||||
|
||||
@ -52,7 +62,36 @@ Channel = ads131m08_ns.class_(
|
||||
"Channel", sensor.Sensor, cg.Component, voltage_sampler.VoltageSampler
|
||||
)
|
||||
|
||||
CONFIG_SCHEMA = CONFIG_SCHEMA_RMS_SENSORS.extend(
|
||||
#CONFIG_SCHEMA = CONFIG_SCHEMA_RMS_SENSORS.extend(
|
||||
# {
|
||||
# cv.GenerateID(CONF_ADS131M08_ID): cv.use_id(ADS131M08Hub),
|
||||
# cv.Required(CONF_CHANNEL): cv.int_range(min=0, max=MAX_CHANNELS),
|
||||
# cv.Optional(CONF_GAIN, default=1): cv.enum(ALLOWED_GAINS, int=True),
|
||||
# cv.Optional(CONF_OFFSET_CALIBRATION, default=0): cv.int_range(min=-8388608, max=8388607), # should use volts, but need to figure out conversion function first
|
||||
# cv.Optional(CONF_GAIN_CALIBRATION, default=1): cv.float_range(min=0, max=2),
|
||||
# cv.Optional(CONF_PHASE_CALIBRATION, default=0): cv.int_range(min=-512, max=511), # should use degrees, but need to figure out conversion function first
|
||||
# cv.Optional(CONF_INPUT_SELECT, default='normal'): cv.enum(ALLOWED_MUX_INP, int=False),
|
||||
# cv.Optional(CONF_DC_BLOCK, default=False): cv.boolean,
|
||||
# cv.Optional(CONF_NAME): cv.string,
|
||||
# }
|
||||
#).extend(
|
||||
# {
|
||||
# cv.GenerateID(): cv.declare_id(Channel)
|
||||
# }
|
||||
#).extend(cv.polling_component_schema("2s"))
|
||||
|
||||
CONFIG_SCHEMA = (
|
||||
sensor.sensor_schema(
|
||||
Channel,
|
||||
accuracy_decimals=6,
|
||||
icon=ICON_CURRENT_DC,
|
||||
unit_of_measurement=UNIT_VOLT,
|
||||
device_class=DEVICE_CLASS_VOLTAGE,
|
||||
state_class=STATE_CLASS_MEASUREMENT,
|
||||
#).extend(
|
||||
# CONFIG_SCHEMA_RMS_SENSORS
|
||||
)
|
||||
.extend(
|
||||
{
|
||||
cv.GenerateID(CONF_ADS131M08_ID): cv.use_id(ADS131M08Hub),
|
||||
cv.Required(CONF_CHANNEL): cv.int_range(min=0, max=MAX_CHANNELS),
|
||||
@ -62,12 +101,12 @@ CONFIG_SCHEMA = CONFIG_SCHEMA_RMS_SENSORS.extend(
|
||||
cv.Optional(CONF_PHASE_CALIBRATION, default=0): cv.int_range(min=-512, max=511), # should use degrees, but need to figure out conversion function first
|
||||
cv.Optional(CONF_INPUT_SELECT, default='normal'): cv.enum(ALLOWED_MUX_INP, int=False),
|
||||
cv.Optional(CONF_DC_BLOCK, default=False): cv.boolean,
|
||||
#cv.Required(CONF_NAME): cv.string,
|
||||
}
|
||||
).extend(
|
||||
{
|
||||
cv.GenerateID(): cv.declare_id(Channel)
|
||||
}
|
||||
).extend(cv.COMPONENT_SCHEMA)
|
||||
)
|
||||
.extend(cv.polling_component_schema("1s"))
|
||||
)
|
||||
|
||||
# we are using 3 sensors:
|
||||
# 1. channel_sensor: this represents 1 of the 8 ads131m08 channels and is used to program the adc channel gain, offset calibration, etc. This sensor publishes instantaneous sampled value
|
||||
# 2. dc_sensor: to publish averaged dc value
|
||||
@ -89,8 +128,10 @@ async def to_code(config):
|
||||
cg.add(channel_sensor.set_phase_calibration(phase_cal))
|
||||
dc_block = config[CONF_DC_BLOCK]
|
||||
cg.add(channel_sensor.set_dc_block(dc_block))
|
||||
|
||||
await sensor.register_sensor(channel_sensor, config)
|
||||
await cg.register_component(channel_sensor, config)
|
||||
if dc_sensor := await to_code_dc(config):
|
||||
await cg.register_parented(dc_sensor, channel_sensor)
|
||||
if ac_sensor := await to_code_ac(config):
|
||||
await cg.register_parented(ac_sensor, channel_sensor)
|
||||
#if dc_sensor := await to_code_dc(config):
|
||||
# await cg.register_parented(dc_sensor, channel_sensor)
|
||||
#if ac_sensor := await to_code_ac(config):
|
||||
# await cg.register_parented(ac_sensor, channel_sensor)
|
||||
|
||||
@ -25,7 +25,28 @@ void Channel::loop()
|
||||
|
||||
float Channel::sample()
|
||||
{
|
||||
return (this->parent_ == nullptr) ? NAN : this->parent_->get_sampled_value(this->channel_);
|
||||
int32_t raw_value = -1000;
|
||||
return sample(raw_value);
|
||||
}
|
||||
|
||||
float Channel::sample(int32_t& raw_value)
|
||||
{
|
||||
return (this->parent_ == nullptr) ? NAN : this->parent_->get_sample(raw_value, this->channel_, this->gain_, this->input_,
|
||||
this->normalised_phase_calibration(), this->normalised_offset_calibration(), this->normalised_gain_calibration(), !this->dc_block_
|
||||
);
|
||||
}
|
||||
|
||||
void Channel::update() {
|
||||
int32_t raw_value = -1000;
|
||||
float v = this->sample(raw_value);
|
||||
if (!std::isnan(v)) {
|
||||
// if(this->count_ % 10 == 0) {
|
||||
// ESP_LOGI(TAG, "Ch%d: Raw=% 6d %fV", this->channel_, raw_value, v);
|
||||
// }
|
||||
this->count_++;
|
||||
ESP_LOGD(TAG, "Ch%d: Got Voltage=%fV", this->channel_, v);
|
||||
this->publish_state(v);
|
||||
}
|
||||
}
|
||||
|
||||
// converts gain of 0.0 - 2.0 to the corresponding values that ADS131M08 expects
|
||||
|
||||
@ -13,12 +13,13 @@ namespace esphome {
|
||||
namespace ads131m08 {
|
||||
|
||||
class Channel : public sensor::Sensor,
|
||||
public Component,
|
||||
public PollingComponent,
|
||||
public voltage_sampler::VoltageSampler,
|
||||
public Parented<ADS131M08Hub> {
|
||||
public:
|
||||
void loop() override;
|
||||
float sample() override;
|
||||
void update() override;
|
||||
void set_gain(uint8_t value) { this->gain_ = value; }
|
||||
void dump_config() override;
|
||||
void set_channel_number(uint8_t channel) { this->channel_= channel; }
|
||||
@ -32,6 +33,7 @@ class Channel : public sensor::Sensor,
|
||||
uint32_t normalised_gain_calibration() const;
|
||||
uint32_t normalised_offset_calibration() const;
|
||||
int16_t normalised_phase_calibration() const;
|
||||
float sample(int32_t& raw_value);
|
||||
|
||||
protected:
|
||||
uint8_t channel_;
|
||||
@ -43,7 +45,7 @@ class Channel : public sensor::Sensor,
|
||||
uint8_t gain_;
|
||||
ADC_INPUT_CHANNEL_MUX input_;
|
||||
bool first_reading_{true};
|
||||
|
||||
uint64_t count_{0};
|
||||
};
|
||||
|
||||
class RMS_Sensor : public sensor::Sensor,
|
||||
|
||||
@ -18,7 +18,7 @@ AUTO_LOAD = ["sensor",]
|
||||
|
||||
DEPENDENCIES = ["ads131m08"]
|
||||
|
||||
ads131m08_acdc_ns = cg.esphome_ns.namespace("ads131m08_acdc")
|
||||
#ads131m08_acdc_ns = cg.esphome_ns.namespace("ads131m08_acdc")
|
||||
|
||||
RMS_SENSOR = ads131m08_ns.class_(
|
||||
"RMS_Sensor", sensor.Sensor, cg.Component
|
||||
@ -26,7 +26,7 @@ RMS_SENSOR = ads131m08_ns.class_(
|
||||
|
||||
CONFIG_SCHEMA_RMS_SENSORS = cv.Schema(
|
||||
{
|
||||
cv.Required(CONF_DC): sensor.sensor_schema(
|
||||
cv.Optional(CONF_DC): sensor.sensor_schema(
|
||||
RMS_SENSOR,
|
||||
accuracy_decimals=6,
|
||||
icon=ICON_CURRENT_DC,
|
||||
@ -52,6 +52,7 @@ CONFIG_SCHEMA_RMS_SENSORS = cv.Schema(
|
||||
),
|
||||
}
|
||||
). extend (cv.COMPONENT_SCHEMA)
|
||||
|
||||
async def to_code_ac(config):
|
||||
hub = await cg.get_variable(config[CONF_ADS131M08_ID])
|
||||
channel = config[CONF_CHANNEL]
|
||||
@ -66,9 +67,10 @@ async def to_code_ac(config):
|
||||
async def to_code_dc(config):
|
||||
hub = await cg.get_variable(config[CONF_ADS131M08_ID])
|
||||
channel = config[CONF_CHANNEL]
|
||||
dc_config = config.get(CONF_DC)
|
||||
if dc_config := config.get(CONF_DC):
|
||||
sens_dc = await sensor.new_sensor(dc_config)
|
||||
cg.add(sens_dc, config.get(CONF_DC))
|
||||
cg.add(hub.register_sensor_dc(channel, sens_dc))
|
||||
await cg.register_component(sens_dc, config[CONF_DC])
|
||||
return sens_dc
|
||||
return None
|
||||
Loading…
Reference in New Issue
Block a user