Digital Potentiometers Using SPI Bus

I copied the circuit and code from an article on the internet titled; "How to build a Dual Digital Potentiometer Circuit with a MCP4231" The circuit turned a green and red LEDs of and on. I was hoping it would show me how to write code to operate digital pots. I got everything hooked up and wrote the code. I am getting an error in the void loop () part of the code. The error happens on the second time intj=128-i; appears in the code The error message says: 'intj' was not declared in this scope
I don't know how to correct this problem. Could someone help me? Below is a copy of the code. Thanks Keith Hilton Ozark, Missouri
#include <SPI.h>
byte addressRedLED=B00010000;
byte addressGreenLED=B00000000;
int CS=10;
void setup()
{
pinMode (CS,OUTPUT); // put your setup code here, to run once:
SPI.begin();
}
void loop()
{
for(int i= 0;i<=128;i++) // put your main code here, to run repeatedly:
{
intj=128-i;
digitalPotWriteRed(i);
digitalPotWriteGreen(j);
delay(10);
}
delay(2000);
for (int i=128;i>=0;i--)
{
intj=128-i;---------Right here is where I get the error message.
digitalPotWriteRed(i);
digitalPotWriteGreen(j);
delay(10);
}
}
int digitalPotWriteRed(int valueRed)
{
digitalWrite(CS,LOW);
SPI.transfer(addressRedLED);
SPI.transfer(valueRed);
SPI.WRite(CS,HIGH);
}
int digitalPotWriteGreen(int valueGreen)
{digitalWrite(CS,LOW);
SPI.transfer(addressGreenLED);
SPI.transfer(valueGreen);
digitalWrite(CS,HIGH);
}

Please edit your post, select all code and click the </> button to apply so-called code tags and next save your post. It makes it easier to read, easier to copy and prevents the forum software from incorrect interpretation of the code.

Please post the error (there is a copy error messages button at the right in the orange bar; use code tags for that as well.

Please make sure that Enable verbose output during compilation (in file -> preferences) is not ticked before compiling and posting the error messages.

intj is missing a space between int and and j; two times.

SPI.WRite(CS, HIGH);; compare your code in digitalPotWriteGreen with the code in digitalPotWriteRed

Thanks, I will try that.

I've added some more info to post #2.

Yes, thanks sterretje. When I ran the code the error you mentioned came up and I corrected it. Glad you caught that.
The two lights are blinking off and on. The red LED stays on for a couple of seconds then turns off. The green LED flashes and goes off. This keeps repeating. Was wondering how I could get the green LED to stay on longer in the code?
I am new to programing with Arduino and posting code on the Forum--you suggested "select all code and click the </> button to apply so-called code tags". I don't know where to find the button? Thanks Keith Hilton

Blinking or fading?

I'm not quite sure what you mean. One thing about your loop() is that after the second for-loop, you immediately return to the first for-loop. After the first for-loop, you use a delay; maybe adding a delay after the second for-loop achieves what you want to achieve. If not, a better explanation might be in place.

I got this example off of the internet. The example was using two digital pots in a MCP4231 14 pin IC, with the Arduino, controlling a red LED and a green LED. The sketch was supposed to turn the Red LED on, then fade it off---then turn on the green LED on, and fade it off. There isn't much fading going on. The Red LED comes on, and says on for a short time, then quickly goes off. The green LED only flashes once. The flash is real quick on and off, with no fading. I thought this was some kind of official way to use the MCP4231 100K pot. It appears the sketch is screwy. Keith Hilton

I don't know much about digital potentiometers but the below is what your code does.

In the first for-loop,

  1. It writes the values 0..128 to the red pot and 128 to 0 to the green pot. It depends on how the led is connected to the pot if 0 means full on or off. Your pot(s) have 128 discrete steps (values 0..127, not 128) so I suspect that 128 actually needs to be 127 (128 might mean the same as 0).
  2. The code waits a little between the steps (10 milliseconds); so the total fade time is 128 times 10 milliseconds equals 1.28 seconds.

Once the first for-loop is finished, it waits 2 seconds so the last state of the for-loop will remain during that time.

In the second for-loop, the same applies but the fade direction is reversed.

Now loop() is finished, control is returned to the function that called it (main(), hidden for you) which calls loop() again. So you start all over immediately with the first for-loop.

If you want to fade it slower, change delay(10) to e.g. delay(100).
If you want the last state of the for-loop to stay for a while, add e.g. a delay(2000) after the second for-loop.

Below your code adapted to the changes.

#include <SPI.h>
byte addressRedLED = B00010000;
byte addressGreenLED = B00000000;
int CS = 10;
void setup()
{
  pinMode (CS, OUTPUT); // put your setup code here, to run once:
  SPI.begin();
}
void loop()
{
  for (int i = 0; i <= 128; i++) // put your main code here, to run repeatedly:
  {
    int j = 128 - i;
    digitalPotWriteRed(i);
    digitalPotWriteGreen(j);
    // sterretje (10 ms to 100 ms)
    delay(100);
  }

  delay(2000);
  for (int i = 128; i >= 0; i--)
  {
    int j = 128 - i;
    digitalPotWriteRed(i);
    digitalPotWriteGreen(j);
    // sterretje (10 ms to 100 ms)
    delay(100);
  }

  // sterretje
  delay(2000);
}

int digitalPotWriteRed(int valueRed)
{
  digitalWrite(CS, LOW);
  SPI.transfer(addressRedLED);
  SPI.transfer(valueRed);
  digitalWrite(CS, HIGH);
}

int digitalPotWriteGreen(int valueGreen)
{ digitalWrite(CS, LOW);
  SPI.transfer(addressGreenLED);
  SPI.transfer(valueGreen);
  digitalWrite(CS, HIGH);
}

Question / something to think about:
The int in int digitalPotWriteRed(int valueRed) indicates that the function will return a value. Your code however doesn't return a value. And why should that function return a value? It's not used anyway. Same applies for int digitalPotWriteGreen(int valueGreen).

Thank you so much for trying to help me. I will study what you told me and also study your new sketch code. I will get back with you after I study and let you know how it comes out. Thanks so much!!!!! Keith Hilton

Actually I'd tick it - sometimes its useful to see all the noise in case there's something lurking in it (wrong library files, etc).

I'd change to the simpler:

  for (int red = 0; red <= 128; red++)
  {
    digitalPotWriteRed(red);
    digitalPotWriteGreen(128-red);
    delay(100);
  }

No need for a variable just to subtract from 128, and if you do need a variable give is a descriptive name, as in

   int green = 128 - red ;

The MCP4231 uses values 0..128, not 0..127, so your suspicions are wrong - please read datasheets rather than guessing.

Not my code :wink:

Fair enough

Thanks MarkT. I will study what both of you have told me and get back to you with my results. Thanks Keith Hilton

I have studied MarkT's and Sterretje's comments and have some interesting observations. When hooking up a digital potentiometer you have a choice of where the 5 volts is hooked to the potentiometer. Since one of the terminals is hooked to ground, you have a 50% chance of getting the 5 volts and ground hooked the way you want. When you run code to the potentiometer, the wiper is moved according to how the 5 volt power and ground is hooked up. My question then is, how do you know if you have the 5 volts and grounds hooked up correctly to the code you are trying to run? In this example the MCP4231 IC has two digital potentiometers, turning on two different LEDs at different intervals. If one or more of the digital pots is hooked up wrong according to the code that is being run---then the LEDs will not perform as intended. So how do you make sure the way you hook up the potentiometer's terminals is the correct way you have the code written?
Next: MarkT suggests simplifying the code by eliminating the i and the j, and simply coding as Red and Green LEDs. Yes, I like that because it makes the code seem more understandable. On the other hand, we are not dealing with simply the Arduino and the two LEDs. We are dealing with two digital potentiometers. The person who wrote the code probably used the i and j to indicate that there were more things involved besides the two LEDs and the Arduino.
I am going to try both MarkT's and Sterretje's suggestions. But---I am totally confused as to how to guarantee the correct hookup of the terminals of the two digital potentiometers. Meaning how do I know I have hooked the +5 volts and ground terminals correctly when I only have a 50% chance of being correct? Thanks Keith Hilton

The datasheet for the chip should have the pin out and explain what the input codes mean (ie which end of the "track" corresponds to 0 and which to 128).

If you get the polarity wrong just flip the sense in the code - no problem.

No, i and j were just picked as the standard iteration variable names. If you know what you are iterating you can pick more meaningful names - meaningful names are very important if you want to be able to read your code in a years time and make sense of it.

MarkT I tried what you suggested and it worked. Thanks

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.