Home \ Help \ Search \ Login RSS

Welcome, Guest. Please Login

This forum is now READ-ONLY! Please visit http://forum.wiring.co/ for the new forum.

Wiring ForumWiring HardwareTangible computing › Rebound effect of a pushbutton ?

Pages: 1 2 
Rebound effect of a pushbutton ? (Read 22460 times)
12/20/08 at 10:58:37

Jean-Marie   Offline
YaBB Newbies
Arlon - BELGIUM

Posts: 8
*
 
Hello,

I am new to µprocessors and to Wiring. So, I am starting with simple schemas and simple software. (Evenmore, my native language is French).

I have 2 LED’s. I want to turn on one of them and then change the highlighted LED each time I press a button.

This is the schema I realised on a breadboard:
http://www.flickr.com/photos/jmc-at-sterpenich/3122568870/

And then the software:

int LedPin1 = 0;
int LedPin2 = 1;
int ButtonPin = 2;
int val = LOW;
int oldval = LOW;
int Temp;

void setup()
{
 pinMode(LedPin1, OUTPUT);
 pinMode(LedPin2, OUTPUT);
 pinMode(ButtonPin, INPUT);
}

void loop()
{
 val = digitalRead(ButtonPin);    // read input value and store it in val
   if (val != oldval)             // the button has just changed
 {  
   if (oldval == LOW)             // the button has been pressed
    {
      Temp = LedPin1;
      LedPin1 = LedPin2;          // reverse the order of pins
      LedPin2 = Temp;      
    }  
 }
   oldval = val;
   digitalWrite(LedPin1, LOW);    
   digitalWrite(LedPin2, HIGH);    // Highlight the LED associated to LedPin2
}



It looks quite simple. Nevertheless, when I run it, it does’t work consistently. Sometimes I press the button  and nothing is happening. The same LED stays lighted on. I pressed the button 100 times. The highlighted LED changed in 58 % of the cases and stayed the same in 42 %. Sometimes the other LED flashed a little bit but did not really light on.

As I don’t see any error in the hardware or the software (but of course I could be wrong) I think the inconsistent behavior could come from a rebound effect of the pushbutton. But if it is right, I then wonder why it is not mentionned in the examples and tutorials. Could you help me to clarify this apparent inconsistency ?
 
IP Logged
 
Reply #1 - 12/20/08 at 11:13:08

Titus   Offline
Full Member
Wiring Soccer Robot!
Amsterdam

Posts: 176
***
 
Button's can be very, uhm, unprecise.

Actually when you press a button, the signal doesn't change in 1 instant, it bounces up and down a few times(0 to 100 i guess)

try a counter and display the times pressed on the serial monitor, see if you button is a bouncy button:P

If that doesn't help, i will rebuild your test here and see if your code works here Tongue

Titus

Edit, ah you're in Arlon, that's close to me =D
Where did you buy your wiring board? from Hernando?
 

Check www.TeamVossius.nl for our Autonomous soccer robots!
IP Logged
 
Reply #2 - 12/20/08 at 12:18:57

Kars   Offline
YaBB Newbies
Team Vossius
Amsterdam

Posts: 19
*
 
Hey, you made two integer variables called val and oldval
You assign 2 values to it, LOW or HIGH.
Well, thats wrong because an integer could only hold a number, and not a word.
What you want is a boolean, you can assign 2 values to a boolean, TRUE or FALSE

Hope this well help you
 

Buildig the same as Titus ^^
IP Logged
 
Reply #3 - 12/20/08 at 15:48:23

Titus   Offline
Full Member
Wiring Soccer Robot!
Amsterdam

Posts: 176
***
 
I should have seen that.

Only this line will give you an error:
val = digitalRead(ButtonPin);    // read input value and store it in val

I think you could best do that by an if else structure:
if (digital read is high) val = true
else var = false

Good luck

Titus
 

Check www.TeamVossius.nl for our Autonomous soccer robots!
IP Logged
 
Reply #4 - 12/20/08 at 16:24:08

Jean-Marie   Offline
YaBB Newbies
Arlon - BELGIUM

Posts: 8
*
 
Hello, Titus and Kars

Titus first.
Thank you for your excellent idea. I put a counter and wrote its value on the serial monitor.

Here is the software. The changes are in blue.

#include <HardwareSerial.h>

int LedPin1 = 0;
int LedPin2 = 1;
int ButtonPin = 2;
int val = LOW;
int oldval = LOW;
int Temp;

int Counter = 0;


void setup()
{
 pinMode(LedPin1, OUTPUT);
 pinMode(LedPin2, OUTPUT);
 pinMode(ButtonPin, INPUT);

 Serial.begin(9600);
}

void loop()
{
 val = digitalRead(ButtonPin);    // read input value and store it in val
   if (val != oldval)             // the button has just changed
 {

   Counter++;  
   Serial.println (Counter);

   if (oldval == LOW)             // the button has been pressed
    {
      Temp = LedPin1;
      LedPin1 = LedPin2;          // reverse the order of pins
      LedPin2 = Temp;      
    }  
 }
   oldval = val;
   digitalWrite(LedPin1, LOW);    
   digitalWrite(LedPin2, HIGH);    // Highlight the LED associated to pin2
}


Results: sometimes the counter increases by 1 when I press the button. But sometimes it increases by 2,3 or 4 when I press the button or even when I hold it pressed. So the default is due to the bad contact in the button.

Compared to America, Arlon is close to Amsterdam. Ik kan zelfs een beetje Nederlands spreken. (For the others, I said that I can even speak a little bit in Dutch).

I didn't buy my wiring board. It was given to me by my son-in-law who had two boards. I think the fuse fried on the first board. Then he bought a second one before finding about the fuse. So he replaced it on the first board and he gave it to me.

Thanks for your help.



Hello Kars (and last comment of Titus),

I have to investigate a bit more about integers and boolean values before replying, but the software seems to work. I have to find out what sort of variable are HIGH and LOW. I will write a comment as soon as I have an answer.
 
IP Logged
 
Reply #5 - 12/20/08 at 17:25:37

Jean-Marie   Offline
YaBB Newbies
Arlon - BELGIUM

Posts: 8
*
 
Hello Kars,

I suspect you are wrong. LOW and HIGH seem to be integers of special value : 0 and 1.

That's what I understand when I read the description of
digitalRead()
http://wiring.org.co/learning/reference/digitalRead_.html

To confirm this, I added 2 lines in the software:

........
   Counter++;
   Serial.print (oldval);
   Serial.print ("  ");

   Serial.println (Counter);
.........

This way, each time the button was pressed or released (without bouncing), the counter was preceded by 0 or 1.

Anyway, your comment was helpful to highlight this part of the language.  Smiley
 
IP Logged
 
Reply #6 - 12/21/08 at 12:35:26

Titus   Offline
Full Member
Wiring Soccer Robot!
Amsterdam

Posts: 176
***
 
So the problem is solved? And the problem was the push button?

Perhaps you could use the "RISING" command, but it seems to be restricted to the external interrupt pins?
I wish you good luck with your wiring, and remember, we're always here to help.
 

Check www.TeamVossius.nl for our Autonomous soccer robots!
IP Logged
 
Reply #7 - 12/21/08 at 15:53:56

Jean-Marie   Offline
YaBB Newbies
Arlon - BELGIUM

Posts: 8
*
 
Hello Titus,

Well, the problem is understood, but not really solved so far. In fact, it is not a real problem because I am just experimenting and learning.

I will try using RISING and attachInterrupt(). I will let you know if it makes any difference.

Thank you for your help. It is much appreciated.  Smiley
 
IP Logged
 
Reply #8 - 12/22/08 at 16:58:33

Alan_Kilian   Offline
Full Member
Wiring? It looks like
Java to me.

Posts: 118
***
 
Switch debouncing is a very interesting subject.

If you're interested in reading more about it, here are two articles:

http://www.embedded.com/columns/breakpoint/18400810?_requestid=152194

http://embedded.com/showarticle.jhtm?articleid=18902552

 
IP Logged
 
Reply #9 - 12/22/08 at 17:25:30

Jean-Marie   Offline
YaBB Newbies
Arlon - BELGIUM

Posts: 8
*
 
Thank you, Alan, for your comment.

I will go and read these articles. Also, I made the experiments with "attachInterrupt". I will comment later on but for now, I have to make a bread. (a real one, not a breadboard   Wink ).

By the way, does anyone know what I have to do to get a notification of reply in my mailbox ? The case "Notify of replies" is already cheched but is grey and I don't have access to it.
 
IP Logged
 
Reply #10 - 12/22/08 at 19:04:13

Titus   Offline
Full Member
Wiring Soccer Robot!
Amsterdam

Posts: 176
***
 
http://wiring.org.co/cgi-bin/yabb/YaBB.pl?action=shownotify
Is this topic in there?

Titus
 

Check www.TeamVossius.nl for our Autonomous soccer robots!
IP Logged
 
Reply #11 - 12/22/08 at 23:05:43

Jean-Marie   Offline
YaBB Newbies
Arlon - BELGIUM

Posts: 8
*
 
Hello Titus,

Thanks. I hope the notification will work now.

So, first of all the experiments. According to your suggestions, I changed the code like this:

/*
* A pushbutton (pin 2) must reverse the lighting of 2 LED's
*/
#include <HardwareSerial.h>
int LedPin1 = 0;
int LedPin2 = 1;
int ButtonPin = 2;
int Temp;
int Counter = 0;

void setup()
{
 pinMode(LedPin1, OUTPUT);
 pinMode(LedPin2, OUTPUT);
 pinMode(ButtonPin, INPUT);
 Serial.begin(9600);
 attachInterrupt(ButtonPin,shiftLED,FALLING);
}

void loop()
{
}
void shiftLED()
 {
   Counter++;
   Temp = LedPin1;
   LedPin1 = LedPin2;          // reverse the order of pins
   LedPin2 = Temp;
   digitalWrite(LedPin1,LOW);
   digitalWrite(LedPin2,HIGH);    
   Serial.println(Counter);
 }


I didn't change anything to the hardware. As you can see, the main loop is doing nothing. When an interrupt is detected on buttonPin, the shiftLED function is started. I used FALLING mode instead of RISING because, according to the schema, when the button is pressed then the pin is driven to zero.

The code is shorter than the previous version. The circuit is working but the bouncing is even worse than before. I pressed the button 10 times and the counter was already at 31 ! It could be explained by the fact that the empty loop can be interrupted any time. But what happens if the program is interrupted while running the shiftLED function ? I don't know. The only thing I can say is that there is no number missing on the serial monitor, which means that no interrupt happened between "Counter++" (beginning of the function) and Serial.println (end of the function).

In an attempt to stop the program during the bouncing, I inserted "delay(15)" at the beginning of the interrupt function:

void shiftLED()
 {

   
delay(15);  

   
Counter++;
   Temp = LedPin1;
   LedPin1 = LedPin2;          // reverse the order of pins
   LedPin2 = Temp;
   digitalWrite(LedPin1,LOW);
   digitalWrite(LedPin2,HIGH);    
   Serial.println(Counter);
 }


Well, fancy enough, the program compiles and I can upload it to the board but nothing happens when I press the button and the serial monitor stays empty. For the moment, I can't imagine whats going on.

I tried to remove the delay(15) from the interrupt function and put it in the main loop: same result. The program seems to be hanging. Any idea why ?  Roll Eyes



Hello Alan,

I read these two interesting articles. Even if the author said the worst way to cope with bouncing is to wait until it settles down, I tried this solution because it was only one line of program. As you can see, it doesn't work for a reason I ignore. I will try to make a Set-Reset Latch, a Schmitt Trigger or a R-C circuit and let you know the results. On the other hand, I did not understand the way to replace a S-R Latch by wiring the switch to 2 pins and then testing the state of these pins and storing the value in a variable. How does this avoid the problem of bouncing ?
 
IP Logged
 
Reply #12 - 12/23/08 at 16:07:47

Jean-Marie   Offline
YaBB Newbies
Arlon - BELGIUM

Posts: 8
*
 
Hello Alan,

I managed to find some SN7400’s dating from de 80’s. These old IC’s are made of 4 NAND gates, so I used two of them to make an S-R Latch according to your second article. As resistors I took two 10 KΩ. I had to replace the pushbutton by a sliding switch because I don’t have any pushbutton with 3 pins.

For the program, I kept the last version with “attachInterrupt” but removed the “delay(15)” line. Everything went much better than before but it was not perfect yet. I switched on 300 times, counting mentally. At the end, the counter showed 303 on the serial monitor. So 3 bouncings or “doubble count” still appeared. About half the test was made by sliding the switch rather slowly while for the other part the movement was much quicker. All 3 rebounds arose while switching quickly.

To be sure it wasn’t a mental error while counting, I made another 300 switching on but this time making 30 groups of 10 quick movements. I ended with 304 on the counter, which is very consistent with the first test.

So my temporary conclusion: the use of a "bare" S-R Latch is not a 100% secure way to avoid bouncing with a switch. I should try to improve it, perhaps by changing the value of the resistors or adding capacitors.

But Christmas being almost at the door, I wish you all a merry Christmas. See you a bit later.  Smiley Smiley
 
IP Logged
 
Reply #13 - 12/23/08 at 16:55:15

Jean-Marie   Offline
YaBB Newbies
Arlon - BELGIUM

Posts: 8
*
 
To be more complete, I just finished another 30 x 10 switching on with the sliding switch alone (having removed the latch). Well, amazingly the counter of the serial monitor showed exactly 300, without any bouncing !   Shocked

I will do my best to clarify all that after Christmas.
 
IP Logged
 
Reply #14 - 01/12/09 at 16:41:18

Titus   Offline
Full Member
Wiring Soccer Robot!
Amsterdam

Posts: 176
***
 
You might want to take a look at this:

http://www.arduino.cc/playground/Code/Debounce
Debouncing code Tongue
 

Check www.TeamVossius.nl for our Autonomous soccer robots!
IP Logged
 
Pages: 1 2