Будет достаточно проще пользоваться устройством, если мы реализуем звуковое сопровождение, подключим зуммер к нашей плате. У нас немного поменялось расположение элементов, поэтому обновим несколько директив #define, а конкретно зуммер подключим к ШИМ выходу arduino. (Полный код, как обычно будет в конце статьи)
#define buzzer 11 // Контакт динамика
В результате, схема подключения зуммера будет выглядеть так
Почему мы выбрали ШИМ выход? Если на динамик подать 5в, он один раз пикнет и всё, вернее это даже слышно не будет практически. Звук – это аналоговый сигнал, а ШИМ выход без лишней головной боли, сможет имитировать поток импульсов
Для активации ШИМ сигнала, мы можем использовать команду analogWrite( выход , значение); , где всего два аргумента – первый это номер выхода, а второй значение от 0 до 255, которое влияет на степень скважности в ШИМ – сигнале. Я поэкспериментировал, и нашёл оптимальное значение скважности 20, для нормального тона динамика. Соответственно, скважность 0 – полностью выключить звук.
analogWrite(buzzer, 20); // Включаем звук на ШИМ выходе
analogWrite(buzzer, 0); // Выключаем звук на ШИМ выходе
Нужно помнить, что мы не должны использовать delay, в момент создания звуковых эффектов, значит опять будем привязываться к переменной времени контроллера millis().
Попробуем изобразить код на диаграмме. По нажатию кнопки, будем активировать динамик – а потом, при некоторых условиях отключать его, или делать циклы.
Введём флаг ошибки, который будем применять, при нажатии кнопки сброса, неправильном вводе пароля и простое 3 секунды, когда пользователь вдруг перестал вводить пароль
bool keyError; // Флаг ошибки пароля
Также введём переменную, которую будем сравнивать с временем контроллера millis().
uint32_t beep; // Переменная времени задержки зуммера после нажатия кнопки или действия
В цикле loop() у нас будут постоянно проверяться все наши функции.
key_beep_off(); // Выключение звука зуммера
key_beep_ok(); // Звук зуммера при отрытии замка
key_beep_error(); // Звук ошибки зуммера
В цикле обработки клавиши key_scan (), если было зафиксировано нажатие, то запустим звуковой сигнал, и сбросим переменную времени.
beep = millis(); // Приравниваем переменную времени зуммера к времени контроллера
analogWrite(buzzer, 20);
Если это просто нажатая клавиша, без действия, то нам нужен очень кратковременный звук. Как нам узнать, что нажатие не привело к действию? Мы проверим статус закрытого замка, и переменную времени в течении 150мс. Если статус замка закрыт, то через 150мс, звук отключаем. Так мы получим непродолжительный звук, при нажатии любой кнопки.
void key_beep_off() // Выключаем пищалку, если замок остался закрытым, через 150мс
{
if (millis() - beep > 150 && lockType == 1 && digitalRead(lock) == LOW || millis() - beep > 200 && lockType == 0 && digitalRead(lock) == HIGH)
{
analogWrite(buzzer, 0); // Выключаем звук на ШИМ выходе
}
}
Теперь звук ошибки. Предлагаю для понимания сделать два коротких сигнала, обычно этот звук понятен пользователю. Здесь всё очень просто. Нам нужно использовать флаг ошибки keyError. Пока его значение равно 1, мы будем выполнять условия с временным промежутком в 150мс, а в конце просто сбросим его. Просто делаем 3 if, в каждом из котором делаем привязку ко времени. 1)Включаем динамик – > 2) отключаем – > 3) включаем. Потом снимаем флаг keyError == 0.
void key_beep_error() // Функция ошибки клавиатуры - двойной писк
{
if (keyError == 1)
{
if (millis() - beep > 0 && millis() - beep < 150) // Интервал времени от 0 до 150мс - звук есть
{
analogWrite(buzzer, 20); // Включаем звук на ШИМ выходе
}
if (millis() - beep > 150 && millis() - beep < 300) // Интервал времени от 150 до 3000мс - звука нет
{
analogWrite(buzzer, 0); // Выключаем звук на ШИМ выходе
}
if (millis() - beep > 300 && millis() - beep < 450) // Интервал времени от 300 до 450мс - звук есть
{
analogWrite(buzzer, 20); // Включаем звук на ШИМ выходе
}
if (millis() - beep > 450) // По прошествии 450мс
{
analogWrite(buzzer, 0); // Выключаем звук на ШИМ выходе
keyError = 0; // Сбрасываем флаг ошибки открытия
}
}
}
Затем нам нужно в некоторых участках кода, поднимать флаг keyError == 1 и сбрасывать переменную beep. Этот код нам нужно вставить в обработку клавиши # , также он должен исполняться при неправильном вводе пароля, и сбросе его, при простое 3 секунды.
beep = millis(); // Приравниваем переменную времени зуммера к времени контроллера
keyError = 1; // Активируем флаг ошибки зуммера
Теперь разберём звук динамика в момент открытия замка. Чтобы пользователь понимал, что замок ещё открыт (это особенно актуально в случае применения магнитного замка) будем воспроизводить кратковременные бипы. Цикл бипов должен продолжаться, пока открыт замок, для этого у нас была переменная openTime. Т.е. мы можем считывать состояние замка, и бипать, пока beep < openTime. Далее мы организуем цикл включения и выключения динамика, по схожему принципу, как в коде ошибки, но он у нас будет повторять, пока открыт замок. Чтобы цикл повторно запустился, в конце нам нужно обновить переменную beep.
void key_beep_ok()
{
if (millis() - beep < openTime && lockType == 1 && digitalRead(lock) == HIGH || millis() - beep < openTime && lockType == 0 && digitalRead(lock) == LOW)
{
if (millis() - beep > 0 && millis() - beep < 120) // Задаём время от 0 до 120мс - зуммер активен
{
analogWrite(buzzer, 30); // Включаем звук на ШИМ выходе
}
if (millis() - beep > 120 && millis() - beep < 300) // Задаём время от 120 до 300 мс - зуммер не активен
{
analogWrite(buzzer, 0); // Выключаем звук на ШИМ выходе
}
if (millis() - beep > 300) // Свыше 300мс обнуляем переменную времени зуммера, чтобы цикл запустился снова, пока действует время открытия замка
{
beep = millis(); // Приравниваем переменную времени зуммера к времени контроллера
}
}
}
У нас уже прошло достаточно циклов статей по построению нашей системы доступа, поэтому соберём всё в железе, и протестируем, как работает наш код
Записал небольшое видео, где проверим основные функции нашего устройства.
Код этой статьи на github.
Добавить комментарий
Для отправки комментария вам необходимо авторизоваться.