В этом материале мы рассмотрим как можно легко подключить клавиатуру к Raspberry Pi 4 для различных целей.
Для пользователей существует множество способов ввода данных в Raspberry Pi. Одним из них является использование 16-кнопочной клавиатуры, которая содержит цифры от нуля до девяти, а также несколько дополнительных кнопок:
Мы постараемся объяснить как работают такие клавиатуры и как вы можете легко подключать их в свои проекты с Raspberry Pi 4.
Клавиатура
Клавиатуру, которую мы использовали можно разделить на четыре строки и четыре столбца следующим образом:
Чтобы определить, какая кнопка нажата, Raspberry Pi должна послать импульс в каждый из четырех рядов клавиатуры. Когда пользователь нажимает кнопку, которая подключена к линии, которая в настоящий момент находится в HIGH, соответствующая колонка также переходит в HIGH.
Расшифровывая комбинацию строки и столбца, вы можете определить, какая кнопка была нажата. Если пользователь, например, нажимает кнопку B, расположенную во втором ряду в четвертом столбце, Raspberry Pi обнаруживает нажатие этой кнопки, когда посылает импульс на вторую строку, а затем проверяет, какой из четырех столбцов стал HIGH.
Подключение клавиатуры к Raspberry Pi 4
Клавиатуры, которые работают таким образом, не нуждаются в каком-либо питании для работы. Это означает, что вы можете просто подключить все восемь линий данных клавиатуры к любым восьми контактам GPIO на Raspberry Pi:
Мы использовали ту же цветовую схему, что и на изображении выше. Синие соединения соответствуют строкам, а оранжевые - столбцам.
Простой пример кода
После того, как вы установили соединения, соответственно схеме выше, пришло время запустить простую тестовую программу, которая будет выводить кнопки, нажимаемые пользователем на клавиатуре, в консоли Raspberry Pi:
# GPIO setup and imports omitted 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!")
Видно, что тестовая программа содержит метод readLine. Метод readLine отправляет импульс, описанный выше, в одну строку, а затем проверяет, какая из кнопок была нажата, когда линия находится в HIGH. Всё повторяется для всех четырех рядов. Метод также принимает список символов, которым соответствуют кнопки.
Эта программа является простым примером. Он не позволяет обнаружить, удерживается ли кнопка нажатой. Он будет просто распознавать новое нажатие клавиши с каждым импульсом, который он посылает на выходной линии. Программа, которая правильно определяет отдельные нажатия клавиш и реализует простую кодовую блокировку, приводится далее.
Дешевые клавиатуры обычно работают одинаково. У них есть четыре строки и четыре столбца. Вход может быть обнаружен путем отправки импульса в каждой отдельной строке, а затем проверки каждого столбца, чтобы определить, какая кнопка была нажата.
Продвинутый код
Базовое приложение легко реализовать, но если вам нужны более продвинутые функции, код может быстро стать довольно сложным.
Пример 1
import RPi.GPIO as GPIO import time L1 = 5 L2 = 6 L3 = 13 L4 = 19 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!")
Пример 2
import RPi.GPIO as GPIO import time # These are the GPIO pin numbers where the # lines of the keypad matrix are connected L1 = 5 L2 = 6 L3 = 13 L4 = 19 # These are the four columns C1 = 12 C2 = 16 C3 = 20 C4 = 21 # The GPIO pin of the column of the key that is currently # being held down or -1 if no key is pressed keypadPressed = -1 secretCode = "4789" input = "" # Setup GPIO 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) # Use the internal pull-down resistors 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) # This callback registers the key that was pressed # if no other key is currently pressed def keypadCallback(channel): global keypadPressed if keypadPressed == -1: keypadPressed = channel # Detect the rising edges on the column lines of the # keypad. This way, we can detect if the user presses # a button when we send a pulse. GPIO.add_event_detect(C1, GPIO.RISING, callback=keypadCallback) GPIO.add_event_detect(C2, GPIO.RISING, callback=keypadCallback) GPIO.add_event_detect(C3, GPIO.RISING, callback=keypadCallback) GPIO.add_event_detect(C4, GPIO.RISING, callback=keypadCallback) # Sets all lines to a specific state. This is a helper # for detecting when the user releases a button def setAllLines(state): GPIO.output(L1, state) GPIO.output(L2, state) GPIO.output(L3, state) GPIO.output(L4, state) def checkSpecialKeys(): global input pressed = False GPIO.output(L3, GPIO.HIGH) if (GPIO.input(C4) == 1): print("Input reset!"); pressed = True GPIO.output(L3, GPIO.LOW) GPIO.output(L1, GPIO.HIGH) if (not pressed and GPIO.input(C4) == 1): if input == secretCode: print("Code correct!") # TODO: Unlock a door, turn a light on, etc. else: print("Incorrect code!") # TODO: Sound an alarm, send an email, etc. pressed = True GPIO.output(L3, GPIO.LOW) if pressed: input = "" return pressed # reads the columns and appends the value, that corresponds # to the button, to a variable def readLine(line, characters): global input # We have to send a pulse on each line to # detect button presses GPIO.output(line, GPIO.HIGH) if(GPIO.input(C1) == 1): input = input + characters[0] if(GPIO.input(C2) == 1): input = input + characters[1] if(GPIO.input(C3) == 1): input = input + characters[2] if(GPIO.input(C4) == 1): input = input + characters[3] GPIO.output(line, GPIO.LOW) try: while True: # If a button was previously pressed, # check, whether the user has released it yet if keypadPressed != -1: setAllLines(GPIO.HIGH) if GPIO.input(keypadPressed) == 0: keypadPressed = -1 else: time.sleep(0.1) # Otherwise, just read the input else: if not checkSpecialKeys(): 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) else: time.sleep(0.1) except KeyboardInterrupt: print("\nApplication stopped!")
На этом всё. Хороших вам проектов.