Arduino для начинающих. Урок 8. Подключение датчика движения (PIR). Отправка E-mail

Конструкторы для обучения детей робототехнике

Share Button

Продолжаем серию уроков “Arduino для начинающих”.  Сегодня мы разберем проект подключение PIR-датчика (движения) к Arduino и организуем автоматическую отправку e-mail при срабатывании датчика. Arduino является сердцем этого проекта — считывает показания ИК-датчика, и при обнаружении движения отдает компьютеру через порт USB команду отправить письмо. Обработку сигнала, поступающего на компьютер реализуем с помощью программы Python.

Список деталей для сборки модели

Для сборки проекта, описанного в этом уроке, понадобятся следующие детали:

  • Arduino UNO или аналог (подробнее, о том как выбрать Arduino здесь);
  • PIR-датчик (подойдет такой за $ 2);
  • бредбоард (можно купить за $2,4);
  • провода папа-папа (можно купить такую связку с большим запасом).
Arduino UNO

Arduino UNO

PIR-датчик

PIR-датчик

Бредбоард

Бредбоард

Провода папа-папа

Провода папа-папа

Также потребуется компьютер с подключением к Интернету, через него будем отправлять электронную почту! Роль компьютера в этом уроке может выполнять Raspberry Pi.

Схема подключения PIR-датчика к Arduino

К Arduino в этом проекте требуется подключить только PIR-датчик, поэтому провода от датчика можно подключить непосредственно к Arduino. Но т.к. в таком случае провода держаться немного не плотно удобнее использовать схему c бредбоард:

Схема подключения PIR-датчика к бредбоард

Схема подключения PIR-датчика к бредбоард

Arduino скетч

Arduino будет послать сообщение по USB Serial связи при обнаружении движения. Но если посылать e-mail при каждом срабатывании датчика, то можно получить огромное количество писем. Поэтому если прошло еще слишком мало времени от прошлого сигнала — будем посылать другое сообщение.
int pirPin = 7;
int minSecsBetweenEmails = 60; // 1 min
long lastSend = -minSecsBetweenEmails * 1000;
void setup()
{
pinMode(pirPin, INPUT);
Serial.begin(9600);
}
void loop()
{
long now = millis();
if (digitalRead(pirPin) == HIGH)
{
if (now > (lastSend + minSecsBetweenEmails * 1000))
{
Serial.println("MOVEMENT"); lastSend = now;
}
else
{
Serial.println("Too soon"); }
}
delay(500);
}

Переменная «minSecsBetweenEmails» может быть изменена на другое разумное значение. В примере она установлена на 60 секунд, и письма не будут отправлены чаще одной минуты. Чтобы отслеживать, когда последний раз была отдана команда слать e-mail используется переменная «lastSend». Ее инициализируем отрицательным числом, равным числу миллисекунд, указанных в переменной «minSecsBetweenEmails». Это гарантирует нам обработку срабатывания PIR-датчика сразу как только скетч Arduino запущен. В цикле используется функция Millis () чтобы получить число миллисекунд с Arduino и сравнить со временем от прошлого срабатывания датчика и соответствующей отправке сообщения «MOVEMENT» (движение). Если сравнение показывает, что прошло слишком мало времени от прошлого срабатывания датчика, то несмотря на то, что движение было обнаружено, посылаем сообщение «Too soon» (Слишком рано). Перед тем как писать программу на Python для обработки сигнала, поступающего с Arduino на компьютер или Raspberry Pi по USB, можно проверить работу программы на Arduino, просто открыв Serial Monitor на Arduino IDE.

Serial Monitor Arduino IDE

Serial Monitor Arduino IDE

Установка Python и PySerial

Если в проекте используется компьютер с операционной системой Linux, например, Raspberry Pi,  Python уже установлен. Если используется компьтер с операционной системой Windows, то Python требуется установить. В любом случае, потребуется установить библиотеку PySerial чтобы обеспечить связь с Arduino.

Установка Python на Windows

Чтобы установить Python на Windows, скачайте установщик с  https://www.python.org/downloads/. Были сообщения о проблемах с PySerial на Windows при использовании Python 3, поэтому используем  Python 2. После установки Python, в меню Пуск появится соответствующая группа. Но для установки PySerial нужно будет использовать Python из командной строки, поэтому добавим к переменной PATH среды Windows соответствующий каталог. learn_arduino_Python_inst_win_setting_path Чтобы сделать это, нужно зайти в Панель управления Windows, найти System Properties (Свойства системы). Затем нажать на кнопку с надписью Environment Variabes («Переменные среды») и в появившемся окне выбрать «Path» в нижней части System variables (Системные переменные). Нажать кнопку Edit («Изменить»), а затем в конце «Значение переменной», не удаляя имеющийся текст, добавить «; C: \ Python27». Не забывать «;» после каждой указанной папки. Чтобы проверить, что переменную PATH изменили корректно, в командной строке введем команду «“python». Должна появляться подобная картина:

learn_arduino_python_from_dosУстановка PySerial

Независимо от используемой операционной системы, скачиваем .tar.gz установочный пакет для PySerial 2.6 с https://pypi.python.org/pypi/pyserial  Получаем файл с именем pyserial-2.6.tar.gz При использовании Windows нужно распаковать файл в папку. К сожалению, это не обычный файл ZIP, так что, возможно, потребуется скачать, например, 7-zip (http://www.7-zip.org/). При использовании компьютера с операционной системой Linux, например, при использовании в этом проекте Raspberry Pi, нужно открыть терминальную сессию, выполнить команду «CD» с указанием папки куда скачана pyserial-2.6.tar.gz, а затем выполнить следующую команду, чтобы распаковать установщик:
$ tar -xzf pyserial-2.6.tar.gz
Далее независимо от используемой операционной системы в командной строке выполняем команду “CD” c указанием папки pyserial-2.6 и выполняем команду:
sudo python setup.py install

Код на Python

Теперь создаем программу на Python. Для этого копируем данный код в файл с именем «movement.py». На Linux можно использовать «нано» редактор, на Windows, вероятно, самый простой способ сделать файл с помощью редактора Python ‘IDLE » (доступен из группы программ Python в меню Пуск).

import time
import serial
import smtplib
TO = 'putyour@email.here'
GMAIL_USER = 'putyour@email.here'
GMAIL_PASS = 'putyourpasswordhere'
SUBJECT = 'Intrusion!!'
TEXT = 'Your PIR sensor detected movement'
ser = serial.Serial('COM4', 9600)
def send_email():
print("Sending Email")
smtpserver = smtplib.SMTP("smtp.gmail.com",587)
smtpserver.ehlo() smtpserver.starttls()
smtpserver.ehlo smtpserver.login(GMAIL_USER, GMAIL_PASS)
header = 'To:' + TO + '\n' + 'From: ' + GMAIL_USER
header = header + '\n' + 'Subject:' + SUBJECT + '\n'
print header
msg = header + '\n' + TEXT + ' \n\n'
smtpserver.sendmail(GMAIL_USER, TO, msg)
smtpserver.close()
while True:
message = ser.readline()
print(message)
if message[0] == 'M' :
send_email()
time.sleep(0.5)

Перед тем как запустить программу Python вносим некоторые изменения (все они в верхней части программы). Программа предполагает, что электронные письма создаются из аккаунта Gmail. Если его нет регистрируем (даже если это только для этого проекта). Изменяем значение переменной «TO» на адрес электронной почты, куда будут отправляться уведомления. Изменяем значение «GMAIL_USER» на адрес электронной почты Gmail и соответственно пароль в следующей строке (GMAIL_PASS). Также можно изменить тему и текст сообщения для отправки («SUBJECT» и «TEXT»). Необходимо установить последовательный порт, к которому подключена Arduino в строке ser = serial.Serial('COM4', 9600) Для Windows, это будет что-то навроде «COM4» для Linux — что-то навроде «/dev/tty.usbmodem621».  К какому порту компьютера подключена плата смотрим в Arduino IDE в правом нижнем углу. learn_arduino_arduino_ide_port После этих изменений, запускаем программу из командной строки / терминала: python movement.py Готово! Когда PIR-датчик срабатывает вскоре приходит сообщение на указанный e-mail.

Что еще можно сделать с использованием PIR-датчика

Теперь, освоив средства отправки электронной почты с Arduino, можно приступить к расширению возможностей проекта. Можно добавить другие датчики, и, например, отправлять себе по электронной почте почасовые отчеты о температуре. Безусловно, PIR-датчик быть использован непосредственно с Arduino без соединения с компьютером. В этом случае при срабатывании датчика можно включать предупреждающий звуковой сигнал, мигать светодиодом, или  включать освещение в помещении (через высоковольтное реле).

Смотрите также:

Учебный курс “Arduino для начинающих”: главная страница.

Посты по урокам:

  1. Первый урок: Светодиод
  2. Второй урок: Кнопка
  3. Третий урок: Потенциометр
  4. Четвертый урок: Сервопривод
  5. Пятый урок: Трехцветный светодиод
  6. Шестой урок: Пьезоэлемент
  7. Седьмой урок: Фоторезистор
  8. Восьмой урок: Датчика движения (PIR) и E-mail
  9. Девятый урок: Подключение датчика температуры и влажности DHT11 или DHT22

Все посты сайта “Занимательная робототехника” по тегу Arduino.

Наш YouTube канал, где публикуются видео-уроки.

Не знаете, где купить Arduino? Все используемые в уроке комплектующие входят в большинство готовых комплектов Arduino, их также можно приобрести по отдельности. Подробная инструкция по выбору здесь. Низкие цены, спецпредложения и бесплатная доставка на сайтах AliExpress и DealExtreme. Если нет времени ждать посылку из Китая — рекомендуем интернет-магазины Амперка и DESSY. Низкие цены и быструю доставку предлагает интернет-магазин ROBstore.

Смотри также список магазинов.

Автор Александр Гагарин. В статье использованы материалы learn.adafruit.com.

Share Button

39 комментариев к статье “Arduino для начинающих. Урок 8. Подключение датчика движения (PIR). Отправка E-mail”

  1. Aleksandr

    17.10.2014

    О, наконец новый урок!

    Ответить на этот комментарий
  2. Bulatka

    02.11.2014

    Помогите пожалуйста у меня выдает ошибку о том что не может найти файл в директории

    Ответить на этот комментарий
  3. Александр

    14.11.2014

    Какой-то странный множитель 1000l в строке:
    long lastSend = -minSecsBetweenEmails * 1000l;
    почему так?
    Чтобы выразить интервал в миллисекундах достаточно умножить на 1000. А зачем I после 1000?

    Ответить на этот комментарий
  4. Санёк

    24.12.2014

    А мы реализовали на Java. Еще и когда датчик сообщает о движении, то делается скриншот, фото с веб-камеры и берётся список процессов. Всё это упаковывается и отправляется письмо.

    Ответить на этот комментарий
  5. Владимир

    09.01.2015

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

    Ответить на этот комментарий
  6. Всеволод

    11.05.2015

    Я правильно понимаю, что Arduino регистрирует время срабатывания датчика с точностью до миллисекунды? А что если связать Arduino и Raspberry через модуль беспроводной связи? И подключить к Raspberry не один Arduino, а несколько?

    Ответить на этот комментарий
    • Занимательная робототехника

      12.05.2015

      Да, это вполне разумно для систем умный дом. Сбор данных с датчиков проще организовать с Arduino. Пусть датчиков много, плат arduino несколько… тогда, действительно, лучше просто отправлять данные с ардуин, а принимать и обрабатывать, строить логику на одном приемнике Raspberry Pi. Беспроводную связь можно использовать. Многие советуют радиомодуль nrf24l01

      Ответить на этот комментарий
  7. Vladimir

    17.06.2015

    Здравствуйте! В коде на Pyton выдает синтаксическая ошибка в time.sleep(0.5)
    В пайтоне не силен. Что нужно исправить?

    Ответить на этот комментарий
    • Занимательная робототехника

      17.06.2015

      Почему-то слетело форматирование кода. Поправили форматирование. Попробуйте еще раз.

      Ответить на этот комментарий
  8. Vladimir

    17.06.2015

    Теперь ошибка в GMAIL_PASS line 11

    Ответить на этот комментарий
  9. Vladimir

    17.06.2015

    Ошибка: import serial
    Import error: no module name serial
    Что делаю не так?

    Ответить на этот комментарий
  10. Vladimir

    18.06.2015

    Здравствуйте! Разобрался с форматированием. В мониторе последовательного порта показывается, что движение есть. Драйвер для Arduino установлен. При попытке запустить программу через командную строку пишет: C:\Users\Пользователь>python movement.py
    Traceback (most recent call last):
    File «movement.py», line 17, in
    ser = serial.Serial(‘COM20’, 9600)
    File «C:\Python27\lib\site-packages\serial\serialwin32.py», line 38, in __init
    __
    SerialBase.__init__(self, *args, **kwargs)
    File «C:\Python27\lib\site-packages\serial\serialutil.py», line 282, in __init
    __
    self.open()
    File «C:\Python27\lib\site-packages\serial\serialwin32.py», line 66, in open
    raise SerialException(«could not open port %r: %r» % (self.portstr, ctypes.W
    inError()))
    serial.serialutil.SerialException: could not open port ‘COM20’: WindowsError(5,
    ‘\xce\xf2\xea\xe0\xe7\xe0\xed\xee \xe2 \xe4\xee\xf1\xf2\xf3\xef\xe5.’)
    Понял, что не удалось открыть порт com20 к которому подключен Arduino, но ведь же монитор последовательного порта показывает, что все замечательно работает. Может быть подводные камни о которых я не знаю?

    Ответить на этот комментарий
  11. Vladimir

    19.06.2015

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

    Ответить на этот комментарий
  12. Vladimir

    19.06.2015

    Оповещение приходит только один раз при запуске программы с командной строки. Потом никаких оповещений не происходит. Светодиод на Arduino мигает, показывая, что датчик работает. Если включить монитор последовательного порта, также показывает, что работает. Уже всю голову сломал. Направьте в нужном направлении, пожалуйста.

    Ответить на этот комментарий
  13. Vladimir

    22.06.2015

    while True:message = ser.readline()
    print(message)

    if message[0] == ‘M’: sendmail()

    time.sleep(0.5)

    Вот, что у меня.

    Ответить на этот комментарий
  14. Vladimir

    23.06.2015

    Я честно говоря думал, что вы сами являетесь авторами этой статьи , но как всегда автором является кто-то другой. Статья по всей вероятности взята тут: https://learn.adafruit.com/arduino-lesson-17-email-sending-movement-detector

    Ответить на этот комментарий
    • Занимательная робототехника

      23.06.2015

      Владимир, большинство arduino-уроков нашего курса для начинающих составлено нами, в том числе мы снимали видео. Именно этот урок действительно является переводом с adafruit, в конце статьи указано, что использованы материалы learn.adafruit.com. У adafruit качественные материалы. Не видим ничего плохого в том, что их переводят и используют. Мало вероятно, что ada сделали ошибку в коде. Навскидку ее не видно. Хотя, возможно. Все ошибаются.

      Ответить на этот комментарий
  15. Vladimir

    23.06.2015

    Ссылку на оригинальную статью не увидел, извините. Вышел на ресурс adafruit.com через книгу. Не могу решить данную проблему вот, и приходится искать в сети. Самолюбие заставило изучить эту тему подробнее. Возникла задача, ее нужно решить и на пути ее решения (задачи) возникают интересные ситуации. Мне это нравится. Спасибо, что не удалили комментарий. Вот вопрос Вам, а вы сами прежде, чем писать перевод статьи испытали проект на работоспособность? Я найду решение проблемы и продам Вам за вознаграждение! :)

    Ответить на этот комментарий
    • Занимательная робототехника

      25.06.2015

      Хороший комментарий. По делу. Зачем его удалять?
      Вообще, спасибо за обратную связь!
      Не помню собирали ли мы в точности такую же модель.
      Смотря как решение будет оформлено и сколько стоить :-)

      Ответить на этот комментарий
    • K1p

      02.11.2015

      Тут проблема в том, что по последовательному порту передаются байты, а сравнивать их пытаются с символом. Должно быть так:
      if chr(message[0]) == «M»

      Ответить на этот комментарий
  16. lumtrade.com

    20.10.2015

    Фоторезисторы используются в робототехнике как датчики освещенности. Встроенный в робота фоторезистор позволяет определять степень освещенности, определять белые или черные участки на поверхности и в соответствие с этим двигаться по линии или совершать другие действия.

    Ответить на этот комментарий
  17. Алексей

    29.11.2015

    Помогите, плиз. Я первый день с python. У меня выдает ошибку на строку print(‘Sending Email’)

    Ответить на этот комментарий
  18. qwertyhp

    05.01.2016

    Алексей, возможно, ошибка возникает в результате того, что почтовый сервер требует работу по SSL.
    Кстати — а как в python отправлять письма на такие сервера (например, MAIL.RU)? Или на любой другой, чья адресная строка начинается с HTTPS?

    Ответить на этот комментарий
  19. Ренат

    11.01.2016

    Помогите,плиз.Как найти скорость объекта с помощью ультразвукового датчика

    Ответить на этот комментарий
    • Денис

      14.01.2016

      Объект двигается в сторону датчика (либо от него)? Тогда просто следим за временем и изменением расстояния и вычисляем скорость

      Ответить на этот комментарий
  20. Stjopa.rus

    18.01.2016

    Добрый день!
    В программировании ардуино новичок, да и вообще в программировании.
    Может ли кто мне объяснить смысл строки «long lastSend = -minSecsBetweenEmails * 1000;» где получается -60000 если я правильно вкурил это константа и можно её просто вписать одним числом?
    и строка «if (now > (lastSend + minSecsBetweenEmails * 1000))» что тут вообще происходит? -60000 + 60000 = 0?? и с чем тогда сравнивается now, с нулём что ли??

    Ответить на этот комментарий
    • Денис

      18.01.2016

      здесь проверяется, что прошло достаточно времени с прошлого сообщения. в программе задано, что сообщения будут отправляться не чаще, чем раз в минуту. lastSend — это переменная. long lastSend = -minSecsBetweenEmails * 1000 — это начальное значение, задано оно таким, чтобы была программа могла выдать значение сразу при запуске программы

      Ответить на этот комментарий
  21. геннадий

    09.08.2016

    Здравствуйте новичок осваиваю программу собираюсь объединить ухи локатор и и датчик с поочередно работой.трудности с программой.купил речевой плату но она без программ и неясно как запускать а у вашей программы богатая среда програмирования буду осваивать материала много.

    Ответить на этот комментарий
  22. гена

    12.08.2016

    Думаю установить два датчика движения под углом 90 град. И обработать их данные для получения направления движения помогите скетчем

    Ответить на этот комментарий
  23. Vlad

    02.10.2016

    Статья переведена с английского языка. Об этом надо было сказать сразу и указать источник. (https://learn.adafruit.com/arduino-lesson-17-email-sending-movement-detector/breadboard-layout).
    В приведенной здесь статье в скетче ошибки. Код питона после копирования выдает ошибки(программа правильная, но нарушен синтаксис). В англ. источнике все получается. Кто хочет запустить датчик все берите из англ. источника.

    Ответить на этот комментарий
  24. Труба

    10.12.2016

    можете пояснить этот момент такому чайнику , как я ?
    у меня почему то не выходит :
    «После этих изменений, запускаем программу из командной строки / терминала:
    python movement.py»

    Ответить на этот комментарий
  25. Иван

    25.12.2016

    expected an indented block…

    def send_email():

    print(«Sending Email»)

    smtpserver = smtplib.SMTP(«smtp.gmail.com»,587)

    На принте ползунок

    Ответить на этот комментарий
  26. Иван

    25.12.2016

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

    Ответить на этот комментарий
  27. Иван

    25.12.2016

    В общем, используйте оригинальный источник. И те версии ПО, которые указал автор. Всё починил, всё работает.

    Ответить на этот комментарий
  28. Руслан

    26.01.2017

    Здравствуйте, а как сделать что бы датчик движения срабатывал только в темноте. да есть урок с фоторезистором и этот, но вот как объединить эти скетчи?

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

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

© 2014-2017 Занимательная робототехника, Гагарина Д.А., Гагарин А.С., Гагарин А.А. All rights reserved / Все права защищены. Копирование и воспроизведение в любой форме запрещено.
Наверх
Яндекс.Метрика