Arduino, button with 3 states, debouncing problem

I've got a button hooked up to my Arduino and I'm trying to do a state change with 3 different states.

Here is my code:

const int buttonPin = 2;

int buttonState = 0;
int lastButtonState = 0;
int StateNum = 0;

void setup() {
pinMode(buttonPin, INPUT);
}

void loop() {
// read the pushbutton input pin
buttonState = digitalRead(buttonPin);

// change the state of the led when someone pressed the button
if (buttonState == 1) {
stateNum++;
if(stateNum>2) stateNum=0;
}

if (stateNum == 0)
{
doSomething0()
}
elseif (stateNum == 1)
{
doSomething1()
}
elseif (stateNum == 2)
{
doSomething2()
}

// adding a small delay prevents reading the buttonState to fast (debouncing)
delay(20);
}

void doSomething0()
{

}

void doSomething1()
{

}

void doSomething2()
{

}

The problem is, when I press the button "doSomething0()" is called fine, but when I press again "doSomething1" is read very quickly then it jumps to "doSomething2"!

Is this a debouncing problem? If so how can it be solved in my code?

Any help is appreciated.

Regards,
M.

The problem is that the loop keeps running all the time the button is depressed. If someone holds the button down for longer than your delay time (20ms), then its going to go round the loop again, adding 1 to the state, and this will keep going until the button is released.

Ideally, you want to update the states when the button is released (after being pressed). So when the button is pushed you toggle a variable to say it's been pressed, and then only react to the push when the button is released - increasing the state etc. This way it doesn't matter how long the button is held down, it will only increase the state by 1 for each push.

You are not waiting for the button to become un pressed so as you hold it down it just zips through all the states.

EDIT
You beat me by 22 seconds. :wink:

So do I need to make it like this?

const int buttonPin = 2;

int buttonState = 0;
int lastButtonState = 0;
int StateNum = 0;

void setup() {
pinMode(buttonPin, INPUT);
}

void loop() {
// read the pushbutton input pin
buttonState = digitalRead(buttonPin);

if (buttonState != lastButtonState) {

// change the state of the led when someone pressed the button
if (buttonState == 1) {
stateNum++;
if(stateNum>2) stateNum=0;
}

if (stateNum == 0)
{
doSomething0()
}
elseif (stateNum == 1)
{
doSomething1()
}
elseif (stateNum == 2)
{
doSomething2()
}

lastButtonState = buttonState;
}

// adding a small delay prevents reading the buttonState to fast (debouncing)
delay(20);
}

void doSomething0()
{

}

void doSomething1()
{

}

void doSomething2()
{

}

????????

M/

First off pleas post the code correctly. Highlight the code in the reply box and hit the has key. Pleas go back and modify the last post.

This is better but it will advance the state on each press and each unpress, is that what you want.
Also I would put a switch construct in place of all those if .. then .. else lines, they get confusing when you have mre than a couple.

Well I just want it on the unpress, NOT press and unpress.

M.

so you do:-
if ((buttonState != lastButtonState) && (buttonState == HIGH) ) {

Or LOW if it is LOW on a release.