Skip to content
  • Категории
  • Главная
  • Документация
  • Последние
  • Пользователи
Collapse
  1. Главная
  2. Блоги сообщества Raspberry Pi
  3. Запись времени захода в комнату или простой пример работы с прерываниями по GPIO на Python

Запись времени захода в комнату или простой пример работы с прерываниями по GPIO на Python

Запланировано Прикреплена Закрыта Перенесена Блоги сообщества Raspberry Pi
15 Сообщения 2 Posters 162 Просмотры
  • Сначала старые
  • Сначала новые
  • По количеству голосов
Авторизуйтесь, чтобы ответить
Эта тема была удалена. Только пользователи с правом управления темами могут её видеть.
  • piP Не в сети
    piP Не в сети
    pi
    написал в отредактировано pi
    #1

    Привет всем! Сейчас я покажу как можно работать с прерываниями на нашем мини-компьютере, то есть выполнять определенное действие в момент смены сигнала на GPIO.

    В этом примере будем записывать в файл время открытия и закрытия двери в комнату. Для этого я подцепил герконовый извещатель от охранной сигнализации между выводами +3.3V и GPIO7 (номер может быть любым).

    Выглядит это так:

    c7d3b8ce-6043-4e01-a955-9cf844104f0c-image.png

    Здесь задействованы только красный и черный провода, которые идут к извещателю, остальные лишние.

    Извещатель состоит из двух частей, это магнит и геркон. Геркон вешаем на дверной косяк, а магнит на саму дверь. Когда магнит находится у геркона (дверь закрыта), его цепь замкнута и на GPIO7 поступает единица. Если же открыть дверь или перерезать провод, то она оттуда исчезнет, о чем мы и запишем в файл.

    Программная реализация

    Для работы с GPIO нашей малинки существует очень удобная библиотека для Python под названием RPIO (http://pythonhosted.org/RPIO/). Рекомендую всем зайти на этот сайт и изучить документацию и примеры, благо объем ее невелик и написана она несложным языком. Итак, для начала собственно установим Python

    sudo apt-get install python python-setuptools
    

    И библиотеку RPIO

    sudo easy_install -U RPIO
    

    Создадим файл нашего скрипта с названием, к примеру, door.py. Дадим ему права на исполнение:

    chmod +rx door.py
    

    Заполним этот файл следующим содержимым:

    #!/usr/bin/python
    # -*- coding: utf-8 -*-
    import RPIO # Импортируем библиотеку RPIO
    import time # ...и для работы со временем
    input_pins = (7,8,9,10) # Задаем номера пинов, которые будут использоваться под ввод. Лучше внести в этот список побольше пинов, дабы избежать наводок.
    for i in xrange(len(input_pins)): # Включаем их на ввод и подтягиваем к земле
    RPIO.setup(input_pins[i], RPIO.IN, pull_up_down=RPIO.PUD_DOWN)
    door = open('/home/pi/door', 'a',0) # Открываем файл в который будем записывать инфу. 'a' означает режиме записи в конец файла 0 - отключить буферизацию, чтбы информация записывалась незамедлительно.
    
    def write_door_state(gpio_id, val): # Создаем функцию, запускаемую при изменении состояния GPIO
    	if val==0: 
    		door.write (time.strftime("%d.%m.%Y %H:%M:%S")+"\tОткрытие\r\n") #\t - символ табуляции, \r\n - перевод строки
    	else:
    		door.write (time.strftime("%d.%m.%Y %H:%M:%S")+"\tЗакрытие\r\n")
    RPIO.add_interrupt_callback(7, write_door_state,pull_up_down=RPIO.PUD_DOWN,threaded_callback=True, debounce_timeout_ms=50) #Добавляем прерывание, с подтяжкой к земле и подавлением дребезга контактов
    
    RPIO.wait_for_interrupts() # Запускаем ожидание прерываний
    

    Чтобы наш скрипт запускался от имени суперпользователя (а иначе он работать не будет) при старте системы, необходимо в файл /etc/rc.local перед строчкой exit 0 записать путь к нашему скрипту и добавить амперсанд (&) в конце, например

    /home/pi/door.py&
    

    Также можно для удобства в файл ~/.bashrc добавить строки

    echo "Последние 10 событий двери:"
    tail door
    

    Теперь при каждом входе в систему будет выводиться последние 10 строк из нашего лога:

    Последние 10 событий двери:
    26.08.2013 14:24:52     Открытие
    26.08.2013 14:25:03     Закрытие
    27.08.2013 01:37:57     Открытие
    
    1 ответ Последний ответ
    0
    • piP Не в сети
      piP Не в сети
      pi
      написал в отредактировано
      #2

      Спасибо за интересную статью!!! Особенно за программную реализацию!!! Хочу сделать спидометр для велосипеда с применением геркона 😃 Думаю, что код с нуля писать не придется, а достаточно будет этот переделать под свои нужды))

      1 ответ Последний ответ
      0
      • piP Не в сети
        piP Не в сети
        pi
        написал в отредактировано
        #3

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

        1 ответ Последний ответ
        0
        • B Не в сети
          B Не в сети
          blblbl2
          написал в отредактировано
          #4

          Здравствуйте, как с вами связаться ? Есть предложение по расширению этой статьи. Личка на сайте отключена.

          1 ответ Последний ответ
          0
          • B Не в сети
            B Не в сети
            blblbl2
            написал в отредактировано
            #5

            jabber blblbl@dukgo.com. или vk.com/a.s.savchenko

            1 ответ Последний ответ
            0
            • piP Не в сети
              piP Не в сети
              pi
              написал в отредактировано
              #6

              Здравствуйте. я в программировании чайник без ручки. подскажите как написать программу на питоне чтобы при нуле или 1(без разницы) на gpio порт к примеру 17 открывалась ссылка на сайт.

              1 ответ Последний ответ
              0
              • piP Не в сети
                piP Не в сети
                pi
                написал в отредактировано pi
                #7

                Попробуйте следующий вариант:

                import rpio
                import webbrowser
                RPIO.add_interrupt_callback(17, webbrowser.open("http://raspberrypi.ru"),pull_up_down=RPIO.PUD_DOWN, debounce_timeout_ms=50, edge='rising')
                RPIO.wait_for_interrupts()
                

                Ссылка откроется когда на 17 порту будет единица

                1 ответ Последний ответ
                0
                • piP Не в сети
                  piP Не в сети
                  pi
                  написал в отредактировано pi
                  #8

                  добрый день! Такая же ситуация только разбираюсь как работать с GPIO. Задача состоит в том чтобы при срабатывании контактных датчиков (через оптопары) на Localhost отправлялась следующее: Например сработал Pin 17 т.е на нем 1 (или другой контакт всего их задействовано 4 (это датчики положения ворот открыто/закрыто а также кнопки открыть закрыть) то отправится должно:

                  GET/objects/object=sensorMovement2&op=m&m=statusChanged&status=%i HTTP/1.0",
                  

                  Это для управления сценариями в системе MajorDoMo все варианты перепробовал но знаний не хватает…

                  1 ответ Последний ответ
                  0
                  • piP Не в сети
                    piP Не в сети
                    pi
                    написал в отредактировано
                    #9

                    Для практики хорошая адача, но по-делу, стоимость велокомпьютера 300-450 руб и их так много…

                    1 ответ Последний ответ
                    0
                    • piP Не в сети
                      piP Не в сети
                      pi
                      написал в отредактировано
                      #10

                      Запросы можно осуществлять при помощи библиотеки urllib

                      1 ответ Последний ответ
                      0
                      • piP Не в сети
                        piP Не в сети
                        pi
                        написал в отредактировано
                        #11

                        А есть программа наподобие ArduBloсk но для малинки?

                        1 ответ Последний ответ
                        0
                        • piP Не в сети
                          piP Не в сети
                          pi
                          написал в отредактировано pi
                          #12

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

                          10.12.2016 18:32:35 Закрытие
                          10.12.2016 18:33:03 Закрытие
                          10.12.2016 18:33:32 Закрытие
                          10.12.2016 18:33:33 Закрытие
                          

                          никто не сталкивался с таким?

                          1 ответ Последний ответ
                          0
                          • piP Не в сети
                            piP Не в сети
                            pi
                            написал в отредактировано
                            #13

                            Возможно, наводки или дребезг контактов. Добавьте побольше пинов в input_pins и поэкспериментируйте с различными значениями debounce_timeout_ms.

                            1 ответ Последний ответ
                            0
                            • piP Не в сети
                              piP Не в сети
                              pi
                              написал в отредактировано pi
                              #14

                              так и не получилось, играя со значениями, добиться нужного результата… пришлось применить немного говнокода 😄
                              может кому пригодится, у кого геркон будет так же «дрибезжать». возможно проблема в нем, надо попробовать другой поставить.
                              цель была оповещать когда произойдет открытие.

                              #!/usr/bin/python
                              # -*- coding: utf-8 -*-
                              #
                              import RPIO	# Импортируем библиотеку RPIO
                              import time	# ...и для работы со временем
                              import MySQLdb
                              import gc	#чистка мусора
                              import requests
                              import datetime
                              from time import sleep
                              close=0
                              input_pins = (18,19,20,21,22,23,24,25,26,27) # Задаем номера пинов, которые будут использоваться под ввод. Лучше внести в этот список побольше пинов, дабы избежать наводок.
                              for i in xrange(len(input_pins)): # Включаем их на ввод и подтягиваем к земле
                              	RPIO.setup(input_pins[i], RPIO.IN, pull_up_down=RPIO.PUD_DOWN)
                              def write_door_state(gpio_id, val): # Создаем функцию, запускаемую при изменении состояния GPIO
                              	dat=datetime.datetime.now().strftime("%d.%m.%Y %H:%M:%S")
                              	if val==0:
                              		global close
                              		if close==0:
                              			close=1
                              			try:
                              				db = MySQLdb.connect(host="localhost",user="log",passwd="pas",db="1")
                              			except:
                              				print "connection failed"
                              			door = open('/home/pi/project/door', 'w', 0)
                              			door.write (time.strftime("0 "+"%Y-%m-%d %H:%M:%S")+"\tОткрытие\r\n") #\t - символ табуляции, \r\n - перевод строки
                              			try:
                              				cursor = db.cursor()
                              				sql = """insert into door (bool,date,name) values ('%(val)s','%(date)s','%(stat)s')"""%{"val":'0', "date":dat, "stat":'Open'}
                              				cursor.execute(sql)
                              				db.commit()
                              				cursor.close()
                              				time.sleep(5) # delays for 5 seconds
                              			except MySQLdb.Error as e:
                              				print "MySQL Error: %s" % str(e)
                              			else:
                              				db.close()
                              				gc.collect()
                              			door.close()
                              			requests.get("http://sms.ru/sms/send?api_id=блабла&to=номер&text=Door open!") 
                              			time.sleep(60) # delays for 60 seconds	
                              	else:
                              		door = open('/home/pi/project/door', 'w', 0)
                              		close=0
                              		door.write (time.strftime("1 "+"%Y-%m-%d %H:%M:%S")+"\tЗакрытие\r\n")
                              		door.close()
                              # Настраиваем порт на ожидание прерываний и выполнение выщенаписанной функции#Добавляем прерывание, с подтяжкой к земле и подавлением дребезга контактов
                              RPIO.add_interrupt_callback(22, write_door_state,pull_up_down=RPIO.PUD_DOWN, threaded_callback=True, debounce_timeout_ms=50) 
                              
                              RPIO.wait_for_interrupts() # Ждем прихода прерывания.
                              
                              1 ответ Последний ответ
                              0
                              • piP Не в сети
                                piP Не в сети
                                pi
                                написал в отредактировано pi
                                #15

                                SystemError: This module can only be run on a Raspberry Pi! https://github.com/metachris/RPIO/issues/53

                                1 ответ Последний ответ
                                0

                                • Войти

                                • Нет учётной записи? Зарегистрироваться

                                • Login or register to search.
                                • Первое сообщение
                                  Последнее сообщение
                                0
                                • Категории
                                • Главная
                                • Документация
                                • Последние
                                • Пользователи