Прошу прощения за вопрос, который может показаться ламерским. Есть WB SH. Хочу подключить к нему 2 кнопки “сухой контакт” для дальнейшей программной обработки событий с этих кнопок.
Я так понял, что нужно использовать режим GPIO. Дайте готовый рецепт - к каким клеммам лучше подключить обе кнопки?
КАкие настройки сделать в системе, чтобы можнобыло отлавливать факт нажатия (то есть реагировать нужно на восходящий или нисходящий фронт)?
Как отлавливать события? Можно ли через MQTT?
Хороший форум - сам задаешь ответ вопрос и сам на него отвечаешь. Очень мотвирует к самообразованию 
Удалось мне подключить кнопки, хлтя и достаточно кустарною Так что буду рад любы комменатиям.
Для начала определил, какие GPIO-разъемы не используются системой при загрузке (пытался их инициализировать и смотрел на результат). В итоге для двух кнопок удалось задействовать gpio1 и gpio5. Это разъем W3 в секции 1-wire и разъем R4.
Дальше на примере существующих скриптов написал свой
#!/usr/bin/python
#-*- coding: UTF-8 -*-
## copy script to /etc/init.d/
## make <code>chmod a+x mqtt_gpio.py</code>
## use <code>update-rc.d mqtt_gpio.py start 70 2 3 4 5 . stop 20 0 1 6 .</code> (with dots) for autostart script
import mosquitto
import argparse
import WB_IO.GPIO as GPIO
import time
mqttc = mosquitto.Mosquitto("python_gpio")
def event_callback_rising(channel):
mqttc.publish("/events/gpio/switch", ""+str(channel))
def event_callback_falling(channel):
mqttc.publish("/events/gpio/"+str(channel), "falling")
def event_callback_both(channel, event_type):
mqttc.publish("/events/gpio/"+str(channel), "both")
def init_gpio(channel):
GPIO.setup(channel, GPIO.IN, pull_up_down=GPIO.PUD_UP)
GPIO.add_event_detect(channel, GPIO.RISING, event_callback_rising, bouncetime=450)
# GPIO.add_event_detect(channel, GPIO.FALLING, event_callback_falling, bouncetime=450)
# GPIO.add_event_detect(channel, GPIO.BOTH, event_callback_both, bouncetime=450)
def main():
parser = argparse.ArgumentParser(description="homA device simulator", add_help=False)
parser.add_argument('action', nargs='*')
parser.add_argument("-h", "--host", dest="host", type=str,
help="MQTT host", default="localhost")
parser.add_argument("-p", "--port", dest="port", type=int,
help="MQTT port", default="1883")
args = parser.parse_args()
mqttc.will_set("/events/gpio/status", "0")
mqttc.connect(args.host, args.port)
mqttc.publish("/events/gpio/status", "1")
init_gpio(1)
init_gpio(5)
while 1:
rc = mqttc.loop()
if rc != 0:
break
if __name__ == "__main__":
main()
Скрипт инициализирует 2 разъема GPIO на чтение. Далее регистрируем функцию для срабатывания на возрастающий фронт. И подключаемся к брокеру MQTT.
Жобавил этот скрипт в автозагрузку - и теперь при нажатии кнопки появляется событие в очереди MQTT, которое я успешно отрабатываю.
Из недостатков:
- надо как-то бороться с ложными срабатываниями. Я так понимаю, нужно включать подтяжку портов, но подробной инструкции, как это сделать - не нашел. Придется, нваерное, отдельными резисторами подтягивать.
- надо доработать скрипт на обработку ошибок. Так как он запускается при старте системы - должен работать постоянно, несмотря на сбои
Добрый день, alex,
спасибо, что поделились решением! Как вы уже поняли, ответ на ваш вопрос не такой простой
Прошу прощения, что долго собирался вам ответить.
По делу:
- Аппаратную подтяжку GPIO можно активировать не на всех линиях, список GPIO можно найти здесь или тут. На R2-R4 подтяжка по-умолчанию активирована в Device Tree, на клеммниках W* - это аппаратный встроенный резистор.
Так что видимо дело не в подтяжке портов, хотя возможно, что встроенная подтяжка порта R4 (47k), слишком слабая.
Я думаю, что вам имеет смысл сделать программный debouncing: через, скажем, пару миллисекунд после срабатывания прерывания считывать уровень с gpio. Можно это тупо сделать через sleep в обработчике прерывания.
-
Как GPIO по-умолчанию можно использовать клеммники R1-R4 и W3. W1 и W2 можно переключить в режим GPIO в Device Tree
-
В новой версии “драйвера GPIO” для MQTT есть поддержка GPIO, используемых на вход. Там пока правда сделан только polling, событий нет.
Код здесь: https://github.com/contactless/wb-homa-drivers/ , в репозитарии пока старая версия.