В этом уроке мы научимся управлять лампами по хлопкам. Разумеется что вместо ламп можно подключать различные устройства, например, охлаждающие вентиляторы, вытяжки в помещениях, автоматические двери, различные бытовые приборы и т.д. Количество подключаемых устройств и количество хлопков для управления ими можно менять в скетче. Устройства работающие от сети 220 В переменного тока подключаются через Trema твердотельные реле с описанием работы которых можно ознакомиться на странице Wiki - Trema твердотельное реле.
Нам понадобится:
- Arduino Uno х 1шт.
- Trema датчик звука х 1шт.
- Trema твердотельное реле х 3шт.
- Trema Shield x 1шт.
- 3 лампы, 4 клеммника с нажимным рычагом (WAGO) и сетевые провода.
Схема подключения:
Trema датчик звука подключается к любому аналоговому входу Arduino (в уроке используется вывод A0). Лампы подключаются к сети 220 В через Trema твердотельные реле, а они к любым выводам Arduino (в уроке используются выводы 3,6 и 9).
Код программы:
const uint8_t pinSensor = A0; // Номер вывода к которому подключён датчик звука (можно изменить на любой другой аналоговый вывод). const uint16_t varVolume = 400; // Минимальный уровень громкости (значение от 0 до 1023). Чем ниже значение, тем чувствительнее устройство. const uint16_t varDuration = 2000; // Время которое отводится на хлопки (в миллисекундах), за это время Вы должны успеть совершить максимальное количество хлопков. const uint8_t pinLamp[3] = {9,6,3}; // Номера выводов к которым подключены лампы (первая лампа подключена к 9 выводу, вторая к 6 и третья к 3). Можно указывать любые выводы. const uint8_t varLamp[3] = {2,3,4}; // Количество хлопков для реакции ламп (первая лампа реагирует на 2 хлопка, вторая на 3 и третья на 4). Можно указывать любое количество хлопков. bool flgLamp[3] = {0,0,0}; // Флаги состояния ламп (1-вкл / 0-выкл). Установленные в данной строке значения применяются к лампам при старте. uint8_t varSum; // Переменная для подсчёта количества хлопков за время varDuration. uint32_t varTimeOut; // Переменная для хранения времени завершения сессии хлопков. // void setup(){ // for(uint8_t i=0; i<sizeof(pinLamp); i++){ // Проходим по всем выводам к которым подключены лампы ... pinMode (pinLamp[i], OUTPUT); // Конфигурируем вывод очередной лампы как выход (OUTPUT). digitalWrite (pinLamp[i], flgLamp[i]); // Устанавливаем на этом выводе состояние лампы flgLamp. } } // // void loop(){ // // Если зафиксирован хлопок: // if(analogRead(pinSensor)>varVolume){ // Если зафиксирован уровень звука выше значения varVolume, то ... // Считаем количество хлопков за время varDuration: // varSum = 0; // Сбрасываем счетчик количества хлопков. varTimeOut = millis() + varDuration; // Определяем время завершения текущей сессии хлопков (текущее время + varDuration). while(varTimeOut > millis()){ // Уходим в цикл пока не наступит время завершения текущей сессии хлопков ... if(analogRead(pinSensor) > varVolume){ // Если зафиксирован уровень звука выше значения varVolume, то ... while(analogRead(pinSensor) > varVolume){delay(50);} // Уходим в цикл ожидания завершения текущего хлопка. Задержка delay(50) подавляет дребезг начала хлопка. varSum++; delay(50); // Учитываем этот хлопок увеличивая значение varSum. Задержка delay(50) подавляет дребезг окончания хлопка. } } // // Время varDuration вышло, количество хлопков подсчитано и хранится в varSum, выполняем действия: for(uint8_t i=0; i<sizeof(varLamp); i++){ // Проходим по всем лампам ... if(varSum == varLamp[i]){ // Если количество хлопков varSum совпало со значением varLamp одной из ламп, то ... flgLamp[i] =! flgLamp[i]; // Меняем состояние флага flgLamp для этой лампы. digitalWrite(pinLamp[i],flgLamp[i]); // Устанавливаем логический уровень на выводе pinLamp в соответствии со значением флага flgLamp. } } } // // В этом месте можно написать свой код ... // Этот который будет выполняться в то время, пока не фиксируются хлопки. }
Алгоритм работы:
Как только устройство зафиксирует первый громкий звук (хлопок), оно начинает подсчёт этого и всех последующих хлопков в течении времени указанном в константе «varDuration» (время указывается в миллисекундах). По истечении этого времени устройство сверит подчитанное количество хлопков со значениями массива «varLamp» и если будет обнаружено совпадение, то состояние (логический уровень на выводе) лампы будет изменён.
До кода «Setup» определяются переменные и константы, изменяя их значения Вы можете настроить скетч под свои устройства. Назначение переменных и констант указано в комментариях. Отдельно можно сказать про подключение более (или менее) 3 ламп:
Предположим, Вы решили подключить еще одну лампу к 12 выводу Arduino, она должна реагировать на 5 хлопков и должна быть включена при старте, тогда массивы «pinLamp», «varLamp» и «flgLamp» должны быть определены следующим образом:
const uint8_t pinLamp[4] = {9,6,3,12}; // Добавлен вывод № 12 к которому подключена четвёртая лампа const uint8_t varLamp[4] = {2,3,4,5}; // Добавлено количество хлопков = 5, на которое будет реагировать четвёртая лампа bool flgLamp[4] = {0,0,0,1}; // Добавлен флаг состояния четвёрной лампы, указывающий что лампа будет включена при старте
В коде «Setup» прописан цикл «for» от 0 до количества используемых выводов ламп. В теле цикла выводы ламп конфигурируются как выходы и на них устанавливается начальный логический уровень из массива «flgLamp».
В коде «loop» программа выполняется только если уровень сигнала на входе «pinSensor» больше чем значение константы «varVolume». Если это так, то сбрасывается значение счётчика «varSum» и определяется время «varTimeOut» до которого требуется считать хлопки.
Хлопки подсчитываются в теле первого цикла «while» пока значение функции «millis» не станет больше чем значение переменной «varTimeOut». После выхода из цикла «while», количество подсчитанных хлопков, хранимое в переменной «varSum», сравнивается в цикле «for» со значением каждого элемента массива «varLamp». При обнаружении совпадений меняется состояние флага в массиве «flgLamp» и логический уровень на выводе «pinLamp».
Обсуждение