Arduino electronics hardware

Using a Digital Potentiometer (MCP41xxx)

pot_MCP41010Once I started using rotary encoders to provide a ‘modern’ user input experience, the elimination of panel mounted potentiometers for circuit settings and other adjustments was the next logical step. Panel mounted pots have a very different feel from the clicks of a rotary encoder, and potentiometers cannot easily be controlled by a microcontroller.

Digital Potentiometers perform the same functions as mechanical pots but can be automated. So how do they work?

What are Potentiometers?

A mechanical potentiometer is a three-terminal resistor with a sliding or rotating contact. It generally has three pins (A, Wiper, B or 1, Wiper, 2) and comes in many forms ranging from large panel  mount devices to small trimpots designed for PCB adjustments.


All pots are mechanically similar and consist of a resistive element, a sliding contact (wiper) that moves along the element making electrical contact along its length, electrical terminals at each end of the element (pins A and B), a mechanism that moves the wiper from one end to the other, and a housing to contain and protect the element and wiper.

Pots are generally referenced by form factor and overall resistance (the resistance between terminals A and B).

The device can form an adjustable voltage divider if all three terminals are used or, if only two terminals are used (one end and the wiper), it acts as a variable resistor or rheostat.


What is a Digital Potentiometer?

Simply put, a digital potentiometer (aka digipot) is electronic hardware that performs the same functions as analog potentiometers, but they have no moving parts.

The digipot is a mixed signal device. The analog portion is the three terminal ‘analog’ pot. The digital portion contains the interface, control, and registers associated with the device management. The digital signals and settings control the resistance between terminals and wiper.

There are may brands and types of digipots available. One example is the MicroChip MCP 41xxx family of devices, where xxx is the size of the digipot resistance (eg, 010 for 10kΩ, 100 for 100kΩ).

pot_MCP_pinsThe MCP41xxx are implemented as an IC package with one potentiometer per package (a ‘single channel’),  an SPI interface to the microcontroller and three ‘pot’ terminals (A, Wiper and B) that behave just like their mechanical counterparts when used within the manufacturers specifications.

Controlling a Digipot

Pot control is through the SPI interface writing to the 8-bit pot control register. As the pot setting is one byte in size (0-255), these pots can only be set in increments of 1/255th of the full scale resistance of the pot. For example, a 10kΩ pot can be set in increments of 10,000/255 ohms per step (or 39.2Ω/step). In practice this is not a major limitation when using a digipot.

The code below is an example of how this is done. In this simple example the pot setting register is ramped through the 255 steps with a pause in between each so that the multimeter readings could be observed.

MCP41xxx Digital Pot Control
This example controls an MCP41xxx digital potentiometer.
PBn - One side of potentiometer
PWn - Pot wiper
PAn - Other side of potentiometer
The MCP41xxx is SPI-compatible. The hardware is managed by 
sending two bytes:
BYTE 1 - is a command byte (NOP, WRITE, SHUTDOWN)
BYTE 2 - is the data byte (new setpoint value 0-255). 
The MCP IC circuit:
* PB0 No connection
* PA0 Connect to multimeter to measure resistance
* PW0 Connect to multimeter to measure resistance
* CS - to digital pin 10 (SS pin)
* SDI - to digital pin 11 (MOSI pin)
* CLK - to digital pin 13 (SCK pin)
#include <SPI.h>

// Define the MCP41100 OP command bits (only one POT)
// Note: command byte format xxCCxxPP, CC command, PP pot number (01 if selected) 
#define MCP_NOP 0b00000000
#define MCP_WRITE 0b00010001
#define MCP_SHTDWN 0b00100001

// Define the slave select for the digital pot
const int ssMCPin = 10;

#define WAIT_DELAY 1000

void SPIWrite(uint8_t cmd, uint8_t data, uint8_t ssPin)
// SPI write the command and data to the MCP IC connected to the ssPin
  SPI.beginTransaction(SPISettings(14000000, MSBFIRST, SPI_MODE0));
  digitalWrite(ssPin, LOW); // SS pin low to select chip
  SPI.transfer(cmd);        // Send command code
  SPI.transfer(data);       // Send associated value
  digitalWrite(ssPin, HIGH);// SS pin high to de-select chip

void setup() 
  pinMode (ssMCPin, OUTPUT);
  digitalWrite(ssMCPin, HIGH);
  Serial.println(F("[MCP Digital Pot Test]"));

void loop() 
  // step through the range of the digital pot
  for (int i = 0; i < 256; i++) 
    SPIWrite(MCP_WRITE, i, ssMCPin);
  delay (WAIT_DELAY*5);



MicroChip Technology Inc., 2003, “MCP41xxx/MCP42xxx Single/Dual Potentiometer with SPI™ Interface”, Product Datasheet

MicroChip Technology Inc, 2001, “AN691 Optimizing Digital Potentiometer Circuits to Reduce Absolute and Temperature Variations”Application Note

Semiconductor Components Industries LLC, July 2013, “AND8414/D Everything You Wanted to Know About Digital Potentiometer (POT)”, Rev 1, Application Note

2 replies on “Using a Digital Potentiometer (MCP41xxx)”

Hello! thanks for posting the code. but i am interested in using the digital pot to replace the analog pot on the buck/boost converters found cheap on aliexpress or on ebay like this one:

Difficulty with the digital pot is that it can’t withstand more than 5V. In these converters, analog pots see entire OUT voltage like 25V. I don’t know how to replace the analog pot with the digital one in this application.

If it can be replaced, we can use arduino to control output voltage, with appropriate feedback.


Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s