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_DRDY_PIN: GPIO42
|
||||
|
||||
external_components:
|
||||
- source:
|
||||
type: local
|
||||
path: components # Path relative to this YAML file
|
||||
components: [ ads131m08 ]
|
||||
|
||||
spi:
|
||||
- id: spi_bus0
|
||||
clk_pin: ${ESP32_S3_SPI0_SCK}
|
||||
@ -29,15 +23,25 @@ spi:
|
||||
interface: hardware
|
||||
|
||||
ads131m08:
|
||||
id: highres_adc
|
||||
spi_id: spi_bus0
|
||||
cs_pin: ${ADC_CS_PIN}
|
||||
drdy_pin: ${ADC_DRDY_PIN}
|
||||
sync_reset_pin: ${ADC_SYNC_RESET_PIN}
|
||||
reference_voltage: 1.25
|
||||
data_rate: 10MHz
|
||||
clock_frequency: 8192kHz
|
||||
oversampling_ratio: 512
|
||||
- id: highres_adc
|
||||
spi_id: spi_bus0
|
||||
cs_pin: ${ADC_CS_PIN}
|
||||
drdy_pin: ${ADC_DRDY_PIN}
|
||||
sync_reset_pin: ${ADC_SYNC_RESET_PIN}
|
||||
reference_voltage: 1.248 #1.25
|
||||
data_rate: 5MHz
|
||||
clock_frequency: 8192kHz
|
||||
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:
|
||||
- platform: ads131m08
|
||||
@ -49,11 +53,14 @@ sensor:
|
||||
offset_calibration: 0
|
||||
gain_calibration: 0.986
|
||||
ac:
|
||||
name: "Channel 0 AC"
|
||||
id: ads_ch0_ac
|
||||
dc:
|
||||
name: "Channel 0 DC"
|
||||
id: ads_ch0_dc
|
||||
name: "ac_ch0"
|
||||
id: ac_ch0
|
||||
filters:
|
||||
- multiply: 2884
|
||||
- sliding_window_moving_average:
|
||||
window_size: 50
|
||||
send_every: 25
|
||||
send_first_at: 10
|
||||
|
||||
- platform: ads131m08
|
||||
ads131m08_id: highres_adc
|
||||
@ -64,17 +71,34 @@ sensor:
|
||||
offset_calibration: 0
|
||||
gain_calibration: 0.986
|
||||
ac:
|
||||
name: "Channel 1 AC"
|
||||
id: ads_ch1_ac
|
||||
accuracy_decimals: 6
|
||||
state_class: measurement
|
||||
device_class: voltage
|
||||
dc:
|
||||
name: "Channel 1 DC"
|
||||
id: ads_ch1_dc
|
||||
accuracy_decimals: 6
|
||||
state_class: measurement
|
||||
device_class: voltage
|
||||
name: "ac_ch1"
|
||||
id: ac_ch1
|
||||
filters:
|
||||
- multiply: 2884
|
||||
- sliding_window_moving_average:
|
||||
window_size: 50
|
||||
send_every: 25
|
||||
send_first_at: 10
|
||||
|
||||
- platform: ads131m08
|
||||
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/).
|
||||
|
||||
@ -122,19 +122,30 @@ void ADS131M08Hub::dump_config() {
|
||||
this->power_mode_ == VERY_LOW_POWER ? "'very low power'"
|
||||
: this->power_mode_ == LOW_POWER ? "'low power'"
|
||||
: "'high resolution'");
|
||||
ESP_LOGCONFIG(TAG, " Global Chop: %s", this->global_chop_enable_ ? "enable" : "disable");
|
||||
ESP_LOGCONFIG(TAG, " Global Chop Delay: %u", 1 << (1 + this->global_chop_delay_));
|
||||
ESP_LOGCONFIG(TAG, " Current Detect: %s", this->current_detect_enable_ ? "enable" : "disable");
|
||||
ESP_LOGCONFIG(TAG, " Current Detect All: %s", this->current_detect_all_enable_ ? "YES" : "NO");
|
||||
ESP_LOGCONFIG(TAG, " Current Detect Number: %u", 1 << this->current_detect_number_);
|
||||
ESP_LOGCONFIG(TAG, " Current Detect Length: %u", convert_adc_cd_len_to_value(this->current_detect_length_));
|
||||
ESP_LOGCONFIG(TAG, " Current Detect Threshold: %ld", this->current_detect_threshold_);
|
||||
std::string str =" Global Chop";
|
||||
ESP_LOGCONFIG(TAG, "%s: %s", str.c_str(), this->global_chop_enable_ ? "enable" : "disable");
|
||||
ESP_LOGCONFIG(TAG, "%s Delay: %u", str.c_str(), 1 << (1 + this->global_chop_delay_));
|
||||
str = " Current Detect";
|
||||
ESP_LOGCONFIG(TAG, "%s: %s", str.c_str(), this->current_detect_enable_ ? "enable" : "disable");
|
||||
ESP_LOGCONFIG(TAG, "%s All: %s", str.c_str(), this->current_detect_all_enable_ ? "YES" : "NO");
|
||||
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, " Bit Order: %s",
|
||||
this->bit_order_ == spi::BIT_ORDER_MSB_FIRST ? "msb_first"
|
||||
: this->bit_order_ == spi::BIT_ORDER_LSB_FIRST ? "lsb_first"
|
||||
: "unknown");
|
||||
// TODO: add new configs
|
||||
: "invalid");
|
||||
}
|
||||
|
||||
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
|
||||
// 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.
|
||||
float_str ADS131M08Hub::read_multi() {
|
||||
int32_t raw;
|
||||
@ -861,7 +872,11 @@ float_str ADS131M08Hub::read_multi() {
|
||||
}
|
||||
CHIP_SELECTx
|
||||
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;
|
||||
setup_frame(rx_frame, numFrameWords);
|
||||
this->transfer_array(rx_frame);
|
||||
@ -890,7 +905,8 @@ float_str ADS131M08Hub::read_multi() {
|
||||
if(drdy_status == 0){
|
||||
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;
|
||||
drdy_status = drdy_status >> 1;
|
||||
if (data_ready) {
|
||||
@ -901,9 +917,15 @@ float_str ADS131M08Hub::read_multi() {
|
||||
raw = get_sign_ext_frame_word(rx_frame, i + 1);
|
||||
value = this->conversion_factor_ * raw;
|
||||
if (this->rms_enabled_[i]) {
|
||||
(this->num_samples_[i])++;
|
||||
(this->sample_sum_[i]) += value;
|
||||
(this->sample_squared_sum_[i]) += value * value;
|
||||
if(this->num_samples_[i] < sample_target) {
|
||||
(this->num_samples_[i])++;
|
||||
(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 {
|
||||
if(ac_sensor_exist)
|
||||
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 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
|
||||
bool has_mode_reg =
|
||||
(start_address == REG_MODE) || ((start_address < REG_MODE) && ((start_address + nregs) > REG_MODE));
|
||||
bool has_mode_reg = (start_address == REG_MODE) || ((start_address < REG_MODE) && ((start_address + nregs) > REG_MODE));
|
||||
setup_frame(rx_frame, wreg_nwords);
|
||||
{
|
||||
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, "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);
|
||||
return verified;
|
||||
|
||||
@ -150,6 +150,7 @@ class ADS131M08Hub : public Component,
|
||||
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_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:
|
||||
std::string id_;
|
||||
@ -165,6 +166,7 @@ class ADS131M08Hub : public Component,
|
||||
float sampled_values_[ADC_CHANNELS];
|
||||
bool rms_enabled_[MAX_CHANNELS];
|
||||
bool rms_calc_req_{false};
|
||||
int active_channel_count_{0};
|
||||
uint16_t osr_{3};
|
||||
uint16_t global_chop_delay_{16};
|
||||
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);
|
||||
//bool update_averages(uint8_t channel, float rms_ac, float rms_dc);
|
||||
std::atomic<int> adc_init_{0};
|
||||
std::atomic<int> cs_ctr_{
|
||||
0}; // Counter to track nested CS enable/disable calls for proper handling of multiple transfers in a row
|
||||
std::atomic<int> cs_ctr_{0}; // Counter to track nested CS enable/disable calls
|
||||
std::atomic<uint16_t> isr_ctr_{0};
|
||||
void enable(const char *txt);
|
||||
void disable(const char *txt);
|
||||
|
||||
@ -70,16 +70,16 @@ int16_t Channel::normalised_phase_calibration() const
|
||||
|
||||
void Channel::dump_config() {
|
||||
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" \
|
||||
: (this->input_ == ICM_INPUT_SHORTED) ? "shorted" \
|
||||
: (this->input_ == ICM_POSITIVE_DC_TEST_SIGNAL) ? "positive_dc" \
|
||||
: (this->input_ == ICM_NEGATIVE_DC_TEST_SIGNAL) ? "negative_dc" \
|
||||
: "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()
|
||||
|
||||
Loading…
Reference in New Issue
Block a user