Digital Pot MCP41100 with Mega2560 SPI HELP!!!

Has anyone had any luck using the SPI library with the Mega2560? It seems like there is an extra step that no one knows about to get the SPI to work. I am trying to use the MCP41100 digital pot in a project to adjust my voltage, but I can't get the potentiometer value to change from the start up value. I tried using the preloaded example from "file", "example", "SPI", "digitalpotcontrol" just to scale through the pot's 256 values, and I had no luck. I really need this to work on the mega2560 but I also tried using the example code on the Arduino 101, and it didn't work either. Everywhere I looked online people had problems and no one has been able to get it resolved yet. Please if anyone had this problem in the past and figured out what is going on please help. I also tried to adjust the clock cycle speed to below the datasheets max value to ensure the mcp41100 was able to read the databits. The data sheet says 10MHz, and I tried 10000000 and 9000000. Sometime next week when I go to school I will have access to an oscilloscope so I can confirm if I have a clock coming out of pin 52(SCK) or not. I can also use it to see if pin 51 (MOSI) is sending the bits I want from 0-256. and yes I was also setting the ss to low before transmitting.

Folks use it all the time. To send a byte at defualt speed of 4 MHz, SCK low when inactive, MSBFIRST (all default settings):

#include <SPI.h>
byte ssPin = 53;

void setup(){
pinMode (ssPin, OUTPUT);
SPI.begin();
}
void  loop(){
digitalWrite (ssPin, LOW);
SPI.transfer(0x01);
digitalWrite (ssPin, HIGH);
}

This will send 0x01 over the MOSI line over and over and over …

That's my provlem... this code doesn't work

I've used a MCP41010 successfully with an Uno, and I don't think the principles will be any different for you.

Are you aware you have to send a "command byte" to the chip before you send the value that governs potentiometer setting?

Have a look at this link:

You might have to play with the "mode setting" to get it to work.

GypsumFantastic:
I've used a MCP41010 successfully with an Uno, and I don't think the principles will be any different for you.

Are you aware you have to send a "command byte" to the chip before you send the value that governs potentiometer setting?

Have a look at this link:

http://www.instructables.com/id/Digital-Potentiometer-MCP41100-and-Arduino/step3/Arduino-Code/

Yes I see that this tutorial is for a UNO and I have a mega2560. I I've seen that instructable already, and I'm pretty sure that code doesn't work properly for the mega2560. If you look up the Mega2560 on arduino.cc you can find the spi sectcion says,"The Mega 2560 board is compatible with most shields designed for the Uno and the former boards Duemilanove or Diecimila." This is why I'm hesitant to think its my coding or connections. I could be wrong though. I'll try it when I get home. I do know that we have to send a command byte through SPI.transfer first but why, and why use 0x11/0d17? I think i used 00 for the first transfer. To my knowlege the SPI outputs of the arduino can be tied to many digital pots. I thought this was the address we assigned to each one of the pots???
Unless this is the header/handle that tells the ic the start and end of the transmission... that would kind of make sense. If the arduino sends the ic the first digit '1' and that represents the start transmission (1st clock cycle) then sends the ic the second digit '7' that represents the end of the transmission(7th clock cycle), but that would only leave room for the 3bytes during transmission, and this ic has 256 channels so we need 4 bytes/8bits. Do you think I would have to adjust the command byte to make this work for the MCP41100 with 256 channels?

KeithRB:
You might have to play with the “mode setting” to get it to work.

I tried the mode setting at 0, 1, 2, and 3. I also tried MSBFIRST and LSBFIRST.

Also, the IC data sheet says the max clock frequency is 10MHz. So I tried sending the spi settings 10000000 and 9000000 just in case 10 was on the threshold.

here is a list of settings I tried.

SPI.beginTransaction(SPISettings(10000000, MSBFIRST, SPI_MODE0))
SPI.beginTransaction(SPISettings(10000000, MSBFIRST, SPI_MODE1))
SPI.beginTransaction(SPISettings(10000000, MSBFIRST, SPI_MODE2))
SPI.beginTransaction(SPISettings(10000000, MSBFIRST, SPI_MODE3))

SPI.beginTransaction(SPISettings(10000000, LSBFIRST, SPI_MODE[same as above]))

and then the same with 9000000 for the clock transmission.

CrossRoads:
Folks use it all the time. To send a byte at defualt speed of 4 MHz, SCK low when inactive, MSBFIRST (all default settings):

#include <SPI.h>

byte ssPin = 53;

void setup(){
pinMode (ssPin, OUTPUT);
SPI.begin();
}
void  loop(){
digitalWrite (ssPin, LOW);
SPI.transfer(0x01);
digitalWrite (ssPin, HIGH);
}



This will send 0x01 over the MOSI line over and over and over ...

Why are you using 4MHz? is that what the arduino uses as default or is that what the IC accepts?

The mega 2560’s clock runs at 16MHz but the max frequency of the IC clock according to the data sheet is 10MHz. Look at the previous post to see ways that I tried to satisfy the IC requirements.

Also why are you only calling SPI.transfer() one time? I thought it needed to be called twice while ssPin is low.

Here’s a test sketch that works for me. It ramps the resistance from minimum to maximum and back again at a rate that’s easy to measure with a multimeter.

See how you get on with it.

#include <SPI.h>

const byte CS = 10;
int inputpin = A0;
int analogValue;

void setup() {
  pinMode (CS, OUTPUT);
  SPI.begin();
}

void loop() {

  for (int level = 0; level < 255; level++)
  {
    MCP41010Write(level);
    unsigned long startTime = millis();
    delay(50);
  }
  for (int level = 255; level > 0; level--)
  {
    MCP41010Write(level);
       unsigned long startTime = millis();
  delay(50);
  }

}

void MCP41010Write(byte value)
{
  digitalWrite(CS, LOW);
  SPI.transfer(B00010001);
  SPI.transfer(value);
  digitalWrite(CS, HIGH);
}

looks promising... are you using a Mega2560?

I will try it when I get home. It looks like the only thing i have to change is the function title from MCP41010 to MCP41100 and the CS=10 to CS=53. but I'll run it as is first as a test just to see if i can see the change on my meter.

The only thing that I see different that I haven't tried yet is

"SPI.transfer(B00010001);"

why do we send this first anyways? why are we sending d17?

It's the command byte. Have a look at figure 5-2 in the datasheet.

Here's the 8 bits in the byte

X X C1 C0 X X P1 P0

The X's are ignored. Zeroes in my example but it doesn't matter what goes there.

C1 C0 = 0 1 which means write data

P1 P0 = 0 1 which means send data to the first potentiometer in the chip (some of this family of chips have 2 pots inside). I think that even the single-pot chips need 1 in P0.

Good luck!

EDIT - I missed your first question, sorry. No I'm using an Uno but I'd be surprised if it made a difference once you've substituted whatever CS pin you're using.

figure 5-2
ohhhh! ok. Now that's probably what I've been missing. Ill let you know what happens.

what is

unsigned long startTime = millis();
delay(50);

for?

Sorry that's a leftover from when the sketch was doing something slightly different. You can safely ignore or delete the lines about startTime. Similarly the lines near the beginning that mention inputPin and analogValue are redundant.

DUDE IT WORKS!!!! after a couple of weeks of working on this you fixed it in like an hour flat.

THANKYOU!

and it was all because the command bit

so if i wanted to use 3 of these with different values then i should be able to use this code and just parallel the SCKs and the MOSIs?

#include <SPI.h>

const byte CS1 = 45;
const byte CS2 = 47;
const byte CS3 = 49;

void setup(){
  pinMode (CS1, OUTPUT);
  pinMode (CS2, OUTPUT);
  pinMode (CS3, OUTPUT);
  digitalWrite(CS1,HIGH);
  digitalWrite(CS2,HIGH);
  digitalWrite(CS3,HIGH);
  SPI.begin();
}

void loop(){
 digipot1(1);
 digipot2(100);
 digipot3(200);
 delay(50);
}

void digipot1(byte value){
  digitalWrite(CS1, LOW);
  SPI.transfer(B00010001);
  SPI.transfer(value);
  digitalWrite(CS1, HIGH);
}
void digipot2(byte value){
  digitalWrite(CS2, LOW);
  SPI.transfer(B00010001);
  SPI.transfer(value);
  digitalWrite(CS2, HIGH);
}
void digipot3(byte value){
  digitalWrite(CS3, LOW);
  SPI.transfer(B00010001);
  SPI.transfer(value);
  digitalWrite(CS3, HIGH);
}