Lekce 11 - Raspberry Pi - Membránová klávesnice 4x4
V předchozí lekci, Raspberry Pi - Připojení RFID čtečky, jsme si zapojili a naprogramovali RFID čtečku.
Dnes k našemu Raspberry Pi připojíme numpad a budeme skrz něj zadávat čísla. Napíšeme si k tomu jednoduchý kód který je bude vypisovat a vysvětlíme si, jak numpady/keypad/klávesnice vlastně fungují.
Jako už mnohokrát předtím zde ukáži vlastní zapojení a schéma zapojení vytvořené pomocí Fritzing.
Potřebné součástky
K úspěšnému zapojení budeme potřebovat:
- Raspberry Pi
- membránová klávesnice 4x4 (NUMPAD)
- při nejlepším nepájivé pole a několik drátků, případně pouze drátky
Jak funguje numpad?
Jednoduchá klávesnice neboli numpad obsahuje několik přepínačů uspořádaných do mřížky. Vnitřní vodiče spojují jednotlivé řady a sloupce přepínačů tak, že když uživatel stiskne jeden z přepínačů, tento přepínač elektricky spojí jeden řádek se sloupcem. Pokud zařízení Raspberry Pi chce detekovat stisknuté klávesy, vyšle rychlý impuls do každé z čar mřížky přepínače. Když uživatel stiskne tlačítko, toto tlačítko spojí jeden řádek s jedním sloupcem a Raspberry Pi tak dokáže detekovat změnu.
Zapojení numpadu
Jak již bylo řečeno, každý řádek numpadu bereme jako vstup a každý sloupec numpadu jako výstup. Raspberry Pi vysílá pulzy do linek a naslouchá změnám na sloupcích. Proto musíme propojit každý ze čtyř řad a sloupců numpadu s libovolnými osami digitálních I/O pinů na Raspberry Pi:
Programová část
Máme tedy numpad zapojený a víme, jak funguje. Teď si s jeho pomocí a prostřednictvím knihoven Pythonu vyzkoušíme vypsat vstup, který zadáváme.
Import knihoven
Dnes budeme používat především dvě knihovny. První bude tradičně
GPIO
knihovna. Druhá bude knihovna pro import času, která se
nazývá time
. Tyto knihovny samozřejmě musíme mít
nainstalované pomocí pip.
První knihovnu importujeme jednoduše:
import RPi.GPIO as GPIO
Pomocí as
uložíme knihovnu do proměnné GPIO
,
abychom neustále nemuseli psát její název. Poté importujeme celou knihovnu
time
:
import time
Uložení do proměnných
Vytvoříme si proměnné L1-L4
a
C1-C4
do kterých uložíme čísla jednotlivých portů do
kterých jsme zapojili numpad. Piny na numpadu bereme zprava, takže první pin
napravo bude A1
, poslední na levo je pak A8
. Piny
A1-A4
budou zapsány v proměnných C1-C4
.
A5-A8
budou zapsány do L1-L2
. Zápis pinů je
důležitý kvůli správnému určení pozice čísla:
L1 = 26 L2 = 7 L3 = 18 L4 = 1 C1 = 12 C2 = 16 C3 = 20 C4 = 21
Nastavení GPIO
První nastavíme setwarnings
na False
pro
deaktivaci varování. Varování nám říká, že GPIO port se již
používá, protože jsme zastavili program a spustili jej znovu.
Mode nastavíme na BCM
. Více o nastavování GPIO naleznete v
minulé
lekci:
GPIO.setwarnings(False)
GPIO.setmode(GPIO.BCM)
Popišme si jednotlivé části:
- GPIO setup, jak název napovídá, nastavuje GPIO porty.
- OUT - output nastavení portů, když chceme v programu definovat, jakou hodnotu budou porty mít
- IN - input, když necháváme přístupem z venčí definovat hodnotu portů
- L1-L4 - nastavíme na OUT
- C1-C4 - nastavíme na IN
U C1-C4 pak musíme nastavit pull_up/down
:
GPIO.setup(L1, GPIO.OUT) GPIO.setup(L2, GPIO.OUT) GPIO.setup(L3, GPIO.OUT) GPIO.setup(L4, GPIO.OUT) GPIO.setup(C1, GPIO.IN, pull_up_down=GPIO.PUD_DOWN) GPIO.setup(C2, GPIO.IN, pull_up_down=GPIO.PUD_DOWN) GPIO.setup(C3, GPIO.IN, pull_up_down=GPIO.PUD_DOWN) GPIO.setup(C4, GPIO.IN, pull_up_down=GPIO.PUD_DOWN)
Jak funguje rezistor pull_up/down
je vysvětlené v této minulé
lekci Nastavíme na něm hodnotu PUD_DOWN
. To znamená že nám
pokaždé, když tlačítko nebude stlačeno, vyhodí False
.
Funkce readline
Vydefinujeme si funkci readline
:
def readLine(line, characters): GPIO.output(line, GPIO.HIGH) if(GPIO.input(C1) == 1): print(characters[0]) if(GPIO.input(C2) == 1): print(characters[1]) if(GPIO.input(C3) == 1): print(characters[2]) if(GPIO.input(C4) == 1): print(characters[3]) GPIO.output(line, GPIO.LOW)
Do funkce readLine()
vložíme proměnnou line
a
list characters
. Proměnná line
definuje řádek
neboli port L1-L4
a characters
pak znak na řádku se
nacházející. Tyto obě proměnné si definujeme za chvíli. Pomocí
GPIO.output()
nastavíme vždy port L1-L4
(podle
proměnné line
) na hodnotu HIGH
. Vytvoříme si
if
, který bude čekat na GPIO input()
na portech
C1-C4
, a podle toho, na jakém portu bude True
(neboli
1) vypíše znak. Nakonec nastavíme GPIO.output()
portů
L1-L4
(podle proměnné line
) na hodnotu
LOW
.
Try
blok
Pojďme si nyní připravit try
blok, do kterého vložíme
while
cyklus:
try: while True: readLine(L1, ["1","2","3","A"]) readLine(L2, ["4","5","6","B"]) readLine(L3, ["7","8","9","C"]) readLine(L4, ["*","0","#","D"]) time.sleep(0.1) except KeyboardInterrupt: print("\nApplication stopped!")
Poslední věcí, kterou musíme nastavit jsou proměnnou line
a
list characters
. Vypíšeme si blok Try
, abychom mohly
ošetřit případné výjimky (exceptions) v kódu a vložíme do něj
nekonečný cyklus while
s hodnotou True
. Nekonečný
cyklus zajistí, že se bude kód v něm vložený neustále opakovat, a my
budeme moci neustále zadávat nové kódy. Ve while
cyklu si pak
definujeme naší funkci readline()
, do ní dáme název portu a 4
znaky (characters) které se na řádku portu mohou nacházet.
Například tedy L1 - ["1","2","3","A"]
definujeme jako list, ze
kterého pak budeme brát jednotlivé znaky.
Vysvětlení
Try
blok nám tedy vyzkouší nekonečný cyklus (žádný
cyklus by neměl být nekonečný), ve které máme nadefinované jednotlivé
řádky a znaky na nich. Program skočí do funkce readline()
, do
které nám vloží číslo portu do proměnné line
a list znaků
do listu characters
. Poté počká na stisknutí tlačítka.
While
opakovaně volá funkci readline()
pro každý
řádek klávesnice L1-L4
. Proto když na numpadu stiskneme
tlačítko, přiřadí se hodnota na jednom z portů C1-C2
. Funkce
If
které neustále dokola porovnávají zda má C1-C4
hodnotu True
najdou správný port a ten vydefinuje pozici na
řádku.
Celý kód pak vypadá takto:
import RPi.GPIO as GPIO import time L1 = 26 L2 = 7 L3 = 18 L4 = 1 C1 = 12 C2 = 16 C3 = 20 C4 = 21 GPIO.setwarnings(False) GPIO.setmode(GPIO.BCM) GPIO.setup(L1, GPIO.OUT) GPIO.setup(L2, GPIO.OUT) GPIO.setup(L3, GPIO.OUT) GPIO.setup(L4, GPIO.OUT) GPIO.setup(C1, GPIO.IN, pull_up_down=GPIO.PUD_DOWN) GPIO.setup(C2, GPIO.IN, pull_up_down=GPIO.PUD_DOWN) GPIO.setup(C3, GPIO.IN, pull_up_down=GPIO.PUD_DOWN) GPIO.setup(C4, GPIO.IN, pull_up_down=GPIO.PUD_DOWN) def readLine(line, characters): GPIO.output(line, GPIO.HIGH) if(GPIO.input(C1) == 1): print(characters[0]) if(GPIO.input(C2) == 1): print(characters[1]) if(GPIO.input(C3) == 1): print(characters[2]) if(GPIO.input(C4) == 1): print(characters[3]) GPIO.output(line, GPIO.LOW) try: while True: readLine(L1, ["1","2","3","A"]) readLine(L2, ["4","5","6","B"]) readLine(L3, ["7","8","9","C"]) readLine(L4, ["*","0","#","D"]) time.sleep(0.1) except KeyboardInterrupt: print("\nApplication stopped!")
Věřím, že se vám připojení a nakódování numpadu podařilo. Své dojmy a případné dotazy můžete zanechat v diskusi pod článkem 🙂
V další lekci, Raspberry Pi - Senzor vlhkosti půdy, si k Raspberry Pi připojíme senzor vlhkosti půdy.