Сигнализация на моём шкафу с инструментом начиналась честно: дверь открылась — светодиод заморгал. Моргал он ровно до того вечера, когда я вышел в коридор: огонёк читается на два метра, а уведомление нужно через дверь и через стену. Звук читается ушами из любой точки квартиры, поэтому финальная версия зазвучала: мало света на фоторезисторе — значит дверь открыли и лампу изнутри загасили — зуммер воет сиреной, пока не нажмёшь кнопку подтверждения. Собирается это на трёх деталях, которые уже стоят на вашей макетке: зуммер на D8, фоторезистор на A1 и кнопка на D2.
По пути разберём три приёма, из которых состоит любая звуковая сигнализация, от гаражной до охранной: порог с двумя границами вместо одной (иначе трещотка), сирену с нарастанием частоты от 400 до 1200 Гц и дежурный бип 100 мс каждые 2 секунды без единого delay. Фоторезистор с делителем и analogRead разобраны в уроке про ночной светильник, а у кодового замка из урока про клавиатуру 4x4 тревога была только на светодиодах — сюда она добавляет голос.
Порог с гистерезисом: две границы вместо одной
Соблазн — одна граница: меньше 250 — тревога, больше — норма. Я так и сделал в первой версии и получил трещотку: показания analogRead дрожат на 10-20 единиц даже на неподвижном фоторезисторе — свет от лампы мерцает, рука отбрасывает тень, соседний прибор щёлкает реле. Значение 249 — тревога, 252 — норма, 247 — снова тревога: режим дёргается чаще, чем зуммер успевает пикать, и в журнале вместо истории событий каша из переключений.
Лечение — две границы с зазором, приём, который в электронике зовут гистерезисом: тревога включается ниже 250, а снимается только выше 350. Между границами лежит мёртвая зона в сто единиц, где режим не меняется ни при каком дрожании: чтобы выйти из тревоги, свет обязан вернуться по-настоящему, а не дёрнуться на пару делений. Зазор подбирается под задачу: для света в шкафу хватает сотни, для температуры берут меньше, для уличного датчика с сырой погодой — больше.
Пороги удобно проверять вольтами: шаг analogRead — около 4,9 мВ (5 В на 1024 деления), мои 250 единиц — это 1,2 вольта на ножке A1, а зазор гистерезиса в сотню единиц — полвольта. И помните, что вся шкала живёт от питания платы: USB-порт даёт 4,8-5,1 В в зависимости от компьютера, и показания ползут пропорционально. Порог, подобранный от адаптера на 5,0 В, съест процентов три от USB — ещё один довод за широкую мёртвую зону вместо точной границы.
const int BUZZER = 8; void setup() { pinMode(BUZZER, OUTPUT); Serial.begin(9600); Serial.println("Sirena: 400 -> 1200 Hz");} void loop() { for (int f = 400; f <= 1200; f = f + 20) { tone(BUZZER, f, 8); // шаг тона на 8 мс delay(8); } noTone(BUZZER); delay(300);}Сирена — лестница из сорока одного шага: for проходит частоты от 400 до 1200 с шагом 20 Гц, на каждой tone(BUZZER, f, 8) держит тон восемь миллисекунд, и весь подъём занимает около 330 мс. Низкие 400 Гц звучат глухо, верхние 1200 — звонко, и ухо читает нарастание как знакомый вой из фильмов. Пауза 300 мс после подъёма даёт вое дыхание: без неё сирена превращается в ровный треск одинаковой высоты.
У версии с for есть предел, о который я упёрся на собственной сигнализации: пока крутится цикл, скетч мёртв. 330 мс подъёма плюс пауза — и так по кругу; кнопка подтверждения опрашивается реже, чем раз в полсекунды, и нажатие в 100-150 мс проскакивает между опросами, попадая в лучшем случае через раз. Для сирены-украшения это терпимо, для сигнализации с кнопкой нет: подтверждение обязано срабатывать с первого касания.
Характер войны правится двумя числами: шагом частоты и паузой на шаге. Крупный шаг 100 Гц по 6 мс — резкий улюлюкающий вой, мелкий 20 Гц по 20 мс — медленное рычание с подъёмом почти в секунду. Я начинал с классики 20 Гц и 8 мс, а для ночного коридора потом растянул подъём — резкий вой среди ночи пугает не только воров.
Три режима и ни одного delay
Рабочая сигнализация живёт автоматом из трёх режимов, как светофор из урока про конечный автомат. Режим 0 — дежурка: раз в две секунды бип на 1500 Гц длиной 100 мс, слышно, что плата жива и смотрит. Режим 1 — тревога: частота шагает по пиле от 400 до 1200 силами millis(), по 40 Гц каждые 40 мс, полный подъём за 800 мс, и никакого блокирующего for. Режим 2 — подтверждено: кнопка на D2 по фронту глушит зуммер и держит тишину, пока свет не вернётся выше границы отпускания.
На дежурном бипе задержусь с числами: 100 мс из 2000 — это пять процентов времени, 72 минуты писка за сутки. Для шкафа в коридоре нормально, для спальни нет: интервал правится одной константой, и мой ход — поднимать его до 10-15 секунд, как только сигнализация переезжает в жилую комнату. Кнопка опрашивается каждый проход loop() по фронту HIGH-LOW, как учил урок про дребезг, а millis-гейты бипа и шагов сирены — тот же приём, что в парктронике; принцип «loop() без длинных пауз» расписан в уроке про millis() вместо delay.
Отдельно про потолок сирены. Резонанс корпуса в 2-4 кГц громче, но ровный тон на этой высоте — писк парковочного радара, который через минуту перестаёшь замечать: ухо привыкает к постоянной частоте. Пила с подъёмом держит внимание именно изменением: каждая ступень — новое событие для слуха. Поэтому тревожные сирены везде ползают по частоте вверх-вниз, а не висят на одной ноте; и 1200 Гц в моём потолке — не предел громкости, а граница, за которой писк превращается в занозу в ухе.
| Режим | Звук | Выход из режима |
|---|---|---|
| 0 — дежурка | бип 1500 Гц, 100 мс каждые 2000 мс | свет упал ниже 250 — переход в тревогу |
| 1 — тревога | пила 400-1200 Гц, подъём 800 мс, по кругу | кнопка D2 — подтверждено; свет выше 350 — дежурка |
| 2 — подтверждено | тишина: тревога заглушена кнопкой | свет вернулся выше 350 — дежурка |
Пороги 250 и 350 — не магия, а мои числа после калибровки: включите печать ldr= из скетча и запишите показания в темноте шкафа и под лампой. У моего набора было 120 в темноте и 600 под лампой; пороги ставятся посередине с зазором в сотню единиц. На чужом фоторезисторе с другим делителем цифры будут другими — пересчитывайте по своим показаниям, а не копируйте мои: один вечер с журналом экономит неделю с угадыванием.
Задача на вырост: добавить вторую ветку тревоги — слишком яркий свет тоже повод пискнуть. Логика зеркальная: если analogRead выше 900 дольше пары секунд — кто-то светит в датчик фонариком, и это тоже вход в режим 1. Автомат при этом не меняется: у него просто возникает второй вход в тревогу. Дальше по этой схеме ставятся любые датчики — геркон на дверь, газовый MQ-2, датчик наклона: меняется условие входа, машина состояний остаётся.
В симуляторе собрана полная версия: тяните слайдер фоторезистора вниз — ниже 250 стартует тревога, и частота поползёт по пиле от 400 до 1200. Кнопка D2 глушит вой одним нажатием, и в мониторе видно смену режима в парах ldr=409 rezim=1, ldr=409 rezim=2. Верните свет выше 350 — сигнализация вернётся в дежурку и продолжит бипать раз в две секунды. Если тревога не стартует — первым делом смотрите ldr=: возможно, показание ещё в мёртвой зоне между границами, и это нормальное поведение, а не поломка.
- Порог с гистерезисом — две границы: тревога ниже 250, отбой выше 350; мёртвая зона гасит дребезг показаний в 10-20 единиц
- Классическая сирена — for от 400 до 1200 Гц шагом 20 с tone(..., 8) на каждый шаг: подъём 330 мс, но цикл блокирует скетч
- Millis-версия сирены — пила по 40 Гц каждые 40 мс, подъём 800 мс, кнопка опрашивается каждый проход loop()
- Дежурный бип 100 мс каждые 2000 мс — пять процентов времени; в жилой комнате интервал поднимают до 10-15 секунд
- Кнопка D2 по фронту глушит тревогу в режим подтверждённого — тишина держится, пока свет не вернётся выше границы отпускания
- 1. Почему у порога тревоги делают две границы, а не одну?
- 2. Тревога включилась: света мало. Что снимет её без кнопки?
- 3. Сколько длится один подъём классической сирены из for-цикла: 400-1200 Гц шагом 20, tone(..., 8) на каждый шаг?
- 4. Какую долю времени кричит дежурный бип 100 мс каждые 2000 мс?
- 5. Кнопка подтверждения тревоги срабатывает через раз. Классическая причина?
Частые вопросы по теме урока
- Почему у порога тревоги делают две границы, а не одну?
- Показания analogRead дрожат на 10-20 единиц даже на неподвижном датчике. Гистерезис — зазор между границами включения и отпускания — гасит трещотку. у аналоговых показаний есть дрожь в 10-20 единиц: у одной границы режим дёргается туда-сюда
- Тревога включилась: света мало. Что снимет её без кнопки?
- Автоматический выход из тревоги — только возврат света выше 350. Между 250 и 350 мёртвая зона: там режим не меняется ни при каком дрожании. свет должен подняться выше границы отпускания, которая выше порога включения
- Сколько длится один подъём классической сирены из for-цикла: 400-1200 Гц шагом 20, tone(..., 8) на каждый шаг?
- От 400 до 1200 с шагом 20 — 41 шаг по 8 мс, около 330 мс. Заодно цикл блокирует loop() на всё это время — потому в сигнализации с кнопкой нужна millis-версия. около 330 мс — 41 шаг по 8 мс
- Какую долю времени кричит дежурный бип 100 мс каждые 2000 мс?
- 100 из 2000 — пять процентов, или 72 минуты писка за сутки. Для шкафа терпимо, для спальни интервал поднимают до 10-15 секунд. около пяти процентов — 100 мс из 2000
- Кнопка подтверждения тревоги срабатывает через раз. Классическая причина?
- Блокирующий for-цикл сирены держит loop() полсекунды, и digitalRead редко попадает в короткое нажатие. Лечение — шаги по millis() без длинных пауз. в режиме тревоги крутится блокирующий цикл: опрос раз в полсекунды, нажатие в 100-150 мс теряется