Analog Pot Read for Digital Pot Control

Recently found this code that takes an analog read value and converts it to a signal for a digi pot control, basically an analog pot controlling the digi pot. I'm using a MCP41050 which is confirmed working with other code.

#include <SPI.h>

// include the SPI library:

const int slaveSelectPin = 10; // set pin 10 as the slave select for the digital pot:
float valueAnalogPot; // potValue divided by 8. 1024 values/128 7 bit resistor resolution:
int digiPotData; // value of analog pot scaled and cast into an integer:

void setup() {

  pinMode (slaveSelectPin, OUTPUT); // set the slaveSelectPin as an output:
  SPI.begin(); // initialize SPI:
  Serial.begin(9600); //serial communication to screen:

  
  digitalPotWrite(0, 0);
  delay(1);
  digitalPotWrite(16, 0);
  delay(1);

}


void loop() {

  int potValue = analogRead(A0); //store ADC of pot value 0-1023 in potValue:
  Serial.println(potValue); //print value between 0-1023 to screen int datatype:
  //delay(1); //stability

  valueAnalogPot = potValue / 8; // scaled to fit 7 bit pot:
  digiPotData = (int) valueAnalogPot; //cast to integer to be used as data byte for digipot

  int CommandByte = 0; // Pot 0 – Write Mode:

  // change the resistance on this digital pot 0 to scaled version of the analog pot:
  digitalPotWrite(CommandByte, digiPotData);
  delay(10);

}

int digitalPotWrite(int CommandByte, int value) {
  // take the SS pin low to select the chip:
  digitalWrite(slaveSelectPin, LOW);
  // send in the address and value via SPI:
  SPI.transfer(CommandByte);
  SPI.transfer(value);
  // take the SS pin high to de-select the chip:
  digitalWrite(slaveSelectPin, HIGH);
}

I can't get the digi pot wiper to move at all. It's stuck at about ~43k. This code was used for MCP4241. I've tried scaling the bit rate up to match the 41050 but no luck. What else could I be missing?

What is the value of valueAnalogPot?

Adopt this sequence to your MCP41050 digipot. See the data sheet Figure 5-2 for the right Command byte.

You can simply convert the 10 bit Arduino ADC value into the required 8 bit digipot value by potValue >> 2, no floats required.

valueAnalogPot = potValue / 8;
valueAnalogPot = (float)potvalue/8.0;

Tom... :grinning: :+1: :coffee: :australia:

How exactly would I go about writing the correct sequence? Fairly new to SPI. When I try to change the power up values in void setup, I can't get it to even go through a check during a power up.

When I do this, it gives me an error saying that 'potvalue' is not declared... I made it an integer and the error went away but I dont know if thats normal or not.

Right, a compiler is very picky about case, 'v' is not the same as 'V'.

Sorry my error.

valueAnalogPot = (float)potValue/8.0;

Tom... :grinning: :+1: :coffee: :australia:

Why not
potValue = potValue >> 2;
Do you know that the 8 Bit AVRs have no DIV instruction and must do all divisions in code? Even if the compiler can optimize a division, the float conversion and later back again costs time and possibly also program memory.

Yes I do, and bow to your greater wisdom.

Tom... :grinning: :+1: :coffee: :australia:

Sorry for the inappropriate address. Your expertise is well known and appreciated :slight_smile:

1 Like

My bad for this one it was just off by a capital letter. It was late :sweat_smile:

Even with these changes, its still not doing anything. The way the address it's being fed is definitely the issue by looking at the data sheet. I have no idea how to change it. I was looking at this example to maybe gain an understanding:

#include <SPI.h>
byte address = 0x11;
int CS= 10;
int i=0;

void setup()
{
  pinMode (CS, OUTPUT);
  SPI.begin();
  // adjust high and low resistance of potentiometer
  // adjust Highest Resistance .
   digitalPotWrite(0x00);
   delay(1000);

      // adjust  wiper in the  Mid point  .
   digitalPotWrite(0x80);
   delay(1000);

   // adjust Lowest Resistance .
   digitalPotWrite(0xFF);
   delay(1000);
}

void loop()
{
    for (i = 0; i <= 255; i++)
    {
      digitalPotWrite(i);
      delay(10);
    }
    delay(500);
    for (i = 255; i >= 0; i--)
    {
      digitalPotWrite(i);
      delay(10);
    }
}

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

Just a simple fade in fade out timed procedure. Maybe this is the one I should edit for external pot control? Thank y'all for the info so far.

Is the SPI mode and bit order (SPISettings) as required?

How do you check the functionality - circuit diagram?

Schematic:

oh whoops pin 3 on mcp411 goes to pin 11 on arduino my mistake!

Hi,
I completely missed this..

What other code?
Can you post a copy please?
I Googled;

mcp41050 arduino

And got this site;

Thanks.. Tom... :grinning: :+1: :coffee: :australia:

Oh yeah the code I used to test the digipot is in post #13. It’s a simple fader with no external control.

Initially you specified a 50k pot, but what's that MCP411?

How much current do you think will run through the LED?
How much current does the digipot support - 1mA! You may have killed it already...

Hi,

Have you tried the code in post#13 again to prove your digipot is still working?
Do you have a DMM to measure the resistance?

It sounds a simple job to add the external control Pot.
Can you please post a circuit diagram of your porject, include the pot and digipot as well ass power connections?
A hand drawn schematic will be fine.

Thanks... Tom... :grinning: :+1: :coffee: :australia: