Arduino для начинающих. Урок 8. Подключение датчика движения (PIR). Отправка E-mail
Продолжаем серию уроков “Arduino для начинающих”. Сегодня мы разберем проект подключение PIR-датчика (движения) к Arduino и организуем автоматическую отправку e-mail при срабатывании датчика. Arduino является сердцем этого проекта — считывает показания ИК-датчика, и при обнаружении движения отдает компьютеру через порт USB команду отправить письмо. Обработку сигнала, поступающего на компьютер реализуем с помощью программы Python.
Список деталей для сборки модели
Для сборки проекта, описанного в этом уроке, понадобятся следующие детали:
- Arduino UNO или аналог (подробнее, о том как выбрать Arduino здесь);
- PIR-датчик (подойдет такой за $ 2);
- бредбоард (можно купить за $2,4);
- провода папа-папа (можно купить такую связку с большим запасом).
Также потребуется компьютер с подключением к Интернету, через него будем отправлять электронную почту! Роль компьютера в этом уроке может выполнять Raspberry Pi.
Схема подключения PIR-датчика к Arduino
К Arduino в этом проекте требуется подключить только PIR-датчик, поэтому провода от датчика можно подключить непосредственно к Arduino. Но т.к. в таком случае провода держаться немного не плотно удобнее использовать схему c бредбоард:
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.
Установка 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 соответствующий каталог. Чтобы сделать это, нужно зайти в Панель управления Windows, найти System Properties (Свойства системы). Затем нажать на кнопку с надписью Environment Variabes («Переменные среды») и в появившемся окне выбрать «Path» в нижней части System variables (Системные переменные). Нажать кнопку Edit («Изменить»), а затем в конце «Значение переменной», не удаляя имеющийся текст, добавить «; C: \ Python27». Не забывать «;» после каждой указанной папки. Чтобы проверить, что переменную PATH изменили корректно, в командной строке введем команду «“python». Должна появляться подобная картина:
Установка 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 в правом нижнем углу. После этих изменений, запускаем программу из командной строки / терминала: python movement.py
Готово! Когда PIR-датчик срабатывает вскоре приходит сообщение на указанный e-mail.
Что еще можно сделать с использованием PIR-датчика
Теперь, освоив средства отправки электронной почты с Arduino, можно приступить к расширению возможностей проекта. Можно добавить другие датчики, и, например, отправлять себе по электронной почте почасовые отчеты о температуре. Безусловно, PIR-датчик быть использован непосредственно с Arduino без соединения с компьютером. В этом случае при срабатывании датчика можно включать предупреждающий звуковой сигнал, мигать светодиодом, или включать освещение в помещении (через высоковольтное реле).
Смотрите также:
Учебный курс “Arduino для начинающих”: главная страница.
Посты по урокам:
- Первый урок: Светодиод
- Второй урок: Кнопка
- Третий урок: Потенциометр
- Четвертый урок: Сервопривод
- Пятый урок: Трехцветный светодиод
- Шестой урок: Пьезоэлемент
- Седьмой урок: Фоторезистор
- Восьмой урок: Датчика движения (PIR) и E-mail
- Девятый урок: Подключение датчика температуры и влажности DHT11 или DHT22
Все посты сайта “Занимательная робототехника” по тегу Arduino.
Наш YouTube канал, где публикуются видео-уроки.
Не знаете, где купить Arduino? Все используемые в уроке комплектующие входят в большинство готовых комплектов Arduino, их также можно приобрести по отдельности. Подробная инструкция по выбору здесь. Низкие цены, спецпредложения и бесплатная доставка на сайтах AliExpress и DealExtreme. Если нет времени ждать посылку из Китая — рекомендуем интернет-магазины Амперка и DESSY. Низкие цены и быструю доставку предлагает интернет-магазин ROBstore.
Смотри также список магазинов.
Автор Александр Гагарин. В статье использованы материалы learn.adafruit.com.
Aleksandr
17.10.2014
О, наконец новый урок!
Bulatka
02.11.2014
Помогите пожалуйста у меня выдает ошибку о том что не может найти файл в директории
Александр
14.11.2014
Какой-то странный множитель 1000l в строке:
long lastSend = -minSecsBetweenEmails * 1000l;
почему так?
Чтобы выразить интервал в миллисекундах достаточно умножить на 1000. А зачем I после 1000?
Занимательная робототехника
15.11.2014
Спасибо. Верно. Исправили.
Санёк
24.12.2014
А мы реализовали на Java. Еще и когда датчик сообщает о движении, то делается скриншот, фото с веб-камеры и берётся список процессов. Всё это упаковывается и отправляется письмо.
Владимир
09.01.2015
Могли бы Вы описать свой проект по-подробней? (нужно реализовать: при срабатывании сенсора движения ноут посылает фото с вебки на почту..
С уважением, Владимир
Всеволод
11.05.2015
Я правильно понимаю, что Arduino регистрирует время срабатывания датчика с точностью до миллисекунды? А что если связать Arduino и Raspberry через модуль беспроводной связи? И подключить к Raspberry не один Arduino, а несколько?
Занимательная робототехника
12.05.2015
Да, это вполне разумно для систем умный дом. Сбор данных с датчиков проще организовать с Arduino. Пусть датчиков много, плат arduino несколько… тогда, действительно, лучше просто отправлять данные с ардуин, а принимать и обрабатывать, строить логику на одном приемнике Raspberry Pi. Беспроводную связь можно использовать. Многие советуют радиомодуль nrf24l01
Vladimir
17.06.2015
Здравствуйте! В коде на Pyton выдает синтаксическая ошибка в time.sleep(0.5)
В пайтоне не силен. Что нужно исправить?
Занимательная робототехника
17.06.2015
Почему-то слетело форматирование кода. Поправили форматирование. Попробуйте еще раз.
Vladimir
17.06.2015
Теперь ошибка в GMAIL_PASS line 11
Vladimir
17.06.2015
Ошибка: import serial
Import error: no module name serial
Что делаю не так?
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, но ведь же монитор последовательного порта показывает, что все замечательно работает. Может быть подводные камни о которых я не знаю?
Vladimir
19.06.2015
Проблема решена. Причина была в том, что я использовал монитор последовательного порта до того как пытался включить программу через консоль. Спасибо за отличный урок. Бился 3 дня и вот все замечательно работает. Пока нашел решение проблемы узнал много нового для себя. Вы заставили меня думать! Спасибо!
Занимательная робототехника
19.06.2015
Отлично! Рады, что arduino-урок понравился и помог в самообучении.
Vladimir
19.06.2015
Оповещение приходит только один раз при запуске программы с командной строки. Потом никаких оповещений не происходит. Светодиод на Arduino мигает, показывая, что датчик работает. Если включить монитор последовательного порта, также показывает, что работает. Уже всю голову сломал. Направьте в нужном направлении, пожалуйста.
Александр
22.06.2015
цикл в коде имеeтся (while True:) ?
Может у вас условие не выполняется? if message[0] == ‘M’ :
Vladimir
22.06.2015
while True:message = ser.readline()
print(message)
if message[0] == ‘M’: sendmail()
time.sleep(0.5)
Вот, что у меня.
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 сделали ошибку в коде. Навскидку ее не видно. Хотя, возможно. Все ошибаются.
Vladimir
23.06.2015
Ссылку на оригинальную статью не увидел, извините. Вышел на ресурс adafruit.com через книгу. Не могу решить данную проблему вот, и приходится искать в сети. Самолюбие заставило изучить эту тему подробнее. Возникла задача, ее нужно решить и на пути ее решения (задачи) возникают интересные ситуации. Мне это нравится. Спасибо, что не удалили комментарий. Вот вопрос Вам, а вы сами прежде, чем писать перевод статьи испытали проект на работоспособность? Я найду решение проблемы и продам Вам за вознаграждение! :)
Занимательная робототехника
25.06.2015
Хороший комментарий. По делу. Зачем его удалять?
Вообще, спасибо за обратную связь!
Не помню собирали ли мы в точности такую же модель.
Смотря как решение будет оформлено и сколько стоить :-)
K1p
02.11.2015
Тут проблема в том, что по последовательному порту передаются байты, а сравнивать их пытаются с символом. Должно быть так:
if chr(message[0]) == «M»
lumtrade.com
20.10.2015
Фоторезисторы используются в робототехнике как датчики освещенности. Встроенный в робота фоторезистор позволяет определять степень освещенности, определять белые или черные участки на поверхности и в соответствие с этим двигаться по линии или совершать другие действия.
Алексей
29.11.2015
Помогите, плиз. Я первый день с python. У меня выдает ошибку на строку print(‘Sending Email’)
qwertyhp
05.01.2016
Алексей, возможно, ошибка возникает в результате того, что почтовый сервер требует работу по SSL.
Кстати — а как в python отправлять письма на такие сервера (например, MAIL.RU)? Или на любой другой, чья адресная строка начинается с HTTPS?
Ренат
11.01.2016
Помогите,плиз.Как найти скорость объекта с помощью ультразвукового датчика
Денис
14.01.2016
Объект двигается в сторону датчика (либо от него)? Тогда просто следим за временем и изменением расстояния и вычисляем скорость
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 — это начальное значение, задано оно таким, чтобы была программа могла выдать значение сразу при запуске программы
геннадий
09.08.2016
Здравствуйте новичок осваиваю программу собираюсь объединить ухи локатор и и датчик с поочередно работой.трудности с программой.купил речевой плату но она без программ и неясно как запускать а у вашей программы богатая среда програмирования буду осваивать материала много.
гена
12.08.2016
Думаю установить два датчика движения под углом 90 град. И обработать их данные для получения направления движения помогите скетчем
Vlad
02.10.2016
Статья переведена с английского языка. Об этом надо было сказать сразу и указать источник. (https://learn.adafruit.com/arduino-lesson-17-email-sending-movement-detector/breadboard-layout).
В приведенной здесь статье в скетче ошибки. Код питона после копирования выдает ошибки(программа правильная, но нарушен синтаксис). В англ. источнике все получается. Кто хочет запустить датчик все берите из англ. источника.
Труба
10.12.2016
можете пояснить этот момент такому чайнику , как я ?
у меня почему то не выходит :
«После этих изменений, запускаем программу из командной строки / терминала:
python movement.py»
Иван
25.12.2016
expected an indented block…
def send_email():
print(«Sending Email»)
smtpserver = smtplib.SMTP(«smtp.gmail.com»,587)
На принте ползунок
Иван
25.12.2016
Забыл что питон любит отступы и без них работать не может…
Иван
25.12.2016
Кто подскажет, почему цикл 1 раз всего на почту отправляет письмо?
Иван
25.12.2016
В общем, используйте оригинальный источник. И те версии ПО, которые указал автор. Всё починил, всё работает.
Руслан
26.01.2017
Здравствуйте, а как сделать что бы датчик движения срабатывал только в темноте. да есть урок с фоторезистором и этот, но вот как объединить эти скетчи?
Григорий
14.06.2017
Ошибка: import serial
Import error: no module name serial
Что делаю не так?
Leliil
21.03.2018
А как подключить несколько PIR датчиков? Например 5-6
Nina
18.12.2018
Напишем программу для считывания значений с пироэлектрического датчика движения. Подключить PIR датчик к микроконтроллеру просто. Датчик выдает цифровой сигнал, так что все, что вам необходимо — считывать с пина Arduino сигнал HIGH (рбнаружено движение) или LOW (движения нет).
Антон
08.05.2019
У меня получается так что программа срабатывает только один раз.
Т.е смс на эмеил приходит с начале и все
Потом сколько не жди нового Сообщения не приходить
Хотя в ардуино,через монитор порта значения появляются каждую минуту