работа с GPIO raspberry

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

Модератор: immortal

DiminatorDK
Сообщения: 104
Зарегистрирован: Сб фев 20, 2016 12:19 pm
Благодарил (а): 7 раз
Поблагодарили: 2 раза

работа с GPIO raspberry

Сообщение DiminatorDK » Пн окт 14, 2019 11:51 pm

никак не могу понять, как работать из MD с GPIO raspberry? Хочу решить простую задачу, кнопка на один gpio и лампу на другой. Понятно что через обвязку. Но как обращаться к gpio ? Как включать/выключать? Статус и так далее? В идеале хочется отловить статус от кнопки и на основе него изменить состояние gpoi выхода (лампочки).
Какие нибудь примеры бы посмотреть. Может быть что-то готовое есть в этом направлении?
Alex13
Сообщения: 23
Зарегистрирован: Пт дек 14, 2018 7:43 am
Благодарил (а): 1 раз
Поблагодарили: 0

Re: работа с GPIO raspberry

Сообщение Alex13 » Ср окт 16, 2019 1:15 pm

viewtopic.php?t=3613
Тут читал?
Аватара пользователя
omship
Сообщения: 8
Зарегистрирован: Вс июн 11, 2017 11:07 am
Откуда: Краснодар
Благодарил (а): 6 раз
Поблагодарили: 0

Re: работа с GPIO raspberry

Сообщение omship » Ср окт 16, 2019 9:46 pm

Создал объект GPIO_21, выбрал класс SMotions, в свойствах есть поле GPIO_21.status, где прописывать это выражение-

Код: Выделить всё

if (!$gpio) {
$gpio=exec ('sudo gpio read 21');
sg('GPIO_21.status', $gpio); 
} 
в методе motionDetected ?
#ЗасебяизаСашку!
fandaymon
Сообщения: 1570
Зарегистрирован: Сб янв 13, 2018 5:00 pm
Благодарил (а): 40 раз
Поблагодарили: 578 раз

Re: работа с GPIO raspberry

Сообщение fandaymon » Ср окт 16, 2019 10:36 pm

omship писал(а):
Ср окт 16, 2019 9:46 pm
Создал объект GPIO_21, выбрал класс SMotions, в свойствах есть поле GPIO_21.status, где прописывать это выражение-

Код: Выделить всё

if (!$gpio) {
$gpio=exec ('sudo gpio read 21');
sg('GPIO_21.status', $gpio); 
} 
в методе motionDetected ?
Нет. Так он никогда не отработает. Те датчики, которые должны вызывать реакцию системы (движения, протечки) лучше опрашивать в собственном цикле - у Сергея есть заготовка /scripts/sample_cycle_arduino_direct.php (её надо настроить и переименовать в cycle_arduino_direct.php), ну или считывать показания програмкой на питоне и отправлять показания либо напрямую, либо через MQTT. Можно ещё написать скрипт на баше, чтобы в цикле читать через gpio read, а отправлять через mosquitto_pub
Всё это есть на форуме
За это сообщение автора fandaymon поблагодарил:
omship (Ср окт 16, 2019 11:40 pm)
Рейтинг: 1.16%
Аватара пользователя
omship
Сообщения: 8
Зарегистрирован: Вс июн 11, 2017 11:07 am
Откуда: Краснодар
Благодарил (а): 6 раз
Поблагодарили: 0

Re: работа с GPIO raspberry

Сообщение omship » Ср окт 16, 2019 11:33 pm

Спасибо, что ответили! Что бы считать состояние пина -нужно редактировать /scripts/sample_cycle_arduino_direct.php, это наверно путь истинных самураев PHP
ну или считывать показания програмкой на питоне и отправлять показания либо напрямую, либо через MQTT
через MQTT работает как-то через одно место:

Код: Выделить всё

#!/usr/bin/env python
import paho.mqtt.publish as publish
import os
import RPi.GPIO as GPIO 
import time

GPIO.setmode(GPIO.BCM) 
GPIO.setwarnings(False)

pin = 21

GPIO.setup(pin, GPIO.IN, GPIO.PUD_UP)

def pub (topic, val):
        publish.single("homebridge/to/"+topic, val)

def gpio_status():
    Current_State = GPIO.input(pin)
    return(Current_State)

while True:
   	
    if GPIO.input(pin) == False:
        pub("Status",gpio_status())
	print("no")
	time.sleep(100)
    else:
	if GPIO.input(pin) == True:
            pub("Status",gpio_status())
            print("yes")
            time.sleep(10)     

GPIO.cleanup()
а как на Питоне отправлять на прямую?
#ЗасебяизаСашку!
fandaymon
Сообщения: 1570
Зарегистрирован: Сб янв 13, 2018 5:00 pm
Благодарил (а): 40 раз
Поблагодарили: 578 раз

Re: работа с GPIO raspberry

Сообщение fandaymon » Чт окт 17, 2019 12:16 am

omship писал(а):
Ср окт 16, 2019 11:33 pm
Спасибо, что ответили! Что бы считать состояние пина -нужно редактировать /scripts/sample_cycle_arduino_direct.php, это наверно путь истинных самураев PHP
а как на Питоне отправлять на прямую?
У меня как-то так работало
СпойлерПоказать

Код: Выделить всё

import RPi.GPIO as GPIO
import time
import datetime
import urllib
# Use BCM GPIO references instead of physical pin numbers
GPIO.setmode(GPIO.BOARD)
# Define GPIO to use on Pi
GPIO_PIR = 11

# Set pin as input
GPIO.setup(GPIO_PIR,GPIO.IN) # Echo
Current_State = 0
Previous_State = 0


try:
  # Loop until PIR output is 0
  while GPIO.input(GPIO_PIR)==1:
    Current_State = 0
  # Loop until users quits with CTRL-C
  while True :
    # Read PIR state
    Current_State = GPIO.input(GPIO_PIR)
    if Current_State==1 and Previous_State==0:
      # PIR is triggered
      print " Motion detected!"
      status = " Motion detected!"
      link="http://127.0.0.1/objects/?object=HallMotion&op=m&m=motionDetected&"
      f=urllib.urlopen(link)
      # Record previous state
      Previous_State=1
    elif Current_State==0 and Previous_State==1:
      # REED has returned to ready state
      #print " Ready"
      Previous_State=0
    # Wait for 10 milliseconds
    time.sleep(0.01)
except KeyboardInterrupt:
  print " Quit"
# Reset GPIO settings
  GPIO.cleanup()
Когда срабатывал датчик запускался метод motionDetected объекта HallMotion
Питон - второй. У третьего urllib по другому работает

Но кстати с MQTT вроде никаких проблем нету и работает вроде получше
Для примера - RFLink на ардуинке подключен к малинке
СпойлерПоказать

Код: Выделить всё

import serial
import paho.mqtt.client as mqtt

client=mqtt.Client('RFLink')
client.connect('192.168.1.64',port=1883)
with serial.Serial('/dev/ttyUSB0',57600) as s:
    while True:
       d=s.readline()
       mq=d.split(";")
       if mq[2]=='Xiron':
           client.connect('192.168.1.64',port=1883)
           if '=' in mq[4]:
               v,val=mq[4].split('=')
           else:
               val=mq[4]
           val=str(int(val,16)/10)
           client.publish("rflink/"+mq[3]+"/TEMP/",val)
           if '=' in mq[5]:
               v,val=mq[5].split('=')
           else:
               val=mq[5]
           client.publish("rflink/"+mq[3]+"/HUM/",val)
           if '=' in mq[6]:
               v,val=mq[6].split('=')
           else:
               val=mq[6]
           client.publish("rflink/"+mq[3]+"/BAT/",val)
       elif mq[2]=='Kaku':
           client.connect('192.168.1.64',port=1883)
           client.publish("rflink/"+mq[3]+"/"+mq[4]+"/",mq[5])
В модуле MQTT подписка на топик rflink/# и всё прекрасно присылается
По протоколу Xiron - датчики температуры/влажности, по протоколу Kaku - розетки

Кстати - очень внимательно надо смотреть какой именно GPIO.setmode выставлен - у них разная нумерация входов, на эти грабли я наступал...

Код конечно написан не очень - я в самом начале изучения питона
DiminatorDK
Сообщения: 104
Зарегистрирован: Сб фев 20, 2016 12:19 pm
Благодарил (а): 7 раз
Поблагодарили: 2 раза

Re: работа с GPIO raspberry

Сообщение DiminatorDK » Чт окт 17, 2019 1:14 am

Мда, круто... Спасибо за примеры.
Попробую немного проще спросить, если не затруднит, можно пример как физической кнопкой изменить параметр объекта? Именно кнопкой а не выключателем. Т.е. произошло короткое нажатие. Опрос в цикле мне кажется не вариант?
fandaymon
Сообщения: 1570
Зарегистрирован: Сб янв 13, 2018 5:00 pm
Благодарил (а): 40 раз
Поблагодарили: 578 раз

Re: работа с GPIO raspberry

Сообщение fandaymon » Чт окт 17, 2019 1:37 am

DiminatorDK писал(а):
Чт окт 17, 2019 1:14 am
Мда, круто... Спасибо за примеры.
Попробую немного проще спросить, если не затруднит, можно пример как физической кнопкой изменить параметр объекта? Именно кнопкой а не выключателем. Т.е. произошло короткое нажатие. Опрос в цикле мне кажется не вариант?
Датчик движения это по сути кнопка и есть - подаёт на вход gpio единицу при детектировании движения, на какое-то время, а потом возвращает ноль. Далее надо как-то эту единицу отловить - циклом, программой на питоне, баш-скриптом, чем-нибудь ещё и передать в МДМ. Через API - https://kb.mjdm.ru/http-ssilki-dlya-ra ... majordomo/ , отправив в свойство объекта или вызвав метод объекта, через MQTT - опубликовав топик, например, /knopka/1 и привязав в модуле MQTT к этому топику свой объект, ну или если чтение было в цикле, то можно просто при помощи setGlobal(объект.свойство,1) занести значение в свойство объекта. Конечно при любом способе необходимо посылать информацию только при изменении сигнала на входе (либо при появлении 1, либо когда значение меняется, в зависимости от задачи) и устранять дребезг контактов (обычно просто задаём какой-то интервал между считыванием показаний)
fandaymon
Сообщения: 1570
Зарегистрирован: Сб янв 13, 2018 5:00 pm
Благодарил (а): 40 раз
Поблагодарили: 578 раз

Re: работа с GPIO raspberry

Сообщение fandaymon » Чт окт 17, 2019 2:12 am

Схематично как включать/выключать лампу кнопкой

1. Создать объект Lamp (для примера) класса SRelays (там прописаны методы TurnOn,TurnOff и switch)
2. В метод TurnOn вписать

Код: Выделить всё

exec ('sudo gpio mode 21 out');
exec ('sudo gpio write 21 1');
3. В метод TurnOff вписать

Код: Выделить всё

exec ('sudo gpio mode 21 out');
exec ('sudo gpio write 21 0');
4. Линк должен быть такой
link="http://127.0.0.1/objects/?object=Lamp&op=m&m=switch"

В принципе всё - кнопка будет переключать 21 пин. В теории 8-) Скорее всего окажется, что пользователь под которым крутится апач, не может вызывать sudo, но об этом тоже можно почитать на форуме в соответствующих темах.
За это сообщение автора fandaymon поблагодарил:
omship (Чт окт 17, 2019 9:34 am)
Рейтинг: 1.16%
DiminatorDK
Сообщения: 104
Зарегистрирован: Сб фев 20, 2016 12:19 pm
Благодарил (а): 7 раз
Поблагодарили: 2 раза

Re: работа с GPIO raspberry

Сообщение DiminatorDK » Чт окт 17, 2019 12:03 pm

Спасибо! Это, включение нагрузки , а мне надо изменить статус объекта или запустить событие при срабатывании кнопки на gpio. И тут, если я правильно понял, нативного пути нет?
Ответить