In this project we are going to interface a digital potentiometer with arduino. In this demonstration potentiometer MCP41010 is used but you can use any digital potentiometer of MC41** series.
By Ankit Negi
INTRODUCTION TO MC41010
Digital potentiometers are just like any analog potentiometer with three terminals with only one difference. Whereas in analog one you have to manually change the wiper position, In case of digital potentiometer wiper position is set according to the signal given to potentiometer using any microcontroller or microprocessor.
FIG. MC41010 IC pinout
MC41010 is an 8 pin dual in line package IC. Just like any analog potentiometer this IC comes in 5k, 10k, 50k, and 100k. In this circuit 10k potentiometer is used
MC4131 have following 8 terminals:
Pin no. Pin Name Little description
1 CS This pin is used to select the slave or peripheral connected to arduino. If this is
Low then MC41010 is selected and if this is high then MC41010 is deselected.
2 SCLK Shared/Serial Clock, arduino gives clock for initialization of data transfer from
Arduino to IC and vice versa.
3 SDI/SDO Serial data is transferred between arduino and IC through this pin
4 VSS Ground terminal of arduino is connected to this pin of IC.
5 PA0 This is one terminal of the potentiometer.
6 PW0 This terminal is wiper terminal of the potentiometer( to change resistance)
7 PB0 This is another terminal of the potentiometer.
8 VCC Power to IC is given through this pin.
This IC contains only one potentiometer. Some IC have at most two potentiometer inbuilt. This
The value of the resistance between wiper and any other terminal is changed in 256 steps, from 0 to 255. Since we are using a 10k resistor value of resistor is changed in steps of:
10k/256= 39 ohms per step between 0 and 255
COMPONENTS
We need following components for this project.
1. ARDUINO
2. MC41010 IC
3. 220 OHM RESISTOR
4. LED
5. CONNECTING WIRES
Make connections as shown in fig.
1. Connect cs pin to digital pin 10.
2. Connect SCK pin to digital pin 13.
3. Connect SDI/SDO pin to digital pin 11.
4. VSS to ground pin of arduino
5. PA0 to 5v pin of arduino
6. PB0 to ground of arduino
7. PWO to analog pin A0 of arduino.
8. VCC to 5 v of arduino.
PROGRAM CODE 1
This code prints the voltage change across wiper terminal and ground on Serial Monitor of Arduino IDE.
#include <SPI.h>
int CS = 10 ; // initialising variable CS pin as pin 10 of arduino
int x ; // initialising variable x
float Voltage ; // initialising variable voltage
int I ; // this is the variable which changes in steps and hence changes resistance accordingly.
void setup()
{
pinMode (CS , OUTPUT) ; // initialising 10 pin as output pin
pinMode (A0, INPUT) ; // initialising pin A0 as input pin
SPI.begin() ; // this begins Serial peripheral interfece
Serial.begin(9600) ; // this begins serial communications between arduino and ic.
}
void loop()
{
for (int i = 0; i <= 255; i++)// this run loops from 0 to 255 step with 10 ms delay between each step
{
digitalPotWrite(i) ; // this writes level i to ic which determines resistance of ic
delay(10);
x = analogRead(A0) ; // read analog values from pin A0
Voltage = (x * 5.0 )/ 1024.0;// this converts the analog value to corresponding voltage level
Serial.print("Level i = " ) ; // these serial commands print value of i or level and voltage across wiper
Serial.print(i) ; // and gnd on Serial monitor of arduino IDE
Serial.print("\t Voltage = ") ;
Serial.println(Voltage,3) ;
}
delay(500);
for (int i = 255; i >= 0; i--) // this run loops from 255 to 0 step with 10 ms delay between each step
{
digitalPotWrite(i) ;
delay(10) ;
x = analogRead(A0) ;
Voltage = (x * 5.0 )/ 1024.0 ; // this converts the analog value to corresponding voltage level
Serial.print("Level i = " ) ; // these serial commands print value of i or level and voltage across wiper
Serial.print(i); // and gnd on Serial monitor of arduino IDE
Serial.print("\t Voltage = ");
Serial.println(Voltage,3);
}
}
int digitalPotWrite(int value) // this block is explained in coding section
{
digitalWrite(CS, LOW);
SPI.transfer(B00010001);
SPI.transfer(value);
digitalWrite(CS, HIGH);
EXPLAINING CODE 1:
To use digital potentiometer with arduino you need to include SPI library first which is provided in arduino IDE itself. Just call the library with this command:
#include <SPI.h>
In void setup, pins are assigned as output or input. And commands to begin SPI and serial communication between arduino and ic is also given which are:
SPI.begin(); and Serial.begin(9600);
In void loop, for loop is used to change the resistance of digital pot in total 256 steps. First from 0 to 255 and then again back to 0 with 10 milliseconds delay between each step:
for (int i = 0; i <= 255; i++) and for (int i = 255; i >= 0; i--)
digitalPotWrite(i) function writes theese value to change resistance at particular address of ic.
Resistance between wiper and end terminal can be calculated using these formulae:
R1= 10k*(256-level)/256 + Rw
And
R2= 10k*level/256 + Rw
Here R1= resistance between wiper and one terminal
R2= resistance between wiper and other terminal
Level = step at a particular instant ( variable “I” used in for loop)
Rw= resistance of wiper terminal ( can be found in datasheet of the ic )
Using digitalPotWrite() function the digital potentiometer chip is selected by assigning LOW voltage to CS pin. Now as the ic is selected, an address must be called on which data will be written. In the last portion of code :
SPI.transfer(B00010001);
Address is called which is B00010001 to select the wiper terminal of the ic on which data will be written. And hence for loop’s value i.e, i is written to change the resistance.
CIRCUIT WORKING:
As long as value of i keeps changing input to A0 pin of arduino also keeps changing between 0 and 1023. This happens because wiper terminal is directly connected to A0 pin, and other terminal of potentiometer are connected to 5volt and ground respectively. Now when resistance changes so do voltage across it which is directly taken by arduino as input and thus we get a voltage value on serial monitor for a particular value of resistance.
SIMULATION 1:
These are some simulation pictures for this circuit at various values of i:
Now just connect an led in series with 220ohm resistor to wiper terminal of IC as shown in figure.
CODE 2:
#include <SPI.h>
int CS = 10;
int x;
float Voltage;
int i;
void setup()
{
pinMode (CS , OUTPUT);
pinMode (A0, INPUT);
SPI.begin();// this begins Serial peripheral interfece
}
void loop()
{
for (int i = 0; i <= 255; i++)// this run loops from 0 to 255 step with 10 ms delay between each step
{
digitalPotWrite(i);// this writes level i to ic which determines resistance of ic
delay(10);
}
delay(500);
for (int i = 255; i >= 0; i--)// this run loops from 255 to 0 step with 10 ms delay between each step
{
digitalPotWrite(i);
delay(10);
}
}
int digitalPotWrite(int value)// this block is explained in coding section
{
digitalWrite(CS, LOW);
SPI.transfer(B00010001);
SPI.transfer(value);
digitalWrite(CS, HIGH);
}
EXPLAINING CODE 2:
This code is similar to code 1 except that there are no serial commands in this code. So no values will be printed on serial monitor.
WORKING EXPLANATION
Since led is connected between wiper terminal and ground as resistance changes so do voltage across led. And hence as resistance across which led is connected rises from 0ohm to maximum so do brightness of led. Which again slowly fade away due to decrease in resistance from maximum to 0v.
Simulation2
Simulation3