Skip to content

Instantly share code, notes, and snippets.

@frequenzteiler
Forked from gregorthebigmac/digital_pot.ino
Last active August 29, 2015 14:14
Show Gist options
  • Save frequenzteiler/b222fbd69aec26d586ce to your computer and use it in GitHub Desktop.
Save frequenzteiler/b222fbd69aec26d586ce to your computer and use it in GitHub Desktop.
#include <math.h> // math library for Arduino
const int U_D = 2; // U/D pin on AD5220
const int clk = 5; // CLK pin on AD5220
volatile int counter = 0; // volatile integers are basically global variables, so any function can use them
volatile int pot[2]; // using an array to compare old pot value to new pot value to see if it has changed
volatile int diff[2]; // using a separate variable so we don't accidentally modify our read values
volatile int vol = 0; // volatile integers are basically global variables, so any function can use them
void setup()
{
Serial.begin(9600); // telling the Arduino it will be sending data to the debug terminal at 9600 baud
pinMode(U_D, OUTPUT); // setting the U/D pin out as an OUTPUT pin
pinMode(clk, OUTPUT); // setting the CLK pin out as an OUTPUT pin
delay(500); // half second delay
Serial.println("Funtions check ok. Starting program...");
delay(1000); // full second delay
pot[1] = analogRead(A0); // reading position of pot at startup to see what the volume was at when it was used last
vol_startup(); // calling this function once to set the volume to whatever the user had it set to last
}
void loop()
{
pot[1] = analogRead(A0); // getting new position of pot
diff[1] = floor(pot[1] / 8); // using diff[] to compare new pot reading to old pot reading. If it changes by less than 8,
diff[0] = floor(pot[0] / 8); // the difference will be zero. This also helps create stability in the reading. I'm relying on
// diff being an integer to truncate decimals. By using the floor() function, I'm making sure it rounds down
if (diff[1] != diff[0]) // if the new pot position is not equal to the old one, then execute this block of code
{
Serial.print("Pot[0] = ");
Serial.println(pot[0]); // showing old pot position for comparison
Serial.print("Pot[1] = ");
Serial.println(pot[1]); // getting feedback of new pot position
Serial.print("Diff[0] = ");
Serial.println(diff[0]); // for debugging purposes
Serial.print("Diff[1] = ");
Serial.println(diff[1]); // for debugging purposes
change_vol(); // calling a function which will change the volume if the new pot reading is different from the old one
}
// we're at the end of the main loop. at this point in the program, everything that needs to happen
pot[0] = pot[1]; // has happened, so we're making the old position of the pot equal to the new one we took earlier
} // so we can compare it to the newer one we're about to take when the loop resets
void vol_startup() // this function turns the volume all the way down at startup, then brings it back up to the user's last setting
{
vol = pot[1] / 8; // pot[] value is 10 bit resolution, vol[] is 8 bit. divide pot[] by 8 to put them on the same scale
Serial.println(pot[1]); // printing both values for debug purposes
Serial.println(vol); // printing both values for debug purposes
counter = 0; // reseting the value of the counter
while (counter < 128) // this is going to 128 to make sure the volume is turned all the way down
{
U_D_LOW(); // calling function to reduce resistance, therefore reducing volume
}
Serial.println("Vol = 0"); // showing volume is 0 before bringing it up to last known value
counter = 0;
while (counter < vol) // now we're bringing the volume back up to whatever the user had it set to before it was
{ // powered off last
U_D_HIGH(); // calling function to increase resistance to increase volume
}
Serial.print("Vol = "); // once the loop finishes, it outputs the current volume
Serial.println(vol);
}
void change_vol() // this function is called earlier. it changes the volume when the user
{ // changes the position of the volume knob
if (diff[1] > diff[0]) // if the new position is higher resistance than the old position
{
vol = vol - (diff[1] - diff[0]); // the new volume is being adjusted according to the difference between the
counter = 0; // new and old pot positions
while (counter < (diff[1] - diff[0])) // the loop repeats once per position change (for example, if the pot moves by
{ // 5 positions, the loop repeats 5 times)
U_D_HIGH(); // calling function to increase resistance, and therefore increase volume
}
}
else if (diff[1] < diff[0]) // if the new pot position is lower than the old one
{
vol = vol + (diff[0] - diff [1]); // adjusting volume by difference between pot positions
counter = 0;
while (counter < (diff[0] - diff[1])) // the loop repeats once per position change (for example, if the pot moves by
{ // 7 positions, the loop repeats 7 times)
U_D_LOW();
}
}
Serial.print("Vol = "); // displaying new volume value
Serial.println(vol);
}
// I wrote separate functions for the setting the U/D pin LOW or HIGH and sending pulses, because I didn't feel like typing
// the same 6 lines of code over and over again, plus it helps cut down on the size of the program
void U_D_LOW() // this function decreases resistance, which therefore decreases the volume
{
digitalWrite(U_D, LOW); // setting U/D pin to LOW to decrease resistance
digitalWrite(clk, HIGH); // starting CLK pin pulse
delay(10); // delay 10 ms
digitalWrite(clk, LOW); // ending CLK pin pulse
counter ++; // same as saying counter = counter + 1
delay(10); // delay 10 ms
}
void U_D_HIGH() // this function decreases resistance, which therefore decreases the volume
{
digitalWrite(U_D, HIGH); // setting U/D pin to HIGH to increase resistance,
digitalWrite(clk, HIGH); // starting CLK pulse
delay(10); // delay 10 ms
digitalWrite(clk, LOW); // ending CLK pulse
counter ++; // same as saying counter = counter +1
delay(10); // delay 10 ms
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment