With a pushbutton, you always need a pullup/pulldown.
Now the internal pullup/pulldown is often adequate for the task at hand. You also need to be aware that all mechanical switches have bounce, and by this I mean that you may very well get multiple edges per press of the button.
Here's a really good article about switch bounce:
http://www.ganssle.com/debouncing.htm
When I use interrupts, then I normally use the following debouncing algorithim:
1 - Setup a falling edge interrupt (assume closing the switch grounds the input)
2 - When the edge occurs, disable the interrupt and start a timer for 20 milliseconds.
3 - When the timer interrupt occurs, check the level of the GPIO line and use that level as the switch value.
You can also do this in a polling fashion and not bother with interrupts at all. This works really well when you have a regular main loop (I often use a main loop which runs on some regular period like 10 msecs. This article describes some background:
http://members.shaw.ca/climber/avrbuttons.html
I created the following C code that I've used before in my robots:
https://github.com/dhylands/projects/bl ... n/Switch.h
https://github.com/dhylands/projects/bl ... n/Switch.c
It works really well when you need to keep track of a bunch of buttons (it's really easy to support up to 32 for example).
Due to the fact that you can't allocate memory from an interrupt, I'd be inclined to just have the interrupt set a flag indicating that the button was pressed. Then your main loop can just do something simple like:
Code: Select all
if start_pressed:
start_pressed = False
pyb.delay(20)
re-enable the ExtInt interrupt
if start.pin.value():
# do your start collection process
and have the exti interrupt set start_pressed to True, and disable itself
Another way would be to have an event queue, and have the button presses add an event to the queue and have the main loop dequeue and process events from the event queue.
I'd be happy to code up a more complete example if the above is still too abstract.