I have recently purchased a MCP41010 Digital Potentiometer that I want to control using a Arduino Pro Mini. It is controlled via the SPI protocol. To start with, I made a test script, as below:
//Test Code to find/control a digital potentiometer (MCP41010)
//Uses SPI communication
//
//Based on 'DigitalPotControl', the SPI library demo code
//
// Potentiometer connections (from chip to arduino):
// Chip Select CS(1) is connected to SS (pin 53 on Arduino mega, pin 10 on Arduino Pro mini)
// Serial Clock SCK(2) is connected to SCK (pin 52 on Arduino mega, pin 13 on Arduino Pro mini)
// Serial Input SI(3) is connected to MOSI (pin 51on Arduino mega, pin 11 on Arduino Pro mini)
// Neg Power Vss(4) is connected to GND
// Pot. A pin PA0(5) is connected to GND
// Pot. Wiper pin PW0(6) is connected to pin A1
// Pot. B pin PB0(7) is connected to 5V
// Pos Power Vdd(8) is connected to pin 3
//Include the SPI library
#include <SPI.h>
//Set the slave select pin (as in description)
const int SSpin = 10; //set to 53 for Arduino MEGA, 10 for Arduino Pro Mini
//Set the wipe input pin (as in description)
const int Wpin = 1;
//Set the power pin (as in description)
const int POWpin = 3;
//Define variables for storing current and last read voltage
float voltage = 0;
float prevoltage = 0;
//Main setup function
void setup() {
//Set Power pin as output, and set it high to turn on chip
pinMode(POWpin, OUTPUT);
digitalWrite(POWpin, HIGH);
//Set slave select pin as output, and set it high to de-select chip
pinMode(SSpin, OUTPUT);
digitalWrite(SSpin, HIGH);
//Set wiper pin as input
pinMode(Wpin, INPUT);
//Initialise SPI
SPI.begin();
//Initialise Serial
Serial.begin(9600);
}
void loop() {
//Loop through 128 channel, to find the digital potentiometer:
for (int channel=0; channel<256; channel++) {
//Get initial voltage, and store in prevoltage
prevoltage = (float)analogRead(Wpin)*5.0/1024.0;
//Loop throught the resistance on this channel, from min to max
for (int resist=0; resist<256; resist++) {
//Set resistance
MCP41010Write(channel,resist);
delay(2);
//Read input, and convert to Volts
voltage = (float)analogRead(Wpin)*5.0/1024.0;
//If it has changed from previous voltage (by at least 0.01 Volts) display results
if (abs(voltage-prevoltage)>0.01) {
//Print results to serial
Serial.print("Resistance on Channel ");
Serial.print(channel);
Serial.print(" set to ");
Serial.print(resist);
Serial.print(", reading: ");
Serial.print(voltage);
Serial.println("V");
}
delay(2);
//Update previous voltage
prevoltage=voltage;
}
//Print update
Serial.print("Done testing channel ");
Serial.println(channel);
}
//Turn off Chip, and display end of test message
Serial.println("End of Test");
digitalWrite(POWpin, LOW);
digitalWrite(SSpin, LOW);
}
void MCP41010Write(int address, int value) {
//Take the slave select pin low, to select chip
digitalWrite(SSpin, LOW);
//Send the address, followed by the value to set
SPI.transfer(address);
SPI.transfer(value);
//Take the slave select pin high, to de-select the chip
digitalWrite(SSpin, HIGH);
}
I tested this script on the Dig. Pot., using an Arduino Mega (as I had one lying around) and it worked fine, with no results until channel 17, where the returning voltage smoothly swept from 5V to 0V.
However, when I tested the script on the Dig. Pot. using a 5V Arduino Pro Mini, I got a different result. No channel gave the expected result of a smooth sweep from 5V to 0V. Instead there was just the occasional random change in the return V, with no obvious pattern.
What am I doing wrong? Why does the Arduino Pro Mini appear to be sending random data when using SPI?