Before changing ads1115_int to directly publish from ISR

This commit is contained in:
Chris Stuurman 2026-01-11 20:34:38 +02:00
parent 76fd7fa443
commit a105cf0748
14 changed files with 1324 additions and 165 deletions

View File

@ -9,11 +9,11 @@ CONF_ALERT_RDY_PIN = "alert_rdy_pin"
DEPENDENCIES = ["i2c"]
MULTI_CONF = True
ads1115_ns = cg.esphome_ns.namespace("ads1115_int")
ADS1115Component = ads1115_ns.class_("ADS1115Component", cg.Component, i2c.I2CDevice)
ads1115_int_ns = cg.esphome_ns.namespace("ads1115_int")
ADS1115Component = ads1115_int_ns.class_("ADS1115Component", cg.Component, i2c.I2CDevice)
CONF_CONTINUOUS_MODE = "continuous_mode"
CONF_ADS1115_ID = "ads1115_int_id"
CONF_ADS1115_ID = "ads1115_id"
CONFIG_SCHEMA = (
cv.Schema(

View File

@ -66,12 +66,12 @@ void ADS1115Component::setup() {
return;
}
this->prev_config_ = config;
if(!this->set_alert_ready_mode()) {
if(!this->set_data_ready_mode()) {
this->mark_failed();
return;
}
}
bool ADS1115Component::set_alert_ready_mode()
bool ADS1115Component::set_data_ready_mode()
{
uint16_t config = this->prev_config_;
// Set comparator que mode - assert after one conversion
@ -107,7 +107,7 @@ bool ADS1115Component::is_data_ready(ADS1115Multiplexer multiplexer)
return false;
return this->data_ready_[index];
}
void ADS1115Component::clear_alert_ready(ADS1115Multiplexer multiplexer)
void ADS1115Component::clear_data_ready(ADS1115Multiplexer multiplexer)
{
int index = static_cast<int>(multiplexer);
if(index < 0 || index >= 8)
@ -116,7 +116,7 @@ void ADS1115Component::clear_alert_ready(ADS1115Multiplexer multiplexer)
}
// call only when data_ready_ is true
double ADS1115Component::read_data(ADS1115Multiplexer multiplexer, ADS1115Gain gain, ADS1115Resolution resolution, ADS1115Samplerate samplerate)
double ADS1115Component::read_data(int16_t& raw_value, ADS1115Multiplexer multiplexer, ADS1115Gain gain, ADS1115Resolution resolution, ADS1115Samplerate samplerate)
{
uint16_t config = this->prev_config_;
// Multiplexer
@ -139,7 +139,7 @@ double ADS1115Component::read_data(ADS1115Multiplexer multiplexer, ADS1115Gain g
config |= 0b1000000000000000;
}
this->clear_alert_ready(multiplexer);
this->clear_data_ready(multiplexer);
//ESP_LOGI(TAG, "'mux:%d': Gain=%d, Res=%d, CONF=<0x%04X>", static_cast<int>(multiplexer), static_cast<int>(gain), static_cast<int>(resolution), config);
// write config if in single-shot mode or config has changed
if (!this->continuous_mode_ || this->prev_config_ != config) {
@ -148,6 +148,9 @@ double ADS1115Component::read_data(ADS1115Multiplexer multiplexer, ADS1115Gain g
return false;
}
this->prev_config_ = config;
//
// removed delay
//
if (!this->continuous_mode_) {
uint32_t start = millis();
// wait for conversion to complete
@ -184,6 +187,7 @@ double ADS1115Component::read_data(ADS1115Multiplexer multiplexer, ADS1115Gain g
}
}
auto signed_conversion = static_cast<int16_t>(raw_conversion);
raw_value = signed_conversion;
double millivolts;
double divider = (resolution == ADS1115_16_BITS) ? 32768.0f : 2048.0f;
switch (gain) {

View File

@ -53,11 +53,11 @@ class ADS1115Component : public Component, public i2c::I2CDevice {
void set_continuous_mode(bool continuous_mode) { continuous_mode_ = continuous_mode; }
// Method to read converted data
double read_data(ADS1115Multiplexer multiplexer, ADS1115Gain gain, ADS1115Resolution resolution, ADS1115Samplerate samplerate);
double read_data(int16_t& raw_value, ADS1115Multiplexer multiplexer, ADS1115Gain gain, ADS1115Resolution resolution, ADS1115Samplerate samplerate);
void set_alert_pin(InternalGPIOPin *pin) { alert_pin_ = pin; }
bool set_alert_ready_mode();
bool set_data_ready_mode();
bool is_data_ready(ADS1115Multiplexer multiplexer);
void clear_alert_ready(ADS1115Multiplexer multiplexer);
void clear_data_ready(ADS1115Multiplexer multiplexer);
protected:
uint16_t prev_config_{0};

View File

@ -12,12 +12,12 @@ from esphome.const import (
UNIT_VOLT,
)
from .. import CONF_ADS1115_ID, ADS1115Component, ads1115_ns
from .. import CONF_ADS1115_ID, ADS1115Component, ads1115_int_ns
AUTO_LOAD = ["voltage_sampler"]
DEPENDENCIES = ["ads1115"]
DEPENDENCIES = ["ads1115_int"]
ADS1115Multiplexer = ads1115_ns.enum("ADS1115Multiplexer")
ADS1115Multiplexer = ads1115_int_ns.enum("ADS1115Multiplexer")
MUX = {
"A0_A1": ADS1115Multiplexer.ADS1115_MULTIPLEXER_P0_N1,
"A0_A3": ADS1115Multiplexer.ADS1115_MULTIPLEXER_P0_N3,
@ -29,7 +29,7 @@ MUX = {
"A3_GND": ADS1115Multiplexer.ADS1115_MULTIPLEXER_P3_NG,
}
ADS1115Gain = ads1115_ns.enum("ADS1115Gain")
ADS1115Gain = ads1115_int_ns.enum("ADS1115Gain")
GAIN = {
"6.144": ADS1115Gain.ADS1115_GAIN_6P144,
"4.096": ADS1115Gain.ADS1115_GAIN_4P096,
@ -39,13 +39,13 @@ GAIN = {
"0.256": ADS1115Gain.ADS1115_GAIN_0P256,
}
ADS1115Resolution = ads1115_ns.enum("ADS1115Resolution")
ADS1115Resolution = ads1115_int_ns.enum("ADS1115Resolution")
RESOLUTION = {
"16_BITS": ADS1115Resolution.ADS1115_16_BITS,
"12_BITS": ADS1115Resolution.ADS1015_12_BITS,
}
ADS1115Samplerate = ads1115_ns.enum("ADS1115Samplerate")
ADS1115Samplerate = ads1115_int_ns.enum("ADS1115Samplerate")
SAMPLERATE = {
"8": ADS1115Samplerate.ADS1115_8SPS,
"16": ADS1115Samplerate.ADS1115_16SPS,
@ -57,7 +57,7 @@ SAMPLERATE = {
"860": ADS1115Samplerate.ADS1115_860SPS,
}
ADS1115Sensor = ads1115_ns.class_(
ADS1115Sensor = ads1115_int_ns.class_(
"ADS1115Sensor", sensor.Sensor, cg.Component, voltage_sampler.VoltageSampler
)

View File

@ -9,9 +9,14 @@ static const char *const TAG = "ads1115_int.sensor";
void ADS1115Sensor::loop() {
if (parent_->is_data_ready(this->multiplexer_)) {
this->parent_->clear_alert_ready(this->multiplexer_);
double v = this->parent_->read_data(this->multiplexer_, this->gain_, this->resolution_, this->samplerate_);
this->parent_->clear_data_ready(this->multiplexer_);
int16_t raw_value = -1000;
double v = this->parent_->read_data(raw_value, this->multiplexer_, this->gain_, this->resolution_, this->samplerate_);
if (!std::isnan(v)) {
if(this->count_ % 10 == 0) {
ESP_LOGI(TAG, "'% -18s': Raw=% 6d %fV", this->get_name().c_str(), raw_value, v);
}
this->count_++;
ESP_LOGD(TAG, "'%s': Got Voltage=%fV", this->get_name().c_str(), v);
this->publish_state(v);
}

View File

@ -30,7 +30,7 @@ class ADS1115Sensor : public sensor::Sensor,
ADS1115Gain gain_;
ADS1115Resolution resolution_;
ADS1115Samplerate samplerate_;
uint64_t count_{0};
};
} // namespace ads1115

View File

@ -0,0 +1,32 @@
import esphome.codegen as cg
from esphome.components import i2c
import esphome.config_validation as cv
from esphome.const import CONF_ID
DEPENDENCIES = ["i2c"]
MULTI_CONF = True
ads1115_pol_ns = cg.esphome_ns.namespace("ads1115_pol")
ADS1115Component = ads1115_pol_ns.class_("ADS1115Component", cg.Component, i2c.I2CDevice)
CONF_CONTINUOUS_MODE = "continuous_mode"
CONF_ADS1115_ID = "ads1115_id"
CONFIG_SCHEMA = (
cv.Schema(
{
cv.GenerateID(): cv.declare_id(ADS1115Component),
cv.Optional(CONF_CONTINUOUS_MODE, default=False): cv.boolean,
}
)
.extend(cv.COMPONENT_SCHEMA)
.extend(i2c.i2c_device_schema(None))
)
async def to_code(config):
var = cg.new_Pvariable(config[CONF_ID])
await cg.register_component(var, config)
await i2c.register_i2c_device(var, config)
cg.add(var.set_continuous_mode(config[CONF_CONTINUOUS_MODE]))

View File

@ -0,0 +1,223 @@
#include "ads1115_pol.h"
#include "esphome/core/hal.h"
#include "esphome/core/log.h"
namespace esphome {
namespace ads1115_pol {
static const char *const TAG = "ads1115_pol";
static const uint8_t ADS1115_REGISTER_CONVERSION = 0x00;
static const uint8_t ADS1115_REGISTER_CONFIG = 0x01;
void ADS1115Component::setup() {
uint16_t value;
if (!this->read_byte_16(ADS1115_REGISTER_CONVERSION, &value)) {
this->mark_failed();
return;
}
uint16_t config = 0;
// Clear single-shot bit
// 0b0xxxxxxxxxxxxxxx
config |= 0b0000000000000000;
// Setup multiplexer
// 0bx000xxxxxxxxxxxx
config |= ADS1115_MULTIPLEXER_P0_N1 << 12;
// Setup Gain
// 0bxxxx000xxxxxxxxx
config |= ADS1115_GAIN_6P144 << 9;
if (this->continuous_mode_) {
// Set continuous mode
// 0bxxxxxxx0xxxxxxxx
config |= 0b0000000000000000;
} else {
// Set singleshot mode
// 0bxxxxxxx1xxxxxxxx
config |= 0b0000000100000000;
}
// Set data rate - 860 samples per second
// 0bxxxxxxxx100xxxxx
config |= ADS1115_860SPS << 5;
// Set comparator mode - hysteresis
// 0bxxxxxxxxxxx0xxxx
config |= 0b0000000000000000;
// Set comparator polarity - active low
// 0bxxxxxxxxxxxx0xxx
config |= 0b0000000000000000;
// Set comparator latch enabled - false
// 0bxxxxxxxxxxxxx0xx
config |= 0b0000000000000000;
// Set comparator que mode - disabled
// 0bxxxxxxxxxxxxxx11
config |= 0b0000000000000011;
if (!this->write_byte_16(ADS1115_REGISTER_CONFIG, config)) {
this->mark_failed();
return;
}
this->prev_config_ = config;
}
void ADS1115Component::dump_config() {
ESP_LOGCONFIG(TAG, "ADS1115:");
LOG_I2C_DEVICE(this);
if (this->is_failed()) {
ESP_LOGE(TAG, ESP_LOG_MSG_COMM_FAIL);
}
}
float ADS1115Component::request_measurement(int16_t& raw_value, ADS1115Multiplexer multiplexer, ADS1115Gain gain,
ADS1115Resolution resolution, ADS1115Samplerate samplerate) {
uint16_t config = this->prev_config_;
// Multiplexer
// 0bxBBBxxxxxxxxxxxx
config &= 0b1000111111111111;
config |= (multiplexer & 0b111) << 12;
// Gain
// 0bxxxxBBBxxxxxxxxx
config &= 0b1111000111111111;
config |= (gain & 0b111) << 9;
// Sample rate
// 0bxxxxxxxxBBBxxxxx
config &= 0b1111111100011111;
config |= (samplerate & 0b111) << 5;
if (!this->continuous_mode_) {
// Start conversion
config |= 0b1000000000000000;
}
if (!this->continuous_mode_ || this->prev_config_ != config) {
if (!this->write_byte_16(ADS1115_REGISTER_CONFIG, config)) {
this->status_set_warning();
return NAN;
}
this->prev_config_ = config;
// Delay calculated as: ceil((1000/SPS)+.5)
if (resolution == ADS1015_12_BITS) {
switch (samplerate) {
case ADS1115_8SPS:
delay(9);
break;
case ADS1115_16SPS:
delay(5);
break;
case ADS1115_32SPS:
delay(3);
break;
case ADS1115_64SPS:
case ADS1115_128SPS:
delay(2);
break;
default:
delay(1);
break;
}
} else {
switch (samplerate) {
case ADS1115_8SPS:
delay(126); // NOLINT
break;
case ADS1115_16SPS:
delay(63); // NOLINT
break;
case ADS1115_32SPS:
delay(32);
break;
case ADS1115_64SPS:
delay(17);
break;
case ADS1115_128SPS:
delay(9);
break;
case ADS1115_250SPS:
delay(5);
break;
case ADS1115_475SPS:
delay(3);
break;
case ADS1115_860SPS:
delay(2);
break;
}
}
// in continuous mode, conversion will always be running, rely on the delay
// to ensure conversion is taking place with the correct settings
// can we use the rdy pin to trigger when a conversion is done?
if (!this->continuous_mode_) {
uint32_t start = millis();
while (this->read_byte_16(ADS1115_REGISTER_CONFIG, &config) && (config >> 15) == 0) {
if (millis() - start > 100) {
ESP_LOGW(TAG, "Reading ADS1115 timed out");
this->status_set_warning();
return NAN;
}
yield();
}
}
}
uint16_t raw_conversion;
if (!this->read_byte_16(ADS1115_REGISTER_CONVERSION, &raw_conversion)) {
this->status_set_warning();
return NAN;
}
if (resolution == ADS1015_12_BITS) {
bool negative = (raw_conversion >> 15) == 1;
// shift raw_conversion as it's only 12-bits, left justified
raw_conversion = raw_conversion >> (16 - ADS1015_12_BITS);
// check if number was negative in order to keep the sign
if (negative) {
// the number was negative
// 1) set the negative bit back
raw_conversion |= 0x8000;
// 2) reset the former (shifted) negative bit
raw_conversion &= 0xF7FF;
}
}
auto signed_conversion = static_cast<int16_t>(raw_conversion);
raw_value = signed_conversion;
float millivolts;
float divider = (resolution == ADS1115_16_BITS) ? 32768.0f : 2048.0f;
switch (gain) {
case ADS1115_GAIN_6P144:
millivolts = (signed_conversion * 6144) / divider;
break;
case ADS1115_GAIN_4P096:
millivolts = (signed_conversion * 4096) / divider;
break;
case ADS1115_GAIN_2P048:
millivolts = (signed_conversion * 2048) / divider;
break;
case ADS1115_GAIN_1P024:
millivolts = (signed_conversion * 1024) / divider;
break;
case ADS1115_GAIN_0P512:
millivolts = (signed_conversion * 512) / divider;
break;
case ADS1115_GAIN_0P256:
millivolts = (signed_conversion * 256) / divider;
break;
default:
millivolts = NAN;
}
this->status_clear_warning();
return millivolts / 1e3f;
}
} // namespace ads1115
} // namespace esphome

View File

@ -0,0 +1,64 @@
#pragma once
#include "esphome/components/i2c/i2c.h"
#include "esphome/core/component.h"
#include <vector>
namespace esphome {
namespace ads1115_pol {
enum ADS1115Multiplexer {
ADS1115_MULTIPLEXER_P0_N1 = 0b000,
ADS1115_MULTIPLEXER_P0_N3 = 0b001,
ADS1115_MULTIPLEXER_P1_N3 = 0b010,
ADS1115_MULTIPLEXER_P2_N3 = 0b011,
ADS1115_MULTIPLEXER_P0_NG = 0b100,
ADS1115_MULTIPLEXER_P1_NG = 0b101,
ADS1115_MULTIPLEXER_P2_NG = 0b110,
ADS1115_MULTIPLEXER_P3_NG = 0b111,
};
enum ADS1115Gain {
ADS1115_GAIN_6P144 = 0b000,
ADS1115_GAIN_4P096 = 0b001,
ADS1115_GAIN_2P048 = 0b010,
ADS1115_GAIN_1P024 = 0b011,
ADS1115_GAIN_0P512 = 0b100,
ADS1115_GAIN_0P256 = 0b101,
};
enum ADS1115Resolution {
ADS1115_16_BITS = 16,
ADS1015_12_BITS = 12,
};
enum ADS1115Samplerate {
ADS1115_8SPS = 0b000,
ADS1115_16SPS = 0b001,
ADS1115_32SPS = 0b010,
ADS1115_64SPS = 0b011,
ADS1115_128SPS = 0b100,
ADS1115_250SPS = 0b101,
ADS1115_475SPS = 0b110,
ADS1115_860SPS = 0b111
};
class ADS1115Component : public Component, public i2c::I2CDevice {
public:
void setup() override;
void dump_config() override;
/// HARDWARE_LATE setup priority
void set_continuous_mode(bool continuous_mode) { continuous_mode_ = continuous_mode; }
/// Helper method to request a measurement from a sensor.
float request_measurement(int16_t& raw_value, ADS1115Multiplexer multiplexer, ADS1115Gain gain, ADS1115Resolution resolution,
ADS1115Samplerate samplerate);
protected:
uint16_t prev_config_{0};
bool continuous_mode_;
};
} // namespace ads1115
} // namespace esphome

View File

@ -0,0 +1,98 @@
import esphome.codegen as cg
from esphome.components import sensor, voltage_sampler
import esphome.config_validation as cv
from esphome.const import (
CONF_GAIN,
CONF_ID,
CONF_MULTIPLEXER,
CONF_RESOLUTION,
CONF_SAMPLE_RATE,
DEVICE_CLASS_VOLTAGE,
STATE_CLASS_MEASUREMENT,
UNIT_VOLT,
)
from .. import CONF_ADS1115_ID, ADS1115Component, ads1115_pol_ns
AUTO_LOAD = ["voltage_sampler"]
DEPENDENCIES = ["ads1115_pol"]
ADS1115Multiplexer = ads1115_pol_ns.enum("ADS1115Multiplexer")
MUX = {
"A0_A1": ADS1115Multiplexer.ADS1115_MULTIPLEXER_P0_N1,
"A0_A3": ADS1115Multiplexer.ADS1115_MULTIPLEXER_P0_N3,
"A1_A3": ADS1115Multiplexer.ADS1115_MULTIPLEXER_P1_N3,
"A2_A3": ADS1115Multiplexer.ADS1115_MULTIPLEXER_P2_N3,
"A0_GND": ADS1115Multiplexer.ADS1115_MULTIPLEXER_P0_NG,
"A1_GND": ADS1115Multiplexer.ADS1115_MULTIPLEXER_P1_NG,
"A2_GND": ADS1115Multiplexer.ADS1115_MULTIPLEXER_P2_NG,
"A3_GND": ADS1115Multiplexer.ADS1115_MULTIPLEXER_P3_NG,
}
ADS1115Gain = ads1115_pol_ns.enum("ADS1115Gain")
GAIN = {
"6.144": ADS1115Gain.ADS1115_GAIN_6P144,
"4.096": ADS1115Gain.ADS1115_GAIN_4P096,
"2.048": ADS1115Gain.ADS1115_GAIN_2P048,
"1.024": ADS1115Gain.ADS1115_GAIN_1P024,
"0.512": ADS1115Gain.ADS1115_GAIN_0P512,
"0.256": ADS1115Gain.ADS1115_GAIN_0P256,
}
ADS1115Resolution = ads1115_pol_ns.enum("ADS1115Resolution")
RESOLUTION = {
"16_BITS": ADS1115Resolution.ADS1115_16_BITS,
"12_BITS": ADS1115Resolution.ADS1015_12_BITS,
}
ADS1115Samplerate = ads1115_pol_ns.enum("ADS1115Samplerate")
SAMPLERATE = {
"8": ADS1115Samplerate.ADS1115_8SPS,
"16": ADS1115Samplerate.ADS1115_16SPS,
"32": ADS1115Samplerate.ADS1115_32SPS,
"64": ADS1115Samplerate.ADS1115_64SPS,
"128": ADS1115Samplerate.ADS1115_128SPS,
"250": ADS1115Samplerate.ADS1115_250SPS,
"475": ADS1115Samplerate.ADS1115_475SPS,
"860": ADS1115Samplerate.ADS1115_860SPS,
}
ADS1115Sensor = ads1115_pol_ns.class_(
"ADS1115Sensor", sensor.Sensor, cg.PollingComponent, voltage_sampler.VoltageSampler
)
CONFIG_SCHEMA = (
sensor.sensor_schema(
ADS1115Sensor,
unit_of_measurement=UNIT_VOLT,
accuracy_decimals=3,
device_class=DEVICE_CLASS_VOLTAGE,
state_class=STATE_CLASS_MEASUREMENT,
)
.extend(
{
cv.GenerateID(CONF_ADS1115_ID): cv.use_id(ADS1115Component),
cv.Required(CONF_MULTIPLEXER): cv.enum(MUX, upper=True, space="_"),
cv.Required(CONF_GAIN): cv.enum(GAIN, string=True),
cv.Optional(CONF_RESOLUTION, default="16_BITS"): cv.enum(
RESOLUTION, upper=True, space="_"
),
cv.Optional(CONF_SAMPLE_RATE, default="860"): cv.enum(
SAMPLERATE, string=True
),
}
)
.extend(cv.polling_component_schema("60s"))
)
async def to_code(config):
var = cg.new_Pvariable(config[CONF_ID])
await sensor.register_sensor(var, config)
await cg.register_component(var, config)
await cg.register_parented(var, config[CONF_ADS1115_ID])
cg.add(var.set_multiplexer(config[CONF_MULTIPLEXER]))
cg.add(var.set_gain(config[CONF_GAIN]))
cg.add(var.set_resolution(config[CONF_RESOLUTION]))
cg.add(var.set_samplerate(config[CONF_SAMPLE_RATE]))

View File

@ -0,0 +1,36 @@
#include "ads1115_pol_sensor.h"
#include "esphome/core/log.h"
namespace esphome {
namespace ads1115_pol {
static const char *const TAG = "ads1115_pol.sensor";
float ADS1115Sensor::sample(int16_t& raw_value) {
return this->parent_->request_measurement(raw_value, this->multiplexer_, this->gain_, this->resolution_, this->samplerate_);
}
void ADS1115Sensor::update() {
int16_t raw_value = -1000;
float v = this->sample(raw_value);
if (!std::isnan(v)) {
if(this->count_ % 10 == 0) {
ESP_LOGI(TAG, "'% -18s': Raw=% 6d %fV", this->get_name().c_str(), raw_value, v);
}
this->count_++;
ESP_LOGD(TAG, "'%s': Got Voltage=%fV", this->get_name().c_str(), v);
this->publish_state(v);
}
}
void ADS1115Sensor::dump_config() {
LOG_SENSOR(" ", "ADS1115_pol Sensor", this);
ESP_LOGCONFIG(TAG, " Multiplexer: %u", this->multiplexer_);
ESP_LOGCONFIG(TAG, " Gain: %u", this->gain_);
ESP_LOGCONFIG(TAG, " Resolution: %u", this->resolution_);
ESP_LOGCONFIG(TAG, " Sample rate: %u", this->samplerate_);
}
} // namespace ads1115
} // namespace esphome

View File

@ -0,0 +1,38 @@
#pragma once
#include "esphome/core/component.h"
#include "esphome/core/helpers.h"
#include "esphome/components/sensor/sensor.h"
#include "esphome/components/voltage_sampler/voltage_sampler.h"
#include "../ads1115_pol.h"
namespace esphome {
namespace ads1115_pol {
/// Internal holder class that is in instance of Sensor so that the hub can create individual sensors.
class ADS1115Sensor : public sensor::Sensor,
public PollingComponent,
//public voltage_sampler::VoltageSampler,
public Parented<ADS1115Component> {
public:
void update() override;
void set_multiplexer(ADS1115Multiplexer multiplexer) { this->multiplexer_ = multiplexer; }
void set_gain(ADS1115Gain gain) { this->gain_ = gain; }
void set_resolution(ADS1115Resolution resolution) { this->resolution_ = resolution; }
void set_samplerate(ADS1115Samplerate samplerate) { this->samplerate_ = samplerate; }
float sample(int16_t& raw_value);
void dump_config() override;
protected:
ADS1115Multiplexer multiplexer_;
ADS1115Gain gain_;
ADS1115Resolution resolution_;
ADS1115Samplerate samplerate_;
uint64_t count_{0};
};
} // namespace ads1115
} // namespace esphome

View File

@ -84,6 +84,29 @@ void ADS131M08Hub::txf_init()
}
}
void ADS131M08Hub::initialize_ads131m08_datasheet()
{
// enableSupplies();
// GPIO.inputEnable('input'); // Enable GPIO connected to DRDY
// clkout.enable(8192000); // Enable 8.192 MHz clock to CLKIN
// SPI.enable(); // Enable SPI port
// SPI.wordLengthSet(24); // ADC default word length is 24 bits
// SPI.configCS(STAY_ASSERTED);// Configure CS to remain asserted until frame is complete
while(!GPIO.read()){} // Wait for DRDY to go high indicating it is ok to talk to ADC
adcRegisterWrite(REG_CLOCK, MASK_CLOCK_ALL_CH_DISABLE | OSR_1024 | PM_HIGH_RESOLUTION, 24); // Write CLOCK register; Turn off all channels so short frames can be written during config; // Re-write defaults for other bits in CLOCK register
adcRegisterWrite(REG_MODE, MODE_NO_RESET | DRDY_FMT_PULSE | WLENGTH_24_BITS | TIMEOUT_ENABLED, 24); // Write MODE register; Clear the RESET flag, make DRDY active low pulse; Re-write defaults for other bits in MODE register
adcRegisterWrite(REG_GAIN1, PGAGAIN3_32 | PGAGAIN1_32, 24); // Write GAIN1 register; Set channels 1 and 3 PGA gain to 32 in this example; Leave channels 0 and 2 at default gain of 1
adcRegisterWrite(REG_THRSHLD_LSB, 0x09, 24); // Write THRSHLD_LSB register; Set DCBLOCK filter to have a corner frequency of 622 mHz
DMA.triggerSet(SPI);// Configure DMA to trigger when data comes in on the MCU SPI port
DMA.txAddrSet(SPI.rxAddr());// Set the DMA to take from the incoming SPI port
DMA.rxAddrSet(&adcData);// Set the DMA to send ADC data to a predefined memory location
adcRegisterWrite(REG_MODE, WLENGTH_32_BITS_MSB_SIGN_EXTEND | DRDY_FMT_PULSE | TIMEOUT_ENABLED, 24); // Write MODE register; Make ADC word size 32 bits to accommodate DMA; Re-write other set bits in MODE register
SPI.wordLengthSet(32); // Set SPI word size to 32 bits to accomodate DMA
adcRegisterWrite(REG_CLOCK, MASK_CLOCK_ALL_CH_ENABLE | OSR_1024 | PM_HIGH_RESOLUTION, 32); // Write CLOCK register; Turn on all ADC channels; Re-write defaults for other bits in CLOCK register
GPIO.interuptEnable();// Enable DRDY interrupt and begin streaming data
}
/* adcRegisterWrite
Short function that writes one ADC register at a time.
Blocks return until SPI is idle.
@ -114,37 +137,10 @@ bool ADS131M08Hub::adcRegisterWrite(unsigned short addrMask, unsigned short data
return true;
}
void ADS131M08Hub::initialize_ads131m08_datasheet()
{
// enableSupplies();
// GPIO.inputEnable('input'); // Enable GPIO connected to DRDY
// clkout.enable(8192000); // Enable 8.192 MHz clock to CLKIN
// SPI.enable(); // Enable SPI port
// SPI.wordLengthSet(24); // ADC default word length is 24 bits
// SPI.configCS(STAY_ASSERTED);// Configure CS to remain asserted until frame is complete
while(!GPIO.read()){} // Wait for DRDY to go high indicating it is ok to talk to ADC
adcRegisterWrite(REG_CLOCK, MASK_CLOCK_ALL_CH_DISABLE | OSR_1024 | PM_HIGH_RESOLUTION, 24); // Write CLOCK register; Turn off all channels so short frames can be written during config
// Re-write defaults for other bits in CLOCK register
adcRegisterWrite(REG_MODE, MODE_NO_RESET | DRDY_FMT_PULSE | WLENGTH_24_BITS | TIMEOUT_ENABLED, 24); // Write MODE register; Clear the RESET flag, make DRDY active low pulse
// Re-write defaults for other bits in MODE register
adcRegisterWrite(REG_GAIN1, PGAGAIN3_32 | PGAGAIN1_32, 24); // Write GAIN1 register; Set channels 1 and 3 PGA gain to 32 in this example
// Leave channels 0 and 2 at default gain of 1
adcRegisterWrite(REG_THRSHLD_LSB, 0x09, 24); // Write THRSHLD_LSB register; Set DCBLOCK filter to have a corner frequency of 622 mHz
DMA.triggerSet(SPI);// Configure DMA to trigger when data comes in on the MCU SPI port
DMA.txAddrSet(SPI.rxAddr());// Set the DMA to take from the incoming SPI port
DMA.rxAddrSet(&adcData);// Set the DMA to send ADC data to a predefined memory location
adcRegisterWrite(REG_MODE, WLENGTH_32_BITS_MSB_SIGN_EXTEND | DRDY_FMT_PULSE | TIMEOUT_ENABLED, 24); // Write MODE register; Make ADC word size 32 bits to accommodate DMA;
// Re-write other set bits in MODE register
SPI.wordLengthSet(32); // Set SPI word size to 32 bits to accomodate DMA
adcRegisterWrite(REG_CLOCK, MASK_CLOCK_ALL_CH_ENABLE | OSR_1024 | PM_HIGH_RESOLUTION, 32); // Write CLOCK register; Turn on all ADC channels; Re-write defaults for other bits in CLOCK register
GPIO.interuptEnable();// Enable DRDY interrupt and begin streaming data
}
// ********************** end of from datasheet ************************
/*
void ADS131M08::read_all_channels()
void ADS131M08Hub::read_all_channels()
{
// Send RDATA command or read data directly
SPI.transfer(0x12); // RDATA command
@ -187,6 +183,662 @@ void ADS131M08Hub::read_data_()
}
}
// =============== from tpcorrea =================
ADS131M08Hub::ADS131M08Hub() : csPin(0), drdyPin(0), clkPin(0), misoPin(0), mosiPin(0), resetPin(0)
{
for( uint16_t i = 0U; i < 8; i++){
fullScale.ch[i].f = 1.2; // +-1.2V
pgaGain[i] = ADS131M08_PgaGain::PGA_1;
resultFloat.ch[i].f = 0.0;
resultRaw.ch[i].u[0] = 0U;
resultRaw.ch[i].u[1] = 0U;
}
}
uint8_t ADS131M08Hub::writeRegister(uint8_t address, uint16_t value)
{
uint16_t res;
uint8_t addressRcv;
uint8_t bytesRcv;
uint16_t cmd = 0;
digitalWrite(csPin, LOW);
delayMicroseconds(1);
cmd = (CMD_WRITE_REG) | (address << 7) | 0;
//res = spi.transfer16(cmd);
spi.transfer16(cmd);
spi.transfer(0x00);
spi.transfer16(value);
spi.transfer(0x00);
for(int i = 0; i < 8; i++)
{
spi.transfer16(0x0000);
spi.transfer(0x00);
}
res = spi.transfer16(0x0000);
spi.transfer(0x00);
for(int i = 0; i < 9; i++)
{
spi.transfer16(0x0000);
spi.transfer(0x00);
}
delayMicroseconds(1);
digitalWrite(csPin, HIGH);
addressRcv = (res & REGMASK_CMD_READ_REG_ADDRESS) >> 7;
bytesRcv = (res & REGMASK_CMD_READ_REG_BYTES);
if (addressRcv == address)
{
return bytesRcv + 1;
}
return 0;
}
void ADS131M08Hub::writeRegisterMasked(uint8_t address, uint16_t value, uint16_t mask)
{
// Escribe un valor en el registro, aplicando la mascara para tocar unicamente los bits necesarios.
// No realiza el corrimiento de bits (shift), hay que pasarle ya el valor corrido a la posicion correcta
// Leo el contenido actual del registro
uint16_t register_contents = readRegister(address);
// Cambio bit aa bit la mascara (queda 1 en los bits que no hay que tocar y 0 en los bits a modificar)
// Se realiza un AND co el contenido actual del registro. Quedan "0" en la parte a modificar
register_contents = register_contents & ~mask;
// se realiza un OR con el valor a cargar en el registro. Ojo, valor debe estar en el posicion (shitf) correcta
register_contents = register_contents | value;
// Escribo nuevamente el registro
writeRegister(address, register_contents);
}
uint16_t ADS131M08Hub::readRegister(uint8_t address)
{
uint16_t cmd;
uint16_t data;
cmd = CMD_READ_REG | (address << 7 | 0);
digitalWrite(csPin, LOW);
delayMicroseconds(1);
//data = spi.transfer16(cmd);
spi.transfer16(cmd);
spi.transfer(0x00);
for(int i = 0; i < 9; i++)
{
spi.transfer16(0x0000);
spi.transfer(0x00);
}
data = spi.transfer16(0x0000);
spi.transfer(0x00);
for(int i = 0; i < 9; i++)
{
spi.transfer16(0x0000);
spi.transfer(0x00);
}
delayMicroseconds(1);
digitalWrite(csPin, HIGH);
return data;
}
void ADS131M08Hub::begin(uint8_t clk_pin, uint8_t miso_pin, uint8_t mosi_pin, uint8_t cs_pin, uint8_t drdy_pin, uint8_t reset_pin)
{
// Set pins up
csPin = cs_pin;
drdyPin = drdy_pin;
clkPin = clk_pin;
misoPin = miso_pin;
mosiPin = mosi_pin;
resetPin = reset_pin;
spi = SPIClass(mosi_pin, miso_pin, clk_pin, cs_pin);
spi.begin();
spi.beginTransaction(settings);
// Configure chip select as an output
pinMode(csPin, OUTPUT);
pinMode(resetPin, OUTPUT);
// Configure DRDY as an input
pinMode(drdyPin, INPUT);
}
int8_t ADS131M08Hub::isDataReadySoft(byte channel)
{
if (channel == 0)
{
return (readRegister(REG_STATUS) & REGMASK_STATUS_DRDY0);
}
else if (channel == 1)
{
return (readRegister(REG_STATUS) & REGMASK_STATUS_DRDY1);
}
else if (channel == 2)
{
return (readRegister(REG_STATUS) & REGMASK_STATUS_DRDY2);
}
else if (channel == 3)
{
return (readRegister(REG_STATUS) & REGMASK_STATUS_DRDY3);
}
else if (channel == 4)
{
return (readRegister(REG_STATUS) & REGMASK_STATUS_DRDY4);
}
else if (channel == 5)
{
return (readRegister(REG_STATUS) & REGMASK_STATUS_DRDY5);
}
else if (channel == 6)
{
return (readRegister(REG_STATUS) & REGMASK_STATUS_DRDY6);
}
else if (channel == 7)
{
return (readRegister(REG_STATUS) & REGMASK_STATUS_DRDY7);
}
else
{
return -1;
}
}
bool ADS131M08Hub::isResetStatus(void)
{
return (readRegister(REG_STATUS) & REGMASK_STATUS_RESET);
}
bool ADS131M08Hub::isLockSPI(void)
{
return (readRegister(REG_STATUS) & REGMASK_STATUS_LOCK);
}
bool ADS131M08Hub::setDrdyFormat(uint8_t drdyFormat)
{
if (drdyFormat > 1)
{
return false;
}
else
{
writeRegisterMasked(REG_MODE, drdyFormat, REGMASK_MODE_DRDY_FMT);
return true;
}
}
bool ADS131M08Hub::setDrdyStateWhenUnavailable(uint8_t drdyState)
{
if (drdyState > 1)
{
return false;
}
else
{
writeRegisterMasked(REG_MODE, drdyState < 1, REGMASK_MODE_DRDY_HiZ);
return true;
}
}
bool ADS131M08Hub::setPowerMode(uint8_t powerMode)
{
if (powerMode > 3)
{
return false;
}
else
{
writeRegisterMasked(REG_CLOCK, powerMode, REGMASK_CLOCK_PWR);
return true;
}
}
bool ADS131M08Hub::setOsr(uint16_t osr)
{
if (osr > 7)
{
return false;
}
else
{
writeRegisterMasked(REG_CLOCK, osr << 2 , REGMASK_CLOCK_OSR);
return true;
}
}
void ADS131M08Hub::setFullScale(uint8_t channel, float scale)
{
if (channel > 7) {
return;
}
this->fullScale.ch[channel].f = scale;
}
float ADS131M08Hub::getFullScale(uint8_t channel)
{
if (channel > 7) {
return 0.0;
}
return this->fullScale.ch[channel].f;
}
void ADS131M08Hub::reset()
{
digitalWrite(this->resetPin, LOW);
delay(10);
digitalWrite(this->resetPin, HIGH);
}
bool ADS131M08Hub::setChannelEnable(uint8_t channel, uint16_t enable)
{
if (channel > 7)
{
return false;
}
if (channel == 0)
{
writeRegisterMasked(REG_CLOCK, enable << 8, REGMASK_CLOCK_CH0_EN);
return true;
}
else if (channel == 1)
{
writeRegisterMasked(REG_CLOCK, enable << 9, REGMASK_CLOCK_CH1_EN);
return true;
}
else if (channel == 2)
{
writeRegisterMasked(REG_CLOCK, enable << 10, REGMASK_CLOCK_CH2_EN);
return true;
}
else if (channel == 3)
{
writeRegisterMasked(REG_CLOCK, enable << 11, REGMASK_CLOCK_CH3_EN);
return true;
}
else if (channel == 4)
{
writeRegisterMasked(REG_CLOCK, enable << 11, REGMASK_CLOCK_CH4_EN);
return true;
}
else if (channel == 5)
{
writeRegisterMasked(REG_CLOCK, enable << 11, REGMASK_CLOCK_CH5_EN);
return true;
}
else if (channel == 6)
{
writeRegisterMasked(REG_CLOCK, enable << 11, REGMASK_CLOCK_CH6_EN);
return true;
}
else if (channel == 7)
{
writeRegisterMasked(REG_CLOCK, enable << 11, REGMASK_CLOCK_CH7_EN);
return true;
}
return false;
}
bool ADS131M08Hub::setChannelPGA(uint8_t channel, ADS131M08_PgaGain pga)
{ uint16_t pgaCode = (uint16_t) pga;
if (channel > 7)
{
return false;
}
if (channel == 0)
{
writeRegisterMasked(REG_GAIN1, pgaCode, REGMASK_GAIN_PGAGAIN0);
this->pgaGain[0] = pga;
return true;
}
else if (channel == 1)
{
writeRegisterMasked(REG_GAIN1, pgaCode << 4, REGMASK_GAIN_PGAGAIN1);
this->pgaGain[1] = pga;
return true;
}
else if (channel == 2)
{
writeRegisterMasked(REG_GAIN1, pgaCode << 8, REGMASK_GAIN_PGAGAIN2);
this->pgaGain[2] = pga;
return true;
}
else if (channel == 3)
{
writeRegisterMasked(REG_GAIN1, pgaCode << 12, REGMASK_GAIN_PGAGAIN3);
this->pgaGain[3] = pga;
return true;
}
if (channel == 4)
{
writeRegisterMasked(REG_GAIN2, pgaCode, REGMASK_GAIN_PGAGAIN4);
this->pgaGain[4] = pga;
return true;
}
else if (channel == 5)
{
writeRegisterMasked(REG_GAIN2, pgaCode << 4, REGMASK_GAIN_PGAGAIN5);
this->pgaGain[5] = pga;
return true;
}
else if (channel == 6)
{
writeRegisterMasked(REG_GAIN2, pgaCode << 8, REGMASK_GAIN_PGAGAIN6);
this->pgaGain[6] = pga;
return true;
}
else if (channel == 7)
{
writeRegisterMasked(REG_GAIN2, pgaCode << 12, REGMASK_GAIN_PGAGAIN7);
this->pgaGain[7] = pga;
return true;
}
return false;
}
ADS131M08_PgaGain ADS131M08Hub::getChannelPGA(uint8_t channel)
{
if(channel > 7)
{
return ADS131M08_PgaGain::PGA_INVALID;
}
return this->pgaGain[channel];
}
void ADS131M08Hub::setGlobalChop(uint16_t global_chop)
{
writeRegisterMasked(REG_CFG, global_chop << 8, REGMASK_CFG_GC_EN);
}
void ADS131M08Hub::setGlobalChopDelay(uint16_t delay)
{
writeRegisterMasked(REG_CFG, delay << 9, REGMASK_CFG_GC_DLY);
}
bool ADS131M08Hub::setInputChannelSelection(uint8_t channel, uint8_t input)
{
if (channel > 3)
{
return false;
}
if (channel == 0)
{
writeRegisterMasked(REG_CH0_CFG, input, REGMASK_CHX_CFG_MUX);
return true;
}
else if (channel == 1)
{
writeRegisterMasked(REG_CH1_CFG, input, REGMASK_CHX_CFG_MUX);
return true;
}
else if (channel == 2)
{
writeRegisterMasked(REG_CH2_CFG, input, REGMASK_CHX_CFG_MUX);
return true;
}
else if (channel == 3)
{
writeRegisterMasked(REG_CH3_CFG, input, REGMASK_CHX_CFG_MUX);
return true;
}
else if (channel == 4)
{
writeRegisterMasked(REG_CH4_CFG, input, REGMASK_CHX_CFG_MUX);
return true;
}
else if (channel == 5)
{
writeRegisterMasked(REG_CH5_CFG, input, REGMASK_CHX_CFG_MUX);
return true;
}
else if (channel == 6)
{
writeRegisterMasked(REG_CH6_CFG, input, REGMASK_CHX_CFG_MUX);
return true;
}
else if (channel == 7)
{
writeRegisterMasked(REG_CH7_CFG, input, REGMASK_CHX_CFG_MUX);
return true;
}
return false;
}
bool ADS131M08Hub::setChannelOffsetCalibration(uint8_t channel, int32_t offset)
{
uint16_t MSB = offset >> 8;
uint8_t LSB = offset;
if (channel > 7)
{
return false;
}
if (channel == 0)
{
writeRegisterMasked(REG_CH0_OCAL_MSB, MSB, 0xFFFF);
writeRegisterMasked(REG_CH0_OCAL_LSB, LSB << 8, REGMASK_CHX_OCAL0_LSB);
return true;
}
else if (channel == 1)
{
writeRegisterMasked(REG_CH1_OCAL_MSB, MSB, 0xFFFF);
writeRegisterMasked(REG_CH1_OCAL_LSB, LSB << 8, REGMASK_CHX_OCAL0_LSB);
return true;
}
else if (channel == 2)
{
writeRegisterMasked(REG_CH2_OCAL_MSB, MSB, 0xFFFF);
writeRegisterMasked(REG_CH2_OCAL_LSB, LSB << 8, REGMASK_CHX_OCAL0_LSB);
return true;
}
else if (channel == 3)
{
writeRegisterMasked(REG_CH3_OCAL_MSB, MSB, 0xFFFF);
writeRegisterMasked(REG_CH3_OCAL_LSB, LSB << 8 , REGMASK_CHX_OCAL0_LSB);
return true;
}
else if (channel == 4)
{
writeRegisterMasked(REG_CH4_OCAL_MSB, MSB, 0xFFFF);
writeRegisterMasked(REG_CH4_OCAL_LSB, LSB << 8 , REGMASK_CHX_OCAL0_LSB);
return true;
}
else if (channel == 5)
{
writeRegisterMasked(REG_CH5_OCAL_MSB, MSB, 0xFFFF);
writeRegisterMasked(REG_CH5_OCAL_LSB, LSB << 8 , REGMASK_CHX_OCAL0_LSB);
return true;
}
else if (channel == 6)
{
writeRegisterMasked(REG_CH6_OCAL_MSB, MSB, 0xFFFF);
writeRegisterMasked(REG_CH6_OCAL_LSB, LSB << 8 , REGMASK_CHX_OCAL0_LSB);
return true;
}
else if (channel == 7)
{
writeRegisterMasked(REG_CH7_OCAL_MSB, MSB, 0xFFFF);
writeRegisterMasked(REG_CH7_OCAL_LSB, LSB << 8 , REGMASK_CHX_OCAL0_LSB);
return true;
}
return false;
}
bool ADS131M08Hub::setChannelGainCalibration(uint8_t channel, uint32_t gain)
{
uint16_t MSB = gain >> 8;
uint8_t LSB = gain;
if (channel > 7)
{
return false;
}
if (channel == 0)
{
writeRegisterMasked(REG_CH0_GCAL_MSB, MSB, 0xFFFF);
writeRegisterMasked(REG_CH0_GCAL_LSB, LSB << 8, REGMASK_CHX_GCAL0_LSB);
return true;
}
else if (channel == 1)
{
writeRegisterMasked(REG_CH1_GCAL_MSB, MSB, 0xFFFF);
writeRegisterMasked(REG_CH1_GCAL_LSB, LSB << 8, REGMASK_CHX_GCAL0_LSB);
return true;
}
else if (channel == 2)
{
writeRegisterMasked(REG_CH2_GCAL_MSB, MSB, 0xFFFF);
writeRegisterMasked(REG_CH2_GCAL_LSB, LSB << 8, REGMASK_CHX_GCAL0_LSB);
return true;
}
else if (channel == 3)
{
writeRegisterMasked(REG_CH3_GCAL_MSB, MSB, 0xFFFF);
writeRegisterMasked(REG_CH3_GCAL_LSB, LSB << 8, REGMASK_CHX_GCAL0_LSB);
return true;
}
else if (channel == 4)
{
writeRegisterMasked(REG_CH4_GCAL_MSB, MSB, 0xFFFF);
writeRegisterMasked(REG_CH4_GCAL_LSB, LSB << 8, REGMASK_CHX_GCAL0_LSB);
return true;
}
else if (channel == 5)
{
writeRegisterMasked(REG_CH5_GCAL_MSB, MSB, 0xFFFF);
writeRegisterMasked(REG_CH5_GCAL_LSB, LSB << 8, REGMASK_CHX_GCAL0_LSB);
return true;
}
else if (channel == 6)
{
writeRegisterMasked(REG_CH6_GCAL_MSB, MSB, 0xFFFF);
writeRegisterMasked(REG_CH6_GCAL_LSB, LSB << 8, REGMASK_CHX_GCAL0_LSB);
return true;
}
else if (channel == 7)
{
writeRegisterMasked(REG_CH7_GCAL_MSB, MSB, 0xFFFF);
writeRegisterMasked(REG_CH7_GCAL_LSB, LSB << 8, REGMASK_CHX_GCAL0_LSB);
return true;
}
return false;
}
bool ADS131M08Hub::isDataReady()
{
if (digitalRead(drdyPin) == HIGH)
{
return false;
}
return true;
}
uint16_t ADS131M08Hub::getId()
{
return readRegister(REG_ID);
}
uint16_t ADS131M08Hub::getModeReg()
{
return readRegister(REG_MODE);
}
uint16_t ADS131M08Hub::getClockReg()
{
return readRegister(REG_CLOCK);
}
uint16_t ADS131M08Hub::getCfgReg()
{
return readRegister(REG_CFG);
}
AdcOutput ADS131M08Hub::readAdcRaw(void)
{
uint8_t x = 0;
uint8_t x2 = 0;
uint8_t x3 = 0;
int32_t aux;
AdcOutput res;
digitalWrite(csPin, LOW);
delayMicroseconds(1);
x = spi.transfer(0x00);
x2 = spi.transfer(0x00);
spi.transfer(0x00);
this->resultRaw.status = ((x << 8) | x2);
for(int i = 0; i<8; i++)
{
x = spi.transfer(0x00);
x2 = spi.transfer(0x00);
x3 = spi.transfer(0x00);
aux = (((x << 16) | (x2 << 8) | x3) & 0x00FFFFFF);
if (aux > 0x7FFFFF)
{
this->resultRaw.ch[i].i = ((~(aux)&0x00FFFFFF) + 1) * -1;
}
else
{
this->resultRaw.ch[i].i = aux;
}
}
delayMicroseconds(1);
digitalWrite(csPin, HIGH);
return this->resultRaw;
}
float ADS131M08Hub::scaleResult(uint8_t num)
{
if( num >= 8) {
return 0.0;
}
return this->resultFloat.ch[num].f = (float)(this->resultRaw.ch[num].i * rawToVolts * this->fullScale.ch[num].f);
}
AdcOutput ADS131M08Hub::scaleResult(void)
{
// update status
this->resultFloat.status = this->resultRaw.status;
// Scale all channels
for(int i = 0; i<8; i++)
{
this->scaleResult(i);
}
return this->resultFloat;
}
AdcOutput ADS131M08Hub::readAdcFloat(void)
{
this->readAdcRaw();
return this->scaleResult();
}
// end of from tpcorrea
void ADS131M08Hub::dump_config()
{
ESP_LOGCONFIG(TAG, "ADS131M08:");

View File

@ -2,7 +2,7 @@ external_components:
- source:
type: local
path: components # Path relative to this YAML file
components: [ ads131m08, ads1115_int ]
components: [ ads1115_int, ads1115_pol ] #, ads131m08 ]
packages:
- !include common/wifi.yaml
@ -259,20 +259,27 @@ i2c:
scl: GPIO22
scan: true
id: bus_a
frequency: 10kHz
frequency: 400kHz
ads1115:
- address: 0x4A
id: ads1115_4A
continuous_mode: true
ads1115_pol:
- address: 0x49
id: ads1115_49
continuous_mode: true
ads1115_int:
- address: 0x48
id: ads1115_48
alert_rdy_pin: GPIO3
continuous_mode: true
ads1115:
- address: 0x49
id: ads1115_49
continuous_mode: true
- address: 0x4A
id: ads1115_4A
continuous_mode: true
alert_rdy_pin:
number: GPIO3
mode:
input: true
pullup: true
spi:
- id: spi_bus0
@ -1490,45 +1497,45 @@ binary_sensor:
//ESP_LOGI("solar", "Heating enabled? : %s", enabled ? "Yes" : "No");
return enabled;
ads131m08:
id: highres_adc
cs_pin: GPIO5
drdy_pin: GPIO10
reference_voltage: 1.25
#ads131m08:
# id: highres_adc
# cs_pin: GPIO5
# drdy_pin: GPIO10
# reference_voltage: 1.25
sensor:
- platform: ads131m08
ads131m08_id: highres_adc
channel: 0
name: "ADS Channel 0 Voltage"
- platform: ads131m08
ads131m08_id: highres_adc
channel: 1
name: "ADS Channel 1 Voltage"
- platform: ads131m08
ads131m08_id: highres_adc
channel: 2
name: "ADS Channel 2 Voltage"
- platform: ads131m08
ads131m08_id: highres_adc
channel: 3
name: "ADS Channel 3 Voltage"
- platform: ads131m08
ads131m08_id: highres_adc
channel: 4
name: "ADS Channel 4 Voltage"
- platform: ads131m08
ads131m08_id: highres_adc
channel: 5
name: "ADS Channel 5 Voltage"
- platform: ads131m08
ads131m08_id: highres_adc
channel: 6
name: "ADS Channel 6 Voltage"
- platform: ads131m08
ads131m08_id: highres_adc
channel: 7
name: "ADS Channel 7 Voltage"
# - platform: ads131m08
# ads131m08_id: highres_adc
# channel: 0
# name: "ADS Channel 0 Voltage"
# - platform: ads131m08
# ads131m08_id: highres_adc
# channel: 1
# name: "ADS Channel 1 Voltage"
# - platform: ads131m08
# ads131m08_id: highres_adc
# channel: 2
# name: "ADS Channel 2 Voltage"
# - platform: ads131m08
# ads131m08_id: highres_adc
# channel: 3
# name: "ADS Channel 3 Voltage"
# - platform: ads131m08
# ads131m08_id: highres_adc
# channel: 4
# name: "ADS Channel 4 Voltage"
# - platform: ads131m08
# ads131m08_id: highres_adc
# channel: 5
# name: "ADS Channel 5 Voltage"
# - platform: ads131m08
# ads131m08_id: highres_adc
# channel: 6
# name: "ADS Channel 6 Voltage"
# - platform: ads131m08
# ads131m08_id: highres_adc
# channel: 7
# name: "ADS Channel 7 Voltage"
- platform: debug
free:
@ -1542,7 +1549,7 @@ sensor:
# NB! Keep all ads1115 sample rates the same. Update intervals should be more than or equal to 1/sample_rate
# ads1115_48
- platform: ads1115
- platform: ads1115_pol
multiplexer: 'A2_A3'
gain: 2.048 # 4.096
ads1115_id: ads1115_49
@ -1555,25 +1562,25 @@ sensor:
unit_of_measurement: "A"
icon: "mdi:current"
update_interval: 8ms #5ms
filters:
# - offset: 0.0002
- lambda: return x * x;
- sliding_window_moving_average:
window_size: 1250 #1250 #5000
send_every: 208 #208 #416
send_first_at: 208 #208 #416
- lambda: return sqrt(x);
- multiply: 95 #88.44
- offset: 0.0 #-0.2
- lambda: |-
if(abs(x) < 0.1)
return 0.0;
return x;
#filters:
## - offset: 0.0002
# - lambda: return x * x;
# - sliding_window_moving_average:
# window_size: 1250 #1250 #5000
# send_every: 208 #208 #416
# send_first_at: 208 #208 #416
# - lambda: return sqrt(x);
# - multiply: 95 #88.44
# - offset: 0.0 #-0.2
# - lambda: |-
# if(abs(x) < 0.1)
# return 0.0;
# return x;
- platform: ads1115_int
multiplexer: 'A0_A1'
gain: 2.048 # 4.096
ads1115_int_id: ads1115_48
ads1115_id: ads1115_48
sample_rate: 860 # 475 #860
state_class: measurement
device_class: current
@ -1583,26 +1590,26 @@ sensor:
unit_of_measurement: "A"
icon: "mdi:current"
# update_interval: 8ms #5ms
filters:
# - offset: 0.0002
- lambda: return x * x;
- sliding_window_moving_average:
window_size: 1250 #1250 #5000
send_every: 208 #208 #416
send_first_at: 208 #208 #416
- lambda: return sqrt(x);
- multiply: 555 #95 #88.44
- offset: 0.0 #-0.2
- lambda: |-
if(abs(x) < 0.1)
return 0.0;
return x;
#filters:
## - offset: 0.0002
# - lambda: return x * x;
# - sliding_window_moving_average:
# window_size: 1250 #1250 #5000
# send_every: 208 #208 #416
# send_first_at: 208 #208 #416
# - lambda: return sqrt(x);
# - multiply: 555 #95 #88.44
# - offset: 0.0 #-0.2
# - lambda: |-
# if(abs(x) < 0.1)
# return 0.0;
# return x;
# ads1115_49
- platform: ads1115_int
multiplexer: 'A2_A3'
gain: 2.048 # 4.096
ads1115_int_id: ads1115_48
ads1115_id: ads1115_48
name: "ADC Geyser Current"
id: geyser_current
sample_rate: 860 #860
@ -1612,30 +1619,30 @@ sensor:
unit_of_measurement: "A"
icon: "mdi:current"
#update_interval: 8ms #5ms
filters:
- lambda: return x * x;
- sliding_window_moving_average:
window_size: 1250 #1250 #5000
send_every: 208 #208 #416
send_first_at: 208 #208 #416
- lambda: return sqrt(x);
- multiply: 555 #92.1 #91.1 #88.44
- offset: 0.0 #-0.2
- lambda: |-
if(abs(x) < 0.1)
return 0.0;
return x;
on_value_range:
- below: 5.0
then:
- lambda: |-
ESP_LOGI("geyser", "No geyser current detected. Geyser not heating.");
- above: 5.0
then:
- lambda: |-
ESP_LOGI("geyser", "Geyser current detected. Geyser was energised.");
#filters:
# - lambda: return x * x;
# - sliding_window_moving_average:
# window_size: 1250 #1250 #5000
# send_every: 208 #208 #416
# send_first_at: 208 #208 #416
# - lambda: return sqrt(x);
# - multiply: 555 #92.1 #91.1 #88.44
# - offset: 0.0 #-0.2
## - lambda: |-
## if(abs(x) < 0.1)
## return 0.0;
## return x;
##on_value_range:
# - below: 5.0
# then:
# - lambda: |-
# ESP_LOGI("geyser", "No geyser current detected. Geyser not heating.");
# - above: 5.0
# then:
# - lambda: |-
# ESP_LOGI("geyser", "Geyser current detected. Geyser was energised."); #
- platform: ads1115
- platform: ads1115_pol
multiplexer: A0_A1
gain: 2.048 # 4.096
ads1115_id: ads1115_49
@ -1651,20 +1658,20 @@ sensor:
unit_of_measurement: "A"
icon: "mdi:current"
update_interval: 8ms #5ms
filters:
# - offset: 0.0002
- lambda: return x * x;
- sliding_window_moving_average:
window_size: 1250 #1250 #5000
send_every: 208 #208 #416
send_first_at: 208 #208 #416
- lambda: return sqrt(x);
- multiply: 95.8 #88.44
- offset: 0.0 #-0.2
- lambda: |-
if(abs(x) < 0.1)
return 0.0;
return x;
#filters:
## - offset: 0.0002
# - lambda: return x * x;
# - sliding_window_moving_average:
# window_size: 1250 #1250 #5000
# send_every: 208 #208 #416
# send_first_at: 208 #208 #416
# - lambda: return sqrt(x);
# - multiply: 95.8 #88.44
# - offset: 0.0 #-0.2
# - lambda: |-
# if(abs(x) < 0.1)
# return 0.0;
# return x;
# mod end #######################
#
# ads1115_4A