Экономим порты (подключение кнопок по i2c)
-
Как известно, портов много не бывает. По этому жалко их тратить на подключение банальных кнопок. Особенно когда кнопок много.
Все уже придумали до нас. I2c шина позволяет подключить до 120 устройств потратив на это всего 2 пина на RPi.
Тем более, что есть отличная вешь: PCF8574(PCF8575). Дистанционный 8-битный расширитель ввода – вывода I2C-шины на 8(16) портов соответственно. Вот к нему то мы и будем цеплять кнопки.
Буква А в маркировке определяет базовый адрес чипа.
Буква P - тип корпуса (DIP1)Описание микросхемы для любознательных
Выводы A0-A2 позволяют изменить адрес чипа на шине путем подачи на них высокого или низкого уровня.
Hint: Обязательно подайте на них или 3.3В или массу. Не подключенные выводы источник презабавнейших глюков.VDD питание +3.3ВVSS земля.SDA/SCL соответственно I2C шина.P0-P7 8 доп портов.INT - крайне полезная вещь - выход прерывания. Т.е. нам не придется постоянно опрашивать микросхему, чтобы определить, изменилось ли состояние портов. Достаточно это сделать после прихода этого самого прерывания :)Я навесил на нее 2 кнопки на порты P4 и P5. Кнопки замыкают эти порты на землю. С железом на этом закончили. Далее все понятно из кода и коментариев к нему:
#!/usr/bin/python# -*- coding: utf-8 -*-# Адрес микросхемы PCF8574i2c_addr = 0x20# импортируем необходимые библиотеки import smbus as smbus import RPIOfrom time import *from subprocess import Popen, PIPE #configure I2C bus for functionsi2c = smbus.SMBus(1)# Настраиваем 25 порт GPIO и подтягиваем его на земл. RPIO.setup(25, RPIO.IN, pull_up_down=RPIO.PUD_DOWN)# Здесь то, что мы делаем по приходу прерыванияdef gpio_callback(gpio_id, val): try : # Читаем из PCF8574 temp = i2c.read_byte( i2c_addr ) print 'PCF8574 at address 0x{0:2x} READ 0x{1:2x}'.format( i2c_addr, temp ) except IOError : print 'PCF8574 Device not found at I2C address 0x{1:2x}'.format( i2c_addr ) error = 1 # Нажата кнопка на порту P4 if (hex(temp)== hex(0xdf)): # Тут я дергаю экранчик, подключение которого я в прошлой записи описывал. #p = Popen('/home/pi/mj/LCD-Char/LCD-Test-mj-v4.py Key=1 1 VAL=Press 2', stdout=PIPE, shell=True) print("gpio %s: %s" % (gpio_id, val)) # Нажата кнопка на порту P5 if (hex(temp)== hex(0xef)): #p = Popen('/home/pi/mj/LCD-Char/LCD-Test-mj-v4.py Key=2 1 VAL=Press 2', stdout=PIPE, shell=True) print("gpio %s: %s" % (gpio_id, val)) # Одновременно нажаты обе кнопки if (hex(temp)== hex(0xcf)): #p = Popen('/home/pi/mj/LCD-Char/LCD-Test-mj-v4.py Key=1+2 1 VAL=Press 2', stdout=PIPE, shell=True) print("gpio %s: %s" % (gpio_id, val)) fleg=1 # Настраиваем порт на ожидание прерываний и выполнение выщенаписанной функции RPIO.add_interrupt_callback(25, gpio_callback, pull_up_down=RPIO.PUD_UP, debounce_timeout_ms=50) # Ждем прихода прерывания. RPIO.wait_for_interrupts()
Вот, собственно и все.