I am wanting to create a simple button counter using the IO pins instead of the A/B buttons. With the buttons this is easy because of:
is_pressed()
Returns True if the specified button button is pressed, and False otherwise.
was_pressed()
Returns True or False to indicate if the button was pressed since the device started or the last time this method was called.
With the IO pins, there is no was_pressed, only is_touched. How can I create a counter that will wait until is_touched is False?
was_pressed equivelant for IO pins
Re: was_pressed equivelant for IO pins
The way was_pressed works for the buttons is that every 6ms, the MicroPython firmware checks the state of the buttons (which are on pins 5 and 11), and compares them to what state they were 6ms ago. If they go from unpressed to pressed, it sets a flag, which is what was_pressed() returns. was_pressed() also clears the flag.
Unfortunately in micro:bit MicroPython (unlike main MicroPython), you don't have a way to set up a timer to run code in the background, so you have to do that manually in your main loop. The same approach works if you want to use a pin's value (i.e. because it's connected to an external button).
(Sorry this code is untested, but hopefully illustrates what needs to happen).
This gets a bit messy if you want to handle multiple pins. A nicer way to do this would be to make a class:
BUT... if you want a counter, you don't really care about was_touched, you just want ... well.. a counter:
But the problem with all of these approaches is that it means that you can't use sleep() anywhere in your code, because while you're sleeping your main loop isn't looping. So you need a different way to measure time passing. At my last job we spent a lot of time teaching micro:bits, and I wrote this article that might be relevant to this: https://medium.com/groklearning/become- ... b8b4e2d747
Unfortunately in micro:bit MicroPython (unlike main MicroPython), you don't have a way to set up a timer to run code in the background, so you have to do that manually in your main loop. The same approach works if you want to use a pin's value (i.e. because it's connected to an external button).
(Sorry this code is untested, but hopefully illustrates what needs to happen).
Code: Select all
pin0_flag = False
pin0_last_state = False
def check_pin0_touch():
global pin0_flag, pin0_last_state
pin0_state = pin0.is_touched()
if pin0_state and not pin0_last_state:
pin0_flag = True
pin0_last_state = pin0_state
def pin0_was_touched():
global pin0_flag
result = pin0_flag
pin0_flag = False
return result
while True:
check_pin0_touch()
.. other program things...
if pin0_was_touched():
.. increment counter..
Code: Select all
class WasTouchedPin:
def __init__(self, pin):
self._pin = pin
self._flag = False
self._last_state = False
def check(self):
.. same as check_pin0_touch above ..
def was_touched(self):
.. same as was_touched above ...
touch_pins = [WasTouchedPin(pin0), WasTouchedPin(pin1), WasTouchedPin(pin2)]
while True:
for p in touch_pins:
p.check()
.. now you can write touch_pins[2].was_touched()
Code: Select all
class PinCounter:
def __init__(self, pin):
self._pin = pin
self._count = 0
self._last_state = False
def check(self):
state = self._pin.is_touched()
if state and not self._last_state:
self._count += 1
self._last_state = state
def count(self):
result = self._count
self._count = 0
return result
counter_pins = [PinCounter(pin0), PinCounter(pin1), PinCounter(pin2)]
while True:
for p in counter_pins:
p.check()
.. now you can write counter_pins[x].count() to get the count since last time you checked ...