Освой Arduino играючи
/* Моя кошка замечательно разбирается в программировании. Стоит мне объяснить проблему ей - и все становится ясно. */
John Robbins, Debugging Applications, Microsoft Press, 2000
Есть несколько способов детектирования движения: инфракрасные датчики, системы компьютерного зрения, лазерные детекторы, тепловизионные датчики.
Инфракрасные датчики позволяют обнаруживать движение людей в контролируемой зоне, так как тело человека излучает тепло. Датчик движения работает на основе пироэлектрического эффекта (PIR, passive infrared motion sensor). Пироэлектрические датчики просты, недороги и неприхотливы в установке и обслуживании.
Пироэлектрики — это диэлектрики, которые создают электрическое поле при изменении их температуры. На основе пироэлектриков делают датчики измерения температуры, например, LHI778 или IRA-E700. Каждый такой датчик содержит два чувствительных элемента, подключённых с противоположной полярностью.
Сам пироэлектрический датчик как радиодеталь используется в популярном датчике движения HC-SR501, который реализован как готовый модуль с обвязкой. Сверху пироэлектрик окружён полусферой, разбитой на несколько сегментов. Каждый сегмент этой сферы представляет собой линзу, которая фокусирует тепловое излучение на разные участки ПИР-датчика. Часто в качестве линзы используют линзу Френеля.
Внешний вид датчика HC-SR501.
Принцип работы датчик движения следующий. Предположим, что датчик установлен в пустой комнате. Каждый чувствительный элемент получает постоянную дозу излучения, а значит и напряжение на них имеет постоянное значение (левый рисунок).
Как только в комнату заходит человек, он попадает сначала в зону обзора первого элемента, что приводит к появлению положительного электрического импульса на нем (центральный рисунок).
Человек движется, и его тепловое излучение через линзы попадает уже на второй PIR-элемент, который генерирует отрицательный импульс. Электронная схема датчика движения регистрирует эти разнонаправленные импульсы и делает выводы о том, что в поле зрения датчика попал человек. На выходе датчика генерируется положительный импульс (правый рисунок).
Обращайте внимание на распиновку. Данные идут по среднему проводу, а по краям питание и земля.
У датчика имеется два переменных резистора в виде регулировочных винтов (оранжевые) и перемычка для настройки режима. Один из потенциометров регулирует чувствительность прибора. Чем она больше, тем дальше «видит» датчик. Также чувствительность влияет на размер детектируемого объекта. К примеру, можно исключить из срабатывания кота.
Второй потенциометр регулирует время срабатывания. Если датчик обнаружил движение, он генерирует на выходе положительный импульс.
Режим работы модуля задаётся перемычкой (джампером). Есть два режима — режим H и режим L:
Режим H — в этом режиме при срабатывании датчика несколько раз подряд на его выходе (на OUT) остаётся высокий логический уровень (на рисунке выше). В положении H датчик начинает отсчёт времени каждый раз после обнаружения движения. Другими словами, любое шевеление человека вызовет обнуление таймера отсчёта Т. По-умолчанию, перемычка находится в состоянии H.
Режим L — в этом режиме на выходе при каждом срабатывании датчика появляется отдельный импульс. Допустим, мы хотим управлять светом в ванной комнате. Зайдя в комнату, человек вызовет срабатывание датчика, и свет включится ровно на время, заданное резистором времени. По окончании периода, сигнал на выходе вернётся в исходное состояние, и датчик будет дать следующего срабатывания.
HC-SR501 | Arduino
------------------
GND | GND
VCC | 5V
OUT | 7
Для ESP32 используйте 3.3В и подходящий вывод, например, 22.
Скетч.
int ledPin = 13; // инициализируем пин для светодиода
int inputPin = 7; // инициализируем пин для получения сигнала от пироэлектрического датчика движения
int pirState = LOW; // начинаем работу программы, предполагая, что движения нет
int val = 0; // переменная для чтения состояния пина
void setup() {
pinMode(ledPin, OUTPUT); // объявляем светодиод в качестве OUTPUT
pinMode(inputPin, INPUT); // объявляем датчик в качестве INPUT
Serial.begin(9600);
}
void loop() {
val = digitalRead(inputPin); // считываем значение с датчика
if (val == HIGH) { // проверяем, соответствует ли считанное значение HIGH
digitalWrite(ledPin, HIGH); // включаем светодиод
if (pirState == LOW) {
// мы только что включили
Serial.println("Motion detected!");
// мы выводим на серийный монитор изменение, а не состояние
pirState = HIGH;
}
} else {
digitalWrite(ledPin, LOW); // выключаем светодиод
if (pirState == HIGH) {
// мы только что его выключили
Serial.println("Motion ended!");
// мы выводим на серийный монитор изменение, а не состояние
pirState = LOW;
}
}
}
При обнаружения движения должен загораться светодиод. Если движения нет, то светодиод гаснет.
Датчик мне показался достаточно капризным и требующим определённого терпения для точной настройки.
Подробный обзор датчика на видео