Slowed down refresh rate of ac rms sensors with sliding_window_moving_average filter in yaml file. Added sample limit on rms sensor in read_multi procedure. Updated README.md file.
This commit is contained in:
parent
2184825302
commit
40c7cf58e6
@ -15,12 +15,6 @@ substitutions:
|
|||||||
ADC_CS_PIN: GPIO41
|
ADC_CS_PIN: GPIO41
|
||||||
ADC_DRDY_PIN: GPIO42
|
ADC_DRDY_PIN: GPIO42
|
||||||
|
|
||||||
external_components:
|
|
||||||
- source:
|
|
||||||
type: local
|
|
||||||
path: components # Path relative to this YAML file
|
|
||||||
components: [ ads131m08 ]
|
|
||||||
|
|
||||||
spi:
|
spi:
|
||||||
- id: spi_bus0
|
- id: spi_bus0
|
||||||
clk_pin: ${ESP32_S3_SPI0_SCK}
|
clk_pin: ${ESP32_S3_SPI0_SCK}
|
||||||
@ -29,15 +23,25 @@ spi:
|
|||||||
interface: hardware
|
interface: hardware
|
||||||
|
|
||||||
ads131m08:
|
ads131m08:
|
||||||
id: highres_adc
|
- id: highres_adc
|
||||||
spi_id: spi_bus0
|
spi_id: spi_bus0
|
||||||
cs_pin: ${ADC_CS_PIN}
|
cs_pin: ${ADC_CS_PIN}
|
||||||
drdy_pin: ${ADC_DRDY_PIN}
|
drdy_pin: ${ADC_DRDY_PIN}
|
||||||
sync_reset_pin: ${ADC_SYNC_RESET_PIN}
|
sync_reset_pin: ${ADC_SYNC_RESET_PIN}
|
||||||
reference_voltage: 1.25
|
reference_voltage: 1.248 #1.25
|
||||||
data_rate: 10MHz
|
data_rate: 5MHz
|
||||||
clock_frequency: 8192kHz
|
clock_frequency: 8192kHz
|
||||||
oversampling_ratio: 512
|
oversampling_ratio: 512
|
||||||
|
spi_mode: MODE1
|
||||||
|
dcblock_filter: 5 # 10Hz
|
||||||
|
power_mode: high
|
||||||
|
global_chop: no
|
||||||
|
global_chop_delay: 1024
|
||||||
|
current_detect: disable
|
||||||
|
current_detect_all: no
|
||||||
|
current_detect_number: 16
|
||||||
|
current_detect_length: 768
|
||||||
|
current_detect_threshold: -500
|
||||||
|
|
||||||
sensor:
|
sensor:
|
||||||
- platform: ads131m08
|
- platform: ads131m08
|
||||||
@ -49,11 +53,14 @@ sensor:
|
|||||||
offset_calibration: 0
|
offset_calibration: 0
|
||||||
gain_calibration: 0.986
|
gain_calibration: 0.986
|
||||||
ac:
|
ac:
|
||||||
name: "Channel 0 AC"
|
name: "ac_ch0"
|
||||||
id: ads_ch0_ac
|
id: ac_ch0
|
||||||
dc:
|
filters:
|
||||||
name: "Channel 0 DC"
|
- multiply: 2884
|
||||||
id: ads_ch0_dc
|
- sliding_window_moving_average:
|
||||||
|
window_size: 50
|
||||||
|
send_every: 25
|
||||||
|
send_first_at: 10
|
||||||
|
|
||||||
- platform: ads131m08
|
- platform: ads131m08
|
||||||
ads131m08_id: highres_adc
|
ads131m08_id: highres_adc
|
||||||
@ -64,17 +71,34 @@ sensor:
|
|||||||
offset_calibration: 0
|
offset_calibration: 0
|
||||||
gain_calibration: 0.986
|
gain_calibration: 0.986
|
||||||
ac:
|
ac:
|
||||||
name: "Channel 1 AC"
|
name: "ac_ch1"
|
||||||
id: ads_ch1_ac
|
id: ac_ch1
|
||||||
accuracy_decimals: 6
|
filters:
|
||||||
state_class: measurement
|
- multiply: 2884
|
||||||
device_class: voltage
|
- sliding_window_moving_average:
|
||||||
dc:
|
window_size: 50
|
||||||
name: "Channel 1 DC"
|
send_every: 25
|
||||||
id: ads_ch1_dc
|
send_first_at: 10
|
||||||
accuracy_decimals: 6
|
|
||||||
state_class: measurement
|
- platform: ads131m08
|
||||||
device_class: voltage
|
ads131m08_id: highres_adc
|
||||||
|
channel: 2
|
||||||
|
id: ads_ch2
|
||||||
|
gain: 1
|
||||||
|
input_select: normal
|
||||||
|
offset_calibration: 0
|
||||||
|
gain_calibration: 1.36153846
|
||||||
|
dc_block: enable
|
||||||
|
ac:
|
||||||
|
name: "ac_ch2"
|
||||||
|
id: ac_ch2
|
||||||
|
device_class: current
|
||||||
|
filters:
|
||||||
|
- multiply: 62.97
|
||||||
|
- sliding_window_moving_average:
|
||||||
|
window_size: 50
|
||||||
|
send_every: 25
|
||||||
|
send_first_at: 10
|
||||||
```
|
```
|
||||||
|
|
||||||
For more information, visit the [ESPHome documentation](https://esphome.io/).
|
For more information, visit the [ESPHome documentation](https://esphome.io/).
|
||||||
|
|||||||
@ -122,19 +122,30 @@ void ADS131M08Hub::dump_config() {
|
|||||||
this->power_mode_ == VERY_LOW_POWER ? "'very low power'"
|
this->power_mode_ == VERY_LOW_POWER ? "'very low power'"
|
||||||
: this->power_mode_ == LOW_POWER ? "'low power'"
|
: this->power_mode_ == LOW_POWER ? "'low power'"
|
||||||
: "'high resolution'");
|
: "'high resolution'");
|
||||||
ESP_LOGCONFIG(TAG, " Global Chop: %s", this->global_chop_enable_ ? "enable" : "disable");
|
std::string str =" Global Chop";
|
||||||
ESP_LOGCONFIG(TAG, " Global Chop Delay: %u", 1 << (1 + this->global_chop_delay_));
|
ESP_LOGCONFIG(TAG, "%s: %s", str.c_str(), this->global_chop_enable_ ? "enable" : "disable");
|
||||||
ESP_LOGCONFIG(TAG, " Current Detect: %s", this->current_detect_enable_ ? "enable" : "disable");
|
ESP_LOGCONFIG(TAG, "%s Delay: %u", str.c_str(), 1 << (1 + this->global_chop_delay_));
|
||||||
ESP_LOGCONFIG(TAG, " Current Detect All: %s", this->current_detect_all_enable_ ? "YES" : "NO");
|
str = " Current Detect";
|
||||||
ESP_LOGCONFIG(TAG, " Current Detect Number: %u", 1 << this->current_detect_number_);
|
ESP_LOGCONFIG(TAG, "%s: %s", str.c_str(), this->current_detect_enable_ ? "enable" : "disable");
|
||||||
ESP_LOGCONFIG(TAG, " Current Detect Length: %u", convert_adc_cd_len_to_value(this->current_detect_length_));
|
ESP_LOGCONFIG(TAG, "%s All: %s", str.c_str(), this->current_detect_all_enable_ ? "YES" : "NO");
|
||||||
ESP_LOGCONFIG(TAG, " Current Detect Threshold: %ld", this->current_detect_threshold_);
|
ESP_LOGCONFIG(TAG, "%s Number: %u", str.c_str(), 1 << this->current_detect_number_);
|
||||||
|
ESP_LOGCONFIG(TAG, "%s Length: %u", str.c_str(), convert_adc_cd_len_to_value(this->current_detect_length_));
|
||||||
|
ESP_LOGCONFIG(TAG, "%s Threshold: %ld", str.c_str(), this->current_detect_threshold_);
|
||||||
|
str =" DC Block Filter";
|
||||||
|
if(this->dcblock_filter_ == 0) {
|
||||||
|
ESP_LOGCONFIG(TAG, "%s: 0 (disabled)", str.c_str());
|
||||||
|
}
|
||||||
|
else if(this->dcblock_filter_ > 15) {
|
||||||
|
ESP_LOGCONFIG(TAG, "%s: %u (invalid)", str.c_str(), this->dcblock_filter_);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
ESP_LOGCONFIG(TAG, "%s('a'): %u (1/%u)", str.c_str(), this->dcblock_filter_, convert_adc_dc_block_to_value(this->dcblock_filter_));
|
||||||
|
}
|
||||||
ESP_LOGCONFIG(TAG, " SPI Mode: %d", this->mode_);
|
ESP_LOGCONFIG(TAG, " SPI Mode: %d", this->mode_);
|
||||||
ESP_LOGCONFIG(TAG, " Bit Order: %s",
|
ESP_LOGCONFIG(TAG, " Bit Order: %s",
|
||||||
this->bit_order_ == spi::BIT_ORDER_MSB_FIRST ? "msb_first"
|
this->bit_order_ == spi::BIT_ORDER_MSB_FIRST ? "msb_first"
|
||||||
: this->bit_order_ == spi::BIT_ORDER_LSB_FIRST ? "lsb_first"
|
: this->bit_order_ == spi::BIT_ORDER_LSB_FIRST ? "lsb_first"
|
||||||
: "unknown");
|
: "invalid");
|
||||||
// TODO: add new configs
|
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t ADS131M08Hub::update_adc_word_length() {
|
uint8_t ADS131M08Hub::update_adc_word_length() {
|
||||||
@ -835,7 +846,7 @@ void ADS131M08Hub::read_single() {
|
|||||||
}
|
}
|
||||||
// do not like what the following procedure does at all (it blocks for +-40ms), but at the moment do not know how to get
|
// do not like what the following procedure does at all (it blocks for +-40ms), but at the moment do not know how to get
|
||||||
// DRDY interrupt / ISR / loop setup to respond fast enough to read multiple frames with no or the minimum possible
|
// DRDY interrupt / ISR / loop setup to respond fast enough to read multiple frames with no or the minimum possible
|
||||||
// missed frames in quick succession idealy would want to read +- 200 24/32bit in 40ms. Gor now, this seems to be the
|
// missed frames in quick succession idealy would want to read +- 200 24/32bit in 40ms. For now, this seems to be the
|
||||||
// only way to do it.
|
// only way to do it.
|
||||||
float_str ADS131M08Hub::read_multi() {
|
float_str ADS131M08Hub::read_multi() {
|
||||||
int32_t raw;
|
int32_t raw;
|
||||||
@ -861,7 +872,11 @@ float_str ADS131M08Hub::read_multi() {
|
|||||||
}
|
}
|
||||||
CHIP_SELECTx
|
CHIP_SELECTx
|
||||||
uint32_t settling_end_time = loop_start_time;
|
uint32_t settling_end_time = loop_start_time;
|
||||||
while ((elapsed_time < sample_time) && (iteration++ < 1000)) {
|
uint32_t samples_per_second = 8000; // for osr of 512
|
||||||
|
uint32_t sample_target = (sample_time * samples_per_second) / 1000000; // sample_time is in microseconds
|
||||||
|
//ESP_LOGI(TAG,"sample_target: %lu active_channel_count_: %d", sample_target, this->active_channel_count_);
|
||||||
|
int nchannels_sampled = 0;
|
||||||
|
while ((elapsed_time < sample_time) && (nchannels_sampled < this->active_channel_count_) && (iteration++ < 1000)) {
|
||||||
result[2] = iteration;
|
result[2] = iteration;
|
||||||
setup_frame(rx_frame, numFrameWords);
|
setup_frame(rx_frame, numFrameWords);
|
||||||
this->transfer_array(rx_frame);
|
this->transfer_array(rx_frame);
|
||||||
@ -890,7 +905,8 @@ float_str ADS131M08Hub::read_multi() {
|
|||||||
if(drdy_status == 0){
|
if(drdy_status == 0){
|
||||||
result[3]++;
|
result[3]++;
|
||||||
}
|
}
|
||||||
for (i = 0; i < ADC_CHANNELS && drdy_status != 0; i++) {
|
nchannels_sampled = 0;
|
||||||
|
for (i = 0; (i < ADC_CHANNELS) && (drdy_status != 0); i++) {
|
||||||
data_ready = drdy_status & 1;
|
data_ready = drdy_status & 1;
|
||||||
drdy_status = drdy_status >> 1;
|
drdy_status = drdy_status >> 1;
|
||||||
if (data_ready) {
|
if (data_ready) {
|
||||||
@ -901,9 +917,15 @@ float_str ADS131M08Hub::read_multi() {
|
|||||||
raw = get_sign_ext_frame_word(rx_frame, i + 1);
|
raw = get_sign_ext_frame_word(rx_frame, i + 1);
|
||||||
value = this->conversion_factor_ * raw;
|
value = this->conversion_factor_ * raw;
|
||||||
if (this->rms_enabled_[i]) {
|
if (this->rms_enabled_[i]) {
|
||||||
(this->num_samples_[i])++;
|
if(this->num_samples_[i] < sample_target) {
|
||||||
(this->sample_sum_[i]) += value;
|
(this->num_samples_[i])++;
|
||||||
(this->sample_squared_sum_[i]) += value * value;
|
(this->sample_sum_[i]) += value;
|
||||||
|
(this->sample_squared_sum_[i]) += value * value;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
nchannels_sampled++;
|
||||||
|
//ESP_LOGI(TAG,"target: %lu ac_cnt: %d it: %d sampled: %d time: %lu", sample_target, this->active_channel_count_, iteration, nchannels_sampled, elapsed_time);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
if(ac_sensor_exist)
|
if(ac_sensor_exist)
|
||||||
this->sensors_ac[i]->publish_state(value);
|
this->sensors_ac[i]->publish_state(value);
|
||||||
@ -1190,8 +1212,7 @@ bool ADS131M08Hub::adc_register_write(uint16_t start_address, const uint16_str &
|
|||||||
uint16_t addr_regcnt_mask = (start_address << 7) | ((nregs - 1) & MASK_CMD_RW_REG_COUNT);
|
uint16_t addr_regcnt_mask = (start_address << 7) | ((nregs - 1) & MASK_CMD_RW_REG_COUNT);
|
||||||
uint16_t wreg_addr_opcode = CMD_WREG | addr_regcnt_mask; // Combine WREG command, start_address and register count
|
uint16_t wreg_addr_opcode = CMD_WREG | addr_regcnt_mask; // Combine WREG command, start_address and register count
|
||||||
uint16_t rreg_addr_opcode = CMD_RREG | addr_regcnt_mask; // Combine RREG command, start_address and register count
|
uint16_t rreg_addr_opcode = CMD_RREG | addr_regcnt_mask; // Combine RREG command, start_address and register count
|
||||||
bool has_mode_reg =
|
bool has_mode_reg = (start_address == REG_MODE) || ((start_address < REG_MODE) && ((start_address + nregs) > REG_MODE));
|
||||||
(start_address == REG_MODE) || ((start_address < REG_MODE) && ((start_address + nregs) > REG_MODE));
|
|
||||||
setup_frame(rx_frame, wreg_nwords);
|
setup_frame(rx_frame, wreg_nwords);
|
||||||
{
|
{
|
||||||
CHIP_SELECT
|
CHIP_SELECT
|
||||||
@ -1217,6 +1238,11 @@ bool ADS131M08Hub::adc_register_write(uint16_t start_address, const uint16_str &
|
|||||||
//ESP_LOGW(TAG, "Write: %s", reg_data_to_string(start_address + i, data[i]).c_str());
|
//ESP_LOGW(TAG, "Write: %s", reg_data_to_string(start_address + i, data[i]).c_str());
|
||||||
//ESP_LOGW(TAG, "Ack : %s", reg_data_to_string(start_address + i, rxdata[i]).c_str());
|
//ESP_LOGW(TAG, "Ack : %s", reg_data_to_string(start_address + i, rxdata[i]).c_str());
|
||||||
}
|
}
|
||||||
|
if((start_address + i) == REG_CLOCK) {
|
||||||
|
// count the number of channels that were enabled
|
||||||
|
uint16_t clock_reg_data = data[i] & MASK_CLOCK_ALLCH;
|
||||||
|
this->active_channel_count_ = std::popcount(clock_reg_data);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
delay_microseconds_safe(T_REGACQ);
|
delay_microseconds_safe(T_REGACQ);
|
||||||
return verified;
|
return verified;
|
||||||
|
|||||||
@ -150,6 +150,7 @@ class ADS131M08Hub : public Component,
|
|||||||
uint32_t convert_adc_clock_cycles_to_micros(uint32_t cycles);
|
uint32_t convert_adc_clock_cycles_to_micros(uint32_t cycles);
|
||||||
uint16_t convert_adc_osr_to_value(uint16_t adc_osr) { auto osr = 1 << (7 + adc_osr); return (osr == 16384) ? 16256 : osr; }
|
uint16_t convert_adc_osr_to_value(uint16_t adc_osr) { auto osr = 1 << (7 + adc_osr); return (osr == 16384) ? 16256 : osr; }
|
||||||
uint16_t convert_adc_cd_len_to_value(uint16_t adc_cd_len) { return adc_cd_len >= sizeof(current_detect_lengths) ? 0 : current_detect_lengths[adc_cd_len]; }
|
uint16_t convert_adc_cd_len_to_value(uint16_t adc_cd_len) { return adc_cd_len >= sizeof(current_detect_lengths) ? 0 : current_detect_lengths[adc_cd_len]; }
|
||||||
|
uint16_t convert_adc_dc_block_to_value(uint16_t dcblock) { return dcblock > 15 ? 0 : (1 << (dcblock + 1)); } // returns denominator of 'a' coefficient
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
std::string id_;
|
std::string id_;
|
||||||
@ -165,6 +166,7 @@ class ADS131M08Hub : public Component,
|
|||||||
float sampled_values_[ADC_CHANNELS];
|
float sampled_values_[ADC_CHANNELS];
|
||||||
bool rms_enabled_[MAX_CHANNELS];
|
bool rms_enabled_[MAX_CHANNELS];
|
||||||
bool rms_calc_req_{false};
|
bool rms_calc_req_{false};
|
||||||
|
int active_channel_count_{0};
|
||||||
uint16_t osr_{3};
|
uint16_t osr_{3};
|
||||||
uint16_t global_chop_delay_{16};
|
uint16_t global_chop_delay_{16};
|
||||||
bool global_chop_enable_{false};
|
bool global_chop_enable_{false};
|
||||||
@ -203,8 +205,7 @@ class ADS131M08Hub : public Component,
|
|||||||
int32_t SET_IRAM get_sign_ext_frame_word(const spiframe &frame, int w_index);
|
int32_t SET_IRAM get_sign_ext_frame_word(const spiframe &frame, int w_index);
|
||||||
//bool update_averages(uint8_t channel, float rms_ac, float rms_dc);
|
//bool update_averages(uint8_t channel, float rms_ac, float rms_dc);
|
||||||
std::atomic<int> adc_init_{0};
|
std::atomic<int> adc_init_{0};
|
||||||
std::atomic<int> cs_ctr_{
|
std::atomic<int> cs_ctr_{0}; // Counter to track nested CS enable/disable calls
|
||||||
0}; // Counter to track nested CS enable/disable calls for proper handling of multiple transfers in a row
|
|
||||||
std::atomic<uint16_t> isr_ctr_{0};
|
std::atomic<uint16_t> isr_ctr_{0};
|
||||||
void enable(const char *txt);
|
void enable(const char *txt);
|
||||||
void disable(const char *txt);
|
void disable(const char *txt);
|
||||||
|
|||||||
@ -70,16 +70,16 @@ int16_t Channel::normalised_phase_calibration() const
|
|||||||
|
|
||||||
void Channel::dump_config() {
|
void Channel::dump_config() {
|
||||||
ESP_LOGCONFIG(TAG, "Channel %" PRIu8 ":", this->channel_);
|
ESP_LOGCONFIG(TAG, "Channel %" PRIu8 ":", this->channel_);
|
||||||
ESP_LOGCONFIG(TAG, " Gain: %" PRIu8, 1 << this->gain_);
|
|
||||||
ESP_LOGCONFIG(TAG, " Gain calibration: %f", this->gain_cal_);
|
|
||||||
ESP_LOGCONFIG(TAG, " Offset calibration: %" PRIu32, this->offset_cal_);
|
|
||||||
ESP_LOGCONFIG(TAG, " Phase calibration: %" PRId32, this->phase_cal_);
|
|
||||||
ESP_LOGCONFIG(TAG, " DC block: %s", this->dc_block_ ? "YES" : "NO");
|
|
||||||
ESP_LOGCONFIG(TAG, " Input select: %s", (this->input_ == ICM_AIN0P_AIN0N) ? "normal" \
|
ESP_LOGCONFIG(TAG, " Input select: %s", (this->input_ == ICM_AIN0P_AIN0N) ? "normal" \
|
||||||
: (this->input_ == ICM_INPUT_SHORTED) ? "shorted" \
|
: (this->input_ == ICM_INPUT_SHORTED) ? "shorted" \
|
||||||
: (this->input_ == ICM_POSITIVE_DC_TEST_SIGNAL) ? "positive_dc" \
|
: (this->input_ == ICM_POSITIVE_DC_TEST_SIGNAL) ? "positive_dc" \
|
||||||
: (this->input_ == ICM_NEGATIVE_DC_TEST_SIGNAL) ? "negative_dc" \
|
: (this->input_ == ICM_NEGATIVE_DC_TEST_SIGNAL) ? "negative_dc" \
|
||||||
: "invalid");
|
: "invalid");
|
||||||
|
ESP_LOGCONFIG(TAG, " Gain: %" PRIu8, 1 << this->gain_);
|
||||||
|
ESP_LOGCONFIG(TAG, " Gain calibration: %f", this->gain_cal_);
|
||||||
|
ESP_LOGCONFIG(TAG, " Offset calibration: %" PRIu32, this->offset_cal_);
|
||||||
|
ESP_LOGCONFIG(TAG, " Phase calibration: %" PRId32, this->phase_cal_);
|
||||||
|
ESP_LOGCONFIG(TAG, " DC block: %s", this->dc_block_ ? "YES" : "NO");
|
||||||
}
|
}
|
||||||
|
|
||||||
void RMS_Sensor::loop()
|
void RMS_Sensor::loop()
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user