Control digital potentiometer through home assistant via esphome?

Hi!

I currently use esphome for various sensors like temperature and energy meters where esphome publish data to home assistant via its API. But how can I do it the other way around?

I would like a float entity in home assistant that, when it is updated, the state (temperature) is sent to esphome and is used to set a specific resistance for a MCP4161 (digital potentiometer) connected via SPI to a esp8266 (wemos d1 mini).
Can this even be done in esphome or should I write an arduino sketch that get the entity state via MQTT?

BR/Nicklas

2 Likes
1 Like

Thanks! Can’t understand why I missed the home assistant sensor.

Seems to be working fine. I can set the state in HA and I see that the value is read by the esp.

Now I guess I have to write a custom spi device https://esphome.io/custom/spi.html
Should it be included with:

esphome:
  includes:
    - my_custom_spi_device.h

How can I use the state value in the custom spi code?

I have a arduino sketch like this. I can set any value between 1-255 and it works.

#include <SPI.h>

byte address = 0x00;
int CS= D8;

void setup()
{
pinMode (CS, OUTPUT);
SPI.begin();
digitalPotWrite(150)
}

void loop()
{

}

int digitalPotWrite(int value)
{
digitalWrite(CS, LOW);
SPI.transfer(address);
SPI.transfer(value);
digitalWrite(CS, HIGH);
}

How can I rewrite this for esphome and replace the value “150” with the value from home assistant?
I know that I have to recalculate the temperature to a proper wiper value between 1-255 but first I need to find out how to get the custom spi component to work.

BR/Nicklas

Trying to compile but always get:

src/my_custom_spi_device.h: In member function 'virtual void MyCustomComponent::setup()':
src/my_custom_spi_device.h:11:5: error: 'SPI' was not declared in this scope
SPI.pins(SCK_PIN, MISO_PIN, MOSI_PIN, CS_PIN);
^

I thought the spi.h was included with esphome.h ?

have you ever found a solution for this? i need it too

3 Likes

I’m also trying to do something like this but i have no idea how to do…

i resolved creatin a custom float output component

1 Like

Great, I’m quite unexperienced, i tried unsuccesfully to understand how to do… Could you share some code and help me?

#include "esphome.h"
using namespace esphome;

class ad8400 : public FloatOutput, public Component {
 public:
  void setup() override {
    // This will be called by App.setup()
    pinMode(D8, OUTPUT);
    SPI.begin();
  }

  void write_state(float state) override {
    // state is the amount this output should be on, from 0.0 to 1.0
    // we need to convert it to an integer first
    int value = state * 255;
    ESP_LOGD("custom",  "Valore: %d", value);
    ad8400write(value);
  }
 protected:
  void ad8400write(int value) {
    digitalWrite(D8, LOW);
    SPI.transfer(0);
    SPI.transfer(value);
    digitalWrite(D8, HIGH);
  }
};

My component was a ad8400 but it doesnt matter as is a spi component. You have to pass value with .setvalue() in range from 0.0 to 1.0 then inside the componet it is converted back to 1 to 255

Hi,
How do you add this code in esphome? Can it be included where the yaml code is?
Thanks,
Nicklas

I tried to add it with an include in the yaml file:

esphome:
includes:
- my_custom_spi_device.h

But I get the following errors when trying to compile:

In file included from src/main.cpp:12:0:
src/my_custom_spi_device.h:4:34: error: expected class-name before ‘,’ token
class ad8400 : public FloatOutput, public Component {
^
src/my_custom_spi_device.h:12:8: error: ‘void ad8400::write_state(float)’ marked override, but does not override
void write_state(float state) override {
^
src/my_custom_spi_device.h: In member function ‘virtual void ad8400::setup()’:
src/my_custom_spi_device.h:9:5: error: ‘SPI’ was not declared in this scope
SPI.begin();
^
src/my_custom_spi_device.h: In member function ‘void ad8400::ad8400write(int)’:
src/my_custom_spi_device.h:22:5: error: ‘SPI’ was not declared in this scope
SPI.transfer(0);
^
*** [/data/testnode/.pioenvs/testnode/src/main.cpp.o] Error 1

I’m doing this:
https://esphome.io/components/output/custom.html?highlight=custom%20output

But I don’t know how to get an entity in home assistant with a state that is used as value in the class written in C++.

This does not create an entity in HA:

output:
- platform: custom
  type: float
  lambda: |-
    auto my_custom_float_output = new MyCustomFloatOutput();
    App.register_component(my_custom_float_output);
    return {my_custom_float_output};

  outputs:
    id: custom_float

Can someone with more esphome/c++ knowledge give me a hint?
Thanks!

No one?

It is now compiling without error I just need to figure out how to get the entity in HA. The state of this entity should be used as value in MyCustomFloatOutput

Did you ever get this working? I need to do something similar with MCP41xxx

1 Like

Would also like to know if anyone has ever gotten something like this working. Would like to control thermostat by inputting a resistance.

I also would like to set a 150kΩ digital potentiometer with esp8266 to work in Home Assistant. This subject should be very popular. It is very useful for a lot of things.

I’m very interested in learning how to do this. I have several of the Xaiomi temperature sensors, and would like to figure out a way to use their average and input that into my T6 Honeywell thermostat.

I am not sure how that relates to digital potentiometers?

Various Xiaomi temp sensors are dealt with here. Xiaomi Mijia BLE Sensors — ESPHome

Here’s the connection. I have multiple Xiaomi thermometers around the house. Each of them connect via BLE to an ESP32 that sends their updates via Wi-Fi to home assistant. I can easily average those temperature reading, or get the min/max. I also have a T6 Honeywell thermostat that is integrated with HA. Now the T6 has an input for a remote temperature sensor (thermistor), but it has to be wired in. Since I already have all of these Xiaomi sensors around the house, I thought it would be nice to use their average as an input to the Thermostat rather than just having it use one point of measurement at the thermostat. My idea was to use another ESP32 with a digipot to set the resistance that correlates to the average of the Xiaomi temperatures. The digipot would then be wired into the thermostat emulating a thermistor. Make sense?

1 Like