Controlling Multiple Digital Potentiometers

I have an Arduino Uno and a Mega.
I'm relatively new to Arduinos so I'm still learning the ways around them. I'm working on a project where I want to output various different resistance values using digital potentiometers. The purpose of this is to output pairs of unique resistance values. If possible, I want to control as many digital potentiometers as possible (analog potentiometers would be inconvenient since I'll be needing to change the resistance values relatively frequently).

I've looked up the two methods that are used to with digital potentiometers: I2C and SPI.

The I2C method uses the AD5171 which outputs one resistance value. From the Arduino website, it says that 2 of these potentiometers can be used (not sure how. by using unique addresses?). Would it be possible to use more than 2 of these digital potentiometer.

The SPI method uses the AD5206 which "has six variable resistors (potentiometers) built in for individual electronic control." (does this mean I can have 6 different resistance values from one AD5206?).
The problem with this is that I'm using SPI to load an array of resistance values from an SD card (using SD card module). Worst case, I can manually fill in the array in the program but I'd have to enter hundreds of entries...
For some reason, the website to the link isn't working so I read an archive of the page.

https://web.archive.org/web/20170816063456/https://www.arduino.cc/en/Tutorial/DigitalPotControl

I've read about digital potentiometers but I have never had experience with them. Any help would be appreciated.

The problem with this is that I'm using SPI to load an array of resistance values from an SD card (

Only at the beginning of the program?

Perhaps you should google I2C and SPI and learn a bit about what each is and how they work. I think you'll be pleasantly surprised to find out that you can share between the SD card and the 6-way digitpot.

If "as many as possible" is 6 or greater then you really have to use the AD5206 devices. Each additional one will only require one more digital output pin on your Arduino. I just had a quick look at the datasheet. The 6 pots are totally independent. They don't share any pins. So one pot could be a 0-3V divider and another could be 0-5V on the same chip. (However all of the pot pin voltages must be between the ground and supply voltage of the AD5206 chip. That's important.)

There should be no issue at all sharing the SPI bus between the SD card and many AD5206 units.

@Delta_G
Thank you for the tip. Yes, I am only using the SD card during setup(). After researching, it seems like I have to set the CS/SS Low when I want to communicate to a specific SPI device and set the other SPI devices HIGH. It would look something like

void setup() {

      pinMode(9, OUTPUT);      //SD Card 
      digitalWrite(9, LOW);     //SD Card 
      pinMode(10, OUTPUT);    //CAN Case or other SPI device
      digitalWrite(10, HIGH);   //CAN Case or other SPI device
   
      //Fill in array when SD Card info...
     
      //Turn off slave communication with SD card
      digitalWrite(9, HIGH);     //SD Card 
     
}


loop(){

      digitalWrite(10, LOW);     //Other SPI device
    
      //Do something with SPI device...

     //Turn off slave communication with
     digitalWrite(10, HIGH);     //Other SPI device


}

It's not quite that simple. Some SPI devices treat the CS pin as a 'transaction' so when CS goes high, it does what you requested. This lets you set up a complex request and have it all happen 'at once'.

Use the SD.h library for simple communication with an SD card. It will manage the CS pin itself.

Your setup should set the special hardware CS pin to OUTPUT (otherwise the Arduino tries to act as a slave) and then set the actual pins used for your devices to OUTPUT and digitalWrite( ... , HIGH); Usually you would use the special pin as CS for one of your devices. For most Arduinos, that's pin 10. All the examples that come with the SD library use pin 10 as CS.

@MorganS
I was planning to use 6 or more potentiometers. I'll look into the AD5206.

Your setup should set the special hardware CS pin to OUTPUT (otherwise the Arduino tries to act as a slave) and then set the actual pins used for your devices to OUTPUT and digitalWrite( ... , HIGH);

SD Card - Pin 10 //inputs information into Arduino
CAN Shield - Pin 9 //Arduino outputs information through CAN shield
Planning on using digital potentiometer later.

Does this mean that I would have to set my Arduino as a slave ( pinMode(10,INPUT) ) for the first part of my code when I load information from the SD Card into my Arduino? Then also set the CAN Shield pin to an output and the Arduino to a master once I'm done using the SD Card?

pinMode(9, OUTPUT); //For CAN Shield (this is done when I call "MCP_CAN CAN(9);" in the code below

Would the SD card library do the initialization? And when I load info from the SD Card, would my Arduino be a slave during that case?

I basically initialize the SD Card with Pin 10. I read that the hardware makes Pin 10 "specially" for SPI. Why can't I assign the SD Card CS pin a pin other than 10? What if I had another SPI device (like an older version of a CAN shield - v1.0) that also uses pin 10? How would I be able to deal with the issue? Fortunately, my CAN shield is the newer one so it uses pin 9.

CAN Shield Library - GitHub - Seeed-Studio/Seeed_Arduino_CAN: Seeed Arduino CAN-BUS library - MCP2518FD&MCP2515&MCP2551

The following is the rough idea of my code for this SPI communication.

#include <SPI.h>          //SPI is used to talk to the CAN Controller
#include <SD.h>           //For SD Card
#include <mcp_can.h>   //For CAN Shield

#define CS_PIN 10     //used for SD CARD


setup(){
 
//SD Card Section

  if (!SD.begin(CS_PIN)) {
      errorHalt("begin failed");
  }

  file = SD.open("CSVTxt.txt");

  //load information into array...

  file.close(); //now close file

  digitalWrite(CS_Pin,HIGH);  //Would I do this to stop SPI communication with the SD Card?
   




//CAN Shield Section (uses SPI) and I only want to use this SPI CAN shield from now on
    
  MCP_CAN CAN(9);      // Set CS to pin 9/10
                                   // Use pin 10 for Seeed Studio CAN Shield up to version 1.0
                                   // Use pin 9 for Seeed Studio CAN shield version 1.1 and higher

   START_INIT:

    if(CAN_OK == CAN.begin(CAN_250KBPS))      //setting CAN baud rate to 250Kbps
    {
        Serial.println("CAN BUS Shield init ok!");
    }
    else
    {
        Serial.println("CAN BUS Shield init fail");
        Serial.println("Init CAN BUS Shield again");
        delay(100);
        goto START_INIT;
    }

}


loop(){

// SPI only use CAN Shield now
//Do something with CAN shield

}

I appreciate the advice and tips.

Sorry, I was typing on a phone and trying to cram a complex subject into as few words as possible.

No, you always want your Arduino in SPI master mode. If you use pin 10 for the SD card then SD.begin(CS_PIN) will take care of this. If you use any other pin then you must set pin 10 to OUTPUT before calling SD.begin().

If you have two shields that are both physically wired to use pin 10 then you have to cut the wire on one of those shields and connect it to a different pin. This usually isn't a problem as most shields provide a jumper or other means of selecting a different physical pin.

Read the documentation on each of the devices you plan to use. You can find lots of tutorials online that talk about SPI communications in general as well as the ones that are specifically for your hardware.

You can talk to either device at any time during the program. You can even open a file on the SD card, write a few bytes, grab data from the CAN shield, write that to the SD card, then close the file.

@MorganS

Thank you for your help.
Just to clarify, if I use two SPI devices (SD Card with PIN 10 and a different SPI with PIN 9), I'll only have to set Pin 9 as OUTPUT because SD.begin(CS_Pin) will declare Pin 10 as Output for me.

I'll test things out and let you know if I have any other problems.

I would have to open up the library to check. Why don't you look for yourself? It's open source.

Or just set it to OUTPUT anyway, before calling .begin()