LED Fader with 3 Preset Buttons... solved!

Hello,
My name is Kevin and I'm new to the forum and Arduino in general. I have been reading up on C programming as much as possible and have been writing some simple sketches with success but I have hit a wall when trying to combine some simple elements into a more complicated sketch.

What I am trying to accomplish consists of a single LED, 3 potentiometers, and 3 momentary pushbuttons. The idea is to have 3 preset levels of brightness for the LED, set by a dedicated potentiometer and accessed by pushing the correlated dedicated button. These will be direct access buttons so pushing one goes directly to that preset and essentially "cancels" the previous settings. As such, the LED will alway be on and only needs to be able to change brightness.

I am very new to all this and have been scouring the forums for ideas and trying different things to no avail. I have tried to create a frame work of code to act a a baseline for some assistance because I am in over my head :o .

/*Program to have 3 independent levels of LED brightness set by a dedicated 
potentiometer and accessed by a dedicated switch*/

                //-------- FOR THE POTENTIOMETERS --------

 const byte potPin1 = A0;  //input pin that the wiper of pot1 is connected to
 const byte potPin2 = A1;  //input pin that the wiper of pot2 is connected to
 const byte potPin3 = A2;  //input pin that the wiper of pot3 is connected to
 int potValue1;  //variable to store the reading from pot1 wiper
 int potValue2;  //variable to store the reading from pot2 wiper
 int potValue3;  //variable to store the reading from pot3 wiper
 
 
                //-------- FOR THE PUSH BUTTONS --------
 const byte buttonPin1 = 2;  //input pin for push button 1 
 const byte buttonPin2 = 3;  //input pin for push button 2
 const byte buttonPin3 = 4;  //input pin for push button 3
 byte button1State;  
 byte button2State;
 byte button3State;
                
                
                //-------- FOR THE LED --------
 const int ledPin = 9;  //the pin that the led is attached to
 int ledBrightnessValue1;  //variable to store the value written to the led
 int ledBrightnessValue2;  //variable to store the value written to the led
 int ledBrightnessValue3;  //variable to store the value written to the led
 
 
 void setup() 
 {
   pinMode(ledPin, OUTPUT);  //set pin 9 as an output
   digitalWrite(ledPin, LOW);  //led is off by default
   pinMode(buttonPin1, INPUT_PULLUP);  //activate internal pullup resistors
   pinMode(buttonPin2, INPUT_PULLUP);  //activate internal pullup resistors
   pinMode(buttonPin3, INPUT_PULLUP);  //activate internal pullup resistors
 }


 void loop()
 {
 
 }
   
 void checkButtons()
 {
   button1State = digitalRead(buttonPin1); //check to see if button 1 is pressed
   button2State = digitalRead(buttonPin2); //check to see if button 2 is pressed
   button3State = digitalRead(buttonPin3); //check to see if button 3 is pressed
 }
   
 void readPotentiometer1()
 {
   potValue1 = analogRead(potPin1);  //read the value from the pot1 wiper
 }
 
 
 void readPotentiometer2()
 {
   potValue2 = analogRead(potPin2);  //read the value from the pot2 wiper
 }
 
 
 void readPotentiometer3()
 {
   potValue3 = analogRead(potPin3);  //read the value from the pot3 wiper
 }
 
 
 void setLedBrightness1()
 {
   ledBrightnessValue1 = map(potValue1, 0, 1023, 0, 255);  //map pot1 value to the range of a digital output
    analogWrite(ledPin, ledBrightnessValue1);  //write the value to the LED
 }
 
 void setLedBrightness2()
 {
   ledBrightnessValue2 = map(potValue2, 0, 1023, 0, 255);  //map pot2 value to the range of a digital output
    analogWrite(ledPin, ledBrightnessValue2);  //write the value to the LED
 }
 
 void setLedBrightness3()
 {
   ledBrightnessValue3 = map(potValue3, 0, 1023, 0, 255);  //map pot3 value to the range of a digital output
    analogWrite(ledPin, ledBrightnessValue3);  //write the value to the LED
 }
 
 
void setLedFade()
 {
   if (button1State == LOW){
     readPotentiometer1;
     setLedBrightness1;
   }
   
   if (button2State == LOW){
     readPotentiometer2;
     setLedBrightness2;
   }
   
   if (button3State == LOW){
     readPotentiometer3;
     setLedBrightness3;
   }
   
 }

I understand that the above is incomplete and will not do anything as is. I have tried to put the main things that I need to happen in their own functions but I am not sure what functions I need to put in the main loop or if I need more functions to represent what I'm trying to accomplish. If I put all of the functions in the main loop then all of the pots are active at the same time... not what I intended! I might need more variables too?!

At this point I'm having a hard time seeing the woods from the trees so any guidance or assistance would be greatly appreciated. I'm willing to put in the time to figure this out if there is an example or information that I need to read up on too. Anything helps. Thank you in advance :slight_smile: ,
Kevin

Ok, after some time away from the code I now have a little more clarity. By putting some of my functions in the loop I am able to get some things to happen.

If I put checkButtons() in the loop I can get results with a single button press like I want:

void loop()
{
  checkButtons();
  if (button1State == LOW)
  {
    digitalWrite(ledPin, HIGH);    
  }
  if (button2State == LOW)
  {
    digitalWrite(ledPin, LOW);
  }
  if (button3State == LOW)
  {
    digitalWrite(ledPin, HIGH);
  }

}

}

Now button1 turns the LED on, button2 turns it off, and button3 turns it back on again. That's a step in the right direction. However, when I put this code in:

void loop()
{
  checkButtons();
  if (button1State == LOW)
  {
    readPotentiometer1();  
    setLedBrightness1();  
  }
  if (button2State == LOW)
  {
    readPotentiometer2();  
    setLedBrightness2();
  }
  if (button3State == LOW)
  {
    readPotentiometer3();  
    setLedBrightness3();
  }

}

the LED turns on but the potentiometers do not do anything. Hmmm... Stumped again. Any help would be greatly appreciated. Thanks,
Kevin

P.S., Here is the full code as it stands right now:

/*Program to have 3 independent levels of LED brightness set by a dedicated 
 potentiometer and accessed by a dedicated switch*/

//-------- FOR THE POTENTIOMETERS --------

const byte potPin1 = A0;  //input pin that the wiper of pot1 is connected to
const byte potPin2 = A1;  //input pin that the wiper of pot2 is connected to
const byte potPin3 = A2;  //input pin that the wiper of pot3 is connected to
int potValue1;  //variable to store the reading from pot1 wiper
int potValue2;  //variable to store the reading from pot2 wiper
int potValue3;  //variable to store the reading from pot3 wiper


//-------- FOR THE PUSH BUTTONS --------
const byte buttonPin1 = 2;  //input pin for push button 1 
const byte buttonPin2 = 3;  //input pin for push button 2
const byte buttonPin3 = 4;  //input pin for push button 3
byte button1State;  
byte button2State;
byte button3State;


//-------- FOR THE LED --------
const int ledPin = 9;  //the pin that the led is attached to
int ledBrightnessValue1;  //variable to store the value written to the led
int ledBrightnessValue2;  //variable to store the value written to the led
int ledBrightnessValue3;  //variable to store the value written to the led


void setup() 
{
  pinMode(ledPin, OUTPUT);  //set pin 9 as an output
  digitalWrite(ledPin, LOW);  //led is off by default
  pinMode(buttonPin1, INPUT_PULLUP);  //activate internal pullup resistors
  pinMode(buttonPin2, INPUT_PULLUP);  //activate internal pullup resistors
  pinMode(buttonPin3, INPUT_PULLUP);  //activate internal pullup resistors
}


void loop()
{
  checkButtons();
  if (button1State == LOW)
  {
    readPotentiometer1();  
    setLedBrightness1();  
  }
  if (button2State == LOW)
  {
    readPotentiometer2();  
    setLedBrightness2();
  }
  if (button3State == LOW)
  {
    readPotentiometer3();  
    setLedBrightness3();
  }

}

void checkButtons()
{
  button1State = digitalRead(buttonPin1); //check to see if button 1 is pressed
  button2State = digitalRead(buttonPin2); //check to see if button 2 is pressed
  button3State = digitalRead(buttonPin3); //check to see if button 3 is pressed
}

void readPotentiometer1()
{
  potValue1 = analogRead(potPin1);  //read the value from the pot1 wiper
}


void readPotentiometer2()
{
  potValue2 = analogRead(potPin2);  //read the value from the pot2 wiper
}


void readPotentiometer3()
{
  potValue3 = analogRead(potPin3);  //read the value from the pot3 wiper
}


void setLedBrightness1()
{
  ledBrightnessValue1 = map(potValue1, 0, 1023, 0, 255);  //map pot1 value to the range of a digital output
  analogWrite(ledPin, ledBrightnessValue1);  //write the value to the LED
}

void setLedBrightness2()
{
  ledBrightnessValue2 = map(potValue2, 0, 1023, 0, 255);  //map pot2 value to the range of a digital output
  analogWrite(ledPin, ledBrightnessValue2);  //write the value to the LED
}

void setLedBrightness3()
{
  ledBrightnessValue3 = map(potValue3, 0, 1023, 0, 255);  //map pot3 value to the range of a digital output
  analogWrite(ledPin, ledBrightnessValue3);  //write the value to the LED
}

I can't see any obvious errors in your code, so I'd suggest using serial output with your potentiometer readings and the mapped brightness levels to see if they're as expected.

Thank you so much Martin-X! It is working now. The issue was that I needed to be holding the button down while I was turning the pot in order to see the brightness change. The serial monitor pointed out that it was writing the actual value but I needed to press the button after each new pot setting in order to write the new value to the LED. Here is the updated and slightly simplified code:

/*Program to have 3 independent levels of LED brightness set by a dedicated 
 potentiometer and accessed by a dedicated switch*/

//-------- FOR THE POTENTIOMETERS --------
const byte potPin1 = A0;  //input pin that the wiper of pot1 is connected to
const byte potPin2 = A1;  //input pin that the wiper of pot2 is connected to
const byte potPin3 = A2;  //input pin that the wiper of pot3 is connected to
int potValue1;  //variable to store the reading from pot1 wiper
int potValue2;  //variable to store the reading from pot2 wiper
int potValue3;  //variable to store the reading from pot3 wiper

//-------- FOR THE PUSH BUTTONS --------
const byte buttonPin1 = 2;  //input pin for push button 1 
const byte buttonPin2 = 3;  //input pin for push button 2
const byte buttonPin3 = 4;  //input pin for push button 3
byte button1State;  
byte button2State;
byte button3State;

//-------- FOR THE LED --------
const int ledPin = 9;  //the pin that the led is attached to
int ledBrightnessValue1;  //variable to store the value written to the led
int ledBrightnessValue2;  //variable to store the value written to the led
int ledBrightnessValue3;  //variable to store the value written to the led

void setup() 
{
  pinMode(ledPin, OUTPUT);  //set pin 9 as an output
  digitalWrite(ledPin, LOW);  //led is off by default
  pinMode(buttonPin1, INPUT_PULLUP);  //activate internal pullup resistors
  pinMode(buttonPin2, INPUT_PULLUP);  //activate internal pullup resistors
  pinMode(buttonPin3, INPUT_PULLUP);  //activate internal pullup resistors
}

void loop()
{
  readPotentiometers();
  checkButtons();
  if (button1State == LOW)
  {
    setLedBrightness1();
  }
  if(button2State == LOW)
  {
    setLedBrightness2();
  }
  if(button3State == LOW)
  {
    setLedBrightness3();
  }
}  

void checkButtons()
{
  button1State = digitalRead(buttonPin1); //check to see if button 1 is pressed
  button2State = digitalRead(buttonPin2); //check to see if button 2 is pressed
  button3State = digitalRead(buttonPin3); //check to see if button 3 is pressed
}

void readPotentiometers()
{
  potValue1 = analogRead(potPin1);  //read the value from the pot1 wiper
  potValue2 = analogRead(potPin2);  //read the value from the pot2 wiper
  potValue3 = analogRead(potPin3);  //read the value from the pot3 wiper
}

void setLedBrightness1()
{
  ledBrightnessValue1 = map(potValue1, 0, 1023, 0, 255);  //map pot1 value to the range of a digital output
  analogWrite(ledPin, ledBrightnessValue1);  //write the value to the LED
}

void setLedBrightness2()
{
  ledBrightnessValue2 = map(potValue2, 0, 1023, 0, 255);  //map pot2 value to the range of a digital output
  analogWrite(ledPin, ledBrightnessValue2);  //write the value to the LED
}

void setLedBrightness3()
{
  ledBrightnessValue3 = map(potValue3, 0, 1023, 0, 255);  //map pot3 value to the range of a digital output
  analogWrite(ledPin, ledBrightnessValue3);  //write the value to the LED
}

Now the next step is, how do I keep the button state active (or continually analogWrite the ledBrightnessValue) so that I can visually adjust the LED brightness on the fly without having to hold the button down? Any suggestions would be greatly appreciated. I'll have to think about this for awhile. Thank you for the help!

try learning about arrays to simplify your program...

try this (compiles but not tested)

something like:

const int potPin[] = {A0,A1,A2};

const int buttonPin[] = {2, 3, 4};

const int ledPin = 9;  //the pin that the led is attached to

int state = -1;

void setup() 
{
  pinMode(ledPin, OUTPUT);  //set pin 9 as an output
  digitalWrite(ledPin, LOW);  //led is off by default
  for (byte i = 0; i < 3; i++)
  {
    pinMode(buttonPin[i], INPUT_PULLUP);
  }
}

void loop()
{
  for (byte i = 0; i < 3; i++)
  {
    if (digitalRead(buttonPin[i]) == LOW)
    {
      state = i;
      break;
    }
  }
  analogWrite(ledPin, map(analogRead(potPin[state]), 0, 1023, 0, 255));
}

Thank you for taking the time to write that up Bulldog! I'll have to take a look at that more closely to make sure I understand what's going on. I'm just starting to mess around with arrays. I know the way I wrote the program has lot's of unnecessary code but it's easier for me to visualize what's going on that way and get something to work.

I still haven't come up with a solution to how to have the pot be read on a regular basis without needing to update the brightness by pressing the switch. Pin change interrupts were the closest thing I found but it seemed overly complicated for what I'm trying to accomplish. Does anyone have an suggestions on how I can achieve that? As I always I greatly appreciate the help ;D .
-Kevin

Did you run the code sample?

in the code I wrote (and if you run it you will see) it will real-time adjust the brightness of the last selected button by dialing the corresponding potentiometer.

this runs MANY thousands of times in a second:

analogWrite(ledPin, map(analogRead(potPin[state]), 0, 1023, 0, 255));

Fantastic! Thank you :smiley: Sorry I hadn't run the code before that last post. I didn't realize that it addressed the brightness adjustment. I was too busy looking up arrays and trying to make things more complicated :blush:. Meanwhile, you had already posted exactly what I was trying to do. That is a great help. Now I just have to go through one line at at time and make sure I understand exactly how it works.
Many thanks,
Kevin

Ok, I have gone through the code and added comments to what I think is going on:

const int potPin[] = {A0,A1,A2};  //array to hold the pin #'s that the pot wipers are attached to

const int buttonPin[] = {2, 3, 4};  //array to hold the pin #'s that the buttons are attached to

const int ledPin = 9;  //the pin that the led is attached to

int state = -1;  //I don't understand why this is set to -1??

void setup() 
{
  pinMode(ledPin, OUTPUT);  //set pin 9 as an output
  digitalWrite(ledPin, LOW);  //set LED off
  for (byte i = 0; i < 3; i++)  //define counting variable i, stay in the loop while i < 3, i increases by 1 every loop
  {
    pinMode(buttonPin[i], INPUT_PULLUP);  //sequentially sets the 1st, 2nd, and 3rd item in the array buttonPin to HIGH each time through the loop
  }
}

void loop()
{
  for (byte i = 0; i < 3; i++)  // define counting variable "i", stay in the loop while i < 3, i increases by 1 every loop
  {
    if (digitalRead(buttonPin[i]) == LOW)  //checks the buttonPin array to see if any buttons go low
    {
      state = i;  //if a button goes low, assign whichever location it is in the array to the variable "state"
      break;  //leave the loop
    }
  }
  analogWrite(ledPin, map(analogRead(potPin[state]), 0, 1023, 0, 255));  
/*set the brightness of the LED by reading the analog input that has the same location 
in the array "potPin" as in the array "buttonPin" and map it to the range of a digital output pin*/
                                                                     
}                                 
}

I think I have a handle on it but just want to make sure my understanding is correct. The two questions I do have are:

Why is the state set to -1? Is it to constrain the possible definitions to between -1 and <3 when in conjunction with the for loop?

Why is "i" used as a counting variable? It seems like this occurs a lot in code and I am curious if there is a specific reason or if it is just a convention.

Thanks,
Kevin

it looks like mostly you understand.

Solderfumes73:
Ok, I have gone through the code and added comments to what I think is going on:

pinMode(buttonPin[i], INPUT_PULLUP);  //sequentially sets the 1st, 2nd, and 3rd item in the array buttonPin to HIGH each time through the loop

it sets the 0th, 1st and 2nd pin in the array (array elements start with zero, not one) to INPUT mode and turns on the internal pull-up resistor, so you don't have to put a resistor on your pushbutton switch.

Why is the state set to -1? Is it to constrain the possible definitions to between -1 and <3 when in conjunction with the for loop?

I set the state to a known number, outside the range of the three states (0, 1, and 2) so that the led is not on when the program starts.

Why is "i" used as a counting variable? It seems like this occurs a lot in code and I am curious if there is a specific reason or if it is just a convention.

it is more or less a convention. The variable is declared (e.g. int i = 0) and will stay in use (you can google: variable scope) only for the time it is used within the for loop.

break;  //leave the loop

I put this in there if more than one button is pressed, the first button detected as LOW (lowest element in the button pin array) will control the led. try it... holding two or even three down at once.

Awesome! You really went above the call of duty to help me out, Bulldog. Thank you!