Работа мечты в один клик 💼

💭Мечтаешь работать в Сбере, но не хочешь проходить десять кругов HR-собеседований? Теперь это проще, чем когда-либо!
💡AI-интервью за 15 минут – и ты уже на шаг ближе к своей новой работе.
Как получить оффер? 📌 Зарегистрируйся 📌 Пройди AI-интервью 📌 Получи обратную связь сразу же!
HR больше не тянут время – рекрутеры свяжутся с тобой в течение двух дней! 🚀
Реклама. ПАО СБЕРБАНК, ИНН 7707083893. Erid 2VtzquscAwp
Что делаем?
Делаем простую сигнализацию на ультразвуковом датчике расстояния HC-SR04. Когда датчик обнаруживает препятствие, мы получаем уведомление в мобильном приложении IFTTT о срабатывании сигнализации, а камера делает 3 снимка, которые отправляются с Gmail-почты на любую другую почту.
Что понадобится?
- Raspberry Pi 3/4.
- Резисторы 1 кОм и 2 кОм по 1 шт.
- Ультразвуковой датчик расстояния HC-SR04.
- Модуль камеры Raspberry Pi Camera v1.3 или v2.1.
Установка операционной системы
Скачаем операционную систему Raspberry Pi OS и установим ее на microSD-карту с помощью balenaEtcher.
Ультразвуковой датчик HC-SR04
Что такое ультразвук?
Человек слышит звуки в диапазоне от 20 (низкий бас) до 20 000 Гц (высокочастотный свист). Ультразвук имеет частоту более 20 000 Гц и поэтому человек его не слышит.

Датчик HC-SR04 работает, как сонар:
- Отправляет ультразвуковой импульс.
- Ловит отраженный от препятствия импульс.
- Вычисляет сколько времени потребовалось импульсу, чтобы достигнуть препятствия и вернуться обратно.

Характеристики датчика HC-SR04:
- Напряжение питания: 5 В.
- Диапазон расстояний: 2-400 см.
- Эффективный угол наблюдения: 15°.
- Рабочий угол наблюдения: 30°.

Как вычислить пройденное расстояние?
Зная скорость распространения звука в среде и временной интервал, можем вычислить расстояние:
Датчик считает расстояние туда-обратно. Нам нужна половина этого значения:
Скорость звука при температуре 20°C составляет 34 300 см/с.
После подстановки значений получаем:
Нумерация пинов Raspberry Pi
В Малине используют две системы нумерации пинов:
GPIO.BOARD
– пины нумеруются слева направо и сверху вниз от 1 до 40.GPIO.BCM
– пины нумеруются по Broadcom SOC и называются GPIO [номер]. На рис. в скобках указаны альтернативные значения пинов.
Мы будем использовать нумерацию GPIO.BCM со значениями пинов по умолчанию.

Схема подключения HC-SR04 к Raspberry Pi
- Пин питания
VCC
подключаем к пину5V
на Малине (красная линия). - Пин земли
GND
подключаем к пинуGND
на Малине (синяя линия). - Пин
Echo
подключаем кGPIO 26
(зеленая линия). - Пин
Trig
подключаем кGPIO 19
(оранжевая линия).

После получения импульса на пине Echo
устанавливается логический уровень 5 В, а Малина работает с логикой 3.3 В. Чтобы понизить напряжение добавим в схему два резистора разных номиналов, образующих делитель напряжения. Для расчета номиналов воспользуемся онлайн-калькулятором:

Нам нужны резисторы 1 и 2 кОм. Можно подобрать резисторы других номиналов. Главное – получить напряжение не выше 3.3 В, чтобы не испортить Малину.
На макетной плате поменяем положение датчика на «от» Raspberry Pi:

Подключение камеры
Установим шлейф камеры в Малину:

Присоединим шлейф к камере аналогичным образом:

Камера по умолчанию отключена. Для активации камеры зайдем в Меню
→ Preferences
→ Raspberry Pi Configuration
:

Перейдем во вкладку Interfaces
и активируем камеру:

Создание апплета IFTTT
Зарегистрируемся на сайте IFTTT и перейдем на страницу создания апплета.
В условие If This добавим Receive a web request
, в условие Then That
– Send a notification from IFTTT app
.

В условии If This
назовем событие signal
:

Теперь перейдем на страницу Вебхуков и кликнем по кнопке Documentation
:

Впишем название события signal
и получим ссылку, которая активирует наше событие.

Установим мобильное приложение IFTTT на Android или iOS, чтобы получать уведомления.
Установка библиотек
Установим библиотеку yagmail для отправки почты с аккаунта Gmail:
pip3 install yagmail
Остальные библиотеки – RPi.GPIO
для работы с пинами и picamera
для управления камерой – предустановлены.
Запускаем код
Импортируем необходимые библиотеки:
from picamera import PiCamera
import RPi.GPIO as GPIO
import datetime
import requests
import yagmail
import time
import os
Напишем функцию create_shots_folder()
, которая создает папку для снимков:
# функция, проверяющая наличие/создающая папку shots
def create_shots_folder():
# если папки shots не существует
if not os.path.exists('shots'):
# то создать папку shots в текущем каталоге
os.mkdir('shots')
Функция take_shots(number_of_shots)
управляет камерой и принимает на вход в качестве аргумента количество снимков number_of_shots:
# функция, управляющая камерой
def take_shots(number_of_shots):
# инициализация камеры
camera = PiCamera()
# задаем разрешение снимка
camera.resolution = (1024, 768)
# список, в который добавим пути к снимкам
shots = []
# цикл, который number_of_shots-раз сделает снимки с паузой 0.5 сек
for i in range(number_of_shots):
# получим текущую дату и время без миллисекунд
time_of_the_crime = datetime.datetime.today().replace(microsecond=0)
# присвоим снимку имя: текущая дата и время плюс расширение .jpg
shot_name = str(time_of_the_crime) + '.jpg'
# получим путь к снимку
shot_path = os.path.join(os.getcwd(), 'shots', shot_name)
# сделаем снимок и сохраним его в папку shots под именем shot_name
camera.capture(shot_path)
print('Сделал снимок:', shot_name)
# добавим путь к снимку в список снимков shots
shots.append(shot_path)
# пауза между снимками в секундах
pause = 0.5
time.sleep(pause)
# отключим камеру
camera.close()
return shots
Здесь:
shot_name
– название снимка: текущая дата и время без миллисекунд.shot_path
– путь к снимку.shots
– список с путями.pause
– пауза между снимками.
Функция send_email()
отправляет снимки с Gmail-почты на любую другую почту:
def send_email(sender_email, sender_email_password, recipient_email, number_of_shots):
# список с путями снимков
shots = take_shots(number_of_shots)
# senders_email - Gmail-адрес отправителя
# senders_email_password - пароль от Gmail
email = yagmail.SMTP(user=sender_email, password=sender_email_password)
# subject - тема письма
# contents - содержимое письма
# attachments - вложения (снимки)
email.send(to=recipient_email, subject='Проникновение в помещение', contents='Тревога!', attachments=shots)
print('Снимки отправлены на почту.\n')
sender_email
– адрес Gmail-почты и пароль от нееsender_email_password
.recipient_email
– почтовый адрес получателя.
Чтобы отправить почту через скрипт, нужно открыть доступ для небезопасных приложений. Для этого зайдите в профиль Гугл-почты
→ Безопасность
→ Ненадежные приложения, у которых есть доступ к аккаунту
и откройте доступ ненадежным приложениям.

Функция send_ifttt_notification()
отправляет POST-запрос в IFTTT, активируя апплет:
def send_ifttt_notification():
# ссылка на апплет IFTTT
link = 'https://maker.ifttt.com/trigger/НАЗВАНИЕ_ПРИЛОЖЕНИЯ/with/key/КЛЮЧ'
# отправляем post-запрос в IFTTT, чтобы сработал апплет
requests.post(link)
print('Уведомление отправлено в приложение IFTTT.')
Пины нужно объявлять один раз, поэтому напишем отдельную функцию setup_GPIO()
и вызовем ее в начале работы отдельно один раз:
def setup_GPIO():
# отключим уведомления об ошибках
GPIO.setwarnings(False)
# используем нумерацию выводов BCM
GPIO.setmode(GPIO.BCM)
# пин Trig
TRIGGER = 19
# пин Echo
ECHO = 26
# установим режим работы пина TRIGGER на Выход
GPIO.setup(TRIGGER, GPIO.OUT)
# установим режим работы пина ECHO на Вход со стягивающим резистором
GPIO.setup(ECHO, GPIO.IN, pull_up_down=GPIO.PUD_DOWN)
return TRIGGER, ECHO
Здесь:
TRIGGER
иECHO
подключены к пинамGPIO 19
и26
соответственно.GPIO.setup(TRIGGER, GPIO.OUT)
– пинTRIGGER
установлен на выходной сигнал.GPIO.setup(ECHO, GPIO.IN, pull_up_down=GPIO.PUD_DOWN)
– пинECHO
установлен на входной сигнал со стягивающим резисторомGPIO.PUD_DOWN
, который устанавливает на пине изначальное значениеLOW
. Без этой опции на пине из-за помех может появиться логическая единица и мы получим ложное срабатывание и первый циклwhile
в функцииultrasonic_detection()
не сработает.
Функция pause()
добавляет паузу после объявления пинов. Без паузы датчик работает некорректно.
def ultrasonic_detection(TRIGGER, ECHO):
# подадим импульс, т . е. установим состояние пина на HIGH
GPIO.output(TRIGGER, GPIO.HIGH)
# длительность импульса 0.00001 сек
time.sleep(0.00001)
# установим состояние пина TRIGGER на LOW
GPIO.output(TRIGGER, GPIO.LOW)
# считываем состояние пина ECHO
# пока ничего не происходит, фиксируем текущее время start
while GPIO.input(ECHO) == 0:
start = time.time()
# если обнаружено движение, зафиксируем время end
while GPIO.input(ECHO) == 1:
end = time.time()
Здесь:
GPIO.output(TRIGGER, GPIO.HIGH)
– чтобы запустить датчик в работу, подаем на пинTrigger
импульс длительностью 10 микросекунд (time.sleep(0.00001)
)while GPIO.input(ECHO) == 0
– пока отраженного сигнала нет, присваиваем переменнойstart
текущее время.while GPIO.input(ECHO) == 1
– при получении отраженного сигнала, фиксируем времяend
.
# рассчитаем длительность сигнала
signal_duration = end - start
# рассчитаем расстояние до объекта
distance = round(signal_duration * 17150, 2)
distance
– длительность сигнала, округленная до второго значения после запятой.
# если объект обнаружен на расстоянии от 3 до 15 см
if 3 < distance < 15:
print("Замечено движение на расстоянии", distance, "см. от датчика.")
# отправим уведомление в приложение IFTTT
send_ifttt_notification()
# отправим снимки на почту
send_email(sender_email='gmail', sender_email_password='gmail_password',
recipient_email='email', number_of_shots=3)
Если препятствие обнаружено на расстоянии 3-15 см, то в приложение IFTTT отправляется уведомление, а на почту – снимки.
def main():
create_shots_folder()
TRIGGER, ECHO = setup_GPIO()
pause(10)
while True:
try:
ultrasonic_detection(TRIGGER, ECHO)
except KeyboardInterrupt:
GPIO.cleanup()
if __name__ == "__main__":
main()
Здесь:
except KeyboardInterrupt: GPIO.cleanup()
– возвращает пины в начальное состояние при выходе из программы черезCTRL + C
.
При обнаружение движения скрипт будет выводить следующее:

У меня ничего не работает
На СтакОверфлоу у многих возникает проблема с тем, что второй цикл while GPIO.input(ECHO) == 1:
не срабатывает, то есть сигнал ECHO
всегда равен 0
. Возможно, резисторы не касаются дорожек макетной платы. Установите ножки строго вертикально, чтобы они не изгибались и попадали на дорожку.

Если и это не помогло, то запустите скрипт и завершите работу, нажав Ctrl + C
, чтобы сработало исключение KeyboardInterrupt: GPIO.cleanup()
и пины вернулись к исходным значениям.
Если температура окружающей среды изменилась, то подкорректируйте скорость звука в среде.
Со звукопоглощающими материалами датчик HC-SR04 работать не будет.
GitHub
Код лежит в репозитории ultrasonic-rpi-alarm.
В этой статье мы:
- научились программировать Raspberry Pi 3/4;
- работать с пинами GPIO;
- управлять камерой Raspberry Pi Camera и датчиком расстояния HC-SR04;
- отправлять почту с вложениями;
- создавать апплеты IFTTT.
Материалы по теме
- Что должен знать начинающий IoT-разработчик в 2021 году?
- 25 ресурсов для изучения IoT-разработки в 2021 году: онлайн-университеты, каналы, блоги и подкасты
- 37 лучших каналов YouTube про робототехнику: от новичка до профессионала
- Планирование маршрута роботом при помощи RRT
- Робот в лабиринте: обрабатываем в Python очереди с приоритетом
Комментарии