Fixed recovery from reset. Recovery working ok now. Added more hub configs. Need stil to update hub dump_config and calculation of settling times
This commit is contained in:
parent
de74905436
commit
7d374b6cb4
@ -11,12 +11,76 @@ CONF_SYNC_RESET_PIN = "sync_reset_pin"
|
||||
CONF_CLOCK_FREQUENCY = "clock_frequency"
|
||||
CONF_ADS131M08_ID = "ads131m08_id"
|
||||
CONF_OVERSAMPLING_RATIO = "oversampling_ratio"
|
||||
CONF_POWER_MODE = "power_mode"
|
||||
CONF_GLOBAL_CHOP = "global_chop"
|
||||
CONF_GLOBAL_CHOP_DELAY = "global_chop_delay"
|
||||
CONF_DCBLOCK_FILTER = "dcblock_filter"
|
||||
CONF_CURRENT_DETECT = "current_detect"
|
||||
CONF_CURRENT_DETECT_ALL = "current_detect_all"
|
||||
CONF_CURRENT_DETECT_NUMBER = "current_detect_number"
|
||||
CONF_CURRENT_DETECT_LENGTH = "current_detect_length"
|
||||
CONF_CURRENT_DETECT_THRESHOLD = "current_detect_threshold"
|
||||
|
||||
DEPENDENCIES = ["spi"]
|
||||
|
||||
ads131m08_ns = cg.esphome_ns.namespace("ads131m08")
|
||||
ADS131M08Hub = ads131m08_ns.class_("ADS131M08Hub", cg.Component, spi.SPIDevice)
|
||||
|
||||
POWER_MODE = ads131m08_ns.enum("ADC_POWERMODE")
|
||||
POWER_MODES = {
|
||||
0: POWER_MODE.VERY_LOW_POWER,
|
||||
1: POWER_MODE.LOW_POWER,
|
||||
2: POWER_MODE.HIGH_RESOLUTION, # default
|
||||
3: POWER_MODE.HIGH_RESOLUTION2,
|
||||
"very_low": POWER_MODE.VERY_LOW_POWER,
|
||||
"low": POWER_MODE.LOW_POWER,
|
||||
"high": POWER_MODE.HIGH_RESOLUTION,
|
||||
}
|
||||
|
||||
GLOBAL_CHOP_DELAY = ads131m08_ns.enum("ADC_GLOBAL_CHOP_DELAY")
|
||||
GLOBAL_CHOP_DELAYS = {
|
||||
2: GLOBAL_CHOP_DELAY.GC_DEL2,
|
||||
4: GLOBAL_CHOP_DELAY.GC_DEL4,
|
||||
8: GLOBAL_CHOP_DELAY.GC_DEL8,
|
||||
16: GLOBAL_CHOP_DELAY.GC_DEL16, # default
|
||||
32: GLOBAL_CHOP_DELAY.GC_DEL32,
|
||||
64: GLOBAL_CHOP_DELAY.GC_DEL64,
|
||||
128: GLOBAL_CHOP_DELAY.GC_DEL128,
|
||||
256: GLOBAL_CHOP_DELAY.GC_DEL256,
|
||||
512: GLOBAL_CHOP_DELAY.GC_DEL512,
|
||||
1024: GLOBAL_CHOP_DELAY.GC_DEL1024,
|
||||
2048: GLOBAL_CHOP_DELAY.GC_DEL2048,
|
||||
4096: GLOBAL_CHOP_DELAY.GC_DEL4096,
|
||||
8192: GLOBAL_CHOP_DELAY.GC_DEL8192,
|
||||
16384: GLOBAL_CHOP_DELAY.GC_DEL16384,
|
||||
32768: GLOBAL_CHOP_DELAY.GC_DEL32768,
|
||||
65536: GLOBAL_CHOP_DELAY.GC_DEL65536,
|
||||
}
|
||||
|
||||
CURRENT_DETECT_NUMBER = ads131m08_ns.enum("ADC_CURRENT_DETECT_NUMBER")
|
||||
CURRENT_DETECT_NUMBERS = {
|
||||
1: CURRENT_DETECT_NUMBER.CD_NUM1, # default
|
||||
2: CURRENT_DETECT_NUMBER.CD_NUM2,
|
||||
4: CURRENT_DETECT_NUMBER.CD_NUM4,
|
||||
8: CURRENT_DETECT_NUMBER.CD_NUM8,
|
||||
16: CURRENT_DETECT_NUMBER.CD_NUM16,
|
||||
32: CURRENT_DETECT_NUMBER.CD_NUM32,
|
||||
64: CURRENT_DETECT_NUMBER.CD_NUM64,
|
||||
128: CURRENT_DETECT_NUMBER.CD_NUM128,
|
||||
}
|
||||
|
||||
CURRENT_DETECT_LENGTH = ads131m08_ns.enum("ADC_CURRENT_DETECT_LENGTH")
|
||||
CURRENT_DETECT_LENGTHS = {
|
||||
128: CURRENT_DETECT_LENGTH.CD_LEN128, # default
|
||||
256: CURRENT_DETECT_LENGTH.CD_LEN256,
|
||||
512: CURRENT_DETECT_LENGTH.CD_LEN512,
|
||||
768: CURRENT_DETECT_LENGTH.CD_LEN768,
|
||||
1280: CURRENT_DETECT_LENGTH.CD_LEN1280,
|
||||
1792: CURRENT_DETECT_LENGTH.CD_LEN1792,
|
||||
2560: CURRENT_DETECT_LENGTH.CD_LEN2560,
|
||||
3584: CURRENT_DETECT_LENGTH.CD_LEN3584,
|
||||
}
|
||||
|
||||
OSR = ads131m08_ns.enum("ADS131M08_OVERSAMPLING_RATIO")
|
||||
OSRS = {
|
||||
128: OSR.OSR_128,
|
||||
@ -56,6 +120,15 @@ CONFIG_SCHEMA = (
|
||||
cv.Optional(CONF_REFERENCE_VOLTAGE, default=1.2): cv.float_range(
|
||||
min=1.1, max=1.3
|
||||
),
|
||||
cv.Optional(CONF_DCBLOCK_FILTER, default=0): cv.int_range(min=0, max=15),
|
||||
cv.Optional(CONF_POWER_MODE, default=2): cv.enum(POWER_MODES, int=False),
|
||||
cv.Optional(CONF_GLOBAL_CHOP, default=False): cv.boolean,
|
||||
cv.Optional(CONF_GLOBAL_CHOP_DELAY, default=16): cv.enum(GLOBAL_CHOP_DELAYS, int=True),
|
||||
cv.Optional(CONF_CURRENT_DETECT, default=False): cv.boolean,
|
||||
cv.Optional(CONF_CURRENT_DETECT_ALL, default=False): cv.boolean,
|
||||
cv.Optional(CONF_CURRENT_DETECT_NUMBER, default=1): cv.enum(CURRENT_DETECT_NUMBERS, int=True),
|
||||
cv.Optional(CONF_CURRENT_DETECT_LENGTH, default=128): cv.enum(CURRENT_DETECT_LENGTHS, int=True),
|
||||
cv.Optional(CONF_CURRENT_DETECT_THRESHOLD, default=0):cv.int_range(min=-8388608, max=8388607),
|
||||
}
|
||||
)
|
||||
.extend(cv.COMPONENT_SCHEMA)
|
||||
@ -77,4 +150,22 @@ async def to_code(config):
|
||||
cg.add(var.set_osr(osr))
|
||||
reference_voltage = config[CONF_REFERENCE_VOLTAGE]
|
||||
cg.add(var.set_reference_voltage(reference_voltage))
|
||||
dcblock_filter = config[CONF_DCBLOCK_FILTER]
|
||||
cg.add(var.set_dcblock_filter(dcblock_filter))
|
||||
power_mode = config[CONF_POWER_MODE]
|
||||
cg.add(var.set_power_mode(power_mode))
|
||||
global_chop = config[CONF_GLOBAL_CHOP]
|
||||
cg.add(var.set_global_chop(global_chop))
|
||||
global_chop_delay = config[CONF_GLOBAL_CHOP_DELAY]
|
||||
cg.add(var.set_global_chop_delay(global_chop_delay))
|
||||
current_detect = config[CONF_CURRENT_DETECT]
|
||||
cg.add(var.set_current_detect(current_detect))
|
||||
current_detect_all = config[CONF_CURRENT_DETECT_ALL]
|
||||
cg.add(var.set_current_detect_all(current_detect_all))
|
||||
current_detect_number = config[CONF_CURRENT_DETECT_NUMBER]
|
||||
cg.add(var.set_current_detect_number(current_detect_number))
|
||||
current_detect_length = config[CONF_CURRENT_DETECT_LENGTH]
|
||||
cg.add(var.set_current_detect_length(current_detect_length))
|
||||
current_detect_threshold = config[CONF_CURRENT_DETECT_THRESHOLD]
|
||||
cg.add(var.set_current_detect_threshold(current_detect_threshold))
|
||||
cg.add(var.set_drdy_pin(drdy))
|
||||
|
||||
@ -74,7 +74,6 @@ void ADS131M08Hub::setup() {
|
||||
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."));
|
||||
@ -126,6 +125,7 @@ void ADS131M08Hub::dump_config() {
|
||||
this->bit_order_ == 1 ? "msb_first"
|
||||
: this->bit_order_ == 0 ? "lsb_first"
|
||||
: "unknown");
|
||||
// TODO: add new configs
|
||||
}
|
||||
|
||||
uint8_t ADS131M08Hub::update_adc_word_length() {
|
||||
@ -173,13 +173,13 @@ float ADS131M08Hub::update_conversion_factor() {
|
||||
bool ADS131M08Hub::adc_initialize(uint8_t word_length) {
|
||||
this->adc_init_++;
|
||||
update_adc_word_length();
|
||||
if (!adc_register_write(REG_CLOCK, (reg_clock_allch_off | this->osr_ << 2), __LINE__)) {
|
||||
if (!adc_register_write(REG_CLOCK, (reg_clock_allch_off), __LINE__)) {
|
||||
ESP_LOGE(TAG, "CLOCK register write / read to turn off all channels failed");
|
||||
return false;
|
||||
}
|
||||
ESP_LOGV(TAG, "Turned off all channels so short frames can be written during config");
|
||||
|
||||
if (!adc_register_write(REG_MODE, MODE_MASK_RESET_HAPPENED & reg_mode_cfg24, __LINE__)) {
|
||||
if (!adc_register_write(REG_MODE, MODE_MASK_RESET_CLEAR & reg_mode_cfg24, __LINE__)) {
|
||||
ESP_LOGE(TAG, "MODE register write / read to set word size to 24bits failed");
|
||||
return false;
|
||||
}
|
||||
@ -189,16 +189,25 @@ bool ADS131M08Hub::adc_initialize(uint8_t word_length) {
|
||||
ESP_LOGE(TAG, "THRSHLD_LSB register write / read to set DBLOCK filter failed");
|
||||
return false;
|
||||
}
|
||||
ESP_LOGV(TAG, "Written THRSHLD_LSB register; Set DCBLOCK filter to have a corner frequency of 622 mHz");
|
||||
ESP_LOGV(TAG, "Written THRSHLD_LSB register; Set DCBLOCK filter to have a corner frequency of 0.622Hz");
|
||||
|
||||
if (!adc_set_word_length(word_length))
|
||||
return false;
|
||||
// we leave should channels off, as the individual sensors should turn it on
|
||||
if (!adc_register_write(REG_CLOCK, (reg_clock_allch_off | this->osr_ << 2), __LINE__)) {
|
||||
ESP_LOGE(TAG, "CLOCK register write / read to turn-off all channels failed");
|
||||
if (!adc_register_write(REG_CLOCK, (reg_clock_allch_off), __LINE__)) {
|
||||
ESP_LOGE(TAG, "CLOCK register write / read to turn-off all channels and set osr failed");
|
||||
return false;
|
||||
}
|
||||
|
||||
set_current_detect_threshold();
|
||||
set_current_detect_length();
|
||||
set_current_detect_number();
|
||||
set_current_detect_all();
|
||||
set_current_detect();
|
||||
set_global_chop_delay();
|
||||
set_global_chop();
|
||||
set_power_mode();
|
||||
set_dc_block_filter();
|
||||
set_osr();
|
||||
if (!drdy_pin_->digital_read()) {
|
||||
ESP_LOGE(TAG, "DRDY pin is low after initialization!");
|
||||
return false;
|
||||
@ -229,19 +238,19 @@ bool ADS131M08Hub::adc_restore_registers() {
|
||||
int store_nwords = sizeof(settings.data) / sizeof(settings.data[0]);
|
||||
success = adc_register_write(j + REG_MODE, settings.data[j], __LINE__, false);
|
||||
if(!success) {
|
||||
ESP_LOGD(TAG, "restoring %s reg: %04X failed", reg_addr_to_string(j + REG_MODE).c_str(), settings.data[j]);
|
||||
auto reg = reg_addr_to_string(j + REG_MODE) + " reg";
|
||||
ESP_LOGW(TAG, "Restoring %-12s data: %04X failed", reg.c_str(), settings.data[j]);
|
||||
}
|
||||
j++;
|
||||
while(success && (j < store_nwords)) {
|
||||
int i = 0;
|
||||
stored_regs.resize(MAX_FRAME_SIZE - 2);
|
||||
while((i < MAX_FRAME_SIZE - 2) && (j < store_nwords)) {
|
||||
ESP_LOGD(TAG, "restoring %s reg: %04X", reg_addr_to_string(j + REG_MODE).c_str(), stored_regs[i]);
|
||||
ESP_LOGVV(TAG, "Restoring %-12s: %04X", reg_addr_to_string(j + REG_MODE).c_str(), settings.data[j]);
|
||||
stored_regs[i++] = settings.data[j++];
|
||||
}
|
||||
stored_regs.resize(i);
|
||||
success = adc_register_write(j + REG_MODE - i, stored_regs, __LINE__, false);
|
||||
//ESP_LOGD(TAG, "start_addr: %02X i: %02X", j + REG_MODE - , i);
|
||||
}
|
||||
return success;
|
||||
}
|
||||
@ -301,18 +310,18 @@ void ADS131M08Hub::isr_handler(ADS131M08Hub *arg) {
|
||||
{
|
||||
// InterruptLock lock;
|
||||
if (arg != nullptr) {
|
||||
arg->enable_loop_soon_any_context();
|
||||
//arg->enable_loop_soon_any_context();
|
||||
arg->isr_ctr_++;
|
||||
// BaseType_t xHigherPriorityTaskWoken = pdFALSE;
|
||||
// xSemaphoreGiveFromISR(arg->data_ready_semhandle, &xHigherPriorityTaskWoken);
|
||||
// if (xHigherPriorityTaskWoken == pdTRUE) {
|
||||
// portYIELD_FROM_ISR(); // Switch to the waiting task immediately
|
||||
// }
|
||||
BaseType_t xHigherPriorityTaskWoken = pdFALSE;
|
||||
xSemaphoreGiveFromISR(arg->data_ready_semhandle, &xHigherPriorityTaskWoken);
|
||||
if (xHigherPriorityTaskWoken == pdTRUE) {
|
||||
portYIELD_FROM_ISR(); // Switch to the waiting task immediately
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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)
|
||||
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];
|
||||
@ -324,28 +333,50 @@ float ADS131M08Hub::get_sample(int32_t& raw_value, uint8_t channel, uint8_t gain
|
||||
void ADS131M08Hub::loop()
|
||||
{
|
||||
// Check the semaphore (0 timeout means non-blocking)
|
||||
//if (xSemaphoreTake(data_ready_semhandle, 0) == pdTRUE) {
|
||||
if (xSemaphoreTake(data_ready_semhandle, 0) == pdTRUE) {
|
||||
if (this->adc_init_ == 0) {
|
||||
float num_samples = 0;
|
||||
float crc_errors = 0;
|
||||
float iterations = 0;
|
||||
float not_ready = 0;
|
||||
float sps = 0;
|
||||
if(this->recover_count_ > 0) {
|
||||
recover_from_reset();
|
||||
return;
|
||||
}
|
||||
{
|
||||
CHIP_SELECTx
|
||||
uint64_t start = micros();
|
||||
///this->txf_init(); // implementing datasheet recommended TXF init
|
||||
uint32_t start = micros();
|
||||
uint32_t end;
|
||||
this->adc_sync();
|
||||
|
||||
//firstRead = true;
|
||||
//this->txf_init(); // implementing datasheet recommended TXF init
|
||||
int freq = 0;
|
||||
//if(delegate_ != nullptr){
|
||||
// esp_err_t ret = spi_device_get_actual_freq((SPIDelegateHw)delegate_->handle_, &freq);
|
||||
// if (ret != ESP_OK) {
|
||||
// ESP_LOGE(TAG, "SPI get actual frequency failed!");
|
||||
// }
|
||||
// ESP_LOGD(TAG, "spi_freq: %u", freq);
|
||||
//}
|
||||
if (false /*rms_calc_req_*/) {
|
||||
float_str result = read_multi();
|
||||
uint32_t elapsed_time = 0;
|
||||
uint32_t settling_end_time = 2 * get_filter_settling_time();
|
||||
int i = 0;
|
||||
while(elapsed_time < settling_end_time) {
|
||||
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, "start: %u, elapsed: %u, settling_end_time: %u, frame: %s", start, elapsed_time, settling_end_time, 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());
|
||||
auto status = get_unsigned_frame_word(rx_frame, 0, true);
|
||||
update_adc_word_length(status);
|
||||
if(status == RSP_RESET_OK) {
|
||||
recover_from_reset();
|
||||
return;
|
||||
}
|
||||
end = micros();
|
||||
elapsed_time = end - start;
|
||||
i++;
|
||||
//ESP_LOGD(TAG, "iter: %d, elapsed: %u, settle_t: %u", i, elapsed_time, settling_end_time);
|
||||
}
|
||||
//ESP_LOGD(TAG, "iters: %d, elapsed: %u, st: %u", i, elapsed_time, settling_end_time);
|
||||
if (rms_calc_req_) {
|
||||
float_str result = {0, 0, 0, 0, 0};
|
||||
result = read_multi();
|
||||
num_samples = result[0];
|
||||
crc_errors = result[1];
|
||||
iterations = result[2];
|
||||
@ -384,25 +415,7 @@ void ADS131M08Hub::loop()
|
||||
}
|
||||
if (crc_errors > 30) {
|
||||
ESP_LOGW(TAG, "High CRC error rate.");
|
||||
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;
|
||||
}
|
||||
recover_from_reset();
|
||||
//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
|
||||
@ -410,7 +423,7 @@ void ADS131M08Hub::loop()
|
||||
}
|
||||
// ESP_LOGW(TAG, "%llu ms (%llu us), max samples: %u", (end - start)/1000, (end - start), num_samples);
|
||||
}
|
||||
//}
|
||||
}
|
||||
}
|
||||
/// @brief Set 16 bit frameword
|
||||
/// @param frame
|
||||
@ -579,6 +592,10 @@ uint32_t ADS131M08Hub::get_filter_settling_time() {
|
||||
cycles = T_SETTLE_OSR8192;
|
||||
break;
|
||||
}
|
||||
//TODO: create map instead of these lengthy switch statements
|
||||
//switch(this->dcblock_filter) {
|
||||
//
|
||||
//}
|
||||
return convert_adc_clock_cycles_to_micros(cycles);
|
||||
}
|
||||
|
||||
@ -804,13 +821,10 @@ 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 word frames in 2 AC 50/60Hz cycles to
|
||||
// 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
|
||||
// missed frames in quick succession idealy would want to read +- 200 24/32bit in 40ms. Gor now, this seems to be the
|
||||
// only way to do it.
|
||||
float_str ADS131M08Hub::read_multi() {
|
||||
int32_t raw;
|
||||
float value;
|
||||
@ -843,64 +857,18 @@ 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 == CMD_RESET) {
|
||||
if(status == RSP_RESET_OK) {
|
||||
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()) {
|
||||
ESP_LOGW(TAG, "Mid data-read reset detected; restored registers");
|
||||
//delay_microseconds_safe(get_filter_settling_time() + 50);
|
||||
txf_init();
|
||||
return result;
|
||||
}
|
||||
ESP_LOGE(TAG, "ADC reset detected. Unable to recover");
|
||||
//this->mark_failed(LOG_STR("ADC reset detected. Recovery failed"));
|
||||
return result;
|
||||
});
|
||||
//if(adc_reset_retry()) {
|
||||
// if(adc_restore_registers()) {
|
||||
// ESP_LOGW(TAG, "Mid data-read reset detected; restored registers");
|
||||
// return result;
|
||||
// }
|
||||
//}
|
||||
//ESP_LOGE(TAG, "ADC reset detected. Unable to recover");
|
||||
//this->mark_failed(LOG_STR("ADC reset detected. Recovery failed"));
|
||||
//ESP_LOGE(TAG, "ADC reset detected");
|
||||
recover_from_reset();
|
||||
return result;
|
||||
}
|
||||
crc_ok = check_crc(rx_frame);
|
||||
if (crc_ok) {
|
||||
if(status & MASK_STATUS_RESYNC) {
|
||||
settling_end_time = elapsed_time + get_filter_settling_time() + 50; // add 50us for good measure
|
||||
settling_end_time = elapsed_time + 2 * get_filter_settling_time() + 50; // add 50us for good measure
|
||||
}
|
||||
settling_end_time = 0;
|
||||
if(elapsed_time > settling_end_time) {
|
||||
if ((status & MASK_STATUS_RESYNC) == 0) {
|
||||
drdy_status = status & MASK_STATUS_DRDY;
|
||||
@ -925,7 +893,7 @@ float_str ADS131M08Hub::read_multi() {
|
||||
} else {
|
||||
if(ac_sensor_exist)
|
||||
this->sensors_ac[i]->publish_state(value);
|
||||
if(dc_sensor_exist)
|
||||
// if(dc_sensor_exist)
|
||||
this->sensors_dc[i]->publish_state(value);
|
||||
//update_averages(i, value, value);
|
||||
}
|
||||
@ -956,7 +924,7 @@ float_str ADS131M08Hub::read_multi() {
|
||||
//update_averages(i, NAN, NAN);
|
||||
if(ac_sensor_exist)
|
||||
this->sensors_ac[i]->publish_state(NAN);
|
||||
if(dc_sensor_exist)
|
||||
// if(dc_sensor_exist)
|
||||
this->sensors_dc[i]->publish_state(NAN);
|
||||
} else {
|
||||
float sample_sum = sample_sum_[i];
|
||||
@ -968,7 +936,7 @@ float_str ADS131M08Hub::read_multi() {
|
||||
}
|
||||
if(ac_sensor_exist)
|
||||
this->sensors_ac[i]->publish_state(rms_ac);
|
||||
if(dc_sensor_exist)
|
||||
// if(dc_sensor_exist)
|
||||
this->sensors_dc[i]->publish_state(rms_dc);
|
||||
//update_averages(i, rms_ac, rms_dc);
|
||||
}
|
||||
@ -981,6 +949,21 @@ float_str ADS131M08Hub::read_multi() {
|
||||
result[4] = this->sps_;
|
||||
return result;
|
||||
}
|
||||
|
||||
void ADS131M08Hub::recover_from_reset() {
|
||||
update_adc_word_length(WLENGTH_24_BITS); // word length is 24 bits after reset
|
||||
auto wait_after_reset = convert_adc_clock_cycles_to_micros(300);
|
||||
delay_microseconds_safe(wait_after_reset);
|
||||
ESP_LOGW(TAG, "ADC reset detected. Trying to restore registers. Retries: %u", this->recover_count_);
|
||||
if(this->adc_restore_registers()) {
|
||||
ESP_LOGW(TAG, "Mid data-read reset detected; restored registers");
|
||||
this->recover_count_ = 0;
|
||||
return;
|
||||
}
|
||||
this->recover_count_++;
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
/// @brief Updates rolling averages for rms_ac and rms_dc. Window = 2
|
||||
/// @param channel
|
||||
@ -1179,13 +1162,13 @@ bool ADS131M08Hub::adc_register_write(uint16_t start_address, const uint16_str &
|
||||
settings.data[bup_index++] = *i;
|
||||
}
|
||||
}
|
||||
else {
|
||||
int bup_index = start_address - REG_MODE;
|
||||
for(auto i = data.begin(); i != data.end(); i++) {
|
||||
ESP_LOGD(TAG, "Restoring: %-13s: data %04X stored val: %04X Line: %d", reg_addr_to_string(bup_index + REG_MODE).c_str(), *i, settings.data[bup_index], line);
|
||||
bup_index++;
|
||||
}
|
||||
}
|
||||
//else {
|
||||
// int bup_index = start_address - REG_MODE;
|
||||
// for(auto i = data.begin(); i != data.end(); i++) {
|
||||
// ESP_LOGD(TAG, "Restoring: %-13s: data %04X stored val: %04X Line: %d", reg_addr_to_string(bup_index + REG_MODE).c_str(), *i, settings.data[bup_index], line);
|
||||
// bup_index++;
|
||||
// }
|
||||
//}
|
||||
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);
|
||||
@ -1216,9 +1199,9 @@ bool ADS131M08Hub::adc_register_write(uint16_t start_address, const uint16_str &
|
||||
for (int i = 0; i < rxdata.size() && verified; i++) {
|
||||
verified = rxdata[i] == data[i];
|
||||
if (!verified) {
|
||||
ESP_LOGE(TAG, "Write \'%s\' register failed: tx data: 0x%04X, rx data: 0x%04X", reg_addr_to_string(start_address + i).c_str(), data[i], rxdata[i]);
|
||||
// ESP_LOGE(TAG, "Write: %s", reg_data_to_string(start_address + i, data[i]).c_str());
|
||||
ESP_LOGE(TAG, "Ack : %s", reg_data_to_string(start_address + i, rxdata[i]).c_str());
|
||||
ESP_LOGW(TAG, "Write \'%s\' register failed: tx data: 0x%04X, rx data: 0x%04X", reg_addr_to_string(start_address + i).c_str(), data[i], rxdata[i]);
|
||||
//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());
|
||||
}
|
||||
}
|
||||
delay_microseconds_safe(T_REGACQ);
|
||||
@ -1285,12 +1268,6 @@ uint16_str ADS131M08Hub::adc_register_read(uint8_t address, uint8_t nregs) {
|
||||
return result;
|
||||
}
|
||||
|
||||
bool ADS131M08Hub::set_reg_osr() {
|
||||
uint16_t mask = MASK_CLOCK_OSR;
|
||||
uint16_t value = this->osr_ << 2;
|
||||
return adc_register_write_masked(REG_CLOCK, value, mask, __LINE__);
|
||||
}
|
||||
|
||||
uint16_t ADS131M08Hub::convert_value_to_adc_osr(uint16_t osr_value) {
|
||||
uint16_t adc_osr = OSR_1024; // default
|
||||
if (osr_value <= 16256 && osr_value >= 128) {
|
||||
@ -1332,16 +1309,66 @@ bool ADS131M08Hub::set_channel_gain(uint8_t channel, uint8_t gain) {
|
||||
return adc_register_write_masked(reg, value, mask, __LINE__);
|
||||
}
|
||||
|
||||
bool ADS131M08Hub::set_global_chop(uint16_t global_chop) {
|
||||
uint16_t mask = MASK_CFG_GC_EN;
|
||||
uint16_t value = global_chop << 8;
|
||||
//this->settings.reg.cfg = value & mask;
|
||||
bool ADS131M08Hub::set_osr() {
|
||||
uint16_t mask = MASK_CLOCK_OSR;
|
||||
uint16_t value = this->osr_ << 2;
|
||||
return adc_register_write_masked(REG_CLOCK, value, mask, __LINE__);
|
||||
}
|
||||
|
||||
bool ADS131M08Hub::set_current_detect_threshold() {
|
||||
int32_t threshold = this->cd_threshold_;
|
||||
uint16_t MSB = (threshold >> 8) & MASK_THRSHLD_MSB_CD_TH_MSB;
|
||||
uint16_t LSB = (threshold << 8) & MASK_THRSHLD_LSB_CD_TH_LSB;
|
||||
uint16_str masks = {MASK_THRSHLD_MSB_CD_TH_MSB, MASK_THRSHLD_LSB_CD_TH_LSB};
|
||||
uint16_str values = {MSB, LSB};
|
||||
return adc_register_write_masked(REG_THRSHLD_MSB, values, masks, __LINE__);
|
||||
}
|
||||
|
||||
bool ADS131M08Hub::set_current_detect_length() {
|
||||
uint16_t mask = MASK_CFG_CD_LEN;
|
||||
uint16_t value = this->cd_length_ << 1;
|
||||
return adc_register_write_masked(REG_CFG, value, mask, __LINE__);
|
||||
}
|
||||
|
||||
bool ADS131M08Hub::set_global_chop_delay(uint16_t delay) {
|
||||
bool ADS131M08Hub::set_current_detect_number() {
|
||||
uint16_t mask = MASK_CFG_CD_NUM;
|
||||
uint16_t value = this->cd_number_ << 4;
|
||||
return adc_register_write_masked(REG_CFG, value, mask, __LINE__);
|
||||
}
|
||||
|
||||
bool ADS131M08Hub::set_current_detect_all() {
|
||||
uint16_t mask = MASK_CFG_CD_ALLCH;
|
||||
uint16_t value = this->cd_all_enable_ ? mask : 0;
|
||||
return adc_register_write_masked(REG_CFG, value, mask, __LINE__);
|
||||
}
|
||||
|
||||
bool ADS131M08Hub::set_current_detect() {
|
||||
uint16_t mask = MASK_CFG_CD_EN;
|
||||
uint16_t value = this->cd_enable_ ? mask : 0;
|
||||
return adc_register_write_masked(REG_CFG, value, mask, __LINE__);
|
||||
}
|
||||
|
||||
bool ADS131M08Hub::set_power_mode() {
|
||||
uint16_t mask = MASK_CLOCK_PWR;
|
||||
uint16_t value = this->power_mode_;
|
||||
return adc_register_write_masked(REG_CFG, value, mask, __LINE__);
|
||||
}
|
||||
|
||||
bool ADS131M08Hub::set_dc_block_filter() {
|
||||
uint16_t mask = MASK_THRSHLD_LSB_DCBLOCK;
|
||||
uint16_t value = this->dcblock_filter_;
|
||||
return adc_register_write_masked(REG_CFG, value, mask, __LINE__);
|
||||
}
|
||||
|
||||
bool ADS131M08Hub::set_global_chop() {
|
||||
uint16_t mask = MASK_CFG_GC_EN;
|
||||
uint16_t value = this->global_chop_enable_ ? mask : 0;
|
||||
return adc_register_write_masked(REG_CFG, value, mask, __LINE__);
|
||||
}
|
||||
|
||||
bool ADS131M08Hub::set_global_chop_delay() {
|
||||
uint16_t mask = MASK_CFG_GC_DLY;
|
||||
uint16_t value = delay << 9;
|
||||
uint16_t value = this->global_chop_delay_ << 9;
|
||||
return adc_register_write_masked(REG_CFG, value, mask, __LINE__);
|
||||
}
|
||||
|
||||
@ -1587,13 +1614,13 @@ std::string ADS131M08Hub::reg_data_to_string(int address, uint16_t data, bool na
|
||||
str += buffer;
|
||||
}
|
||||
str += " / POWER=";
|
||||
if ((data & MASK_CLOCK_PWR) == PM_VERY_LOW_POWER)
|
||||
if ((data & MASK_CLOCK_PWR) == VERY_LOW_POWER)
|
||||
str += "VERY_LOW";
|
||||
if ((data & MASK_CLOCK_PWR) == PM_LOW_POWER)
|
||||
if ((data & MASK_CLOCK_PWR) == LOW_POWER)
|
||||
str += "VERY_LOW";
|
||||
if ((data & MASK_CLOCK_PWR) == PM_HIGH_RESOLUTION)
|
||||
if ((data & MASK_CLOCK_PWR) == HIGH_RESOLUTION)
|
||||
str += "HIGH_RES";
|
||||
if ((data & MASK_CLOCK_PWR) == PM_HIGH_RESOLUTION2)
|
||||
if ((data & MASK_CLOCK_PWR) == HIGH_RESOLUTION2)
|
||||
str += "HIGH_RES";
|
||||
break;
|
||||
|
||||
|
||||
@ -51,7 +51,7 @@ class ADS131M08Hub : public Component,
|
||||
|
||||
public:
|
||||
// register config values used
|
||||
static constexpr uint16_t reg_clock_cfg = MASK_CLOCK_EXTREF_EN | PM_HIGH_RESOLUTION; // OSR must be added
|
||||
static constexpr uint16_t reg_clock_cfg = MASK_CLOCK_EXTREF_EN | HIGH_RESOLUTION; // OSR must be added
|
||||
static constexpr uint16_t reg_clock_allch_on = MASK_CLOCK_ALLCH | reg_clock_cfg;
|
||||
static constexpr uint16_t reg_clock_allch_off = ~MASK_CLOCK_ALLCH & reg_clock_cfg;
|
||||
static constexpr uint16_t reg_mode_cfg = DRDY_FMT_PULSE | TIMEOUT_ENABLED | CRC_REC_ENABLE | CRC_REG_ENABLE;
|
||||
@ -112,21 +112,38 @@ class ADS131M08Hub : public Component,
|
||||
void dump_config() override;
|
||||
|
||||
bool set_channel_enable(uint8_t channel, bool enable);
|
||||
bool set_global_chop(uint16_t global_chop);
|
||||
bool set_global_chop_delay(uint16_t delay);
|
||||
bool set_channel_input_selection(uint8_t channel, ADC_INPUT_CHANNEL_MUX input);
|
||||
bool set_channel_offset_calibration(uint8_t channel, int32_t offset);
|
||||
bool set_channel_gain_calibration(uint8_t channel, uint32_t gain);
|
||||
bool set_channel_phase_calibration(uint8_t channel, int16_t phase_offset);
|
||||
bool set_dcblock_filter_disable(uint8_t channel, bool disable);
|
||||
bool set_channel_gain(uint8_t channel, uint8_t gain);
|
||||
void set_current_detect_threshold(int32_t threshold) { this->cd_threshold_ = threshold; }
|
||||
void set_current_detect_length(uint16_t length) { this->cd_length_ = length; }
|
||||
void set_current_detect_number(uint16_t number) { this->cd_number_ = number; }
|
||||
void set_current_detect_all(bool enable) { this->cd_all_enable_ = enable; }
|
||||
void set_current_detect(bool enable) { this->cd_enable_ = enable; }
|
||||
void set_global_chop_delay(uint16_t delay) { this->global_chop_delay_ = delay; }
|
||||
void set_global_chop(bool enable) { this->global_chop_enable_ = enable; }
|
||||
void set_power_mode(uint16_t power_mode) { this->power_mode_ = power_mode; }
|
||||
void set_dcblock_filter(uint16_t filter) { this->dcblock_filter_ = filter; }
|
||||
bool set_measure_rms(uint8_t channel, bool enable);
|
||||
bool set_current_detect_threshold();
|
||||
bool set_current_detect_length();
|
||||
bool set_current_detect_number();
|
||||
bool set_current_detect_all();
|
||||
bool set_current_detect();
|
||||
bool set_global_chop_delay();
|
||||
bool set_global_chop();;
|
||||
bool set_power_mode();
|
||||
bool set_dc_block_filter();
|
||||
|
||||
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);
|
||||
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();
|
||||
bool set_osr();
|
||||
uint16_t convert_value_to_adc_osr(uint16_t osr_value);
|
||||
uint16_t convert_adc_osr_to_value(uint16_t adc_osr);
|
||||
uint32_t convert_adc_clock_cycles_to_micros(uint32_t cycles);
|
||||
@ -145,6 +162,15 @@ class ADS131M08Hub : public Component,
|
||||
bool rms_enabled_[MAX_CHANNELS];
|
||||
bool rms_calc_req_{false};
|
||||
uint16_t osr_{3};
|
||||
uint16_t global_chop_delay_{16};
|
||||
bool global_chop_enable_{false};
|
||||
int32_t cd_threshold_{0};
|
||||
uint16_t cd_length_{128};
|
||||
uint16_t cd_number_{1};
|
||||
bool cd_all_enable_{false};
|
||||
bool cd_enable_{false};
|
||||
uint16_t power_mode_{2};
|
||||
uint16_t dcblock_filter_{0};
|
||||
uint8_t update_adc_word_length();
|
||||
uint8_t update_adc_word_length(uint16_t status);
|
||||
void SET_IRAM read_single();
|
||||
@ -195,6 +221,7 @@ class ADS131M08Hub : public Component,
|
||||
}
|
||||
};
|
||||
float update_conversion_factor();
|
||||
void recover_from_reset();
|
||||
//DRAM_ATTR static spiframe rx_frame;
|
||||
|
||||
inline void zero_fill(spiframe& frame) {
|
||||
@ -214,6 +241,7 @@ class ADS131M08Hub : public Component,
|
||||
float conversion_factor_{1.25 / 8388608.0}; // updated when word length changes
|
||||
const uint32_t sample_time_ = 40000; // 40 ms
|
||||
float sps_{0.0f};
|
||||
uint32_t recover_count_{0};
|
||||
uint32_t num_samples_[ADC_CHANNELS];
|
||||
float sample_sum_[ADC_CHANNELS];
|
||||
float sample_squared_sum_[ADC_CHANNELS];
|
||||
|
||||
@ -15,10 +15,10 @@ enum ADC_DRDY_STATE : uint8_t {
|
||||
|
||||
// no shift
|
||||
enum ADC_POWERMODE : uint16_t {
|
||||
PM_VERY_LOW_POWER = 0,
|
||||
PM_LOW_POWER = 1,
|
||||
PM_HIGH_RESOLUTION = 2, // DEFAULT
|
||||
PM_HIGH_RESOLUTION2 = 3,
|
||||
VERY_LOW_POWER = 0,
|
||||
LOW_POWER = 1,
|
||||
HIGH_RESOLUTION = 2, // DEFAULT
|
||||
HIGH_RESOLUTION2 = 3,
|
||||
};
|
||||
|
||||
enum ADC_PGA_GAIN : uint8_t {
|
||||
@ -69,10 +69,6 @@ enum ADC_DELAY {
|
||||
|
||||
};
|
||||
|
||||
|
||||
static constexpr uint16_t MODE_MASK_RESET_HAPPENED = ~0x0400; // DEFAULT
|
||||
static constexpr uint16_t MODE_RESET_HAPPENED = 0x0400;
|
||||
|
||||
enum ADC_CRC: uint16_t {
|
||||
CRC_TYPE_CCITT = 0x0000, // DEFAULT CRC type
|
||||
CRC_TYPE_ANSI = 0x0800,
|
||||
@ -80,10 +76,6 @@ enum ADC_CRC: uint16_t {
|
||||
CRC_REG_ENABLE = 0x2000,
|
||||
};
|
||||
|
||||
static constexpr uint16_t WLENGTH_16_BITS = 0x0000;
|
||||
static constexpr uint16_t WLENGTH_24_BITS = 0x0100; // DEFAULT
|
||||
static constexpr uint16_t WLENGTH_32_BITS_LSB_ZERO_PADDING = 0x0200;
|
||||
static constexpr uint16_t WLENGTH_32_BITS_MSB_SIGN_EXTEND = 0x0300;
|
||||
|
||||
enum ADC_TIMEOUT : uint16_t {
|
||||
TIMEOUT_DISABLED = 0x0000,
|
||||
@ -97,8 +89,6 @@ enum ADC_DRDY_SELECTION : uint16_t {
|
||||
DRDY_SEL_MOST_LEADING_CHAN2 = 0x000C
|
||||
};
|
||||
|
||||
static constexpr uint16_t DRDY_FMT_LEVEL = 0x0000; // Logic low (default)
|
||||
static constexpr uint16_t DRDY_FMT_PULSE = 0x0001; // Low pulse with a fixed duration
|
||||
|
||||
// Commands
|
||||
enum ADC_COMMANDS : uint16_t {
|
||||
@ -115,7 +105,51 @@ enum ADC_COMMANDS : uint16_t {
|
||||
};
|
||||
|
||||
// Responses
|
||||
enum ADC_RESPONSES : uint16_t { RSP_RESET_OK = 0xFF28, RSP_RESET_NOK = 0x0011 };
|
||||
enum ADC_RESPONSES : uint16_t {
|
||||
RSP_RESET_OK = 0xFF28,
|
||||
RSP_RESET_NOK = 0x0011
|
||||
};
|
||||
|
||||
enum ADC_GLOBAL_CHOP_DELAY : uint16_t {
|
||||
GC_DEL2,
|
||||
GC_DEL4,
|
||||
GC_DEL8,
|
||||
GC_DEL16, // default
|
||||
GC_DEL32,
|
||||
GC_DEL64,
|
||||
GC_DEL128,
|
||||
GC_DEL256,
|
||||
GC_DEL512,
|
||||
GC_DEL1024,
|
||||
GC_DEL2048,
|
||||
GC_DEL4096,
|
||||
GC_DEL8192,
|
||||
GC_DEL16384,
|
||||
GC_DEL32768,
|
||||
GC_DEL65536,
|
||||
};
|
||||
|
||||
enum ADC_CURRENT_DETECT_NUMBER : uint16_t {
|
||||
CD_NUM1, // default
|
||||
CD_NUM2,
|
||||
CD_NUM4,
|
||||
CD_NUM8,
|
||||
CD_NUM16,
|
||||
CD_NUM32,
|
||||
CD_NUM64,
|
||||
CD_NUM128,
|
||||
};
|
||||
|
||||
enum ADC_CURRENT_DETECT_LENGTH : uint16_t {
|
||||
CD_LEN128, // default
|
||||
CD_LEN256,
|
||||
CD_LEN512,
|
||||
CD_LEN768,
|
||||
CD_LEN1280,
|
||||
CD_LEN1792,
|
||||
CD_LEN2560,
|
||||
CD_LEN3584,
|
||||
};
|
||||
|
||||
// Used to generalise register config addresses
|
||||
enum REGRELADDR : uint16_t {
|
||||
@ -126,7 +160,17 @@ enum REGRELADDR : uint16_t {
|
||||
REG_CHX_GCAL_LSB,
|
||||
};
|
||||
|
||||
// enum ADC_REG : uint16_t {
|
||||
static constexpr uint16_t MODE_MASK_RESET_CLEAR = ~0x0400;
|
||||
static constexpr uint16_t MODE_RESET_HAPPENED = 0x0400;
|
||||
|
||||
static constexpr uint16_t WLENGTH_16_BITS = 0x0000;
|
||||
static constexpr uint16_t WLENGTH_24_BITS = 0x0100; // DEFAULT
|
||||
static constexpr uint16_t WLENGTH_32_BITS_LSB_ZERO_PADDING = 0x0200;
|
||||
static constexpr uint16_t WLENGTH_32_BITS_MSB_SIGN_EXTEND = 0x0300;
|
||||
|
||||
static constexpr uint16_t DRDY_FMT_LEVEL = 0x0000; // Logic low (default)
|
||||
static constexpr uint16_t DRDY_FMT_PULSE = 0x0001; // Low pulse with a fixed duration
|
||||
|
||||
static constexpr uint16_t REG_ID = 0x00;
|
||||
static constexpr uint16_t REG_STATUS = 0x01;
|
||||
static constexpr uint16_t REG_MODE = 0x02;
|
||||
@ -177,7 +221,7 @@ static constexpr uint16_t REG_CH7_OCAL_LSB = 0x2E;
|
||||
static constexpr uint16_t REG_CH7_GCAL_MSB = 0x2F;
|
||||
static constexpr uint16_t REG_CH7_GCAL_LSB = 0x30;
|
||||
static constexpr uint16_t REGMAP_CRC = 0x3E;
|
||||
// };
|
||||
|
||||
// Mask READ/WRITE_REG
|
||||
static constexpr uint16_t MASK_CMD_RW_REG = 0xE000;
|
||||
static constexpr uint16_t MASK_CMD_RW_REG_ADDRESS = 0x1F80;
|
||||
@ -331,7 +375,7 @@ static constexpr uint8_t DATA_RATE_12 = 12;
|
||||
static constexpr uint8_t DATA_RATE_13 = 13;
|
||||
static constexpr uint8_t DATA_RATE_14 = 14;
|
||||
static constexpr uint8_t DATA_RATE_15 = 15;
|
||||
// Sync Mpdes
|
||||
// Sync Modes
|
||||
static constexpr uint16_t SYNC_CONTINUOUS = 1;
|
||||
static constexpr uint16_t SYNC_PULSE = 0;
|
||||
|
||||
|
||||
@ -5,15 +5,13 @@ 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
|
||||
from ..sensor_rms import RMS_SENSOR_SCHEMA, to_code_ac
|
||||
|
||||
AUTO_LOAD = [
|
||||
"sensor", "voltage_sampler",
|
||||
@ -27,7 +25,6 @@ CONF_INPUT_SELECT = "input_select"
|
||||
CONF_DC_BLOCK = "dc_block"
|
||||
ICON_CURRENT_DC = "mdi:current-dc"
|
||||
|
||||
|
||||
DEPENDENCIES = ["ads131m08"]
|
||||
|
||||
GAIN = ads131m08_ns.enum("ADC_PGA_GAIN")
|
||||
@ -62,24 +59,6 @@ Channel = ads131m08_ns.class_(
|
||||
"Channel", sensor.Sensor, cg.Component, voltage_sampler.VoltageSampler
|
||||
)
|
||||
|
||||
#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,
|
||||
@ -88,8 +67,8 @@ CONFIG_SCHEMA = (
|
||||
unit_of_measurement=UNIT_VOLT,
|
||||
device_class=DEVICE_CLASS_VOLTAGE,
|
||||
state_class=STATE_CLASS_MEASUREMENT,
|
||||
#).extend(
|
||||
# CONFIG_SCHEMA_RMS_SENSORS
|
||||
).extend(
|
||||
RMS_SENSOR_SCHEMA
|
||||
)
|
||||
.extend(
|
||||
{
|
||||
@ -101,16 +80,16 @@ CONFIG_SCHEMA = (
|
||||
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.polling_component_schema("1s"))
|
||||
#.extend(cv.polling_component_schema("1s"))
|
||||
.extend(cv.COMPONENT_SCHEMA)
|
||||
)
|
||||
|
||||
# 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
|
||||
# 3. ac_sensor: to publish rms ac value
|
||||
# we are using 2 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 and can be used for DC measurements
|
||||
# 2. ac_sensor: to publish rms ac value; only use if absolutely necessary as it it expensive in terms of loop time
|
||||
async def to_code(config):
|
||||
channel_sensor = cg.new_Pvariable(config[CONF_ID])
|
||||
await cg.register_parented(channel_sensor, config[CONF_ADS131M08_ID])
|
||||
@ -128,10 +107,9 @@ 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))
|
||||
|
||||
hub = await cg.get_variable(config[CONF_ADS131M08_ID])
|
||||
cg.add(hub.register_sensor_dc(channel, channel_sensor))
|
||||
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 ac_sensor := await to_code_ac(config):
|
||||
await cg.register_parented(ac_sensor, channel_sensor)
|
||||
|
||||
@ -31,23 +31,23 @@ float Channel::sample()
|
||||
|
||||
float Channel::sample(int32_t& raw_value)
|
||||
{
|
||||
return (this->parent_ == nullptr) ? NAN : this->parent_->get_sample(raw_value, this->channel_, this->gain_, this->input_,
|
||||
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);
|
||||
}
|
||||
}
|
||||
//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=% 6ld %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
|
||||
uint32_t Channel::normalised_gain_calibration() const
|
||||
|
||||
@ -13,13 +13,17 @@ namespace esphome {
|
||||
namespace ads131m08 {
|
||||
|
||||
class Channel : public sensor::Sensor,
|
||||
public PollingComponent,
|
||||
public Component, //PollingComponent,
|
||||
public voltage_sampler::VoltageSampler,
|
||||
public Parented<ADS131M08Hub> {
|
||||
public:
|
||||
void loop() override;
|
||||
float sample() override;
|
||||
void update() override;
|
||||
// void update() override;
|
||||
float get_setup_priority() const override {
|
||||
// After the base sensor has been initialized
|
||||
return setup_priority::DATA - 1.0f;
|
||||
}
|
||||
void set_gain(uint8_t value) { this->gain_ = value; }
|
||||
void dump_config() override;
|
||||
void set_channel_number(uint8_t channel) { this->channel_= channel; }
|
||||
|
||||
@ -7,37 +7,20 @@ from esphome.const import (
|
||||
ICON_CURRENT_AC,
|
||||
UNIT_VOLT,
|
||||
CONF_CHANNEL,
|
||||
CONF_NAME,
|
||||
)
|
||||
from .. import CONF_ADS131M08_ID, ads131m08_ns
|
||||
|
||||
CONF_AC = "ac"
|
||||
CONF_DC = "dc"
|
||||
ICON_CURRENT_DC = "mdi:current-dc"
|
||||
|
||||
AUTO_LOAD = ["sensor",]
|
||||
|
||||
DEPENDENCIES = ["ads131m08"]
|
||||
|
||||
#ads131m08_acdc_ns = cg.esphome_ns.namespace("ads131m08_acdc")
|
||||
|
||||
RMS_SENSOR = ads131m08_ns.class_(
|
||||
"RMS_Sensor", sensor.Sensor, cg.Component
|
||||
)
|
||||
|
||||
CONFIG_SCHEMA_RMS_SENSORS = cv.Schema(
|
||||
RMS_SENSOR_SCHEMA = cv.Schema(
|
||||
{
|
||||
cv.Optional(CONF_DC): sensor.sensor_schema(
|
||||
RMS_SENSOR,
|
||||
accuracy_decimals=6,
|
||||
icon=ICON_CURRENT_DC,
|
||||
unit_of_measurement=UNIT_VOLT,
|
||||
device_class=DEVICE_CLASS_VOLTAGE,
|
||||
state_class=STATE_CLASS_MEASUREMENT,
|
||||
).extend(
|
||||
{
|
||||
cv.Required(CONF_NAME): cv.string,
|
||||
}
|
||||
),
|
||||
cv.Optional(CONF_AC): sensor.sensor_schema(
|
||||
RMS_SENSOR,
|
||||
accuracy_decimals=6,
|
||||
@ -45,13 +28,9 @@ CONFIG_SCHEMA_RMS_SENSORS = cv.Schema(
|
||||
unit_of_measurement=UNIT_VOLT,
|
||||
device_class=DEVICE_CLASS_VOLTAGE,
|
||||
state_class=STATE_CLASS_MEASUREMENT,
|
||||
).extend(
|
||||
{
|
||||
cv.Required(CONF_NAME): cv.string,
|
||||
}
|
||||
),
|
||||
}
|
||||
). extend (cv.COMPONENT_SCHEMA)
|
||||
).extend (cv.COMPONENT_SCHEMA)
|
||||
|
||||
async def to_code_ac(config):
|
||||
hub = await cg.get_variable(config[CONF_ADS131M08_ID])
|
||||
@ -63,14 +42,3 @@ async def to_code_ac(config):
|
||||
await cg.register_component(sens_ac, config[CONF_AC])
|
||||
return sens_ac
|
||||
return None
|
||||
|
||||
async def to_code_dc(config):
|
||||
hub = await cg.get_variable(config[CONF_ADS131M08_ID])
|
||||
channel = config[CONF_CHANNEL]
|
||||
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