Multiple buttons with single wire input, help needed.

Hello everyone, I'm new to the Arduino community and have only been learning for a couple of days. I have greatly enjoyed learning and have discovered a lot from looking at these forums. However I'm stumped on my latest endeavor.

I've managed to get each button to control a separate LED through a single analog wire. The problem is I can not figure out for the life of me how to not continue to repeat the effect. For instance, when I press button one, led one increases in brightness. If I hold down button one, led one continues to cycle through it's brightness level.

In short I just want a held button to act as a single button action and not continually repeat. One press, one action, until it is released and pressed again. I've tried several ways of doing this to no avail so I'll share my raw setup up and code. If you can help that would be great, and feel free to be honest if I've just done something completely backwards. I may be a noob but I can take some criticism. Thanks in advance.

And of course, if you want to use this code and/or setup feel free, just please share your uses/discoveries. :slight_smile:

Here's the setup:

And here is my code:

/*

Desired effects:

LED ONE, when button is pressed increase one level in brightness untill button is released, and pressed again, then increase in brightness again
LED TWO, only light whil button two is pressed and held.
LED THREE and FOUR, Light when button is pressed. Turn off when button is pressed for a second time

*/



const int switcharrayPin=0; //switch array to analog pin 0
const int ledonePin=11; // LED ONE
const int ledtwoPin=10; // LED TWO
const int ledthreePin=9; // LED THREE
const int ledfourPin=6; // LED FOUR

int ledonelevel=0; // Set ledone begining level

boolean switchone = false; // Hold value of Switch ONE
boolean switchtwo= false; // Hold value of Switch TWO
boolean switchthree= false; // Hold value of Switch THREE
boolean switchfour = false; // Hold value of Switch FOUR



void setup()
{
  Serial.begin(9600); // Start serial communication
  pinMode (switcharrayPin, INPUT); // set switch array to input
  pinMode (ledonePin, OUTPUT); // set ledone to output
  pinMode (ledtwoPin, OUTPUT); // set ledtwo to output
  pinMode (ledthreePin, OUTPUT); // set ledthree to output
  pinMode (ledfourPin, OUTPUT); // set ledfour to output
}



void loop() 
{
  int switcharrayval = analogRead(switcharrayPin); //Read switcharryPin

    if(switcharrayval > 350 && switcharrayval < 550) //Check if switch one was pressed
  {
    ledonelevel = ledonelevel + 51; // Add 51 to ledonelevel
    if (ledonelevel >255) ledonelevel=0; //Recycle LED after max level
    analogWrite(ledonePin, ledonelevel); // Cycle led through level
  }

  if(switcharrayval > 260 && switcharrayval < 350) // Check if switch two was pressed
  {
    switchtwo=true; // Turn on switch two
  }
  if (switcharrayval < 260 || switcharrayval > 350) // Check if switch two was released
  {
    switchtwo=false; // Turn off switch two
  }
  digitalWrite(ledtwoPin, switchtwo); // Set ledtwo to switch two


    if(switcharrayval > 230 && switcharrayval < 300) // Check if switch three is pressed
  {
    delay(10);
    switchthree=!switchthree; // If so reverse the value of switch three
    digitalWrite(ledthreePin, switchthree); // Set ledthree ledthree to same value as switch three
  }

  if(switcharrayval > 150 && switcharrayval < 225) // Check if switch four is pressed
  {
    switchfour=!switchfour; // If so reverse the value of switch four
    digitalWrite(ledfourPin, switchfour); // Set ledfour to same value as switch four
  }

  Serial.println(analogRead(switcharrayPin)); // Display switcharrayPin value in serial monitor
  delay(100); // Set serial monitor delay
}

The code is a bit confusing. I would write it so that the first thing you do is to set a variable that indicates what switch is being pressed.
Then write the code that does the action you want.
You will need a variable that notes the time when the button was first pressed using millis(), so you will need another that notes what switch was pressed the last time through the loop. I can't see any of that in your code and you need that sort of information if you want to do what you say.

Thanks for the reply!

I know the code I provided won't give the desired result, it was just more or less the foundation that I'm building off of.

I've been fighting with this all night and finally stripped it down to a single led, coded it as if it was a digital switch just provding high or low, and not an analog. Then I just went back and added my if() statements. Finally it works! Now I'd just need to add separate booleans for each of my four LEDS but I might actually be able to handle that. :stuck_out_tongue:

If anyone is interested here is the working code:

/*

 Desired Effects:
 Led One, When button one is pressed, LED one is On. 
 Do not change state untill button is released and pressed again.
 
 */

// Define Constants
const int switcharrayPin=A0; // Set switch array pin to analog pin 0
const int ledonePin=11; // Set LED pin to 11

// Define Variables
boolean switchonecurrent=false; // Boolean to hold current switch position
boolean switchonelast=false; // Boolean to hold last switch position
long int switcharrayvalue=0; // Keep track of the switch value between 0 and 1280



void setup()
{
  pinMode (switcharrayPin, INPUT); //set switch array pin to an input
  pinMode (ledonePin, OUTPUT); // set switch array pin to an output
}




void loop()
{
  switcharrayvalue=analogRead(switcharrayPin); // Read Switch Array
  if(switcharrayvalue > 350 && switcharrayvalue < 550 && switchonelast==false)// See if switch one is pressed when it was not pressed before
  {
    switchonecurrent = !switchonecurrent; // If so, flip switch ones value
    switchonelast=true; // If so, make switch ones last state to true
  }
  else
  {
    if(switcharrayvalue < 350 || switcharrayvalue > 550)// See if button one is not pressed
    {
      switchonelast=false; // If it's not, set switch ones last state to false
    }
  }

  digitalWrite(ledonePin,switchonecurrent); // Write switch ones current state to LED One
}

Well I'm back to bother you guys some more.

I manged to get all four switches controlling their own LED, push on, push off, held buttons ignored. So I'm excited about that. However I still have the obvious issue of the switches bouncing. I've debounced single switches using delay() but I've been told this is bad practice. On top of that I don't really see that being feasible with this switch array. Also with it all being through one analog pin I don't see a hardware solution. I know to you guys this is probably a simple problem but I feel that if I don't really learn and understand these basics I'm just shooting myself in the foot before I learn to walk.

Here is my current code, any comments are always welcome, and of course examples. Thanks so much!

// Define Constants
const int switcharrayPin=A0; // Set switch array pin to analog pin 0
const int ledonePin=11; // Set LED pin to 11
const int ledtwoPin=10; // Set LED two pin to 10
const int ledthreePin=9;// Set LED three to pin 9
const int ledfourPin=6; // Set LED four to pin 6



// Define Variables
long int switcharrayvalue=0; // Keep track of the switch value between 0 and 1280

boolean switchonecurrent=0; // Boolean to hold current switch one position
boolean switchonelast=0; // Boolean to hold last switch one position

boolean switchtwocurrent=0; //Hold switch twos position
boolean switchtwolast=0; //Track switch twos position

boolean switchthreecurrent=0; //hold switch threes position
boolean switchthreelast=0; //track switch threes position

boolean switchfourcurrent=0; //hold switch fours position
boolean switchfourlast=0; //track switch threes position




void setup()
{
  pinMode (switcharrayPin, INPUT); //set switch array pin to an input
  pinMode (ledonePin, OUTPUT); // set LED one pin to output
  pinMode (ledtwoPin, OUTPUT); // set LED two pin to output
  pinMode (ledthreePin, OUTPUT); //set LED three pin to output
  pinMode (ledfourPin, OUTPUT); //set LED four pin to output
}




void loop()
{

  // LED ONE CHECK AND SWITCH CODE
  switcharrayvalue=analogRead(switcharrayPin); // Read Switch Array
  if(switcharrayvalue > 350 && switcharrayvalue < 550 && switchonelast==false)// See if switch one is pressed when it was not pressed before
  {
    switchonecurrent = !switchonecurrent; // If so, flip switch ones value
    switchonelast=true; // If so, make switch ones last state to true
  }
  else
  {
    if(switcharrayvalue < 350 || switcharrayvalue > 550)// See if button one is not pressed
    {
      switchonelast=false; // If it's not, set switch ones last state to false
    }
  }
  digitalWrite(ledonePin,switchonecurrent); // Write switch ones current state to LED One






    //  LED TWO CHECK AND SWITCH CODE
  switcharrayvalue=analogRead(switcharrayPin); // Read Switch Array
  if(switcharrayvalue > 320 && switcharrayvalue < 350 && switchtwolast==false)// See if switch two is pressed when it was not pressed before
  {
    switchtwocurrent = !switchtwocurrent; // If so, flip switch twos value
    switchtwolast=true; // If so, make switch twos last state to true
  }
  else
  {
    if(switcharrayvalue < 320 || switcharrayvalue > 350)// See if button two is not pressed
    {
      switchtwolast=false; // If it's not, set switch twos last state to false
    }
  }

  digitalWrite(ledtwoPin,switchtwocurrent); // Write switch twos current state to LED two





  //  LED THREE SWITCH AND CODE
  switcharrayvalue=analogRead(switcharrayPin); // Read Switch Array
  if(switcharrayvalue > 240 && switcharrayvalue < 260 && switchthreelast==false)// See if switch three is pressed when it was not pressed before
  {
    switchthreecurrent = !switchthreecurrent; // If so, flip switch threes value
    switchthreelast=true; // If so, make switch threes last state to true
  }
  else
  {
    if(switcharrayvalue < 240 || switcharrayvalue > 260)// See if button three is not pressed
    {
      switchthreelast=false; // If it's not, set switch threes last state to false
    }
  }

  digitalWrite(ledthreePin,switchthreecurrent); // Write switch threes current state to LED three




  //  LED FOUR CHECK AND SWITCH CODE
  switcharrayvalue=analogRead(switcharrayPin); // Read Switch Array
  if(switcharrayvalue > 190 && switcharrayvalue < 220 && switchfourlast==false)// See if switch four is pressed when it was not pressed before
  {
    switchfourcurrent = !switchfourcurrent; // If so, flip switch fours value
    switchfourlast=true; // If so, make switch fours last state to true
  }
  else
  {
    if(switcharrayvalue < 190 || switcharrayvalue > 220)// See if button four is not pressed
    {
      switchfourlast=false; // If it's not, set switch fours last state to false
    }
  }

  digitalWrite(ledfourPin,switchfourcurrent); // Write switch fours current state to LED four

}

Look at the blink without delay example, that is the basis of what you want to do.
You get the time now with millis and compair the time now whit the time you want certain actions to finish or change.
Also look up the concept of a state machine it is what you want to implement.