From 28f2582256d030f8b180d3de9178d8d7d685dd40 Mon Sep 17 00:00:00 2001 From: SenexCrenshaw <35600301+SenexCrenshaw@users.noreply.github.com> Date: Wed, 13 Jan 2021 13:33:19 -0500 Subject: [PATCH] Updated Mcp3008 to support reference_voltage and voltage_sampler::VoltageSampler (#1387) Co-authored-by: Jesse Hills <3060199+jesserockz@users.noreply.github.com> --- esphome/components/mcp3008/mcp3008.cpp | 30 +++++++++++++++++--------- esphome/components/mcp3008/mcp3008.h | 19 +++++++++------- esphome/components/mcp3008/sensor.py | 14 ++++++++---- esphome/components/spi/spi.h | 1 + tests/test1.yaml | 11 ++++++++++ 5 files changed, 53 insertions(+), 22 deletions(-) diff --git a/esphome/components/mcp3008/mcp3008.cpp b/esphome/components/mcp3008/mcp3008.cpp index a4d019ab8f..d09c2e4e92 100644 --- a/esphome/components/mcp3008/mcp3008.cpp +++ b/esphome/components/mcp3008/mcp3008.cpp @@ -15,19 +15,18 @@ void MCP3008::setup() { void MCP3008::dump_config() { ESP_LOGCONFIG(TAG, "MCP3008:"); - LOG_PIN(" CS Pin: ", this->cs_); + LOG_PIN(" CS Pin:", this->cs_); } -float MCP3008::read_data_(uint8_t pin) { - uint8_t data_msb = 0; - uint8_t data_lsb = 0; +float MCP3008::read_data(uint8_t pin) { + uint8_t data_msb, data_lsb = 0; uint8_t command = ((0x01 << 7) | // start bit ((pin & 0x07) << 4)); // channel number this->enable(); - this->transfer_byte(0x01); + data_msb = this->transfer_byte(command) & 0x03; data_lsb = this->transfer_byte(0x00); @@ -35,18 +34,29 @@ float MCP3008::read_data_(uint8_t pin) { int data = data_msb << 8 | data_lsb; - return data / 1024.0f; + return data / 1023.0f; } -MCP3008Sensor::MCP3008Sensor(MCP3008 *parent, std::string name, uint8_t pin) +MCP3008Sensor::MCP3008Sensor(MCP3008 *parent, std::string name, uint8_t pin, float reference_voltage) : PollingComponent(1000), parent_(parent), pin_(pin) { this->set_name(name); + this->reference_voltage_ = reference_voltage; } + +float MCP3008Sensor::get_setup_priority() const { return setup_priority::DATA; } + void MCP3008Sensor::setup() { LOG_SENSOR("", "Setting up MCP3008 Sensor '%s'...", this); } -void MCP3008Sensor::update() { - float value_v = this->parent_->read_data_(pin_); - this->publish_state(value_v); +void MCP3008Sensor::dump_config() { + ESP_LOGCONFIG(TAG, "MCP3008Sensor:"); + ESP_LOGCONFIG(TAG, " Pin: %u", this->pin_); + ESP_LOGCONFIG(TAG, " Reference Voltage: %.2fV", this->reference_voltage_); } +float MCP3008Sensor::sample() { + float value_v = this->parent_->read_data(pin_); + value_v = (value_v * this->reference_voltage_); + return value_v; +} +void MCP3008Sensor::update() { this->publish_state(this->sample()); } } // namespace mcp3008 } // namespace esphome diff --git a/esphome/components/mcp3008/mcp3008.h b/esphome/components/mcp3008/mcp3008.h index 594bdc4204..129f299a14 100644 --- a/esphome/components/mcp3008/mcp3008.h +++ b/esphome/components/mcp3008/mcp3008.h @@ -4,38 +4,41 @@ #include "esphome/core/esphal.h" #include "esphome/components/sensor/sensor.h" #include "esphome/components/spi/spi.h" +#include "esphome/components/voltage_sampler/voltage_sampler.h" namespace esphome { namespace mcp3008 { -class MCP3008Sensor; - class MCP3008 : public Component, public spi::SPIDevice { // At 3.3V 2MHz is too fast 1.35MHz is about right + spi::DATA_RATE_75KHZ> { // Running at the slowest max speed supported by the + // mcp3008. 2.7v = 75ksps public: MCP3008() = default; void setup() override; void dump_config() override; float get_setup_priority() const override; + float read_data(uint8_t pin); protected: - float read_data_(uint8_t pin); - - friend class MCP3008Sensor; }; -class MCP3008Sensor : public PollingComponent, public sensor::Sensor { +class MCP3008Sensor : public PollingComponent, public sensor::Sensor, public voltage_sampler::VoltageSampler { public: - MCP3008Sensor(MCP3008 *parent, std::string name, uint8_t pin); + MCP3008Sensor(MCP3008 *parent, std::string name, uint8_t pin, float reference_voltage); + void set_reference_voltage(float reference_voltage) { reference_voltage_ = reference_voltage; } void setup() override; void update() override; + void dump_config() override; + float get_setup_priority() const override; + float sample() override; protected: MCP3008 *parent_; uint8_t pin_; + float reference_voltage_; }; } // namespace mcp3008 diff --git a/esphome/components/mcp3008/sensor.py b/esphome/components/mcp3008/sensor.py index ec7df0429a..9248d51a42 100644 --- a/esphome/components/mcp3008/sensor.py +++ b/esphome/components/mcp3008/sensor.py @@ -1,23 +1,29 @@ import esphome.codegen as cg import esphome.config_validation as cv -from esphome.components import sensor +from esphome.components import sensor, voltage_sampler from esphome.const import CONF_ID, CONF_NUMBER, CONF_NAME from . import mcp3008_ns, MCP3008 +AUTO_LOAD = ['voltage_sampler'] + DEPENDENCIES = ['mcp3008'] -MCP3008Sensor = mcp3008_ns.class_('MCP3008Sensor', sensor.Sensor, cg.PollingComponent) - +MCP3008Sensor = mcp3008_ns.class_('MCP3008Sensor', sensor.Sensor, cg.PollingComponent, + voltage_sampler.VoltageSampler) +CONF_REFERENCE_VOLTAGE = 'reference_voltage' CONF_MCP3008_ID = 'mcp3008_id' CONFIG_SCHEMA = sensor.SENSOR_SCHEMA.extend({ cv.GenerateID(): cv.declare_id(MCP3008Sensor), cv.GenerateID(CONF_MCP3008_ID): cv.use_id(MCP3008), cv.Required(CONF_NUMBER): cv.int_, + cv.Optional(CONF_REFERENCE_VOLTAGE, default='3.3V'): cv.voltage, }).extend(cv.polling_component_schema('1s')) def to_code(config): parent = yield cg.get_variable(config[CONF_MCP3008_ID]) - var = cg.new_Pvariable(config[CONF_ID], parent, config[CONF_NAME], config[CONF_NUMBER]) + var = cg.new_Pvariable(config[CONF_ID], parent, config[CONF_NAME], + config[CONF_NUMBER], config[CONF_REFERENCE_VOLTAGE]) yield cg.register_component(var, config) + yield sensor.register_sensor(var, config) diff --git a/esphome/components/spi/spi.h b/esphome/components/spi/spi.h index 38ed9fb1d4..64364d70c9 100644 --- a/esphome/components/spi/spi.h +++ b/esphome/components/spi/spi.h @@ -50,6 +50,7 @@ enum SPIClockPhase { */ enum SPIDataRate : uint32_t { DATA_RATE_1KHZ = 1000, + DATA_RATE_75KHZ = 75000, DATA_RATE_200KHZ = 200000, DATA_RATE_1MHZ = 1000000, DATA_RATE_2MHZ = 2000000, diff --git a/tests/test1.yaml b/tests/test1.yaml index 4598049732..f2ebca05ab 100644 --- a/tests/test1.yaml +++ b/tests/test1.yaml @@ -197,6 +197,10 @@ wled: adalight: +mcp3008: + - id: 'mcp3008_hub' + cs_pin: GPIO12 + mcp23s08: - id: 'mcp23s08_hub' cs_pin: GPIO12 @@ -207,6 +211,7 @@ mcp23s17: cs_pin: GPIO12 deviceaddress: 1 + sensor: - platform: adc pin: A0 @@ -801,6 +806,12 @@ sensor: id: ph_ezo address: 99 unit_of_measurement: 'pH' + - platform: mcp3008 + update_interval: 5s + mcp3008_id: 'mcp3008_hub' + id: freezer_temp_source + reference_voltage: 3.19 + number: 0 esp32_touch: setup_mode: False