Control Digital Potentiometer

Hi
Trying to get a digital potentiometer working with a Wemos D1 mini and esphome.
The potentiometer is a X9C103s but any examples I can find anywhere is for an arduino.
Is it a lost cause or can it work?

3 Likes

No such component exists for ESPHome. You would have to create your own:

https://esphome.io/custom/custom_component.html

Or, do you really need a digital pot or could you use a 0-5V signal (PWM)?

This thread may help Control digital potentiometer through home assistant via esphome?

Been looking at that but if I understand correctly my potentiometer doesn’t support SPI.

I’m trying to trick my NTC resistor in my heating system to believe it’s Colder / Wormer outside. So I don’t think so.

There is a library here, from this you should be able to make a custom component Arduino library for X9C103P digital potentiometer - Exhibition / Gallery - Arduino Forum

Ah ok. I also found this GitHub - GitMoDu/FastX9CXXX: Arduino library for digital potentiometers X9C102, X9C103, X9C104 and X9C504 but not sure on how to make it work in esphome. My hopes were that someone had made it work and documented how :smirk:
Guess i will just have to put in the hours :slight_smile:

I’ve tried to get something working by using the library suggested.
Not sure what I’m doing so have just tried to get something working by trial and error.
Any help you can give to help me forward would be appreciated.

Library:

/*
 * DigiPotX9Cxxx.h - Arduino library for managing digital potentiometers X9Cxxx (xxx = 102,103,104,503).
 * By Timo Fager, Jul 29, 2011.
 * Released to public domain.
 **/

#ifndef DigiPotX9Cxxx_h
#define DigiPotX9Cxxx_h

#include "Arduino.h"
#include "esphome.h"

#define DIGIPOT_UP   HIGH
#define DIGIPOT_DOWN LOW
#define DIGIPOT_MAX_AMOUNT 99
#define DIGIPOT_UNKNOWN 255

class DigiPot
{
 public:
  DigiPot(uint8_t incPin, uint8_t udPin, uint8_t csPin);
  void increase(uint8_t amount);
  void decrease(uint8_t amount);
  void change(uint8_t direction, uint8_t amount);
  void set(uint8_t value);
  uint8_t get();
  void reset();

 private:
  uint8_t _incPin;
  uint8_t _udPin;
  uint8_t _csPin;
  uint8_t _currentValue;
};

#endif

esphome config:

esphome:
  name: devdevice
  platform: ESP8266
  board: d1_mini
  includes:
    - custom_components/DigiPotX9Cxxx.h
# Enable logging
logger:

captive_portal:

custom_component:
- lambda: |-
    auto my_custom = new DigiPot(2,3,4);
    return {my_custom};

Install error:

/config/esphome/devdevice.yaml: In lambda function:
/config/esphome/devdevice.yaml:28:24: error: converting to 'std::vector<esphome::Component*>' from initializer list would use explicit constructor 'std::vector<_Tp, _Alloc>::vector(std::vector<_Tp, _Alloc>::size_type, const allocator_type&) [with _Tp = esphome::Component*; _Alloc = std::allocator<esphome::Component*>; std::vector<_Tp, _Alloc>::size_type = unsigned int; std::vector<_Tp, _Alloc>::allocator_type = std::allocator<esphome::Component*>]'
     return {my_custom};
                        ^
/config/esphome/devdevice.yaml:28:24: error: invalid conversion from 'DigiPot*' to 'std::vector<esphome::Component*>::size_type {aka unsigned int}' [-fpermissive]
In file included from /root/.platformio/packages/toolchain-xtensa/xtensa-lx106-elf/include/c++/4.8.2/vector:64:0,
                 from /root/.platformio/packages/toolchain-xtensa/xtensa-lx106-elf/include/c++/4.8.2/bits/random.h:34,
                 from /root/.platformio/packages/toolchain-xtensa/xtensa-lx106-elf/include/c++/4.8.2/random:50,
                 from /root/.platformio/packages/toolchain-xtensa/xtensa-lx106-elf/include/c++/4.8.2/bits/stl_algo.h:65,
                 from /root/.platformio/packages/toolchain-xtensa/xtensa-lx106-elf/include/c++/4.8.2/algorithm:62,
                 from /root/.platformio/packages/framework-arduinoespressif8266/cores/esp8266/Arduino.h:238,
                 from src/esphome/core/component.h:5,
                 from src/esphome/components/captive_portal/captive_portal.h:4,
                 from src/esphome.h:2,
                 from src/main.cpp:3:
/root/.platformio/packages/toolchain-xtensa/xtensa-lx106-elf/include/c++/4.8.2/bits/stl_vector.h:271:7: error:   initializing argument 1 of 'std::vector<_Tp, _Alloc>::vector(std::vector<_Tp, _Alloc>::size_type, const allocator_type&) [with _Tp = esphome::Component*; _Alloc = std::allocator<esphome::Component*>; std::vector<_Tp, _Alloc>::size_type = unsigned int; std::vector<_Tp, _Alloc>::allocator_type = std::allocator<esphome::Component*>]' [-fpermissive]
       vector(size_type __n, const allocator_type& __a = allocator_type())
       ^
*** [/data/devdevice/.pioenvs/devdevice/src/main.cpp.o] Error 1
1 Like

You might have more luck with this in the discord server for ESPHome rather than here.
Let me know how you get on as I would also like to use this for the same thermostat spoofing reasons, only I have less coding skills than you do… lol

@PatrikHansson have you managed to get it working? I’m also interested in this!

Hi, sorry for a late response. but no i haven’t had the time to set it up to test. Other things got in the way.

Please post if you get it sorted. I also need this.
Thanks!

Got some help from here. So i can control it manually now at least. Youst need to figure out how to automate it.

1 Like

@PatrikHansson it seems as if the code linked in your post isn’t longer available. Can you maybe post it here your self if you still have the code locally saved?
Thank you in advance :smiley:

Try digital_potentiometer.h · GitHub

1 Like

Thank you very much.

In principle, the code seems to work, but unfortunately it does not work properly for me.
If I now connect my X9C104 to the ESP8266 and a multimeter between RW and RL then I can set the resistance with the slider but the step size does not seem to fit. The values 40 ohm, 1k, 2k,… should be possible, right? But it starts with 30ohm and goes on with 3k, 6k, 9k … and at some point the steps become smaller and smaller.
Is the error here in the hardware or in the code?

I’m also a bit worried because in this video it is mentioned that the CS pin should not be toggled too often, but the linked code does this with every change of value?

All I can see is there are 100 steps. 0-100.