configs/components/ads131m08/ads131m08.cpp

197 lines
5.2 KiB
C++

#include "ads131m08.h"
/*
namespace esphome {
namespace ads131m08 {
static const char *const TAG = "ads131m08";
ADS131M08::ADS131M08(esphome::gpio::GPIOPin *pin)
: drdy_pin_(pin)
{
}
void ADS131M08::set_drdy_pin(InternalGPIOPin *pin)
{
drdy_pin_ = pin;
}
void ADS131M08::set_sensor(int channel, sensor::Sensor *s)
{
channels_[channel] = s;
}
void ADS131M08::set_reference_voltage(float reference_voltage)
{
this->reference_voltage_ = reference_voltage;
}
float ADS131M08::get_setup_priority() const
{
return setup_priority::HARDWARE;
}
void ADS131M08::setup()
{
// Initialize SPI with correct settings for ADS131M08
// SPI mode 1: CPOL=0, CPHA=1
//this->spi_setup();
SPI.begin();
SPI.setDataMode(SPI_MODE1);
SPI.setBitOrder(MSBFIRST);
SPI.setClockDivider(SPI_CLOCK_DIV8); // Adjust clock speed as needed
// Configure DRDY pin
drdy_pin_->setup();
drdy_pin_->pin_mode(esphome::gpio::FLAG_INPUT | esphome::gpio::FLAG_PULLUP);
// Attach interrupt on falling edge of DRDY
// esphome::gpio::attach_interrupt(drdy_pin_, esphome::gpio::INTERRUPT_FALLING_EDGE, [this]() {
// this->data_ready_ = true;
// });
this->drdy_pin_->attach_interrupt(&ADS131M08Component::handle_drdy, this, gpio::INTERRUPT_FALLING_EDGE);
// Initialize ADS131M08
initialize_ads131m08();
}
// interrupt handler
void ADS131M08::handle_drdy(ADS131M08Component *arg)
{
arg->data_ready_ = true;
}
void ADS131M08::loop()
{
if (data_ready_) {
data_ready_ = false;
read_all_channels();
}
}
void ADS131M08::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 ADS131M08::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 ADS131M08::read_all_channels()
{
// Send RDATA command or read data directly
SPI.transfer(0x12); // RDATA command
// Read 24 bytes (3 bytes per channel for 8 channels)
for (int i = 0; i < 24; i++) {
data_buffer_[i] = SPI.transfer(0x00);
}
// Convert to voltages for all channels
//Sensor *channels[8] = {channel1, channel2, channel3, channel4, channel5, channel6, channel7, channel8};
for (int ch = 0; ch < 8; ch++) {
if (this->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);
}
}
}
float ADS131M08::read_data(uint8_t channel)
{
// This function assumes read_all_channels() has been called and data is in data_buffer_
int offset = channel * 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)
return v;
}
void ADS131M08::dump_config() {
ESP_LOGCONFIG(TAG, "ADS131M08:");
LOG_PIN(" CS Pin:", this->cs_);
ESP_LOGCONFIG(TAG, " Reference Voltage: %.2fV", this->reference_voltage_);
}
} // namespace ads131m08
} // namespace esphome
*/
namespace esphome {
namespace ads131m08 {
static const char *const TAG = "ads131m08";
void ADS131M08Hub::setup()
{
this->spi_setup();
this->drdy_pin_->setup();
this->drdy_pin_->attach_interrupt(&ADS131M08Hub::isr, this, gpio::INTERRUPT_FALLING_EDGE);
}
void IRAM_ATTR ADS131M08Hub::isr(ADS131M08Hub *arg)
{
arg->data_ready_ = true;
}
void ADS131M08Hub::loop()
{
if (this->data_ready_) {
this->data_ready_ = false;
this->read_data_();
}
}
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