From d69d0b5dfb3f596ab75975d1affd3445f27e2406 Mon Sep 17 00:00:00 2001 From: Chris Date: Sun, 3 May 2026 00:06:23 +0200 Subject: [PATCH] Publishing directly to sensors from component (hub) loop. Appears to be aorund 4000sps. DC stable, but AC still fluctuating a lot. 20ms sample time. Will try loop sampling instead of ISR sampling next. --- ads131m08/ads131m08.cpp | 315 ++++++++++++-------------- ads131m08/ads131m08.h | 35 ++- ads131m08/sensor/__init__.py | 2 +- ads131m08/sensor/ads131m08_sensor.cpp | 8 +- ads131m08/sensor/ads131m08_sensor.h | 2 +- ads131m08/sensor_rms/__init__.py | 1 - 6 files changed, 181 insertions(+), 182 deletions(-) diff --git a/ads131m08/ads131m08.cpp b/ads131m08/ads131m08.cpp index 3e57264..8a316a4 100644 --- a/ads131m08/ads131m08.cpp +++ b/ads131m08/ads131m08.cpp @@ -17,8 +17,8 @@ namespace ads131m08 { static const char *const TAG = "ads131m08"; static const char *const white_space = " \t\n\r\f\v"; // Defines whitespace -DRAM_ATTR static spiframe tx_frame(ADS131M08Hub::numFrameWords * 4, 0); -DRAM_ATTR static spiframe rx_frame(ADS131M08Hub::numFrameWords * 4, 0); +DRAM_ATTR static spiframe tx_frame(ADS131M08Hub::numFrameWords * 4, 0); +DRAM_ATTR static spiframe rx_frame(ADS131M08Hub::numFrameWords * 4, 0); // ADS131M08Hub::ADS131M08Hub() // : base_frame(40, 0) @@ -114,11 +114,11 @@ void ADS131M08Hub::dump_config() { } uint8_t ADS131M08Hub::update_adc_word_length() { - int word_nbytes = this->adc_word_length_ >> 3; - spiframe frame(2 * word_nbytes, 0); // prepare with CMD_NULL; always cater for crc - write_array(frame); // write CMD_NULL to ADC to retrieve status - read_array(frame); - uint16_t status = frame[0] << 8 | frame[1]; + setup_frame(rx_frame, 2); + transfer_array(rx_frame); // write CMD_NULL to ADC to retrieve status + zero_fill(rx_frame); + transfer_array(rx_frame); + uint16_t status = rx_frame[0] << 8 | rx_frame[1]; // print_command_response_to_string(CMD_NULL, frame).c_str(); return update_adc_word_length(status); } @@ -261,41 +261,49 @@ void ADS131M08Hub::loop() // Check the semaphore (0 timeout means non-blocking) //if (xSemaphoreTake(data_ready_semhandle, 0) == pdTRUE) { if (this->adc_init_ == 0) { - uint32_t num_samples = 0; - uint32_t crc_errors = 0; - uint32_t iterations = 0; - uint32_t not_ready = 0; + float num_samples = 0; + float crc_errors = 0; + float iterations = 0; + float not_ready = 0; + float sps = 0; { CHIP_SELECTx - // Perform the read here safely outside of ISR - uint64_t start = micros(); - // this->txf_init(); // implementing datasheet recommended TXF init in ISR - this->adc_sync(); + uint64_t start = micros(); + this->txf_init(); // implementing datasheet recommended TXF init + //this->adc_sync(); if (rms_calc_req_) { - uint16_str result = read_multi(); + float_str result = read_multi(); num_samples = result[0]; crc_errors = result[1]; iterations = result[2]; not_ready = result[3]; + sps = result[4]; uint64_t end = micros(); - update_averages(SAMPLE_TIME_SENSOR, 1, static_cast(end - start) / 1000.0); - update_averages(MAX_SAMPLES_SENSOR, 1, static_cast(num_samples)); - update_averages(CRC_ERRORS_SENSOR, 1, static_cast(crc_errors)); - uint16_t ctr = isr_ctr_; - update_averages(ISR_COUNT_SENSOR, 1, static_cast(ctr)); - update_averages(ITERATIONS_SENSOR, 1, static_cast(iterations)); - update_averages(NOT_READY_SENSOR, 1, static_cast(not_ready)); + //update_averages(SAMPLE_TIME_SENSOR, 1, static_cast(end - start) / 1000.0); + //update_averages(MAX_SAMPLES_SENSOR, 1, static_cast(num_samples)); + //update_averages(CRC_ERRORS_SENSOR, 1, static_cast(crc_errors)); + //uint16_t ctr = isr_ctr_; + //update_averages(ISR_COUNT_SENSOR, 1, static_cast(ctr)); + //update_averages(ITERATIONS_SENSOR, 1, static_cast(iterations)); + //update_averages(NOT_READY_SENSOR, 1, static_cast(not_ready)); + + if(this->sensors_dc[SAMPLE_TIME_SENSOR] != nullptr) + this->sensors_dc[SAMPLE_TIME_SENSOR]->publish_state((end - start)/1000.0); + if(this->sensors_dc[MAX_SAMPLES_SENSOR] != nullptr) + this->sensors_dc[MAX_SAMPLES_SENSOR]->publish_state(num_samples); + if(this->sensors_dc[CRC_ERRORS_SENSOR] != nullptr) + this->sensors_dc[CRC_ERRORS_SENSOR]->publish_state(crc_errors); + if(this->sensors_dc[ISR_COUNT_SENSOR] != nullptr) { + uint16_t ctr = isr_ctr_; + this->sensors_dc[ISR_COUNT_SENSOR]->publish_state(ctr); + } + if(this->sensors_dc[ITERATIONS_SENSOR] != nullptr) + this->sensors_dc[ITERATIONS_SENSOR]->publish_state(iterations); + if(this->sensors_dc[NOT_READY_SENSOR] != nullptr) + this->sensors_dc[NOT_READY_SENSOR]->publish_state(not_ready); + if(this->sensors_dc[SPS_SENSOR] != nullptr) + this->sensors_dc[SPS_SENSOR]->publish_state(sps); - // if(this->sensors_ac[SAMPLE_TIME_SENSOR] != nullptr) - // this->sensors_ac[SAMPLE_TIME_SENSOR]->publish_state(static_cast(end - start)/1000.0); - // if(this->sensors_ac[MAX_SAMPLES_SENSOR] != nullptr) - // this->sensors_ac[MAX_SAMPLES_SENSOR]->publish_state(static_cast(num_samples)); - // if(this->sensors_ac[CRC_ERRORS_SENSOR] != nullptr) - // this->sensors_ac[CRC_ERRORS_SENSOR]->publish_state(static_cast(crc_errors)); - // if(this->sensors_ac[ISR_COUNT_SENSOR] != nullptr) { - // uint16_t ctr = isr_ctr_; - // this->sensors_ac[ISR_COUNT_SENSOR]->publish_state(static_cast(ctr)); - // } } else { read_single(); } @@ -468,23 +476,17 @@ void ADS131M08Hub::adc_sync() { // ********************** from datasheet ************************ void ADS131M08Hub::txf_init() { CHIP_SELECT + setup_frame(rx_frame, numFrameWords); if (firstRead) { // Clear the ADC's 2-deep FIFO on the first read - for (int i = 0; i < numFrameWords * adc_word_length_; i++) { - this->write_byte(0); - } - for (int i = 0; i < numFrameWords; i++) { - this->read_byte(); // should perhaps read dwords instead of bytes, but we just want to clear the FIFO so it - // doesn't matter much? - } + this->transfer_array(rx_frame); + zero_fill(rx_frame); + this->transfer_array(rx_frame); firstRead = false; // Clear the flag - // we will do this later, after sorting out basic communication - // DMA.enable(); // Let the DMA start sending ADC data to memory - } - // Send the dummy data to the ADC to get the ADC data - for (int i = 0; i < numFrameWords * adc_word_length_; i++) { - this->write_byte(0); } + // Send the nulls to the ADC to get the current ADC data + zero_fill(rx_frame); + this->transfer_array(rx_frame); } bool ADS131M08Hub::adc_reset_retry() { @@ -518,36 +520,34 @@ bool ADS131M08Hub::adc_soft_reset() { uint16_t reset_response; uint16_t cmd = 0; update_adc_word_length(); - size_t word_nbytes = adc_word_length_ >> 3; - int framelength = numFrameWords * word_nbytes; - spiframe frame(framelength, 0); + auto framelength = numFrameWords * (adc_word_length_ >> 3); size_t frame_len; // curly braces confine chip select scope { CHIP_SELECTx cmd = CMD_RESET; - set_frame_word(frame, 0, cmd); - frame.resize(2 * word_nbytes); - frame_len = add_crc(frame); - frame.resize(framelength); + setup_frame(rx_frame, 2); + set_frame_word(rx_frame, 0, cmd); + frame_len = add_crc(rx_frame); + rx_frame.resize(framelength); index += frame_len; for (; index < framelength; index++) { - frame[index] = 0; + rx_frame[index] = 0; } - write_array(frame); - ESP_LOGVV(TAG, "Sent Frame: %s", frame_to_string(frame).c_str()); + ESP_LOGVV(TAG, "Sent Frame: %s", frame_to_string(rx_frame).c_str()); + transfer_array(rx_frame); } delay_microseconds_safe(T_REGACQ); update_adc_word_length(WLENGTH_24_BITS); // should be 24 after reset - word_nbytes = adc_word_length_ >> 3; - frame.resize(numFrameWords * word_nbytes); + setup_frame(rx_frame, numFrameWords); { - CHIP_SELECTx read_array(frame); - reset_response = get_unsigned_frame_word(frame, 0, true); - bool crc_ok = check_crc(frame); - ESP_LOGVV(TAG, "Read Frame: %s CRC: %s", frame_to_string(frame).c_str(), (crc_ok ? "OK" : "FAIL")); + CHIP_SELECTx + transfer_array(rx_frame); + reset_response = get_unsigned_frame_word(rx_frame, 0, true); + bool crc_ok = check_crc(rx_frame); + ESP_LOGVV(TAG, "Read Frame: %s CRC: %s", frame_to_string(rx_frame).c_str(), (crc_ok ? "OK" : "FAIL")); } bool result = reset_response == RSP_RESET_OK; - ESP_LOGVV(TAG, "Reset response: [0x%04X] %s", reset_response, (result ? "OK" : "FAIL")); + ESP_LOGV(TAG, "Reset response: [0x%04X] %s", reset_response, (result ? "OK" : "FAIL")); return result; } @@ -625,27 +625,9 @@ uint16_t ADS131M08Hub::crc(uint16_t crc_register, uint8_t data) { return crc_result; } -void ADS131M08Hub::write_byte(uint8_t byte) { +void ADS131M08Hub::transfer_array(spiframe &frame) { CHIP_SELECT - this->transfer_byte(byte); -} - -uint8_t ADS131M08Hub::read_byte() { - CHIP_SELECT - uint8_t result = this->transfer_byte(0x00); // Send dummy byte to read data - return result; -} - -void ADS131M08Hub::read_array(spiframe &frame) { - CHIP_SELECT - this->transfer_array(frame.data(), frame.size()); -} - -void ADS131M08Hub::write_array(const spiframe &frame) { - CHIP_SELECT - for (size_t i = 0; i < frame.size(); i++) { - this->transfer_byte(frame[i]); - } + Base::transfer_array(frame.data(), (size_t)frame.size()); } //void ADS131M08Hub::transfer_array(const spiframe &tx_frame, spiframe &rx_frame) { @@ -667,28 +649,28 @@ bool ADS131M08Hub::set_measure_rms(uint8_t channel, bool enable) { } void ADS131M08Hub::read_single() { - int word_nbytes = adc_word_length_ >> 3; - int frame_length = numFrameWords * word_nbytes; - spiframe frame(frame_length, 0); - this->read_array(frame); - bool crc_ok = check_crc(frame); - uint16_t drdy_status = get_unsigned_frame_word(frame, 0, true) & MASK_STATUS_DRDY; + setup_frame(rx_frame, numFrameWords); + this->transfer_array(rx_frame); + bool crc_ok = check_crc(rx_frame); + uint16_t drdy_status = get_unsigned_frame_word(rx_frame, 0, true) & MASK_STATUS_DRDY; // data_ready = crc_ok && (drdy_status != 0); if (crc_ok) { // sample channels for (int i = 0; i < ADC_CHANNELS; i++) { bool channel_ready = drdy_status & 1; drdy_status = drdy_status >> 1; - bool ac_sensor_exist = this->sensors_ac[i] != nullptr; - bool dc_sensor_exist = this->sensors_dc[i] != nullptr; - if (channel_ready && (ac_sensor_exist || dc_sensor_exist)) { - int32_t raw = get_sign_ext_frame_word(frame, i + 1); + if (channel_ready) { + int32_t raw = get_sign_ext_frame_word(rx_frame, i + 1); float value = this->conversion_factor_ * raw; this->sampled_values_[i] = value; - if (ac_sensor_exist) - this->sensors_ac[i]->publish_state(value); - if (dc_sensor_exist) - this->sensors_dc[i]->publish_state(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); + } } } } @@ -700,13 +682,13 @@ void ADS131M08Hub::read_single() { // hopefully reliably calculate RMS value, phase offsets, etc. the best the read_multi procedure does is to read about // 66x 16bit / 33x 32bit word frames in 40ms which is far from ideal Once we ge the ISR and loop setup to respond fast // enough, the following procedure should be completely re-designed -uint16_str ADS131M08Hub::read_multi() { +float_str ADS131M08Hub::read_multi() { int32_t raw; float value; - uint16_str result(4, 0); + float_str result(5, 0.0); bool crc_ok, data_ready, ac_sensor_exist, dc_sensor_exist; uint16_t drdy_status, status; - int i, iteration = 0; // going above 255 will result in overflows + int i, iteration = 0; uint32_t elapsed_time = 0; uint32_t loop_start_time = micros(); int word_nbytes = adc_word_length_ >> 3; @@ -722,10 +704,10 @@ uint16_str ADS131M08Hub::read_multi() { sample_squared_sum_[i] = 0; } - while (elapsed_time < this->sample_time_ && iteration++ < 1000) { + while ((elapsed_time < this->sample_time_) && (iteration++ < 1000)) { result[2] = iteration; - std::fill(rx_frame.begin(), rx_frame.end(), 0); - this->read_array(rx_frame); + setup_frame(rx_frame, numFrameWords); + this->transfer_array(rx_frame); //ESP_LOGD(TAG, "frame: %s", frame_to_string(rx_frame).c_str()); //ESP_LOGD(TAG, "iteration: %d, frame: %s", iteration, frame_to_string(rx_frame).c_str()); //ESP_LOGD(TAG, "frame_word%d: %s", 0, frame_words_to_string(rx_frame, 0, 1).c_str()); @@ -743,22 +725,24 @@ uint16_str ADS131M08Hub::read_multi() { for (i = 0; i < ADC_CHANNELS && drdy_status != 0; i++) { data_ready = drdy_status & 1; drdy_status = drdy_status >> 1; - ac_sensor_exist = this->sensors_ac[i] != nullptr; - dc_sensor_exist = this->sensors_dc[i] != nullptr; - if (data_ready && (ac_sensor_exist || dc_sensor_exist)) { - raw = get_sign_ext_frame_word(rx_frame, i + 1); - value = this->conversion_factor_ * raw; + if (data_ready) { this->sampled_values_[i] = value; - if (this->rms_enabled_[i]) { - (this->num_samples_[i])++; - (this->sample_sum_[i]) += value; - (this->sample_squared_sum_[i]) += value * value; - } else { - // if(ac_sensor_exist) - // this->sensors_ac[i]->publish_state(value); - // if(dc_sensor_exist) - // this->sensors_dc[i]->publish_state(value); - update_averages(i, value, value); + ac_sensor_exist = this->sensors_ac[i] != nullptr; + dc_sensor_exist = this->sensors_dc[i] != nullptr; + if (ac_sensor_exist || dc_sensor_exist) { + 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; + } else { + if(ac_sensor_exist) + this->sensors_ac[i]->publish_state(value); + if(dc_sensor_exist) + this->sensors_dc[i]->publish_state(value); + //update_averages(i, value, value); + } } } } @@ -781,11 +765,11 @@ uint16_str ADS131M08Hub::read_multi() { if (num_samples == 0) { // should not happen, but let's play safe and avoid dividing by zero // ESP_LOGW(TAG, "Num samples: %d", num_samples); - update_averages(i, NAN, NAN); - // if(ac_sensor_exist) - // this->sensors_ac[i]->publish_state(NAN); - // if(dc_sensor_exist) - // this->sensors_dc[i]->publish_state(NAN); + //update_averages(i, NAN, NAN); + if(ac_sensor_exist) + this->sensors_ac[i]->publish_state(NAN); + if(dc_sensor_exist) + this->sensors_dc[i]->publish_state(NAN); } else { float sample_sum = sample_sum_[i]; float rms_dc = sample_sum / num_samples; @@ -794,16 +778,22 @@ uint16_str ADS131M08Hub::read_multi() { if (rms_ac_squared > 0) { rms_ac = std::sqrtf(rms_ac_squared); } - this->sps_ = (1e6 * (float) num_samples) / elapsed_time; - update_averages(i, rms_ac, rms_dc); + if(ac_sensor_exist) + this->sensors_ac[i]->publish_state(rms_ac); + if(dc_sensor_exist) + this->sensors_dc[i]->publish_state(rms_dc); + //update_averages(i, rms_ac, rms_dc); } this->num_samples_[i] = 0; this->sample_sum_[i] = 0.0f; this->sample_squared_sum_[i] = 0.0f; } } + this->sps_ = (1e6 * (float) result[0]) / elapsed_time; + result[4] = this->sps_; return result; } +/* /// @brief Updates rolling averages for rms_ac and rms_dc. Window = 2 /// @param channel /// @param rms_ac @@ -897,20 +887,20 @@ float ADS131M08Hub::get_average(uint8_t channel, bool read_ac) { } return result; } - +*/ bool ADS131M08Hub::adc_lock(bool enable) { - int word_nbytes = adc_word_length_ >> 3; - spiframe frame(word_nbytes * 2, 0); + setup_frame(rx_frame, 2); uint16_t command = CMD_UNLOCK; if (enable) { command = CMD_LOCK; } - set_frame_word(frame, 0, command); - add_crc(frame); - write_array(frame); + set_frame_word(rx_frame, 0, command); + add_crc(rx_frame); + transfer_array(rx_frame); delay_microseconds_safe(T_REGACQ); - read_array(frame); - auto ack = get_unsigned_frame_word(frame, 0, true); + zero_fill(rx_frame); + transfer_array(rx_frame); + auto ack = get_unsigned_frame_word(rx_frame, 0, true); return ack == command; } @@ -981,27 +971,26 @@ bool ADS131M08Hub::adc_register_write(uint16_t start_address, const uint16_str & if (nregs == 0) { return false; // invalid } - int word_nbytes = adc_word_length_ >> 3; - int wreg_framelength = word_nbytes * (2 + nregs); // ensure room for crc - int rreg_resp_framelength = word_nbytes * (2 + (nregs == 1 ? -1 : nregs)); // add room for CRC if nregs > 1 - //spiframe frame(wreg_framelength, 0); - //spiframe rxframe(wreg_framelength, 0); + int wreg_nwords = 2 + nregs; // ensure room for crc + int rreg_resp_framelength = 2 + (nregs == 1 ? -1 : nregs); // add room for CRC if nregs > 1 + //spiframe frame(wreg_nwords, 0); + //spiframe rxframe(wreg_nwords, 0); 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)); - tx_frame.resize(wreg_framelength); - rx_frame.resize(wreg_framelength); + setup_frame(rx_frame, wreg_nwords); { - CHIP_SELECT set_frame_word(tx_frame, 0, wreg_addr_opcode); + CHIP_SELECT + set_frame_word(rx_frame, 0, wreg_addr_opcode); for (int i = 0; i < nregs; i++) { - set_frame_word(tx_frame, i + 1, data[i]); + set_frame_word(rx_frame, i + 1, data[i]); } - add_crc(tx_frame); - //ESP_LOGD(TAG, "%s\n", rwreg_command_frame_to_string(tx_frame).c_str()); - //ESP_LOGD(TAG, "Send Frame: %s", frame_to_string(tx_frame).c_str()); - transfer_array(tx_frame.data(), tx_frame.size()); // WREG + add_crc(rx_frame); + //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 } if (has_mode_reg) { update_adc_word_length(); @@ -1032,31 +1021,29 @@ uint16_str ADS131M08Hub::adc_register_read(uint8_t address, uint8_t nregs) { ESP_LOGE(TAG, "Trying to read %d registers. This exceeds maximum register read count of %d!", nregs, MAX_FRAME_SIZE - 2); return result; // invalid } - int word_nbytes = adc_word_length_ >> 3; - int request_framelength = 2 * word_nbytes; // ensure room for crc - int response_framelength = word_nbytes * (2 + (nregs == 1 ? -1 : nregs)); // add room for CRC if nregs > 1 - spiframe frame(response_framelength, 0); + int rreg_nwords = 2; // ensure room for crc + int response_nwords = 2 + (nregs == 1 ? -1 : nregs); // add room for CRC if nregs > 1 uint16_t rreg_addr_opcode = CMD_RREG | (address << 7) | ((nregs - 1) & MASK_CMD_RW_REG_COUNT); // Combine RREG command, address and register count { CHIP_SELECT - frame.resize(request_framelength); - set_frame_word(frame, 0, rreg_addr_opcode); - add_crc(frame); - write_array(frame); // send RREG + setup_frame(rx_frame, rreg_nwords); + set_frame_word(rx_frame, 0, rreg_addr_opcode); + add_crc(rx_frame); + transfer_array(rx_frame); // send RREG } - ESP_LOGVV(TAG, "%s\n", rwreg_command_frame_to_string(frame).c_str()); - ESP_LOGVV(TAG, "Sent Frame: %s", frame_to_string(frame).c_str()); + ESP_LOGVV(TAG, "%s\n", rwreg_command_frame_to_string(rx_frame).c_str()); + ESP_LOGVV(TAG, "Sent Frame: %s", frame_to_string(rx_frame).c_str()); delay_microseconds_safe(T_REGACQ); { CHIP_SELECT - frame.resize(response_framelength); - read_array(frame); + setup_frame(rx_frame, response_nwords); + transfer_array(rx_frame); } - ESP_LOGVV(TAG, "Recv Frame: %s", frame_to_string(frame).c_str()); + ESP_LOGVV(TAG, "Recv Frame: %s", frame_to_string(rx_frame).c_str()); if (nregs > 1) { - bool crc_ok = check_crc(frame); + bool crc_ok = check_crc(rx_frame); if (!crc_ok) { ESP_LOGW(TAG, "CRC failed reading ADC registers!"); result.clear(); @@ -1069,15 +1056,15 @@ uint16_str ADS131M08Hub::adc_register_read(uint8_t address, uint8_t nregs) { // pretend this is the ack if (nregs > 1) { offset = 1; - rreg_ack = get_unsigned_frame_word(frame, 0, true); + rreg_ack = get_unsigned_frame_word(rx_frame, 0, true); } - // uint16_t rreg_ack = (nregs == 1) ? rreg_addr_opcode : get_unsigned_frame_word(frame, 0, true); + // uint16_t rreg_ack = (nregs == 1) ? rreg_addr_opcode : get_unsigned_frame_word(rx_frame, 0, true); nregs = (rreg_ack & MASK_CMD_RW_REG_COUNT) + 1; uint16_t start_addr = (rreg_ack & MASK_CMD_RW_REG_ADDRESS) >> 7; for (int i = 0; i < nregs; i++) { - result[i] = get_unsigned_frame_word(frame, i + offset, true); + result[i] = get_unsigned_frame_word(rx_frame, i + offset, true); } - print_command_response_to_string(rreg_addr_opcode, frame); + print_command_response_to_string(rreg_addr_opcode, rx_frame); delay_microseconds_safe(1); return result; } diff --git a/ads131m08/ads131m08.h b/ads131m08/ads131m08.h index 0c8bc63..67d186f 100644 --- a/ads131m08/ads131m08.h +++ b/ads131m08/ads131m08.h @@ -25,23 +25,28 @@ namespace ads131m08 { static const uint8_t DEFAULT_WORD_LENGTH = 32; // we use 32 bit to allow for DMA transfers static const int ADC_CHANNELS = 8; -static const int MAX_CHANNELS = 14; // for debugging +static const int MAX_CHANNELS = 15; // for debugging static const int SAMPLE_TIME_SENSOR = 8; // for debugging static const int MAX_SAMPLES_SENSOR = 9; // for debugging static const int CRC_ERRORS_SENSOR = 10; // for debugging static const int ISR_COUNT_SENSOR = 11; // for debugging static const int ITERATIONS_SENSOR = 12; // for debugging static const int NOT_READY_SENSOR = 13; // for debugging +static const int SPS_SENSOR = 14; // for debugging + // #define SET_IRAM IRAM_ATTR #define SET_IRAM typedef std::vector spiframe; typedef uint_str::Ty_string uint16_str; // we want to use the stack to pass small arrays +typedef uint_str::Ty_string float_str; // we want to use the stack to pass small arrays class ADS131M08Hub : public Component, public spi::SPIDevice { + + using Base = spi::SPIDevice; friend class ads131m08_select; public: @@ -91,7 +96,7 @@ 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_average(uint8_t channel, bool read_ac); + //float get_average(uint8_t channel, bool read_ac); bool set_reg_osr(); protected: @@ -110,7 +115,7 @@ class ADS131M08Hub : public Component, uint8_t update_adc_word_length(); uint8_t update_adc_word_length(uint16_t status); void SET_IRAM read_single(); - uint16_str SET_IRAM read_multi(); + float_str SET_IRAM read_multi(); bool adc_lock(bool enable); bool adc_register_write(uint16_t address, uint16_t data); bool adc_register_write(uint16_t address, const uint16_str &data); @@ -121,11 +126,7 @@ class ADS131M08Hub : public Component, bool adc_soft_reset(); void adc_hard_reset(); void adc_sync(); - void write_byte(uint8_t byte); - bool write(uint32_t data, uint8_t adcWordLength); - uint8_t read_byte(); - void write_array(const spiframe &data); - void SET_IRAM read_array(spiframe &buffer); + void SET_IRAM transfer_array(spiframe &frame); //void transfer_array(const spiframe &data_out, spiframe &data_in); uint16_t SET_IRAM get_crc(const spiframe &frame); bool SET_IRAM check_crc(const spiframe &frame_with_crc); @@ -137,7 +138,7 @@ class ADS131M08Hub : public Component, bool SET_IRAM set_frame_word(spiframe &frame, int w_index, uint32_t data); uint32_t SET_IRAM get_unsigned_frame_word(const spiframe &frame, int w_index, bool force_16bits = false); 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 adc_init_{0}; std::atomic cs_ctr_{ 0}; // Counter to track nested CS enable/disable calls for proper handling of multiple transfers in a row @@ -161,12 +162,24 @@ class ADS131M08Hub : public Component, } }; float update_conversion_factor(); + //DRAM_ATTR static spiframe rx_frame; + + inline void zero_fill(spiframe& frame) { + std::fill(frame.begin(), frame.end(), 0); + } + + inline size_t setup_frame(spiframe& frame, uint8_t word_count) { + int word_nbytes = this->adc_word_length_ >> 3; + frame.resize(word_nbytes * word_count); + zero_fill(frame); + return frame.size(); + } private: uint8_t update_state_[MAX_CHANNELS] = {0, 0, 0, 0, 0, 0, 0, 0}; uint8_t adc_word_length_{24}; - float conversion_factor_{1.2 / 8388608.0}; // updated when word length changes - const uint32_t sample_time_ = 40000; // 250 ms + float conversion_factor_{1.25 / 8388608.0}; // updated when word length changes + const uint32_t sample_time_ = 20000; // 250 ms float sps_{0.0f}; uint32_t num_samples_[ADC_CHANNELS]; float sample_sum_[ADC_CHANNELS]; diff --git a/ads131m08/sensor/__init__.py b/ads131m08/sensor/__init__.py index 0f7ba6c..3a8a5da 100644 --- a/ads131m08/sensor/__init__.py +++ b/ads131m08/sensor/__init__.py @@ -9,7 +9,7 @@ AUTO_LOAD = [ "sensor", "voltage_sampler", ] -MAX_CHANNELS = 14 +MAX_CHANNELS = 15 CONF_OFFSET_CALIBRATION = "offset_calibration" CONF_GAIN_CALIBRATION = "gain_calibration" CONF_PHASE_CALIBRATION = "phase_calibration" diff --git a/ads131m08/sensor/ads131m08_sensor.cpp b/ads131m08/sensor/ads131m08_sensor.cpp index f585e43..938a8f0 100644 --- a/ads131m08/sensor/ads131m08_sensor.cpp +++ b/ads131m08/sensor/ads131m08_sensor.cpp @@ -73,10 +73,10 @@ void RMS_Sensor::loop() } } } - else { - float value = this->parent_->get_average(this->calc_rms_); - publish_state(value); - } + //else { + // float value = this->parent_->get_average(this->calc_rms_); + // publish_state(value); + //} } void RMS_Sensor::dump_config() diff --git a/ads131m08/sensor/ads131m08_sensor.h b/ads131m08/sensor/ads131m08_sensor.h index ac18aff..4d25cef 100644 --- a/ads131m08/sensor/ads131m08_sensor.h +++ b/ads131m08/sensor/ads131m08_sensor.h @@ -26,7 +26,7 @@ class Channel : public sensor::Sensor, void set_offset_calibration(int value) { this->offset_cal_ = value; } void set_phase_calibration(int value) { this->phase_cal_ = value; } bool set_calc_rms(bool enable) { this->calc_rms_ = enable; return this->parent_ != nullptr ? this->parent_->set_measure_rms(this->channel_, enable) : false; } - float get_average(bool read_ac) { return this->parent_->get_average(this->channel_, read_ac); } + //float get_average(bool read_ac) { return this->parent_->get_average(this->channel_, read_ac); } void set_mux_input(ADC_INPUT_CHANNEL_MUX value) { this->input_ = value; } uint32_t normalised_gain_calibration() const; uint32_t normalised_offset_calibration() const; diff --git a/ads131m08/sensor_rms/__init__.py b/ads131m08/sensor_rms/__init__.py index 1ef942e..e3036d8 100644 --- a/ads131m08/sensor_rms/__init__.py +++ b/ads131m08/sensor_rms/__init__.py @@ -14,7 +14,6 @@ from .. import CONF_ADS131M08_ID, ads131m08_ns CONF_AC = "ac" CONF_DC = "dc" ICON_CURRENT_DC = "mdi:current-dc" -MAX_CHANNELS = 12 AUTO_LOAD = ["sensor",] DEPENDENCIES = ["ads131m08"]