Raspberry Pi Pico
Digital IN - Pushbuttons
We want to be able to use inputs in our circuits. Pushbuttons also need us to use the built-in resistors. Here is a quick 3-button circuit with the buttons connected to GND and to pins GP18, GP19 and GP20. I like programming circuits with switches because you can be quite creative in your programming.
Here is the same circuit in a Fritzing diagram,
The first program is simply to test the button readings and to see what we get back,
import board from time import sleep from digitalio import DigitalInOut, Pull btnA = DigitalInOut(board.GP18) btnA.switch_to_input(pull = Pull.UP) btnB = DigitalInOut(board.GP19) btnB.switch_to_input(pull = Pull.UP) btnC = DigitalInOut(board.GP20) btnC.switch_to_input(pull = Pull.UP) while True: print(btnA.value, btnB.value, btnC.value) sleep(0.5)
This program uses 'follower' variables to make it possible to track the pressing and the release of each button.
import board from time import sleep from digitalio import DigitalInOut, Pull btnA = DigitalInOut(board.GP18) btnA.switch_to_input(pull = Pull.UP) btnB = DigitalInOut(board.GP19) btnB.switch_to_input(pull = Pull.UP) btnC = DigitalInOut(board.GP20) btnC.switch_to_input(pull = Pull.UP) lastA = lastB = lastC = 1 while True: if btnA.value != lastA: if btnA.value: print("A released") else: print("A pressed") if btnB.value != lastB: if btnB.value: print("B released") else: print("B pressed") if btnC.value != lastC: if btnC.value: print("C released") else: print("C pressed") lastA = btnA.value lastB = btnB.value lastC = btnC.value sleep(0.01)
Since our buttons have two states, we can map these onto binary place values. Grouping those binary values together means that we can use a single integer to represent all of the button states. That also means that we can use a single comparison to determine if there was a change of state for any of the buttons.
import board from time import sleep from digitalio import DigitalInOut, Pull # set up pins btn_pins = [board.GP18, board.GP19, board.GP20] btns = [DigitalInOut(p) for p in btn_pins] # set up as buttons for b in btns: b.switch_to_input(pull = Pull.UP) # function to read buttons into a binary pattern, 1 for pressed def read_btns(btn_list): result = 0 for i, b in enumerate(btn_list): result += (b.value^1)<<i return result # function to determine if a specific button is pressed def pressed(pattern, b): return pattern>>b & 1 previous = 0 while True: reading = read_btns(btns) if reading!=previous: if pressed(reading, 0): print("Button 0 was pressed.") if pressed(reading, 1): print("Button 1 was pressed.") if pressed(reading, 2): print("Button 2 was pressed.") previous = reading sleep(0.01)
The final program uses binary numbers to track the press, hold and release states of each button between readings. Lists of buttons are created and printed. The btn_changes function accepts the current and previous states along with the number of buttons being used. It then creates a 2 bit integer for each button. 01 (1) means that the button was previously not pressed and now is pressed, 10 (2) means that the button has been released. 11 (3) means that the button was held down since last being read. A reading of 00 (0) indicates a button not being pressed at all.
import board from time import sleep from digitalio import DigitalInOut, Pull # set up pins btn_pins = [board.GP18, board.GP19, board.GP20] btns = [DigitalInOut(p) for p in btn_pins] # set up as buttons for b in btns: b.switch_to_input(pull = Pull.UP) # function to read buttons into a binary pattern, 1 for pressed def read_btns(btn_list): result = 0 for i, b in enumerate(btn_list): result += (b.value^1)<<i return result def pressed(pattern, b): return pattern>>b & 1 def btn_changes(current, last, n): return [((last >> i & 1)<<1) + (current >> i & 1) for i in range(n)] previous = 0 while True: reading = read_btns(btns) if reading!=previous: states = btn_changes(reading, previous, 3) press = [i for i,e in enumerate(states) if e==1] release = [i for i,e in enumerate(states) if e==2] held = [i for i,e in enumerate(states) if e==3] print("Pressed", press, "Released:", release, "Held:", held) previous = reading sleep(0.01)