Присоединяйтесь!
Авторизация
I2C    GPIO    Interrupt    PCF8574   

Экономим порты (подключение кнопок по i2c)

19 February 2014 - Автор mj1

Как известно, портов много не бывает. По этому жалко их тратить на подключение банальных кнопок. Особенно когда кнопок много.

Все уже придумали до нас. 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()

Вот, собственно и все.

19 February 2014
mj1
автор статьи

Комментариев: 2

  1. В.П. Столярчук10

    02 March 2014 - Ответить

    Это конечно прекрасно, но ты мне вот скажи, как мне зацепить на i2c несколько одинаковых температурных датчиков??? То что разные датчики можно подключать паралельно я занаю, а вот одинаковые датчики имеют одинаковые адреса. Мне нужно подключать их очень много.

    • admin

      02 March 2014 - ответить

      Использовать датчики, где адрес можно устанавливать самостоятельно

      • В.П. Столярчук10

        02 March 2014 - ответить

        Дык какой например, да и сколько он будет стоить? Если брать например производителя DALLAS, то он будет стоить от 100р., но насколько мне известно, там адрес поменять нельзя.

        • admin

          03 March 2014 - ответить

          Например LM75AD

          • В.П. Столярчук10

            03 March 2014 - ответить

            ОК, даташит скачал, вроде недорого, чота я не вкуриваю как работать с клемами A0-A2 ?! Мне в реале надо подсоединить не менее 64-х датчиков. Если есть возможность то можно пример исходника на С с сохранением данных в файл, буду благодарен.

            • mj1

              07 March 2014 - ответить

              Клеммы А0-А2 это корректировщик адреса. Если на всех лог.0 то адрес равен адресу указанному в документации на ИС. а так, покавая на какую нибудь ногу (ноги) лог. 1 мы получаем обычное 3хбитное двоичное число, которое суммируется с базовым адресом из документации и получается новый адрес этой микрухи. Опять же, микрухи с различными буквенными индексами имеют разные базовые адреса (см. даташит).

      • В.П. Столярчук10

        02 March 2014 - ответить

        Может быть есть какой нибудь контроллер, чтобы используя дополнительный пин для управления - циклом считывать данные по одному адресу по очереди с каждого датчика.

        • mj1

          07 March 2014 - ответить

          не понял вопроса. Есть у тебя int (прерывание). Получил его, вызвал функцию и в цикле считал поочередно со своих датчиков что нужно. В коде у меня как раз это используется (правда код криво отображается, но разобраться можно. Если это то, что тебе нужно, но код непонятен, скажи, я простейший пример тут же в каментах покажу.

  2. Ermito9

    12 December 2014 - Ответить

    Можете разьяснить для новичков. Дополнительное сопротивление между кнопкой и входом нужно вешать?

    • Ermito9

      14 December 2014 - ответить

      Сам себе отвечу. не работало, потому что нужно предварительно питание на пины выставить # make certain the pins are set high so they can be used as inputs b.write_byte(PCF8574, 0xff)

Отправить комментарий

Авторизуйтесь для отправки комментария

Присоединяйтесь
Новые сообщения