Mini and Mirco digital potentiometer control and SPI.transfer()

Hey there,

There are a few helpful tutorials out there on digipot control via SPI with the Uno (MCP4131-digital-potentiometer-circuit and DigitalPotControl).

If I swap the Uno for a Pro Mini will there be any required modifications from these tutorials? I have seen some conflicting information on the pot's wiper terminal address and what to pass into SPI.transfer().

In summary, some clarification on how to use SPI.transfer() with the Mini would be greatly appreciated. Thanks!

In summary, some clarification on how to use SPI.transfer() with the Mini would be greatly appreciated. Thanks!

The Pro Mini exists in two versions, a 5V version at 16MHz and a 3.3V version at 8MHz. The former is identical to the UNO regarding the SPI interface, the later is a bit slower (4MHz max. SPI speed) and operates at the lower voltage but the rest is also identical.

Thanks pylon -- how about the Micro?

how about the Micro?

The Micro uses another processor (ATmega32U4). The SPI pins are not available on the standard pin headers but only on the ICSP header (2x3pin header). Apart from that hardware differences the software usage is identical.

What exactly is your problem? Tell us about the problems you expect (or you've seen)! Also tell us what exact hardware you use as there might be differences among the available chips.

pylon,

I am using the Pro Micro ATmega32U4 5V 16MHz to read in sensor data that has been filtered & amplified by a custom circuit. I recently updated the circuit with a digipot (MCP4131) to put the gain control in the Micro's hands -- unfortunately the digitpot resistance is not changing when hooked up. It sits ~ 2.5k Ohms (probably default) and there is no traffic on the SPI lines or a clock signal, which leads me to believe that the tutorial's serial commands may not be appropriate for the Micro.

The datasheet identifies the Micro's SPI pins no? See this guide

Here are the relevant portions of the code:

#include <SPI.h>
...
// digipot constants
byte address = 0x00; // Address of the wiper terminal of the pot, allows you to change the resistance value of the pot
int CS = 18; // The CS, or Chip Select, pin is the SS (slave select) pin for the SPI interface
int digipot_resistance = 64; // (0-128) 0: min resistance, 128 max resistance
...
void setup() {
  Serial.begin(115200);
  ...
  pinMode (CS, OUTPUT); // set the CS as an output
  SPI.begin();   // initialize SPI
  digitalPotWrite(digipot_resistance); // set initial resistance 
}

void loop() {
  /* Main loop: Sends data to serial if interrupt/timer flag has been triggerd.
  */
  if (!init_setup_flag) {
    setup();
  }

  if (ISRRan) {
    //If interrupted by sensor timer, send data to serial
    send_buffer_to_serial(signal, sampleCounter, data_buffer);
     ...
    // check timer
    if (((millis () - start_time) >= win_len) & (buffer.isFull())) {
      ...
      // update and adjust digitpot resistance
      if (new_resistance != digipot_resistance) {
        digipot_resistance = new_resistance;
        digitalPotWrite(digipot_resistance);
      }
    }
    ISRRan = false;             //Wait until next interrupt
  }
  serialEvent();
}

void digitalPotWrite(int value) {
  /* Establish communication, write value, and end communication with digipot.
     INPUT: value to write (0-128) 0: min resistance, 128 max resistance
  */
  // take the SS pin low (select/initiate communication with the digipot)
  digitalWrite(CS, LOW);
  //  send in the address (wiper terminal) and value via SPI
  SPI.transfer(address);
  SPI.transfer(value);
  // take the SS pin high (de-select/end communication with the digipot)
  digitalWrite(CS, HIGH);
}

A Pro Micro seems to be something completely different from a Arduino Micro unfortunately. Some companies should be punished for their naming of products.

Here are the relevant portions of the code:

Always post complete code. If you don't want to post your whole code shorten it so it shows the same behavior but we don't study code excerpts just to find out that the error was in a part that was not posted. That's just a waste of time.

Please post a wiring diagram (also a complete one!).

Are you using the MCP4131?

Ah that must be my issue, I am following the wrong tutorial :confused: and yes I am using the MCP4131.

The following code exhibits the same issue:

#include <SPI.h>

byte address = 0x00;
int CS= 18;

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

void loop()
{
for (int i = 0; i <= 128; i++)
{
digitalPotWrite(i);
delay(10);
}
delay(500);
for (int i = 128; i >= 0; i--)
{
digitalPotWrite(i);
delay(10);
}
}

int digitalPotWrite(int value)
{
digitalWrite(CS, LOW);
SPI.transfer(address);
SPI.transfer(value);
digitalWrite(CS, HIGH);
}

Here's a helpful post on the sparkfun pro micro atmega32u4:

The Pro Micro is an ATmega32U4-based board made by Sparkfun. It's a Leonardo clone, and uses the same bootloader. Compared to the Leonardo it's missing pins 11, 12, 13, A4 and A5.
...
Quirks to the Arduino 32u4 implementation in general: there's no Timer2 so any library or sketch that uses it won't work, the bootloader's auto-reset process can be overwhelmed by a bad sketch which can require you to manually reset to get a new sketch in (or in worst conditions you might need to use an ISP to reburn the bootloader but I think that's really rare). The various 'standard pins' are all moved around, eg. SPI is on different pins, I2C on different pins. The USB libraries take a huge whack of space so out of your 32kB you lose 4kb to the bootloader and another 3kb in 'overhead' (i.e. any sketch you write will be 3kb bigger because of the USB libraries). The TX/RX LEDs are (IMHO) handled a bit wierd and one of them is the hardware SPI SS pin, so any libraries that are hardwired to use the hardware SPI SS pin won't work.
...
Quirks specific to the Pro Micro: it's missing a few digital pins that appear on the Leonardo (I think it's 11, 12, 13 that are missing). I know they've released a newer version than mine, but if you have an older version, the bootloader is not compatible with Leonardo. There are errors on the schematic that may or may not be fixed now, relating to the assignment of analog pins on the digital side (eg. A8 may or may not be D8, etc).

Sparkfun has a programming for SPI tutorial using the Arduino SPI library, which points out steps my current code omits, including:

If you’re using the SPI Library, you must use the provided SCK, MOSI and MISO pins, as the hardware is hardwired to those pins. There is also a dedicated SS pin that you can use (which must, at least, be set to an output in order for the SPI hardware to function), but note that you can use any other available output pin(s) for SS to your slave device(s) as well.

I plan to implement these recommendations and continue to troubleshoot.

If anyone has experience or suggestions in using SPI with the Sparkfun Pro Micro atmega32u4 5V/16MHz or any comments please reply :slight_smile: