Arduino и HC-SR501 (датчик движения)

Содержание

Сегодня мы будем знакомиться с модулем, позволяющим отслеживать движение – пироэлектрическим инфракрасным (PIR) датчиком движения. Для примера будем использовать модуль HC-SR501, как один из самых популярных и совместимых с Arduino. Чаще всего он используется в устройствах, предназначенных для управления освещением, и для этого может использоваться вкупе с датчиком освещённости.

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

Характеристики датчика по даташиту:

  1. Широкий диапазон рабочего напряжения: 4,5 – 20 В постоянного тока;
  2. Потребляемый ток покоя: ≈50 мкА;
  3. Напряжение на выходе: 3.3 В;
  4. Рабочая температура: от -15° C до 70° C;
  5. Размеры: 32*24 мм;
  6. Два режима работы;
  7. Максимальный угол обнаружения 110°;
  8. Максимальная дистанция срабатывания – от 3 до 7 м (регулируется); При температуре более 30° C это расстояние может уменьшаться.

На модуль установлена линза Френеля, которая фокусирует инфракрасные сигналы на пироэлектрический датчик под названием 500BP. Датчик называется PIR (Passive Infra-Red). Пассивный он потому, что для обнаружения движения не используется какая-либо дополнительная энергия, кроме той, что испускается самими объектами.

500BP состоит из двух чувствительных элементов. Управляющая микросхема модуля регистрирует изменения сигналов от обоих элементов и по характеру их изменения обнаруживает движение объектов, испускающих инфракрасные сигналы (живых организмов).

Arduino и датчик движения HC-SR501

Характеристики HC-SR501

Модуль HC-SR501 имеет 3 вывода:

  • Питание (VCC);
  • Земля (GND);
  • Выход 3v3 (OUT).

Сразу после подачи питания несколько секунд модуль будет калиброваться, в это время возможны ложные срабатывания. Примерно через минуту он перейдёт в режим ожидания. При срабатывании датчика на выходе появляется логическая единица, напряжение 3.3 вольта.

Изменения этого сигнала зависят от выбранного режима работы. Он меняется перемычкой (отмечена на фото с подписями какой режим будет выбран). Если выбран H– при нескольких срабатываниях подряд на выходе датчика остаётся высокий уровень, при L– для каждого срабатывания будет подан свой импульс.

Также на самом модуле можно найти два переменных резистора, регулирующих дистанцию обнаружения движения (Distance Adjust) и время, в течение которого на выходе будет логическая единица (Delay Time Adjust). Дистанция регулируется в пределах 3 – 7 метров, задержка от 5 до 300 секунд.

И ещё немного о его особенностях. При работе с датчиком следует избегать источников света и тепла, закрывающих поверхность объектива модуля. Ветер также может создавать помехи. На большем расстоянии датчик более чувствителен.

Для реализации проекта из этой статьи нам потребуются следующие компоненты:

Подключение HC-SR501 к Arduino

Итак, мы прошли теорию, настало время проверить датчик в работе. Первым этапом станет его подключение к Arduino:

  • GND подключаем к одноимённому выводу Arduino;
  • VCC к 5V;
  • OUT подключим к A0.

Подключение выхода модуля к аналоговому пину связано с тем, что цифровые пины Arduino работают с пятивольтовой логикой, а наш модуль рассчитан на 3.3 В. В скетче за логическую единицу мы примем значение более 500 на аналоговом порту. Это будет около 2.44 В и более.

Схема подключения hc-sr501:

Arduino и датчик движения HC-SR501

Подключение в Arduino IDE

Теперь загружаем в Arduino следующий скетч и открываем монитор порта.

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

Теперь расширим функционал устройства, добавив реле и лампу на 220 В.

Реле подключим к 3 цифровому пину Arduino. Питание – 5V.

Общий провод (COM) реле подключаем к фазе 220 В, NO (Normally Open, нормально разомкнутый контакт, пока через реле не потечёт ток, он будет разомкнут) подключаем к лампе, другой контакт лампы – к нолю 220 В.

Arduino и датчик движения HC-SR501

Теперь немного переделаем скетч, убрав отправку данных в последовательный порт и добавив управление реле.

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

При желании датчик можно подключать напрямую к реле без использования микроконтроллера. Однако в варианте с микроконтроллером возможна более гибкая настройка и простое расширение функциональности.

Товары, используемые в материале

Arduino Nano V3.0

Arduino NANO V3 (ATmega 328P / CH340G)

HC-SR501 - Инфракрасный датчик присутствия (PIR Sensor)

HC-SR501 Инфракрасный датчик движения (PIR)

Одноканальное реле для Arduino

KY-019 Одноканальное реле 250В / 10А

Набор проводов «Мама — Мама», шлейф, 30 см

Шлейф проводов «Мама — Мама» (30см, 40шт.)

Самые популярные материалы в блоге

За все время

За сегодня

Собираем самодельный Arduino - Shrimp

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

Добрый день! Собираю себе небольшую охранную систему состоящую из камеры видеонаблюдения, ПИР-Датчика, прожектора подключенного к Ардуино через реле как в вашей схеме. Устанавливать собираюсь под окном, что бы отпугивать всяких моргинальных личностей из полисадника под окном, которые занимаются всяческими хулиганскими и противоправными действиями. Собрал схему, написал код. Код работает, но никак не могу реализовать в нем интервал задержки в 5 секунд (так называемый период охлаждения) необходимый мне для того, что бы система не срабатывала если объект находится в зоне видимости датчика менее 5 секунд. И наоборот активировала систему, если объект находится в зоне видимости более заданного времени. Перепробовал разные варианты, но результат один и тот же, датчик при получении логической единицы, либо сразу активирует систему, либо система работает некорректно, либо по и стечении заданного интервала датчик активирует систему вне зависимости выполено ли условие или нет. Подскажите пожалуйста, как можно реализовать подобный алгоритм?
У меня уже фантазии на исходе. Делал вариант с флажком, как на вашей схеме с счетчика заданием интервала. Система работает корректно только на отключение. Подойдет ли вариант приравнять датчик к кнопке и использовать этот аргумент как смену режима работы датчика?

Здравствуйте! Проверяйте переменную два раза, один по срабатыванию триггера, а второй через 5 секунд. На самом датчике выставите потенциометром минимально короткую задержку. После 5 секунд проверяйте переменную на наличие логической единицы еще раз, а уже после этого щелкайте актуаторами 🙂

Добрый день уважаемый Вольтик,
помогите пожалуйста в моём случае. У меня есть код и все прекрасно работает. Свет для коридора.
Но я хочу добавить ещё 2 датчика движения на пин. 2 и 4. Понимаю что нужно прописывать для каждого пина свой код и на этом всё! Код оигинальный который работает:
#include

#define piro 8
#define mosfet 9
#define foto A0
#define pot A1
#define switch2 7

#define nightVAL 200
#define minPWM 5
#define smooth 7

Bounce debouncer = Bounce();

pinMode (piro, INPUT);
pinMode (mosfet, OUTPUT);
pinMode (switch2, INPUT_PULLUP);

TCCR1A = TCCR1A 0xe0 | 1;
TCCR1B = TCCR1B 0xe0 | 0x09;

pwm = map (analogRead (pot), 0, 1023, 0, 255);

if (digitalRead (switch2) == LOW)
if (debouncer.fell())
<
for (int i1 = 0; i1 = 0; i2)
<
analogWrite (mosfet, i2);
delay (smooth);
>
>
else if (debouncer.read() == HIGH)
<
if ((analogRead (foto) nightVAL) (digitalRead (piro) == HIGH))
<
analogWrite (mosfet, minPWM);
>

else if (digitalRead (piro) == LOW)
<
digitalWrite (mosfet, LOW);
>
>
>

По вашей аналогии добавил пины и переименовал 8, но что то не то?

#define piro_1 8
#define piro_2 2
#define piro_3 4
#define piro1 10
#define mosfet 9
#define foto A0
#define pot A1
#define switch2 7

#define nightVAL 200
#define minPWM 5
#define smooth 7

Bounce debouncer = Bounce();

pinMode (piro_1, INPUT);
pinMode (piro_2, INPUT);
pinMode (piro_3, INPUT);
pinMode (mosfet, OUTPUT);
pinMode (switch2, INPUT_PULLUP);

TCCR1A = TCCR1A 0xe0 | 1;
TCCR1B = TCCR1B 0xe0 | 0x09;

pwm = map (analogRead (pot), 0, 1023, 0, 255);

if (digitalRead (switch2) == LOW)
if (debouncer.fell())
<
for (int i1 = 0; i1 = 0; i2)
<
analogWrite (mosfet, i2);
delay (smooth);
>
>
else if (debouncer.read() == HIGH)
<
if ((analogRead (foto) nightVAL) (digitalRead (piro_1) == HIGH))
if ((analogRead (foto) nightVAL) (digitalRead (piro_2) == HIGH))
if ((analogRead (foto) nightVAL) (digitalRead (piro_3) == HIGH))
<
analogWrite (mosfet, minPWM);
>

else if (digitalRead (piro_1) == LOW)
else if (digitalRead (piro_2) == LOW)
else if (digitalRead (piro_3) == LOW)
<
digitalWrite (mosfet, LOW);
>
>
>

Пишет мне что эти строчки неправильно:
else if (digitalRead (piro_2) == LOW)
else if (digitalRead (piro_3) == LOW)
Я вас прошу помочь в этом вопросе.
Спасибо!

Для подключения датчиков на пины 2 и 4 в код необходимо внести

int piro_etc = 2
int piro_etc2 = 4

pinMode (piro_etc , INPUT);
pinMode (piro_etc2 , INPUT);

Далее вставить переменные piro_etc и piro_etc2 в рамках логики вашей программы

Здравствуйте помогите пожалуйста собираю систему умный дом на базе ардуино нашол саит https://voltiq.ru/arduino-and-sensor-hc-sr501/
где все расписано купил датчики ARDUINO NANO 3.0 ATMEGA 328,ИК (ИНФРАКРАСНЫЙ) ДАТЧИК ДВИЖЕНИЯ HC-SR501 ДЛЯ ARDUINO,МЕХАНИЧЕСКОЕ РЕЛЕ НА 1 КАНАЛ ДЛЯ ARDUINO ВСЕ соединил по схеме с данного саита код вставил тоже с саита в программу ардуино 1.8.2 включил работает лампочка горит постоянно мне надо чтобы провел руку лампа зажглась убрал руку лампа через некоторое время потухла а она горит постоянно что делать? спасибо!
ВОТ КОД:
/*
* PIR Sensor[PIN GND] — Arduino Nano[PIN GND]
* PIR Sensor[PIN 5V] — Arduino Nano[PIN 5V]
* PIR Sensor[PIN OUT] — Arduino Nano[PIN A0]
* Relay Module[PIN IN] — Arduino Nano[PIN 3]
*/
//relout пин модуля реле
const int relout = 3;
//trigger флаг срабатывания датчика движения
boolean trigger = false;

void setup()
<
/*Стандартная процедура инициализации порта на который подключен модуль реле.
ВАЖНО. чтобы модуль реле оставался в первоначально выключенном состоянии,нужно записать в порт входа/выхода значение HIGH, это позволит избежать ложных &#8220;перещелкиваний&#8221;,
и сохранит состояние реле таким, каким оно было до включения всей схемы в работу*/
pinMode(relout, OUTPUT);
digitalWrite(relout, HIGH);

//задержка в минуту для инициализации датчика
delay(60000);
>

void loop()
<
//Считать значение с аналогового порта А0
//Если значение выше 500
if(analogRead(A0) 500)
<
//Установить флаг срабатывания датчика движения
if(!trigger)
<
trigger = true;
>
>
else
<
//Снять флаг срабатывания датчика движения
trigger = false;
//Выключить реле
digitalWrite(relout, HIGH);
>

//Пока флаг срабатывания датчика движения установлен
while(trigger)
<
//Включить реле
digitalWrite(relout, LOW);
if(analogRead(A0) 500)
<
//Установить флаг срабатывания датчика движения
if(!trigger)
<
trigger = true;
>
>
else
<
//Снять флаг срабатывания датчика движения
trigger = false;
//Выключить реле
digitalWrite(relout, HIGH);
>
>
>

Зачем нужен тригер и цикл while, когда достаточно одного условия вначале loop ? и потом, логика неверная, реле замкнуто когда нет движений а когда есть размыкает, там либо менять местами HIGH с LOW, либо проводок в реле перекинуть. Не написано какой режим установлен на датчике H или L.


Источник: voltiq.ru