Go Down

Topic: Push button switch program (Read 2059 times) previous topic - next topic

it_zac

Hi,

I am trying to program my push button switch to switch on the LED if i press once and to switch off if i press again.
Below is the program i have written.. Its not performing the task i want.

Can someone please check and tell me where I have gone wrong.


int switchpin=2, ledpin=10, reading, current_state, brightness;
int initial_state=LOW;

void setup()
{
  pinMode(ledpin, OUTPUT);
  pinMode(switchpin, INPUT);
}

void loop ()
{
  reading=digitalRead(2);
  current_state=debounce(reading);
 
  if (current_state==HIGH && initial_state==LOW)
  {
    digitalWrite(ledpin, HIGH);
    initial_state=HIGH;
  }
 
  if (current_state==HIGH && initial_state==HIGH)
  {
    digitalWrite(ledpin, LOW);
    initial_state=LOW;
  }

}
 

int debounce(int reading)
{
  current_state=digitalRead(2);
  if (current_state!=reading)
  {
    delay(50);
    current_state=digitalRead(2);
    return(current_state);
  }
  else
  {
    return(current_state);
  }
}

Thanks

InvalidApple

#1
Apr 20, 2012, 08:21 am Last Edit: Apr 20, 2012, 08:30 am by InvalidApple Reason: 1
I would approach the program a bit differently...

I'd try a set up more like
Code: [Select]

int button_pushed(void)
{
  // See if button is pushed
  if (digitalRead(2))
  {

     // Wait for bouncing
     delay(20);

     // if button still pushed
     if (digitalRead(2))
     {
        return 1;
     }

  }

  return 0;    
}


And in the main loop...

Code: [Select]

/* Wait for button to be pushed */
while (!button_pushed());

/* Turn on LED */
digitalWrite(ledpin, HIGH);

/* Wait for button to be let go */
while (button_pushed());

/* Wait for button to be pushed */
while (!button_pushed());

/* Turn off LED */
digitalWrite(ledpin, LOW);

/* Wait for button to be let go */
while (button_pushed());




lampard

I'm doing something similar with MIDI CC changes (switching between two states with one button press).

You might find something useful here: http://arduino.cc/forum/index.php/topic,101751.0.html

All the best!

tgm1175

Try this:

Code: [Select]



#define SWITCHPIN 2
#define LEDPIN 13
#define DEBOUNCE_INTERVAL 250

void setup()
{
  Serial.begin(9600);
  pinMode(LEDPIN, OUTPUT);
  pinMode(SWITCHPIN, INPUT);
  digitalWrite(SWITCHPIN, HIGH);
  attachInterrupt(0, &onButtonPress, FALLING);
 
}

void loop()
{
 
}

void onButtonPress()
{
  static unsigned long last_event = 0;
  static  boolean led_state = false;
 
  if (millis() -  last_event > DEBOUNCE_INTERVAL)
  {
     last_event = millis();
     
     led_state=~led_state;
     digitalWrite(LEDPIN, led_state);
     
  }
}

PaulS

Talk about overkill. You don't need interrupts to read a single button press.

OP, the problem with your code is the way you assign a new value to initial_state. You should have this in loop:
Code: [Select]
int ledState = LOW;
void loop()
{
  current_state = digitalRead(2);
  if (current_state != initial_state)
  {
    // A transition occurred
    if(current_state == HIGH)
    {
       // to pressed
       ledState = !ledState;
       digitalWrite(ledpin, ledState);
    }
  }
  initial_state = current_state;
  delay(20); // debounce
}

it_zac

Thanks all.. specially PaulS for pointing out the mistake.

I have one more q.. If i want the led to slowly light up should i put analogWrite instead of digitalwrite and put it in a 'for' loop.

it_zac

Below is the prog.. It's not functioning the way i want
I want the led to light up slowly

{
  reading=digitalRead(switchpin);
  current_state=debounce(reading);
 
  if (current_state!=initial_state)
  {
    if (current_state==HIGH && counter==HIGH)
    {
      while (current_state==HIGH)
      {
        if (brightness<=255)
        {
          brightness=brightness+15;
          analogWrite(ledpin, brightness);
          delay(200);
        }     
      }
    }
   
    if (current_state==HIGH && counter==LOW)
    {
      while (current_state==HIGH)
      {
        if (brightness>=0)
        {
          brightness=brightness-15;
          analogWrite(ledpin, brightness);
          delay(200);
        }             
      }
    }
  }
  initial_state=current_state;
  counter=!counter;
}

it_zac

I want the led to stop at whatever brightness it is once the button is released.. appreciate if someone can help me fix it

PaulS

Code: [Select]
      while (current_state==HIGH)
      {
        if (brightness<=255)
        {
          brightness=brightness+15;
          analogWrite(ledpin, brightness);
          delay(200);
        }     
      }

If this while statement is encountered when current_state contains HIGH, the body is executed. Since nothing in the body ever changes the value of current_state, the while loop will never end.

You need to change the while statement to an if statement. The loop() function takes care of the looping. Get rid of the debounce function. The delay()s in the increment/display steps will take care of any bouncing issues.

rheine

#9
Jul 06, 2012, 03:45 am Last Edit: Jul 06, 2012, 05:15 am by rheine Reason: 1
My two cens for ON OFF button. I'm an old programmer of ancient languages but new to Arduino fun. This reverses the output pin every time the button is pressed.  Some of the delays are left over from other tries. I just needed a quick way to turn ON /OFF and hold that state.

while (buttonState == HIGH) {  
      delay(20);  // debounce
     
     if (digitalRead(led) == HIGH) {    
     digitalWrite(led, LOW);  
     delay(100);  // debounce
     break;    
 }
   if (digitalRead(led) == LOW) {    
     digitalWrite(led, HIGH);  
      delay(100);  // debounce
      break;
   }
 }


Thanks PaulS for all the great coding examples
rheine



Go Up