The source code of all examples can be downloaded from here.
Introduction |
Switches and push buttons are very common input devices for microprocessor systems. They can be considered as digital sensors with two states. Depending on the concrete situation the states are named off/on, pressed/released, Low/High, False/True, 0/1, 0V/3.3V, etc. Despite a switch is the most basic sensor to be connected to the GPIO header, the handling the handling is not straightforward due to the following reasons:
|
Experiment 1: Detecting the state of a push button |
Aim: Circuitry: Program:[►] # Button1.py import RPi.GPIO as GPIO import time # Button pin P_BUTTON = 40 # adapt to your wiring P_LED = 22 # adapt to your wiring def setup(): GPIO.setmode(GPIO.BOARD) GPIO.setup(P_BUTTON, GPIO.IN, GPIO.PUD_UP) GPIO.setup(P_LED, GPIO.OUT) setup() while True: if GPIO.input(P_BUTTON) == GPIO.LOW: GPIO.output(P_LED, GPIO.HIGH) else: GPIO.output(P_LED, GPIO.LOW) time.sleep(0.01) Remarks:
|
Experiment 2: Switch state while pressing the button |
Aim: Circuitry: Program:[►] # Button2.py import RPi.GPIO as GPIO import time P_BUTTON = 40 # adapt to your wiring P_LED = 22 # adapt to your wiring def setup(): GPIO.setmode(GPIO.BOARD) GPIO.setup(P_BUTTON, GPIO.IN, GPIO.PUD_UP) GPIO.setup(P_LED, GPIO.OUT) setup() isLedOn = False isButtonReady = True while True: if isButtonReady and GPIO.input(P_BUTTON) == GPIO.LOW: # pressed isButtonReady = False if not isLedOn: isLedOn = True GPIO.output(P_LED, GPIO.HIGH) else: isLedOn = False GPIO.output(P_LED, GPIO.LOW) if GPIO.input(P_BUTTON) == GPIO.HIGH: # released isButtonReady = True time.sleep(0.01) # remove this line to experience bouncing Remarks: |
Experiment 3:Using an event driven button library |
Normally the push button handling is not your main interest. Because button actions may happen any time, they should be handled by events that trigger a callback function (also called an interrupt routine). But programming with interrupts and events require advanced programming skills. We provide an event-driven button handler that supports the standard button events: BUTTON_PRESSED, BUTTON_RELEASED, BUTTON_LONGPRESSED, BUTTON_CLICKED and BUTTON_DOUBLECLICKED using internal threads. Download the module button.py from here and copy it into the same folder as your program. If you stuty the source code or the Python doc, you see that it is a class library and any number of buttons are supported.
Aim: Circuitry: Program:[►] # Button3.py from button import * import RPi.GPIO as GPIO import time P_BUTTON = 15 # adapt to your wiring P_LED = 7 # adapt to your wiring def setup(): GPIO.setmode(GPIO.BOARD) GPIO.setup(P_LED, GPIO.OUT) button = Button(P_BUTTON) button.addXButtonListener(onButtonEvent) def onButtonEvent(button, event): global isRunning if event == BUTTON_PRESSED: print "pressed" elif event == BUTTON_RELEASED: print "released" elif event == BUTTON_LONGPRESSED: print "long pressed" elif event == BUTTON_CLICKED: print "clicked" elif event == BUTTON_DOUBLECLICKED: print "double clicked" isRunning = False setup() isRunning = True while isRunning: GPIO.output(P_LED, GPIO.HIGH) time.sleep(0.1) GPIO.output(P_LED, GPIO.LOW) time.sleep(0.1) GPIO.cleanup() print "all done" Remarks: You should call GPIO.cleanup() before your program terminates to reset the GPIO to its default state. Otherwise GPIO setup options may survive the program termination and cause conflicts for the next program invocation. If you do not need click and double-click notifications, it is better to use addButtonListener() that takes a callback function that reports BUTTON_PRESSED, BUTTON_RELEASED and BUTTON_LONGPRESSED events only. This eliminates a short delay that is needed to distinguish between click and double-click events. |
A nice application for hams: Using the buzzer to emit Morse code |
It is simple to create a Morse code generator using the active buzzer. The program shows how you should structure your code to make the program pleasant to read for you and the whole Python community. Aim: Circuitry: Program:[►] # MorseGen.py import RPi.GPIO as GPIO import time P_BUZZER = 22 # adapt to your wiring dt = 0.1 # adapt to your speed morse = { 'a':'.-' , 'b':'-...' , 'c':'-.-.' , 'd':'-..' , 'e':'.' , 'f':'..-.' , 'g':'--.' , 'h':'....' , 'i':'..' , 'j':'.---' , 'k':'-.-' , 'l':'.-..' , 'm':'--' , 'n':'-.' , 'o':'---' , 'p':'.--.' , 'q':'--.-' , 'r':'.-.' , 's':'...' , 't':'-' , 'u':'..-' , 'v':'...-' , 'w':'.--' , 'x':'-..-' , 'y':'-.--' , 'z':'--..' , '1':'.----', '2':'..---', '3':'...--', '4':'....-', '5':'.....', '6':'-....', '7':'--...', '8':'---..', '9':'----.', '0':'-----', '-':'-....-', '?':'..--..', ',':'--..--', ':':'---...', '=':'-...-'} def s(n): # wait time.sleep(n * dt) def setup(): GPIO.setmode(GPIO.BOARD) GPIO.setup(P_BUZZER, GPIO.OUT) def dot(): GPIO.output(P_BUZZER, GPIO.HIGH) s(1) GPIO.output(P_BUZZER, GPIO.LOW) s(1) def dash(): GPIO.output(P_BUZZER, GPIO.HIGH) s(3) GPIO.output(P_BUZZER, GPIO.LOW) s(1) def transmit(text): for c in text: if c == " ": s(4) else: c = c.lower() if c in morse: k = morse[c] for x in k: if x == '.': dot() else: dash() s(2) setup() transmit("cq de hb9abh pse k") GPIO.cleanup() print "all done" Remarks:
(*) may be increased for easier reading |