Digital Potentiometer with Particle Photon

I am a novice at programming and circuit design so I appreciate patience from anyone that reads this post. My project requires replacing a potentiometer on a DC motor controller with something controlled by a Photon. A friend suggested a digital potentiometer so I purchased this one from Amazon:

I am open to purchasing an alternative if it would simplify the project. I have been unable to find a library that works with this option nor am I skilled enough to port one made for different devices like Arduino. What is my best option?

@bradtreadwell1900 can you provide more details on the DC motor controller you plan on modifying (brand, voltage, motor type, etc.)? As for the potentiometer, what resistance does the one you want to replace have? Porting of the Arduino library for this chip is straight forward.

As for suitability, there is this board from Adafruit which uses I2C and has an easy library to port. In addition, the analog voltage range and the number of divider steps exceed those of the X9C103S.

Both the X9C103 and the DS3502 have 10K total resistance. This will need to match that of the pot you are replacing paying attention to the voltage across the pot. It must not exceed the ratings of the digital pots.

1 Like

I checked the potentiometer on the controller and it looks to be 0-100k. Here is a link to what I bought. Is there some way to wire my digital pot with some additional resistors to make it work or is there an easier option?

https://www.amazon.com/dp/B081XQLN46/ref=cm_sw_r_cp_apa_glt_fabc_X1GV9PHVYJNPKTPJ4Q5G?_encoding=UTF8&psc=1

@bradtreadwell1900, it’s difficult to know what the current rating on that potentiometer is and what voltage presents itself across it. Can you be more specific on the motor voltage and current that you intend to control?

Not sure on current but the voltage will be max of 24v.

Did a quick search and looks like current is around 20a.

Brad

@bradtreadwell1900, you still haven’t specified the motor you intend to control. Robotshop.com (or any robot parts supplier) has a variety of controllers, some with serial or I2C control.

There are 100K digital pot ICs available but not knowing the voltage being applied across the pot makes it difficult to specify.

Forgive my ignorance. This is for modifying a power wheels car. These appear to be the same motors I’ll be using.
https://www.amazon.com/dp/B075WZ21JW/ref=cm_sw_r_cp_apa_glt_fabc_3SAMTPPXY67TJRXWCX5K?_encoding=UTF8&psc=1

Brad

@bradtreadwell1900, so you want to control the motor with a Photon? You could try replacing the pot with this:

However, the voltage across the potentiometer cannot exceed 5.5v.

So that is essentially what I bought but has a range up to 100k? Given my inexperience, how would I program this with a photon?

Brad

@bradtreadwell1900, this unit is the same but 100K. The absolute max voltage across the pot is 10V. No guarantee that it will work on the PWM controller so you will need to test it.

As for controlling with the Photon, you will need to connect four GPIO to the board along with power (Vin) and GND. There is an article that provides an arduino library which could be easily adapted for the Photon:

I believe you can disconnect the existing pot on the PWM unit and wire in the digital pot instead.

This is good information. I hope to begin testing this week.

Brad

Have everything connected but can’t get a measurement on my meter that shows the value of the pot is changing. A friend helped me with some code from arduino.

My code

// This #include statement was automatically added by the Particle IDE.
#include "DigiPotX9Cxxx.h"

  /*  
Modified on Dec 12, 2020
Modified by MehranMaleki from Arduino Examples
https://electropeak.com/learn/
*/

/*                                                                                                                                     
 * For this example, connect your X9C104 (or the like) as follows:
 * 1 - INC - Arduino pin 2
 * 2 - U/D - Arduino pin 3
 * 3 - RH  - 5V
 * 4 - VSS - GND
 * 5 - RW  - Output: Arduino pin A0 for analogRead
 * 6 - RL  - GND
 * 7 - CS  - Arduino pin 4
 * 8 - VCC - 5V
 */


DigiPot pot(D2,D3,D4);

void setup() {
  //Serial.begin(9600);
}

void loop() {
  //Serial.println("Starting");  
  //float voltage;
  
  for (int i=0; i<100; i++) {
    pot.increase(1);
    //voltage = 5.0 * analogRead(A0)  / 1024;
    //Serial.println(voltage);
    delay(20);
  }
  
  
  for (int i=0; i<100; i++) {
    pot.decrease(1);
    //voltage = 5.0 * analogRead(A0) / 1024;
    //Serial.println(voltage);
    delay(20);
  }

}
 

CPP code

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

#include "Particle.h"
#include "DigiPotX9Cxxx.h"

DigiPot::DigiPot(uint8_t incPin, uint8_t udPin, uint8_t csPin) {
  _incPin = incPin;
  _udPin = udPin;
  _csPin = csPin;  
  _currentValue = DIGIPOT_UNKNOWN;

  pinMode(_incPin, OUTPUT);
  pinMode(_udPin, OUTPUT);
  pinMode(_csPin, OUTPUT);
  digitalWrite(_csPin, HIGH);

}

void DigiPot::reset() {
  // change down maximum number of times to ensure the value is 0
  decrease(DIGIPOT_MAX_AMOUNT);
  _currentValue = 0;
}

void DigiPot::set(uint8_t value) {
  value = constrain(value, 0, DIGIPOT_MAX_AMOUNT);
  if (_currentValue == DIGIPOT_UNKNOWN) reset();
  if (_currentValue > value) {
    change(DIGIPOT_DOWN, _currentValue-value);
  } else if (_currentValue < value) {
    change(DIGIPOT_UP, value-_currentValue);
  }
}

uint8_t DigiPot::get() {
  return _currentValue;
}

void DigiPot::increase(uint8_t amount) {
  amount = constrain(amount, 0, DIGIPOT_MAX_AMOUNT);
  change(DIGIPOT_UP, amount);
}

void DigiPot::decrease(uint8_t amount) {
  amount = constrain(amount, 0, DIGIPOT_MAX_AMOUNT);
  change(DIGIPOT_DOWN, amount);
}

void DigiPot::change(uint8_t direction, uint8_t amount) {
  amount = constrain(amount, 0, DIGIPOT_MAX_AMOUNT);
  digitalWrite(_udPin, direction);
  digitalWrite(_incPin, HIGH);
  digitalWrite(_csPin, LOW);

  for (uint8_t i=0; i<amount; i++) {
    digitalWrite(_incPin, LOW);
    delayMicroseconds(2);
    digitalWrite(_incPin, HIGH);
    delayMicroseconds(2);
    if (_currentValue != DIGIPOT_UNKNOWN) {
      _currentValue += (direction == DIGIPOT_UP ? 1 : -1);
      _currentValue = constrain(_currentValue, 0, DIGIPOT_MAX_AMOUNT);
    }
    
  }
  digitalWrite(_csPin, HIGH);
}


.h code

/*
 * 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 "Particle.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

I’ve tried measuring resistance between vw, vh, and vl of the chip. The same friend suggested connected vl and vh to gnd and vin respectively and measuring voltage between vin and vw. I get a constant reading that matches vin.

What am I missing?

Hi, I don't get it ? may be between VW and GND ? but the code should work.

Could you show us a good quality picture how did you wired up all ?
I mean D2 on Photon should go to INC on pot., D3 on photon to U/D on pot. and D4 on photon to CS pin on pot.
could you try to flash this code:

// This #include statement was automatically added by the Particle IDE.
#include "DigiPotX9Cxxx.h"
#include <Particle.h>

int VW_PIN = A0;
int set = 0;
int set_old = 0;
unsigned long interval = 0;

DigiPot pot(D2,D3,D4);

int set_pot(String message){
    
    int colonPos = message.indexOf(":") ;
    if (colonPos < 0) return -1;        
    String command = message.substring(0,colonPos) ;
    String argument = message.substring(colonPos+1) ;
    if (command.equals("set")){
       set  = argument.toInt();
       return set;
    }else{
      return -1;
      
    } 
}
 
void setup() {
    Particle.function("set_pot_val", set_pot);
}
 
void loop() {
 if (millis() - interval > 100) {
  interval = millis(); 
    if(set != set_old) {
        pot.set(set);
        int temp  =  map(analogRead(VW_PIN), 0, 4095, 0, 330); 
        Particle.publish("A0_val", String(temp), 60, PRIVATE);
        set_old = set;
    }
  }   
}

Then connect Vcc on pot. to Photon VIN as this pin can be used as output ( approximately 4.8V when photon is powered via USB), VH on pot. to Photon 3V3 pin GND and VL to Photon GND finally pot. VW to Photon A0
and use Particle function, which will be available from particle console and send a couple of commands eg:
set:35 then set:0 and then set:95 and see what is going to be published

Thanks for the help. This is appears to have been a bad digital pot. I replaced it with another today and it is working as expected. Excited to see this implemented in the final project.

Brad

This topic was automatically closed 182 days after the last reply. New replies are no longer allowed.