Pages: [1]   Go Down
Author Topic: button toggle  (Read 2106 times)
0 Members and 1 Guest are viewing this topic.
0
Offline Offline
Jr. Member
**
Karma: 0
Posts: 63
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

i have had a look at a few pieces of code on 'toggling' and as i dont understand the use of boolean commands very well i opted to read the button state and use a counter to toggle between outputs, though i'm not sure if its the best way! I have written this piece of code but it doesn't quite work yet. when the button is pressed once the first led comes on and toggles off, the second led doesn't light up. when the first led is on it flickers.
Also the serial monitor only shows up a message when button press is 0 (every two button presses) which suggests that the button presses are being counted ok.

Code:
int button = 2;
int val;        
int val2;
int state;            
int press = 0;  
int led1Pin = 12;
int led2Pin = 13;


void setup() {
  pinMode(button, INPUT);
  Serial.begin(9600);        
  state = digitalRead(button);
 
}


void loop(){
  val = digitalRead(button);
  delay(10);          // wait 10 millis to counter debounce
  val2 = digitalRead(button); //check again to see if button is pressed
  
 
  
  if ((val == val2) && (val != state) && (val == HIGH)) {              
      press++;
    }
    if (press >1) {
    press = 0;
    Serial.print("press number");
    Serial.println (press);
  }
    if (press == 0) {
      digitalWrite(led1Pin, HIGH);
      delay (100);
      digitalWrite (led1Pin, LOW);
      
      
    }
    else {if (press == 1) {
      digitalWrite(led2Pin, HIGH);
      delay (100);
      digitalWrite (led2Pin, LOW);
    }
    }
  
  state = val;
}


this is what I am trying to do; one momentary push button input to toggle between two outputs.  the first button press and release to cause pin 13 HIGH for 100 millis. the second button press to cause pin 12 HIGH for 100 millis. these outputs just need to be single brief pulses to trigger another event.

thanks in advance for any suggestions.
Logged

Seattle, WA USA
Offline Offline
Brattain Member
*****
Karma: 601
Posts: 48569
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I'd start by declaring the led pins to be output pins, in setup.

I'm not sure what the reference to boolean commands is about, since you use no boolean variables.

Your code would be a lot easier to follow it it was uniformly indented. The IDE provides a tool to do that.

You might try turning one LED on when the button is pressed once, and turning the other one off.
When it is pressed again, reverse which one is on.

If all else fails, use the button library.
Logged

0
Offline Offline
Jr. Member
**
Karma: 0
Posts: 63
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Thanks for that.  I don't know how i missed the setup mistake, i think i've been looking at the screen for too long!

The led's toggle as they're supposed to now. The only problem left is the flicker. i guess this is caused by the
Code:
if (press == 0) {
    digitalWrite(led1Pin, HIGH);
    delay (100);
    digitalWrite (led1Pin, LOW);
code running in a loop rather than just running once, is there a way to stop this?
Logged

0
Offline Offline
Jr. Member
**
Karma: 0
Posts: 63
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

2nd problem: when i upload the sketch and it starts running the led on pin 12 lights up and stays on before a button has been pressed!

here is the code now
Code:
int button = 2;
int val;        
int val2;
int state;            
int press = 0;  
int led1Pin = 12;
int led2Pin = 13;


void setup() {
  pinMode(button, INPUT);
  pinMode(led1Pin, OUTPUT);
  pinMode(led2Pin, OUTPUT);
  Serial.begin(9600);        
  state = digitalRead(button);

}


void loop(){

  val = digitalRead(button);
  delay(10);          // wait 10 millis to counter debounce
  val2 = digitalRead(button); //check again to see if button is pressed

  if ((val == val2) && (val != state) && (val == HIGH)) {              
    press++;
  }
  if (press >1) {
    press = 0;
    Serial.print("press number");
    Serial.println (press);
  }
  if (press == 0) {
    digitalWrite(led1Pin, HIGH);
    delay (100);
    digitalWrite (led1Pin, LOW);


  }
  else {
    if (press == 1) {
      digitalWrite(led2Pin, HIGH);
      delay (100);
      digitalWrite (led2Pin, LOW);
    }
  }

  state = val;
}




« Last Edit: May 18, 2010, 03:59:07 pm by chopeone1 » Logged

Manchester (England England)
Offline Offline
Brattain Member
*****
Karma: 604
Posts: 33448
Solder is electric glue
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
the led on pin 12 lights up and stays on before a button has been pressed

So look at the initial states you gave your variables when you declared them.
Logged

0
Offline Offline
Jr. Member
**
Karma: 0
Posts: 63
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

i tried removing the 0 value declared at the start, also i tried setting it to a number other than 0 or 1 but the same thing still happens. i guess it is because the way i have designed the code there are only two possible states for it to be.
Logged

0
Offline Offline
Jr. Member
**
Karma: 0
Posts: 63
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

fixed that one, i added an extra factor to switch the led on, so it couldnt be triggered till a button had been pressed. thanks.

Any ideas on how to stop the leds flicker? i just want them to send out one pulse.
« Last Edit: May 18, 2010, 06:20:06 pm by chopeone1 » Logged

Seattle, WA USA
Offline Offline
Brattain Member
*****
Karma: 601
Posts: 48569
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

The loop function should not do anything unless a button is (being) pressed. When the button is being pressed, and was not before, do something.

You are already testing this. But, you need to move all the code for flashing the LED into that if block, instead of after it.
Logged

0
Offline Offline
Jr. Member
**
Karma: 0
Posts: 63
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

thanks for the advice, though im not sure what you mean by
Quote
But, you need to move all the code for flashing the LED into that if block, instead of after it.
could you explain a bit more? thanks.
Logged

0
Offline Offline
Jr. Member
**
Karma: 0
Posts: 63
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

i worked it out eventually... thanks for all the help. Here is the working
Code:
/* button toggle - use one button to toggle between two outputs on different pins
   momentary push button attached to pin 2
   leds connected to pins 12 & 13
*/

int button = 2;  //button attached to pin 2
int val;        // reads the button state in loop
int val2;       // reads the button state a second time
int state;      // reads the button state in setup and stores it  could have called this button old    
int press = 1; // press counter, i set this to 1 so when the first button is pressed it will give a value of 0 activating the first pin
int led1Pin = 12; // led output 1
int led2Pin = 13; // led output 2
int button1hit = 0;  // secondary code switch stops code running before a button has been pressed


void setup() {
  pinMode(button, INPUT);
  pinMode(led1Pin, OUTPUT);
  pinMode(led2Pin, OUTPUT);
  Serial.begin(9600);        
  state = digitalRead(button);  // read button state and store it to reference against later
  
}


void loop(){

  val = digitalRead(button);
  delay(10);          // wait 10 millis to counter debounce
  val2 = digitalRead(button); //check again to see if button is pressed

  if ((val == val2) && (val != state) && (val == HIGH)) {              
    press++; // counts button presses
    button1hit = 1; //secondary code switch put in place
  }
  if (press > 1) {
    press = 0;    //when button press count passes 1 it resets to zero
    Serial.print("press number");
    Serial.println (press);
  }
  if (press == 0 && button1hit == 1) {
    digitalWrite(led1Pin, HIGH);
    delay (100);                  // send one pulse
    digitalWrite (led1Pin, LOW); // then stop
    button1hit = 0;              // wait for button to be pressed before doing anything else
    


  }
  else {
    if (press == 1 && button1hit == 1) {
      digitalWrite(led2Pin, HIGH);
      delay (100);
      digitalWrite (led2Pin, LOW);
      button1hit = 0;
    }

  }

  state = val;
}





I hope its useful to others!
« Last Edit: May 19, 2010, 05:20:10 am by chopeone1 » Logged

Seattle, WA USA
Offline Offline
Brattain Member
*****
Karma: 601
Posts: 48569
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

You could make this simpler.

This code:
Code:
 if (press > 1) {
    press = 0;    //when button press count passes 1 it resets to zero
    Serial.print("press number");
    Serial.println (press);
  }
can go inside this block:
Code:
 if ((val == val2) && (val != state) && (val == HIGH)) {              
    press++; // counts button presses
    button1hit = 1; //secondary code switch put in place
    // Put the above block here.
  }

Then, notice that you only set button1Hit to 1 in one place. Then, you test, in two places that it is == 1. You could make loop like this:
Code:
void loop()
{
  val = digitalRead(button);
  delay(10);          // wait 10 millis to counter debounce
  val2 = digitalRead(button); //check again to see if button is pressed

  if ((val == val2) && (val != state) && (val == HIGH))
  {              
    press++; // counts button presses
    if (press > 1)
    {
      press = 0;    //when button press count passes 1 it resets to zero
      Serial.print("press number");
      Serial.println (press);
    }

    if (press == 0)
    {
      digitalWrite(led1Pin, HIGH);
      delay (100);                  // send one pulse
      digitalWrite (led1Pin, LOW); // then stop
    }
    else
    {
      digitalWrite(led2Pin, HIGH);
      delay (100);
      digitalWrite (led2Pin, LOW);
    }
  }

  state = val;
}
Logged

Pages: [1]   Go Up
Jump to: