Before changing ads1115_int to directly publish from ISR
This commit is contained in:
parent
76fd7fa443
commit
a105cf0748
@ -9,11 +9,11 @@ CONF_ALERT_RDY_PIN = "alert_rdy_pin"
|
|||||||
DEPENDENCIES = ["i2c"]
|
DEPENDENCIES = ["i2c"]
|
||||||
MULTI_CONF = True
|
MULTI_CONF = True
|
||||||
|
|
||||||
ads1115_ns = cg.esphome_ns.namespace("ads1115_int")
|
ads1115_int_ns = cg.esphome_ns.namespace("ads1115_int")
|
||||||
ADS1115Component = ads1115_ns.class_("ADS1115Component", cg.Component, i2c.I2CDevice)
|
ADS1115Component = ads1115_int_ns.class_("ADS1115Component", cg.Component, i2c.I2CDevice)
|
||||||
|
|
||||||
CONF_CONTINUOUS_MODE = "continuous_mode"
|
CONF_CONTINUOUS_MODE = "continuous_mode"
|
||||||
CONF_ADS1115_ID = "ads1115_int_id"
|
CONF_ADS1115_ID = "ads1115_id"
|
||||||
|
|
||||||
CONFIG_SCHEMA = (
|
CONFIG_SCHEMA = (
|
||||||
cv.Schema(
|
cv.Schema(
|
||||||
|
|||||||
@ -66,12 +66,12 @@ void ADS1115Component::setup() {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this->prev_config_ = config;
|
this->prev_config_ = config;
|
||||||
if(!this->set_alert_ready_mode()) {
|
if(!this->set_data_ready_mode()) {
|
||||||
this->mark_failed();
|
this->mark_failed();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
bool ADS1115Component::set_alert_ready_mode()
|
bool ADS1115Component::set_data_ready_mode()
|
||||||
{
|
{
|
||||||
uint16_t config = this->prev_config_;
|
uint16_t config = this->prev_config_;
|
||||||
// Set comparator que mode - assert after one conversion
|
// Set comparator que mode - assert after one conversion
|
||||||
@ -107,7 +107,7 @@ bool ADS1115Component::is_data_ready(ADS1115Multiplexer multiplexer)
|
|||||||
return false;
|
return false;
|
||||||
return this->data_ready_[index];
|
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);
|
int index = static_cast<int>(multiplexer);
|
||||||
if(index < 0 || index >= 8)
|
if(index < 0 || index >= 8)
|
||||||
@ -116,7 +116,7 @@ void ADS1115Component::clear_alert_ready(ADS1115Multiplexer multiplexer)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// call only when data_ready_ is true
|
// 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_;
|
uint16_t config = this->prev_config_;
|
||||||
// Multiplexer
|
// Multiplexer
|
||||||
@ -139,7 +139,7 @@ double ADS1115Component::read_data(ADS1115Multiplexer multiplexer, ADS1115Gain g
|
|||||||
config |= 0b1000000000000000;
|
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);
|
//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
|
// write config if in single-shot mode or config has changed
|
||||||
if (!this->continuous_mode_ || this->prev_config_ != config) {
|
if (!this->continuous_mode_ || this->prev_config_ != config) {
|
||||||
@ -148,6 +148,9 @@ double ADS1115Component::read_data(ADS1115Multiplexer multiplexer, ADS1115Gain g
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
this->prev_config_ = config;
|
this->prev_config_ = config;
|
||||||
|
//
|
||||||
|
// removed delay
|
||||||
|
//
|
||||||
if (!this->continuous_mode_) {
|
if (!this->continuous_mode_) {
|
||||||
uint32_t start = millis();
|
uint32_t start = millis();
|
||||||
// wait for conversion to complete
|
// 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);
|
auto signed_conversion = static_cast<int16_t>(raw_conversion);
|
||||||
|
raw_value = signed_conversion;
|
||||||
double millivolts;
|
double millivolts;
|
||||||
double divider = (resolution == ADS1115_16_BITS) ? 32768.0f : 2048.0f;
|
double divider = (resolution == ADS1115_16_BITS) ? 32768.0f : 2048.0f;
|
||||||
switch (gain) {
|
switch (gain) {
|
||||||
|
|||||||
@ -53,11 +53,11 @@ class ADS1115Component : public Component, public i2c::I2CDevice {
|
|||||||
void set_continuous_mode(bool continuous_mode) { continuous_mode_ = continuous_mode; }
|
void set_continuous_mode(bool continuous_mode) { continuous_mode_ = continuous_mode; }
|
||||||
|
|
||||||
// Method to read converted data
|
// 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; }
|
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);
|
bool is_data_ready(ADS1115Multiplexer multiplexer);
|
||||||
void clear_alert_ready(ADS1115Multiplexer multiplexer);
|
void clear_data_ready(ADS1115Multiplexer multiplexer);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
uint16_t prev_config_{0};
|
uint16_t prev_config_{0};
|
||||||
|
|||||||
@ -12,12 +12,12 @@ from esphome.const import (
|
|||||||
UNIT_VOLT,
|
UNIT_VOLT,
|
||||||
)
|
)
|
||||||
|
|
||||||
from .. import CONF_ADS1115_ID, ADS1115Component, ads1115_ns
|
from .. import CONF_ADS1115_ID, ADS1115Component, ads1115_int_ns
|
||||||
|
|
||||||
AUTO_LOAD = ["voltage_sampler"]
|
AUTO_LOAD = ["voltage_sampler"]
|
||||||
DEPENDENCIES = ["ads1115"]
|
DEPENDENCIES = ["ads1115_int"]
|
||||||
|
|
||||||
ADS1115Multiplexer = ads1115_ns.enum("ADS1115Multiplexer")
|
ADS1115Multiplexer = ads1115_int_ns.enum("ADS1115Multiplexer")
|
||||||
MUX = {
|
MUX = {
|
||||||
"A0_A1": ADS1115Multiplexer.ADS1115_MULTIPLEXER_P0_N1,
|
"A0_A1": ADS1115Multiplexer.ADS1115_MULTIPLEXER_P0_N1,
|
||||||
"A0_A3": ADS1115Multiplexer.ADS1115_MULTIPLEXER_P0_N3,
|
"A0_A3": ADS1115Multiplexer.ADS1115_MULTIPLEXER_P0_N3,
|
||||||
@ -29,7 +29,7 @@ MUX = {
|
|||||||
"A3_GND": ADS1115Multiplexer.ADS1115_MULTIPLEXER_P3_NG,
|
"A3_GND": ADS1115Multiplexer.ADS1115_MULTIPLEXER_P3_NG,
|
||||||
}
|
}
|
||||||
|
|
||||||
ADS1115Gain = ads1115_ns.enum("ADS1115Gain")
|
ADS1115Gain = ads1115_int_ns.enum("ADS1115Gain")
|
||||||
GAIN = {
|
GAIN = {
|
||||||
"6.144": ADS1115Gain.ADS1115_GAIN_6P144,
|
"6.144": ADS1115Gain.ADS1115_GAIN_6P144,
|
||||||
"4.096": ADS1115Gain.ADS1115_GAIN_4P096,
|
"4.096": ADS1115Gain.ADS1115_GAIN_4P096,
|
||||||
@ -39,13 +39,13 @@ GAIN = {
|
|||||||
"0.256": ADS1115Gain.ADS1115_GAIN_0P256,
|
"0.256": ADS1115Gain.ADS1115_GAIN_0P256,
|
||||||
}
|
}
|
||||||
|
|
||||||
ADS1115Resolution = ads1115_ns.enum("ADS1115Resolution")
|
ADS1115Resolution = ads1115_int_ns.enum("ADS1115Resolution")
|
||||||
RESOLUTION = {
|
RESOLUTION = {
|
||||||
"16_BITS": ADS1115Resolution.ADS1115_16_BITS,
|
"16_BITS": ADS1115Resolution.ADS1115_16_BITS,
|
||||||
"12_BITS": ADS1115Resolution.ADS1015_12_BITS,
|
"12_BITS": ADS1115Resolution.ADS1015_12_BITS,
|
||||||
}
|
}
|
||||||
|
|
||||||
ADS1115Samplerate = ads1115_ns.enum("ADS1115Samplerate")
|
ADS1115Samplerate = ads1115_int_ns.enum("ADS1115Samplerate")
|
||||||
SAMPLERATE = {
|
SAMPLERATE = {
|
||||||
"8": ADS1115Samplerate.ADS1115_8SPS,
|
"8": ADS1115Samplerate.ADS1115_8SPS,
|
||||||
"16": ADS1115Samplerate.ADS1115_16SPS,
|
"16": ADS1115Samplerate.ADS1115_16SPS,
|
||||||
@ -57,7 +57,7 @@ SAMPLERATE = {
|
|||||||
"860": ADS1115Samplerate.ADS1115_860SPS,
|
"860": ADS1115Samplerate.ADS1115_860SPS,
|
||||||
}
|
}
|
||||||
|
|
||||||
ADS1115Sensor = ads1115_ns.class_(
|
ADS1115Sensor = ads1115_int_ns.class_(
|
||||||
"ADS1115Sensor", sensor.Sensor, cg.Component, voltage_sampler.VoltageSampler
|
"ADS1115Sensor", sensor.Sensor, cg.Component, voltage_sampler.VoltageSampler
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@ -9,9 +9,14 @@ static const char *const TAG = "ads1115_int.sensor";
|
|||||||
|
|
||||||
void ADS1115Sensor::loop() {
|
void ADS1115Sensor::loop() {
|
||||||
if (parent_->is_data_ready(this->multiplexer_)) {
|
if (parent_->is_data_ready(this->multiplexer_)) {
|
||||||
this->parent_->clear_alert_ready(this->multiplexer_);
|
this->parent_->clear_data_ready(this->multiplexer_);
|
||||||
double v = this->parent_->read_data(this->multiplexer_, this->gain_, this->resolution_, this->samplerate_);
|
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 (!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);
|
ESP_LOGD(TAG, "'%s': Got Voltage=%fV", this->get_name().c_str(), v);
|
||||||
this->publish_state(v);
|
this->publish_state(v);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -30,7 +30,7 @@ class ADS1115Sensor : public sensor::Sensor,
|
|||||||
ADS1115Gain gain_;
|
ADS1115Gain gain_;
|
||||||
ADS1115Resolution resolution_;
|
ADS1115Resolution resolution_;
|
||||||
ADS1115Samplerate samplerate_;
|
ADS1115Samplerate samplerate_;
|
||||||
|
uint64_t count_{0};
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace ads1115
|
} // namespace ads1115
|
||||||
|
|||||||
32
components/ads1115_pol/__init__.py
Normal file
32
components/ads1115_pol/__init__.py
Normal 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]))
|
||||||
223
components/ads1115_pol/ads1115_pol.cpp
Normal file
223
components/ads1115_pol/ads1115_pol.cpp
Normal 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
|
||||||
64
components/ads1115_pol/ads1115_pol.h
Normal file
64
components/ads1115_pol/ads1115_pol.h
Normal 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
|
||||||
98
components/ads1115_pol/sensor/__init__.py
Normal file
98
components/ads1115_pol/sensor/__init__.py
Normal 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]))
|
||||||
36
components/ads1115_pol/sensor/ads1115_pol_sensor.cpp
Normal file
36
components/ads1115_pol/sensor/ads1115_pol_sensor.cpp
Normal 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
|
||||||
38
components/ads1115_pol/sensor/ads1115_pol_sensor.h
Normal file
38
components/ads1115_pol/sensor/ads1115_pol_sensor.h
Normal 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
|
||||||
@ -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
|
/* adcRegisterWrite
|
||||||
Short function that writes one ADC register at a time.
|
Short function that writes one ADC register at a time.
|
||||||
Blocks return until SPI is idle.
|
Blocks return until SPI is idle.
|
||||||
@ -114,37 +137,10 @@ bool ADS131M08Hub::adcRegisterWrite(unsigned short addrMask, unsigned short data
|
|||||||
return true;
|
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 ************************
|
// ********************** end of from datasheet ************************
|
||||||
|
|
||||||
/*
|
/*
|
||||||
void ADS131M08::read_all_channels()
|
void ADS131M08Hub::read_all_channels()
|
||||||
{
|
{
|
||||||
// Send RDATA command or read data directly
|
// Send RDATA command or read data directly
|
||||||
SPI.transfer(0x12); // RDATA command
|
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()
|
void ADS131M08Hub::dump_config()
|
||||||
{
|
{
|
||||||
ESP_LOGCONFIG(TAG, "ADS131M08:");
|
ESP_LOGCONFIG(TAG, "ADS131M08:");
|
||||||
|
|||||||
239
sthome-ut8.yaml
239
sthome-ut8.yaml
@ -2,7 +2,7 @@ external_components:
|
|||||||
- source:
|
- source:
|
||||||
type: local
|
type: local
|
||||||
path: components # Path relative to this YAML file
|
path: components # Path relative to this YAML file
|
||||||
components: [ ads131m08, ads1115_int ]
|
components: [ ads1115_int, ads1115_pol ] #, ads131m08 ]
|
||||||
|
|
||||||
packages:
|
packages:
|
||||||
- !include common/wifi.yaml
|
- !include common/wifi.yaml
|
||||||
@ -259,21 +259,28 @@ i2c:
|
|||||||
scl: GPIO22
|
scl: GPIO22
|
||||||
scan: true
|
scan: true
|
||||||
id: bus_a
|
id: bus_a
|
||||||
frequency: 10kHz
|
frequency: 400kHz
|
||||||
|
|
||||||
ads1115_int:
|
|
||||||
- address: 0x48
|
|
||||||
id: ads1115_48
|
|
||||||
alert_rdy_pin: GPIO3
|
|
||||||
continuous_mode: true
|
|
||||||
ads1115:
|
ads1115:
|
||||||
- address: 0x49
|
|
||||||
id: ads1115_49
|
|
||||||
continuous_mode: true
|
|
||||||
- address: 0x4A
|
- address: 0x4A
|
||||||
id: ads1115_4A
|
id: ads1115_4A
|
||||||
continuous_mode: true
|
continuous_mode: true
|
||||||
|
|
||||||
|
ads1115_pol:
|
||||||
|
- address: 0x49
|
||||||
|
id: ads1115_49
|
||||||
|
continuous_mode: true
|
||||||
|
|
||||||
|
ads1115_int:
|
||||||
|
- address: 0x48
|
||||||
|
id: ads1115_48
|
||||||
|
continuous_mode: true
|
||||||
|
alert_rdy_pin:
|
||||||
|
number: GPIO3
|
||||||
|
mode:
|
||||||
|
input: true
|
||||||
|
pullup: true
|
||||||
|
|
||||||
spi:
|
spi:
|
||||||
- id: spi_bus0
|
- id: spi_bus0
|
||||||
clk_pin: GPIO18
|
clk_pin: GPIO18
|
||||||
@ -1490,45 +1497,45 @@ binary_sensor:
|
|||||||
//ESP_LOGI("solar", "Heating enabled? : %s", enabled ? "Yes" : "No");
|
//ESP_LOGI("solar", "Heating enabled? : %s", enabled ? "Yes" : "No");
|
||||||
return enabled;
|
return enabled;
|
||||||
|
|
||||||
ads131m08:
|
#ads131m08:
|
||||||
id: highres_adc
|
# id: highres_adc
|
||||||
cs_pin: GPIO5
|
# cs_pin: GPIO5
|
||||||
drdy_pin: GPIO10
|
# drdy_pin: GPIO10
|
||||||
reference_voltage: 1.25
|
# reference_voltage: 1.25
|
||||||
|
|
||||||
sensor:
|
sensor:
|
||||||
- platform: ads131m08
|
# - platform: ads131m08
|
||||||
ads131m08_id: highres_adc
|
# ads131m08_id: highres_adc
|
||||||
channel: 0
|
# channel: 0
|
||||||
name: "ADS Channel 0 Voltage"
|
# name: "ADS Channel 0 Voltage"
|
||||||
- platform: ads131m08
|
# - platform: ads131m08
|
||||||
ads131m08_id: highres_adc
|
# ads131m08_id: highres_adc
|
||||||
channel: 1
|
# channel: 1
|
||||||
name: "ADS Channel 1 Voltage"
|
# name: "ADS Channel 1 Voltage"
|
||||||
- platform: ads131m08
|
# - platform: ads131m08
|
||||||
ads131m08_id: highres_adc
|
# ads131m08_id: highres_adc
|
||||||
channel: 2
|
# channel: 2
|
||||||
name: "ADS Channel 2 Voltage"
|
# name: "ADS Channel 2 Voltage"
|
||||||
- platform: ads131m08
|
# - platform: ads131m08
|
||||||
ads131m08_id: highres_adc
|
# ads131m08_id: highres_adc
|
||||||
channel: 3
|
# channel: 3
|
||||||
name: "ADS Channel 3 Voltage"
|
# name: "ADS Channel 3 Voltage"
|
||||||
- platform: ads131m08
|
# - platform: ads131m08
|
||||||
ads131m08_id: highres_adc
|
# ads131m08_id: highres_adc
|
||||||
channel: 4
|
# channel: 4
|
||||||
name: "ADS Channel 4 Voltage"
|
# name: "ADS Channel 4 Voltage"
|
||||||
- platform: ads131m08
|
# - platform: ads131m08
|
||||||
ads131m08_id: highres_adc
|
# ads131m08_id: highres_adc
|
||||||
channel: 5
|
# channel: 5
|
||||||
name: "ADS Channel 5 Voltage"
|
# name: "ADS Channel 5 Voltage"
|
||||||
- platform: ads131m08
|
# - platform: ads131m08
|
||||||
ads131m08_id: highres_adc
|
# ads131m08_id: highres_adc
|
||||||
channel: 6
|
# channel: 6
|
||||||
name: "ADS Channel 6 Voltage"
|
# name: "ADS Channel 6 Voltage"
|
||||||
- platform: ads131m08
|
# - platform: ads131m08
|
||||||
ads131m08_id: highres_adc
|
# ads131m08_id: highres_adc
|
||||||
channel: 7
|
# channel: 7
|
||||||
name: "ADS Channel 7 Voltage"
|
# name: "ADS Channel 7 Voltage"
|
||||||
|
|
||||||
- platform: debug
|
- platform: debug
|
||||||
free:
|
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
|
# NB! Keep all ads1115 sample rates the same. Update intervals should be more than or equal to 1/sample_rate
|
||||||
# ads1115_48
|
# ads1115_48
|
||||||
- platform: ads1115
|
- platform: ads1115_pol
|
||||||
multiplexer: 'A2_A3'
|
multiplexer: 'A2_A3'
|
||||||
gain: 2.048 # 4.096
|
gain: 2.048 # 4.096
|
||||||
ads1115_id: ads1115_49
|
ads1115_id: ads1115_49
|
||||||
@ -1555,25 +1562,25 @@ sensor:
|
|||||||
unit_of_measurement: "A"
|
unit_of_measurement: "A"
|
||||||
icon: "mdi:current"
|
icon: "mdi:current"
|
||||||
update_interval: 8ms #5ms
|
update_interval: 8ms #5ms
|
||||||
filters:
|
#filters:
|
||||||
# - offset: 0.0002
|
## - offset: 0.0002
|
||||||
- lambda: return x * x;
|
# - lambda: return x * x;
|
||||||
- sliding_window_moving_average:
|
# - sliding_window_moving_average:
|
||||||
window_size: 1250 #1250 #5000
|
# window_size: 1250 #1250 #5000
|
||||||
send_every: 208 #208 #416
|
# send_every: 208 #208 #416
|
||||||
send_first_at: 208 #208 #416
|
# send_first_at: 208 #208 #416
|
||||||
- lambda: return sqrt(x);
|
# - lambda: return sqrt(x);
|
||||||
- multiply: 95 #88.44
|
# - multiply: 95 #88.44
|
||||||
- offset: 0.0 #-0.2
|
# - offset: 0.0 #-0.2
|
||||||
- lambda: |-
|
# - lambda: |-
|
||||||
if(abs(x) < 0.1)
|
# if(abs(x) < 0.1)
|
||||||
return 0.0;
|
# return 0.0;
|
||||||
return x;
|
# return x;
|
||||||
|
|
||||||
- platform: ads1115_int
|
- platform: ads1115_int
|
||||||
multiplexer: 'A0_A1'
|
multiplexer: 'A0_A1'
|
||||||
gain: 2.048 # 4.096
|
gain: 2.048 # 4.096
|
||||||
ads1115_int_id: ads1115_48
|
ads1115_id: ads1115_48
|
||||||
sample_rate: 860 # 475 #860
|
sample_rate: 860 # 475 #860
|
||||||
state_class: measurement
|
state_class: measurement
|
||||||
device_class: current
|
device_class: current
|
||||||
@ -1583,26 +1590,26 @@ sensor:
|
|||||||
unit_of_measurement: "A"
|
unit_of_measurement: "A"
|
||||||
icon: "mdi:current"
|
icon: "mdi:current"
|
||||||
# update_interval: 8ms #5ms
|
# update_interval: 8ms #5ms
|
||||||
filters:
|
#filters:
|
||||||
# - offset: 0.0002
|
## - offset: 0.0002
|
||||||
- lambda: return x * x;
|
# - lambda: return x * x;
|
||||||
- sliding_window_moving_average:
|
# - sliding_window_moving_average:
|
||||||
window_size: 1250 #1250 #5000
|
# window_size: 1250 #1250 #5000
|
||||||
send_every: 208 #208 #416
|
# send_every: 208 #208 #416
|
||||||
send_first_at: 208 #208 #416
|
# send_first_at: 208 #208 #416
|
||||||
- lambda: return sqrt(x);
|
# - lambda: return sqrt(x);
|
||||||
- multiply: 555 #95 #88.44
|
# - multiply: 555 #95 #88.44
|
||||||
- offset: 0.0 #-0.2
|
# - offset: 0.0 #-0.2
|
||||||
- lambda: |-
|
# - lambda: |-
|
||||||
if(abs(x) < 0.1)
|
# if(abs(x) < 0.1)
|
||||||
return 0.0;
|
# return 0.0;
|
||||||
return x;
|
# return x;
|
||||||
|
|
||||||
# ads1115_49
|
# ads1115_49
|
||||||
- platform: ads1115_int
|
- platform: ads1115_int
|
||||||
multiplexer: 'A2_A3'
|
multiplexer: 'A2_A3'
|
||||||
gain: 2.048 # 4.096
|
gain: 2.048 # 4.096
|
||||||
ads1115_int_id: ads1115_48
|
ads1115_id: ads1115_48
|
||||||
name: "ADC Geyser Current"
|
name: "ADC Geyser Current"
|
||||||
id: geyser_current
|
id: geyser_current
|
||||||
sample_rate: 860 #860
|
sample_rate: 860 #860
|
||||||
@ -1612,30 +1619,30 @@ sensor:
|
|||||||
unit_of_measurement: "A"
|
unit_of_measurement: "A"
|
||||||
icon: "mdi:current"
|
icon: "mdi:current"
|
||||||
#update_interval: 8ms #5ms
|
#update_interval: 8ms #5ms
|
||||||
filters:
|
#filters:
|
||||||
- lambda: return x * x;
|
# - lambda: return x * x;
|
||||||
- sliding_window_moving_average:
|
# - sliding_window_moving_average:
|
||||||
window_size: 1250 #1250 #5000
|
# window_size: 1250 #1250 #5000
|
||||||
send_every: 208 #208 #416
|
# send_every: 208 #208 #416
|
||||||
send_first_at: 208 #208 #416
|
# send_first_at: 208 #208 #416
|
||||||
- lambda: return sqrt(x);
|
# - lambda: return sqrt(x);
|
||||||
- multiply: 555 #92.1 #91.1 #88.44
|
# - multiply: 555 #92.1 #91.1 #88.44
|
||||||
- offset: 0.0 #-0.2
|
# - offset: 0.0 #-0.2
|
||||||
- lambda: |-
|
## - lambda: |-
|
||||||
if(abs(x) < 0.1)
|
## if(abs(x) < 0.1)
|
||||||
return 0.0;
|
## return 0.0;
|
||||||
return x;
|
## return x;
|
||||||
on_value_range:
|
##on_value_range:
|
||||||
- below: 5.0
|
# - below: 5.0
|
||||||
then:
|
# then:
|
||||||
- lambda: |-
|
# - lambda: |-
|
||||||
ESP_LOGI("geyser", "No geyser current detected. Geyser not heating.");
|
# ESP_LOGI("geyser", "No geyser current detected. Geyser not heating.");
|
||||||
- above: 5.0
|
# - above: 5.0
|
||||||
then:
|
# then:
|
||||||
- lambda: |-
|
# - lambda: |-
|
||||||
ESP_LOGI("geyser", "Geyser current detected. Geyser was energised.");
|
# ESP_LOGI("geyser", "Geyser current detected. Geyser was energised."); #
|
||||||
|
|
||||||
- platform: ads1115
|
- platform: ads1115_pol
|
||||||
multiplexer: A0_A1
|
multiplexer: A0_A1
|
||||||
gain: 2.048 # 4.096
|
gain: 2.048 # 4.096
|
||||||
ads1115_id: ads1115_49
|
ads1115_id: ads1115_49
|
||||||
@ -1651,20 +1658,20 @@ sensor:
|
|||||||
unit_of_measurement: "A"
|
unit_of_measurement: "A"
|
||||||
icon: "mdi:current"
|
icon: "mdi:current"
|
||||||
update_interval: 8ms #5ms
|
update_interval: 8ms #5ms
|
||||||
filters:
|
#filters:
|
||||||
# - offset: 0.0002
|
## - offset: 0.0002
|
||||||
- lambda: return x * x;
|
# - lambda: return x * x;
|
||||||
- sliding_window_moving_average:
|
# - sliding_window_moving_average:
|
||||||
window_size: 1250 #1250 #5000
|
# window_size: 1250 #1250 #5000
|
||||||
send_every: 208 #208 #416
|
# send_every: 208 #208 #416
|
||||||
send_first_at: 208 #208 #416
|
# send_first_at: 208 #208 #416
|
||||||
- lambda: return sqrt(x);
|
# - lambda: return sqrt(x);
|
||||||
- multiply: 95.8 #88.44
|
# - multiply: 95.8 #88.44
|
||||||
- offset: 0.0 #-0.2
|
# - offset: 0.0 #-0.2
|
||||||
- lambda: |-
|
# - lambda: |-
|
||||||
if(abs(x) < 0.1)
|
# if(abs(x) < 0.1)
|
||||||
return 0.0;
|
# return 0.0;
|
||||||
return x;
|
# return x;
|
||||||
# mod end #######################
|
# mod end #######################
|
||||||
#
|
#
|
||||||
# ads1115_4A
|
# ads1115_4A
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user