Can't write to MCP4261 potentiometer

Hello, I’m trying to control a digital potentiometer MCP4261 (Datasheet). I tried three approaches below, none of which is working. Wiring is at the end.
Since I can’t just measure the resistance with a multimeter when it’s powered, I’m instead measuring the current through the multimeter: wiper (pin 6) to 150ohm Resistor to multimeter (current) to ground. Since I’m feeding +5V, I was expecting that this would vary from about 1 mA to 34 mA, but I can’t get it to budge from 2mA (which matches the default wiper-to-Ground resistance of about 2.6 kOhm) with any of these codes.

(1) Using the MCP4261 Library from https://playground.arduino.cc/Code/Mcp4261 and its example code.
I can run the code fine, but the pot resistance doesn’t change.
I added some serial debugging lines, and I’m finding that the code stops executing or hangs as soon as it tries to write the wiper resistance, i.e., in my setup function I have:

  Serial.println("Setup\n");
  Mcp4261.wiper0_pos(0); 
  Serial.println("write to Wiper0");
  Mcp4261.wiper1_pos(0); 
  Serial.println("write to Wiper1");

And the serial just reads:

Setup

If I comment the Mcp4261.wiperx_pos(x) lines, the serial prints as expected until I get to the next write-to-wiper command:

Setup

write to Wiper0
write to Wiper1

Scale to 100%


(2) I also tried modifying the DigitalPotControl example that comes with the SPI library. This is for an AD5206, so I think maybe I didn’t properly switch the addressing? But I’m learning as I go here so I’m not sure.

/*
  Digital Pot Control

  This example controls an Analog Devices AD5206 digital potentiometer.
  The AD5206 has 6 potentiometer channels. Each channel's pins are labeled
  A - connect this to voltage
  W - this is the pot's wiper, which changes when you set it
  B - connect this to ground.

 The AD5206 is SPI-compatible,and to command it, you send two bytes,
 one with the channel number (0 - 5) and one with the resistance value for the
 channel (0 - 255).

 The circuit:
  * All A pins  of AD5206 connected to +5V
  * All B pins of AD5206 connected to ground
  * An LED and a 220-ohm resisor in series connected from each W pin to ground
  * CS - to digital pin 10  (SS pin)
  * SDI - to digital pin 11 (MOSI pin)
  * CLK - to digital pin 13 (SCK pin)

 created 10 Aug 2010
 by Tom Igoe

 Thanks to Heather Dewey-Hagborg for the original tutorial, 2005

*/


// inslude the SPI library:
#include <SPI.h>


// set pin 10 as the slave select for the digital pot:
const int slaveSelectPin = 10;

void setup() {
  // set the slaveSelectPin as an output:
  pinMode(slaveSelectPin, OUTPUT);
  // initialize SPI:
  SPI.begin();
}

void loop() {
  // go through the six channels of the digital pot:
  for (int channel = 0; channel < 6; channel++) {
    // change the resistance on this channel from min to max:
    for (int level = 0; level < 255; level++) {
      digitalPotWrite(channel, level);
      delay(10);
    }
    // wait a second at the top:
    delay(100);
    // change the resistance on this channel from max to min:
    for (int level = 0; level < 255; level++) {
      digitalPotWrite(channel, 255 - level);
      delay(10);
    }
  }

}

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

(3) Finally I tried writing a simple SPI control from what I’d read in the documentation and a few other examples including this one for a MCP4251, and ended up with the code below.

In table 7-2 in the documenation it says that the SPI string for “write data to volatile wiper 1” is
‘0001 00nn nnnn nnnn’
But I got an error when I tried to write a 16-bit command:
‘B0001010000000000’ was not declared in this scope
So I tried splitting it into two bytes like I’d seen in the other examples:
SPI.transfer(B00010100); //the command byte
SPI.transfer(B00000000); // The data byte
which compiled fine but didn’t seem to change the wiper value.

#include <SPI.h>  // include the SPI library
const int slaveSelectPin = 10;
 
void setup() {
  pinMode (slaveSelectPin, OUTPUT); // slaveSelectPin is an output  
  SPI.begin();    // initialize SPI:
}
 
void loop() {
  // take the SS pin low to select the chip:
  digitalWrite(slaveSelectPin,LOW);
  SPI.transfer(B00010100); //the command byte
  SPI.transfer(B00000000); // The data byte
  digitalWrite(slaveSelectPin,HIGH); 
  delay(10);

}

Wiring setup of MCP4261 pins:

  • 1 CS to Arduino 10
  • 2 SCK to Arduino 13
  • 3 SDI to Arduion 11
  • 4 Vss to Ground
  • 5 P1B to Ground
  • 6 P1W to 150ohm Resistor to multimeter (current) to ground
  • 7 P1A to +5V
  • 8 P0A to +5V
  • 9 P0W unconnected
  • 10 P0B to Ground
  • 11 WP to +5V
  • 12 SHDN to +5V (or in Method 2, to digital pin 7 and a 4.7k pull down resistor)
  • 13 SDO to Arduino 12
  • 14 Vdd to +5V

Thanks for any help getting this working. I’m really feeling stuck on this.

MCP4261_Method1.ino (3.53 KB)

MCP4261_Method2.ino (727 Bytes)

MCP4261_Method3.ino (485 Bytes)