Problem with button

Hello folks, this is my first post, and I hope you people can help me.

The board and the program below is to create a light metronome (if I get this one right, I'll add sound too). So when it starts in 2/2 mode, the red led blinks once, waits a little bit, then the green one blinks, and the process starts over. If you press the button for at least 0,5 s (so you can get status0 and status1 to be 1, so status2 goes 1 too and you go into next tempo - this is all in order to avoid debouncing (status0 and status1) and changing tempo if I keep the button pressed (status2)), you get into 3/3 mode, so red blinks once and green blinks twice, with a wait inbetween. Press the button again and you go into 4/4 mode, so red led blinks once and green three times, with a wait inbetween. Press the button again and you go into 2/2 again. The button is pulled down by a 10K resistor. But when I run it, quite often I press the button, but instead of having the red and green led blinking as shown above, I get only the green one blinking indefinitely, and doesn't matter how much I press the button, the green one keeps on blinking. What am I doing wrong?

 * Metro2
 * Simple  metronome with tempo control

int ledvm = 13;                   // Red LED port 13
int ledvd = 12;                   // Green LED port 12
int btn1 = 11;                    // Button 1 port 11
int tempo = 2;                    // Beats ie 2/2 3/3 or 4/4 
int i = 1;                        // Beat counter
int status0=0;                    // Status 0
int status1=0;                    // Status 1
int status2=0;                    // Status 2

void setup()                      // Runs once
  Serial.begin(9600);             // Serial at 9600 bps
  pinMode(ledvm, OUTPUT);         // Port 13 is LED output
  pinMode(ledvd, OUTPUT);         // Port 12 is LED output
  pinMode(btn1, INPUT);           // Port 11 is button input 

void loop()                       // Repeating part
  if (status0==0 && status1==0 && status2==1) {status2=0;};
  if (status0==1 && status0==status1 && status2==0)
    if (tempo>4) {tempo=2;};
  if (i==1)
    digitalWrite(ledvm, HIGH);    // turns red LED on
    delay(50);                    // waits 0,050 s
    digitalWrite(ledvm, LOW);     // turns red LED off
    delay(450);                   // waits 0,450 s
    digitalWrite(ledvd, HIGH);    // turns green LED on
    delay(50);                    // waits 0,050 s
    digitalWrite(ledvd, LOW);     // turns green LED off
    delay(450);                   // waits 0,450 s
  if (i==tempo) {i=1;} else {i++;};

Anyone have any idea that may help??? If not, thanks anyway....

Mind you, I’m quite new so not really sure what would be causing it, but I know using buttons like that can be a pain… Have you tried using debounce?

I read something about getting way more readings than intended from a single button push? Just an idea, might not even be what you need.

What am I doing wrong?

There is a state transition that leaves the variable i unbounded...

  • Button is not down
  • tempo == 4
  • i == 3
  • Button is pressed
  • tempo is incremented to 5 then set to 2
  • i (== 3) is greater than tempo (== 2) so the last if never resets i to 1

  • Brian

Captain Obvious, the use of status0 and status1 is to avoid debouncing, because you have to wait for at least 0,5s for the button press to be valid. Thanks anyway. ;D


Coding badly, maybe that's where I messed it up. Is good to find someone who can get to see where we mess up :o I'll try another way to debounce without going into that "loop trap". Thanks. :D

Haha, well I gave it a shot!
Hopefully you get things worked out!

Best of luck,