From 04d8593f38d6a412fd39ce3f8b39b8f6fc7bf65a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9my=20JOURDIN?= <2821990+JJK801@users.noreply.github.com> Date: Sat, 6 Feb 2021 16:18:48 +0100 Subject: [PATCH] Add MCP4725 DAC Component (#1418) * Add MCP4725 DAC * Fix lint * Fix lint * Fix lint * Lint & cleanup * Lint again * One more lint * add test Co-authored-by: Guillermo Ruffino --- esphome/components/mcp4725/__init__.py | 0 esphome/components/mcp4725/mcp4725.cpp | 38 ++++++++++++++++++++++++++ esphome/components/mcp4725/mcp4725.h | 23 ++++++++++++++++ esphome/components/mcp4725/output.py | 20 ++++++++++++++ tests/test1.yaml | 5 ++++ 5 files changed, 86 insertions(+) create mode 100644 esphome/components/mcp4725/__init__.py create mode 100644 esphome/components/mcp4725/mcp4725.cpp create mode 100644 esphome/components/mcp4725/mcp4725.h create mode 100644 esphome/components/mcp4725/output.py diff --git a/esphome/components/mcp4725/__init__.py b/esphome/components/mcp4725/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/esphome/components/mcp4725/mcp4725.cpp b/esphome/components/mcp4725/mcp4725.cpp new file mode 100644 index 0000000000..85028d2f39 --- /dev/null +++ b/esphome/components/mcp4725/mcp4725.cpp @@ -0,0 +1,38 @@ +#include "mcp4725.h" +#include "esphome/core/log.h" + +namespace esphome { +namespace mcp4725 { + +static const char *TAG = "mcp4725"; + +void MCP4725::setup() { + ESP_LOGCONFIG(TAG, "Setting up MCP4725 (0x%02X)...", this->address_); + + this->parent_->raw_begin_transmission(this->address_); + + if (!this->parent_->raw_end_transmission(this->address_)) { + this->error_code_ = COMMUNICATION_FAILED; + this->mark_failed(); + + return; + } +} + +void MCP4725::dump_config() { + LOG_I2C_DEVICE(this); + + if (this->error_code_ == COMMUNICATION_FAILED) { + ESP_LOGE(TAG, "Communication with MCP4725 failed!"); + } +} + +// https://learn.sparkfun.com/tutorials/mcp4725-digital-to-analog-converter-hookup-guide?_ga=2.176055202.1402343014.1607953301-893095255.1606753886 +void MCP4725::write_state(float state) { + const uint16_t value = (uint16_t) round(state * (pow(2, MCP4725_RES) - 1)); + + this->write_byte_16(64, value << 4); +} + +} // namespace mcp4725 +} // namespace esphome diff --git a/esphome/components/mcp4725/mcp4725.h b/esphome/components/mcp4725/mcp4725.h new file mode 100644 index 0000000000..d6fa52e323 --- /dev/null +++ b/esphome/components/mcp4725/mcp4725.h @@ -0,0 +1,23 @@ +#pragma once + +#include "esphome/components/output/float_output.h" +#include "esphome/core/component.h" +#include "esphome/components/i2c/i2c.h" + +static const uint8_t MCP4725_ADDR = 0x60; +static const uint8_t MCP4725_RES = 12; + +namespace esphome { +namespace mcp4725 { +class MCP4725 : public Component, public output::FloatOutput, public i2c::I2CDevice { + public: + void setup() override; + void dump_config() override; + void write_state(float state) override; + + protected: + enum ErrorCode { NONE = 0, COMMUNICATION_FAILED } error_code_{NONE}; +}; + +} // namespace mcp4725 +} // namespace esphome diff --git a/esphome/components/mcp4725/output.py b/esphome/components/mcp4725/output.py new file mode 100644 index 0000000000..f9593db1f5 --- /dev/null +++ b/esphome/components/mcp4725/output.py @@ -0,0 +1,20 @@ +import esphome.config_validation as cv +import esphome.codegen as cg +from esphome.components import output, i2c +from esphome.const import CONF_ID + +DEPENDENCIES = ['i2c'] + +mcp4725 = cg.esphome_ns.namespace('mcp4725') +MCP4725 = mcp4725.class_('MCP4725', output.FloatOutput, cg.Component, i2c.I2CDevice) + +CONFIG_SCHEMA = output.FLOAT_OUTPUT_SCHEMA.extend({ + cv.Required(CONF_ID): cv.declare_id(MCP4725), +}).extend(cv.COMPONENT_SCHEMA).extend(i2c.i2c_device_schema(0x60)) + + +def to_code(config): + var = cg.new_Pvariable(config[CONF_ID]) + yield cg.register_component(var, config) + yield i2c.register_i2c_device(var, config) + yield output.register_output(var, config) diff --git a/tests/test1.yaml b/tests/test1.yaml index e1088e0d5a..1893a32b30 100644 --- a/tests/test1.yaml +++ b/tests/test1.yaml @@ -1192,6 +1192,8 @@ output: - platform: esp32_dac pin: GPIO25 id: dac_output + - platform: mcp4725 + id: mcp4725_dac_output e131: @@ -1561,6 +1563,9 @@ switch: - output.set_level: id: dac_output level: !lambda 'return 0.5;' + - output.set_level: + id: mcp4725_dac_output + level: !lambda 'return 0.5;' turn_off_action: - switch.turn_on: living_room_lights_off restore_state: False