From aca56fcdcc0840d1ec590a6b36592b15079c58cb Mon Sep 17 00:00:00 2001 From: WitchKing <31471327+xvil@users.noreply.github.com> Date: Thu, 26 Jan 2023 05:20:45 +0100 Subject: [PATCH] Added support for ADS1015 (#4281) Co-authored-by: vilrexa-at-412611259294 --- esphome/components/ads1115/ads1115.cpp | 36 +++++++++++++++++++++----- esphome/components/ads1115/ads1115.h | 9 ++++++- esphome/components/ads1115/sensor.py | 11 ++++++++ 3 files changed, 48 insertions(+), 8 deletions(-) diff --git a/esphome/components/ads1115/ads1115.cpp b/esphome/components/ads1115/ads1115.cpp index beb379db93..c3f3c00c63 100644 --- a/esphome/components/ads1115/ads1115.cpp +++ b/esphome/components/ads1115/ads1115.cpp @@ -9,7 +9,7 @@ static const char *const TAG = "ads1115"; static const uint8_t ADS1115_REGISTER_CONVERSION = 0x00; static const uint8_t ADS1115_REGISTER_CONFIG = 0x01; -static const uint8_t ADS1115_DATA_RATE_860_SPS = 0b111; +static const uint8_t ADS1115_DATA_RATE_860_SPS = 0b111; // 3300_SPS for ADS1015 void ADS1115Component::setup() { ESP_LOGCONFIG(TAG, "Setting up ADS1115..."); @@ -18,6 +18,9 @@ void ADS1115Component::setup() { this->mark_failed(); return; } + + ESP_LOGCONFIG(TAG, "Configuring ADS1115..."); + uint16_t config = 0; // Clear single-shot bit // 0b0xxxxxxxxxxxxxxx @@ -77,6 +80,7 @@ void ADS1115Component::dump_config() { LOG_SENSOR(" ", "Sensor", sensor); ESP_LOGCONFIG(TAG, " Multiplexer: %u", sensor->get_multiplexer()); ESP_LOGCONFIG(TAG, " Gain: %u", sensor->get_gain()); + ESP_LOGCONFIG(TAG, " Resolution: %u", sensor->get_resolution()); } } float ADS1115Component::request_measurement(ADS1115Sensor *sensor) { @@ -127,27 +131,45 @@ float ADS1115Component::request_measurement(ADS1115Sensor *sensor) { this->status_set_warning(); return NAN; } + + if (sensor->get_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(raw_conversion); float millivolts; + float divider = (sensor->get_resolution() == ADS1115_16_BITS) ? 32768.0f : 2048.0f; switch (sensor->get_gain()) { case ADS1115_GAIN_6P144: - millivolts = signed_conversion * 0.187500f; + millivolts = (signed_conversion * 6144) / divider; break; case ADS1115_GAIN_4P096: - millivolts = signed_conversion * 0.125000f; + millivolts = (signed_conversion * 4096) / divider; break; case ADS1115_GAIN_2P048: - millivolts = signed_conversion * 0.062500f; + millivolts = (signed_conversion * 2048) / divider; break; case ADS1115_GAIN_1P024: - millivolts = signed_conversion * 0.031250f; + millivolts = (signed_conversion * 1024) / divider; break; case ADS1115_GAIN_0P512: - millivolts = signed_conversion * 0.015625f; + millivolts = (signed_conversion * 512) / divider; break; case ADS1115_GAIN_0P256: - millivolts = signed_conversion * 0.007813f; + millivolts = (signed_conversion * 256) / divider; break; default: millivolts = NAN; diff --git a/esphome/components/ads1115/ads1115.h b/esphome/components/ads1115/ads1115.h index 17d5a910d8..0b8bfb339b 100644 --- a/esphome/components/ads1115/ads1115.h +++ b/esphome/components/ads1115/ads1115.h @@ -30,6 +30,11 @@ enum ADS1115Gain { ADS1115_GAIN_0P256 = 0b101, }; +enum ADS1115Resolution { + ADS1115_16_BITS = 16, + ADS1015_12_BITS = 12, +}; + class ADS1115Sensor; class ADS1115Component : public Component, public i2c::I2CDevice { @@ -58,15 +63,17 @@ class ADS1115Sensor : public sensor::Sensor, public PollingComponent, public vol void update() override; void set_multiplexer(ADS1115Multiplexer multiplexer) { multiplexer_ = multiplexer; } void set_gain(ADS1115Gain gain) { gain_ = gain; } - + void set_resolution(ADS1115Resolution resolution) { resolution_ = resolution; } float sample() override; uint8_t get_multiplexer() const { return multiplexer_; } uint8_t get_gain() const { return gain_; } + uint8_t get_resolution() const { return resolution_; } protected: ADS1115Component *parent_; ADS1115Multiplexer multiplexer_; ADS1115Gain gain_; + ADS1115Resolution resolution_; }; } // namespace ads1115 diff --git a/esphome/components/ads1115/sensor.py b/esphome/components/ads1115/sensor.py index 190e641ca3..f0d894e2af 100644 --- a/esphome/components/ads1115/sensor.py +++ b/esphome/components/ads1115/sensor.py @@ -4,6 +4,7 @@ from esphome.components import sensor, voltage_sampler from esphome.const import ( CONF_GAIN, CONF_MULTIPLEXER, + CONF_RESOLUTION, DEVICE_CLASS_VOLTAGE, STATE_CLASS_MEASUREMENT, UNIT_VOLT, @@ -35,6 +36,12 @@ GAIN = { "0.256": ADS1115Gain.ADS1115_GAIN_0P256, } +ADS1115Resolution = ads1115_ns.enum("ADS1115Resolution") +RESOLUTION = { + "16_BITS": ADS1115Resolution.ADS1115_16_BITS, + "12_BITS": ADS1115Resolution.ADS1015_12_BITS, +} + def validate_gain(value): if isinstance(value, float): @@ -63,6 +70,9 @@ CONFIG_SCHEMA = ( cv.GenerateID(CONF_ADS1115_ID): cv.use_id(ADS1115Component), cv.Required(CONF_MULTIPLEXER): cv.enum(MUX, upper=True, space="_"), cv.Required(CONF_GAIN): validate_gain, + cv.Optional(CONF_RESOLUTION, default="16_BITS"): cv.enum( + RESOLUTION, upper=True, space="_" + ), } ) .extend(cv.polling_component_schema("60s")) @@ -77,5 +87,6 @@ async def to_code(config): 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(paren.register_sensor(var))