#include "ads131m08.h" namespace esphome { namespace ads131m08 { static const char *const TAG = "ads131m08"; void ADS131M08Hub::setup() { // Initialize SPI with correct settings for ADS131M08 // SPI mode 1: CPOL=0, CPHA=1 this->spi_setup(); // not sure if next few lines are needed here or is it handled in spi_setup() SPI.begin(); SPI.setDataMode(SPI_MODE1); SPI.setBitOrder(MSBFIRST); SPI.setClockDivider(SPI_CLOCK_DIV8); // Adjust clock speed as needed this->drdy_pin_->setup(); this->drdy_pin_->pin_mode(esphome::gpio::FLAG_INPUT | esphome::gpio::FLAG_PULLUP); this->drdy_pin_->attach_interrupt(&ADS131M08Hub::isr, this, gpio::INTERRUPT_FALLING_EDGE); this->initialize_ads131m08(); } void ADS131M08Hub::initialize_ads131m08() { // Send RESET command SPI.transfer(0x06); delay(1); // Send UNLOCK command SPI.transfer(0x55); SPI.transfer(0x55); // Configure registers as needed (example: set gain, etc.) // Write to MODE register for continuous conversion, disable internal reference (use external MAX6070AAUT12+T at 1.25V) write_register(0x02, 0x0000); // MODE register, continuous mode, INTREF_EN = 0 // Wait for external reference to settle delay(100); // Start conversions SPI.transfer(0x08); // START command } void ADS131M08Hub::write_register(uint8_t reg, uint16_t value) { SPI.transfer(0x40 | reg); // WREG command SPI.transfer(0x00); // Number of registers - 1 (0 for one register) SPI.transfer((value >> 8) & 0xFF); SPI.transfer(value & 0xFF); } void IRAM_ATTR ADS131M08Hub::isr(ADS131M08Hub *arg) { arg->txf_init(); // implementing datasheet recommended TXF init in ISR arg->data_ready_ = true; } void ADS131M08Hub::loop() { if (this->data_ready_) { this->data_ready_ = false; this->read_data_(); } } // ********************** from datasheet ************************ void ADS131M08Hub::txf_init() { if (firstRead) { // Clear the ADC's 2-deep FIFO on the first read for (int i = 0; i sensors_[ch] != nullptr) { int offset = ch * 3; int32_t raw = (data_buffer_[offset] << 16) | (data_buffer_[offset + 1] << 8) | data_buffer_[offset + 2]; if (raw & 0x800000) raw |= 0xFF000000; // Sign extend float v = (raw / 8388608.0) * this->reference_voltage_; // 2^23 = 8388608, Vref = 1.25V (MAX6070AAUT12+T) this->sensors_[ch]->publish_state(v); } } } */ void ADS131M08Hub::read_data_() { this->enable(); // ADS131M08 Frame: 1 Status Word + 8 Channel Words + 1 CRC Word (24-bit words) uint8_t frame[30]; // 10 words * 3 bytes this->read_array(frame, 30); this->disable(); for (int i = 0; i < 8; i++) { if (this->sensors_[i] != nullptr) { // Convert 24-bit two's complement to float (Simplified) int32_t raw = (frame[3+(i*3)] << 16) | (frame[4+(i*3)] << 8) | frame[5+(i*3)]; if (raw & 0x800000) raw |= 0xFF000000; // Sign extend this->sensors_[i]->publish_state(raw * (this->reference_voltage_ / 8388608.0)); // 2^23 = 8388608, Vref = 1.25V ( for MAX6070AAUT12+T ) } } } void ADS131M08Hub::dump_config() { ESP_LOGCONFIG(TAG, "ADS131M08:"); LOG_PIN(" CS Pin:", this->cs_); LOG_PIN(" DRDY Pin:", this->drdy_pin_); ESP_LOGCONFIG(TAG, " Reference Voltage: %.2fV", this->reference_voltage_); } } // namespace ads131m08 } // namespace esphome