Активный бузер
Звуковой излучатель со встроенным электронным генератором: чтобы он запищал, достаточно подать на управляющий вывод логическую единицу или ноль — генерировать сигнал самостоятельно не нужно.
🔊 Активный бузер
Активный бузер — это звуковой излучатель со встроенным электронным генератором:
чтобы он запищал, достаточно подать на управляющий вывод логическую единицу или ноль
(в зависимости от схемы) — самому городить переменный сигнал не нужно. Этим он
отличается от пассивного бузера, которому для звука требуется PWM-сигнал (tone());
подробнее — в THEORY.md.
Этот модуль реализует неблокирующие звуковые сигналы (одиночный писк и два готовых паттерна) через машину состояний — программа не “зависает” на время сигнала.
📋 Навигация
| Файл | Что внутри |
|---|---|
| WIRING.md | Схема подключения через транзистор, полярность (Active Low/High) |
| THEORY.md | Физика активного излучателя, сравнение с пассивным, разбор паттернов |
| PREZ.md | Презентация модуля — 5 тезисов для урока |
🛠 Состав компонента
include/ActiveBuzzer.h— интерфейс класса драйвера.src/ActiveBuzzer.cpp— машина состояний неблокирующих сигналов.src/main.cpp— тестовый стенд с управлением по Serial.
🚀 Сборка и прошивка (PlatformIO)
cd Components/ActiveBuzzer
pio run -t upload && pio device monitorПо умолчанию используется GPIO 15 (см. BUZZER_PIN в main.cpp) —
поменяйте на свой пин при необходимости.
Команды тестового стенда
1— короткий писк (100 мс)2— длинный писк (1000 мс)3— паттернAlert(прерывистая тревога)4— паттернConfirm(два коротких писка)0— выключить всё
Связанные материалы
- PassiveBuzzer — тот же разъём, другая физика: генератора внутри нет, частоту задаёт программа.
- Резистор — расчёт токоограничения и мощности для обвязки.
- FoxHunter — зуммер как измерительный прибор: громкость и частота писка кодируют расстояние до цели.
🔊 Теория: активные бузеры
1. Конструкция и принцип работы
Бузер (звуковой излучатель) — это компонент, который превращает электрический сигнал в звук. Внутри активного бузера уже впаяна небольшая генераторная схема, которая сама создаёт колебания мембраны на фиксированной частоте (обычно 2–3 кГц).
Поэтому управление предельно простое: подать на управляющий вывод бузера постоянное
напряжение (логический уровень HIGH или LOW, без переменного сигнала) — и он звучит,
пока напряжение не снимут. Это то, что в коде драйвера делает digitalWrite() —
см. ActiveBuzzer.cpp:11-14, метод setPinState().
2. Активный vs пассивный бузер
| Характеристика | Активный бузер | Пассивный бузер |
|---|---|---|
| Как включается | digitalWrite() — постоянный уровень | tone() — переменный сигнал (PWM) |
| Нагрузка на CPU/таймеры | Не использует | Занимает аппаратный таймер под tone() |
| Какие звуки может издавать | Один фиксированный тон | Любая частота, можно играть мелодии |
| Типичное применение | Простые сигналы: пищит/не пищит | Индикация уровней, мелодии |
Это принципиальное отличие определяет и код: там, где пассивному бузеру нужно было бы
менять частоту tone(), активный бузер лишь включается и выключается в нужные моменты
времени — вся “музыка” сводится к тайминг-паттернам.
3. Как драйвер строит сигналы поверх одного тона
Раз у активного бузера нет регулировки частоты, единственный доступный инструмент —
модулировать время включения/выключения. Драйвер реализует это без delay() —
через машину состояний в update(), которая
вызывается на каждой итерации loop() и сравнивает millis() с моментом последнего
переключения:
- Одиночный писк (
beep(durationMs), ActiveBuzzer.cpp:28-36) — включить и выключиться самостоятельно черезdurationMs. Pattern::Alert(ActiveBuzzer.cpp:60-67) — прерывистая тревога: переключение состояния каждыеkAlertPeriodMs(500 мс, ActiveBuzzer.h:68), пока не вызовутturnOff().Pattern::Confirm(ActiveBuzzer.cpp:69-78) — два коротких писка поkConfirmPulseMs(100 мс, ActiveBuzzer.h:69) и автоматическое выключение.
Тайминги 500 мс и 100 мс — не характеристика бузера из даташита, а методический выбор: такие интервалы хорошо различимы на слух и удобны для демонстрации на уроке.
4. Почему нет isAlive()
В большинстве компонентов этого репозитория драйвер умеет проверять, жив ли обмен
данными с датчиком (isAlive()). У активного бузера обмена данными нет вообще —
только один исходящий сигнал digitalWrite(), без какой-либо обратной связи. Поэтому
программно узнать, оборван ли провод или неисправен ли сам зуммер, невозможно —
это физическое ограничение схемы (см. @note в ActiveBuzzer.h:22-25).
🔌 Схема подключения активного бузера
1. Прямое подключение (для маломощных бузеров)
Если бузер потребляет мало тока (ориентировочно до ~20 мА — это типичный безопасный предел на один вывод GPIO ESP32), его можно подключить напрямую к пину:
| Контакт бузера | ESP32 |
|---|---|
| (+) VCC | 3.3V |
| (-) GND | Управляющий пин (например, GPIO 15) через встроенный digitalWrite() |
2. Подключение через транзистор (рекомендуется)
Активные бузеры часто потребляют больше — ориентировочно 30–50 мА для распространённых малогабаритных модулей (без даташита конкретной модели этой цифре не стоит доверять как точной — уточните по факту используемого бузера). Чтобы не перегружать пин ESP32, управляющий сигнал подают через транзистор, а сам бузер запитывают напрямую от VCC/GND:
+3.3V / +5V
│
[BUZZER]
│
[Collector]
│
[ Пин ]──[Resistor 1k]──[ Base ]
│
[Emitter]
│
GND| Контакт | Куда подключается |
|---|---|
| Бузер (+) | 3.3V / 5V |
| Бузер (-) | Collector транзистора |
| Emitter транзистора | GND |
| Base транзистора | Управляющий пин ESP32 через резистор 1 кОм |
Управляющий пин при этом переключает не сам бузер, а транзистор — ток через GPIO остаётся маленьким (ток базы), а бузер получает питание через коллектор-эмиттер.
3. Полярность включения (Active Low / Active High)
- Active HIGH (по умолчанию): бузер (или база транзистора) получает сигнал при
HIGHна пине. - Active LOW: логика инвертирована — передайте
activeLow = trueвторым параметром конструктора, см.ActiveBuzzer.h:34. Как это учитывается внутри —ActiveBuzzer.cpp:11-14.
Методический план урока: активный бузер и неблокирующие сигналы
Паспорт урока
| Параметр | Значение |
|---|---|
| Место в курсе | Components, после LED_middle — первое исполнительное устройство со звуком |
| Длительность | 45 мин |
| Возраст | 12–16, материал двухуровневый |
| Оборудование | ESP32, активный бузер, транзистор с резистором по WIRING.md, макетка — на пару |
| Предварительные знания | setup/loop, digitalWrite, идея millis() вместо delay() |
| Предмет | Информатика (машина состояний), физика (звук как колебания) |
Образовательные цели
По итогам урока ученик умеет:
| № | Цель | Блум | Миллер | Чем доказывается |
|---|---|---|---|---|
| 2.1 | Отличить активный бузер от пассивного по поведению | понимать | знает как | Определяет тип незнакомого бузера опытом |
| 2.2 | Собрать схему с транзистором и объяснить, зачем он нужен | применять | делает | Рабочая схема, устный ответ |
| 2.3 | Запустить готовые паттерны через Serial-команды | применять | делает | Все четыре команды отработаны |
| 2.4 | Объяснить, почему сигналы сделаны без delay() | понимать | знает как | Ответ через «что ещё делает плата» |
| 2.5 | Придумать свой тайминг-паттерн и реализовать его | создавать | делает | Узнаваемый сигнал собственной конструкции |
Чего на этом уроке делать НЕ надо. Не разбирать устройство машины состояний построчно и не вводить
enum classформально. Ученик должен услышать разницу между блокирующим и неблокирующим кодом, а не прочитать про неё. Разбор реализации — для уровня C и для тех, кто сам спросит.
Что должно быть готово заранее
- Схема собрана и проверена лично — транзистор добавляет точек отказа
- Проверено, что бузер именно активный: подать 3,3 В напрямую — должен пищать сам
- Рядом лежит пассивный бузер для контраста (даже если урок по нему отдельный)
- Serial-монитор настроен на нужную скорость, команды
1–4и0проверены - Продуман предел громкости: 20 пищащих бузеров в кабинете — реальная проблема
Про громкость. Заранее договоритесь о правиле: «пищим по команде, а не когда захотелось». Иначе вторая половина урока пройдёт в шуме. Хороший приём — попросить прикрыть бузер пальцем, когда идёт объяснение.
Сценарий занятия (45 минут)
| Время | Блок | Что делает педагог | Что делают ученики |
|---|---|---|---|
| 0–6 | Завязка | Даёт два бузера, просит завести оба | Пробуют, один не работает |
| 6–12 | Разбор загадки | Ведёт к различию активный/пассивный | Формулируют гипотезу |
| 12–20 | Сборка | Проверяет транзистор и полярность | Собирают по WIRING.md |
| 20–28 | Паттерны | Показывает команды Serial | Пробуют все четыре режима |
| 28–38 | Практика | Раздаёт задания по уровням | Делают свой сигнал |
| 38–45 | Итог и ДЗ | Фиксирует различие и принцип | Записывают в журнал |
Ключевой методический принцип — начать с неработающего. Пассивный бузер, подключённый как активный, молчит. Это загадка, из которой рождается вся теория урока. Если начать с объяснения разницы, загадки не будет, и различие останется словами из таблицы.
Блок 1. Завязка (0–6 мин)
Выдать каждой паре два внешне похожих бузера — активный и пассивный — не говоря, чем они отличаются.
«Оба — звуковые излучатели. Подайте на каждый питание и заставьте пищать.»
Что происходит
Активный пищит сразу. Пассивный молчит или едва щёлкает. Дети решают, что он сломан — это ожидаемая и нужная реакция.
| Реакция | Что делать |
|---|---|
| «Этот бракованный» | «Возьмите другой такой же. Тоже молчит? Странный брак, правда?» |
| Пробуют подать больше напряжения | Остановить: «сожжёшь. Дело не в напряжении» |
| Слышат щелчок при подключении | Ценное наблюдение. «Щёлкнул один раз. Почему не продолжает?» |
Довести до вопроса: почему одному хватает постоянного напряжения, а другому нет?
Блок 2. Разбор загадки (6–12 мин)
2.1. Базовый уровень (12–14 лет)
«Звук — это колебание воздуха. Чтобы мембрана колебалась, её надо дёргать туда-сюда много раз в секунду. Постоянное напряжение дёргает её один раз — отсюда щелчок.»
Ключевой вопрос: «Тогда почему первый пищит?»
Потому что внутри у него собственный генератор — маленькая схема, которая сама дёргает мембрану две-три тысячи раз в секунду. Ему достаточно сказать «работай».
Записать на доске различие:
- Активный — генератор внутри. Команда: включить / выключить. Один тон.
- Пассивный — генератора нет. Нужно подавать колебания самому. Любой тон.
Полная таблица сравнения — в THEORY.md, раздел 2.
2.2. Углублённый уровень (14–16 лет)
Добавить количественную сторону:
«Активный бузер звучит на 2–3 кГц. Это не выбор инженера — это резонансная частота его мембраны, зашитая конструкцией. Поменять её нельзя, можно только включать и выключать.»
Отсюда следует главный вопрос урока:
«Если тон один и менять его нельзя — как из такого бузера получить разные сигналы? Тревога и подтверждение должны звучать по-разному.»
Ответ, к которому нужно прийти: менять не частоту, а время — ритм включений. Это и делает драйвер (см. THEORY.md, раздел 3).
Блок 3. Сборка схемы (12–20 мин)
Схема — в WIRING.md. Ключевой момент — транзистор.
Разговор про транзистор (перед сборкой)
«Светодиод мы вешали прямо на ножку платы. Бузер так подключать нельзя. Почему, как думаете?»
Довести до ответа: бузер потребляет заметно больше тока, чем ножка может отдать. Транзистор здесь — усилитель команды: слабый сигнал с ножки управляет сильным током через бузер.
Аналогия: ножка платы — это выключатель в комнате, а не сама электростанция. Выключатель не пропускает через себя весь ток дома — он управляет реле.
Типичные ошибки сборки
| Симптом | Причина | Как ловить |
|---|---|---|
| Тишина при любой команде | Транзистор развёрнут | Сверить распиновку с WIRING.md |
| Пищит непрерывно, не выключается | Перепутана логика Active Low/High | Проверить, какой уровень включает |
| Пищит слабо и хрипло | Нет резистора в базе | Проверить номинал |
| Плата перезагружается при писке | Просадка питания | Питать бузер отдельно от логики |
Блок 4. Паттерны через Serial (20–28 мин)
Открыть монитор порта, показать команды из README.md:
| Команда | Что звучит | Что демонстрирует |
|---|---|---|
1 | короткий писк 100 мс | одиночное событие |
2 | длинный писк 1000 мс | длительность как смысл |
3 | Alert — прерывистая тревога | бесконечный паттерн |
4 | Confirm — два писка | завершающийся паттерн |
0 | тишина | остановка |
Дать всем попробовать. Затем — главный вопрос урока:
«Пока звучит тревога по команде
3— плата занята или свободна? Проверьте: не останавливая тревогу, отправьте4.»
Дети обнаруживают, что плата отвечает во время звучания. Это и есть смысл неблокирующего кода, и он услышан, а не рассказан.
Для контраста можно показать
beepBlocking()из соседнего компонента PassiveBuzzer: во время такого сигнала плата глуха к командам.
Блок 5. Практика по уровням (28–38 мин)
Уровень A (базовый)
- Изменить длительность короткого писка так, чтобы он стал заметно длиннее.
- Сделать
Confirmиз трёх писков вместо двух. Подсказка: искатьkConfirmPulseMsи счётчик в ActiveBuzzer.cpp. - Замедлить тревогу вдвое. (
kAlertPeriodMs)
Уровень B (средний)
- Придумать свой сигнал «ошибка»: он должен на слух отличаться от
AlertиConfirm. Записать ритм на бумаге до кодирования. - Сделать так, чтобы при старте платы звучал короткий сигнал «готов к работе».
- Ответить письменно: что произойдёт, если вызвать
beep()во времяAlert? Проверить на плате, объяснить результат.
Уровень C (продвинутый)
- Добавить новый паттерн в
enum class Patternи реализовать его вupdate(). Это настоящая работа с машиной состояний — см. THEORY.md, раздел 3. - Реализовать «морзянку»: передать бузером три буквы SOS корректными тире и точками.
- Объяснить письменно, почему у этого драйвера нет
isAlive(), хотя он есть почти у всех остальных компонентов курса. Ответ: THEORY.md, раздел 4.
Ответы на вопросы, которые прозвучат
«Можно сделать мелодию на активном бузере?» Нет — тон один. Ритм менять можно, высоту нельзя. Мелодия — это пассивный бузер, следующий урок.
«Почему 500 мс и 100 мс, а не другие числа?» Это методический выбор, а не характеристика из даташита: такие интервалы хорошо различимы на слух. Прямо сказано в THEORY.md. Полезно показать, что в коде бывают числа «потому что удобно», и их автор обязан пояснить.
«А если провод оторвётся — программа узнает?» Нет, и это важное ограничение. У бузера нет обратной связи: плата отдаёт команду и не может проверить результат. Поэтому в ответственных системах звуковой сигнал дублируют световым.
«Зачем транзистор, если светодиод работал напрямую?» Разный ток. Светодиод берёт единицы миллиампер, бузер — десятки. Ножка платы рассчитана на первое.
«Можно без транзистора, если бузер маленький?» Иногда работает, но плата при этом на пределе. Так делать не стоит по той же причине, по которой не стоит носить сумку, набитую до предела прочности ручек.
Итог урока: что записать в журнал
- Активный бузер имеет генератор внутри: команда — включить/выключить, тон один.
- Разные сигналы из одного тона получаются ритмом, а не высотой.
- Неблокирующий код позволяет плате звучать и одновременно слушать команды.
Проверка понимания (экспресс, 2 минуты)
| Вопрос | Ожидаемый ответ |
|---|---|
| Как отличить активный бузер от пассивного за 5 секунд? | Подать постоянное напряжение: активный пищит, пассивный щёлкает |
Чем Alert отличается от Confirm по устройству? | Alert бесконечен, Confirm сам завершается |
| Почему нельзя подключить бузер прямо к ножке? | Ток больше допустимого для вывода |
Что даёт отказ от delay()? | Плата продолжает принимать команды во время сигнала |
Типичные затруднения
| Затруднение | Причина | Что делать |
|---|---|---|
| «Неблокирующий — это как?» | Абстракция без опыта | Только демонстрация: команда 4 во время 3 |
| Меняют частоту в коде, ждут другой тон | Перенос модели с пассивного | Вернуться к физике: генератор зашит в железо |
| Схема не работает из-за транзистора | Три вывода, легко перепутать | Подписать выводы на макетке маркером |
| Шум в кабинете | Все пищат одновременно | Правило «звук по команде», палец на бузер |
Домашнее задание
Обязательная часть: найти дома три устройства с звуковой индикацией (микроволновка, стиральная машина, домофон) и записать, какой у каждого сигнал: один тон или мелодия, какой ритм, что он означает. Это тренирует слышать инженерные решения вокруг.
Уровень A: нарисовать временную диаграмму паттерна Confirm — где включено,
где выключено, сколько миллисекунд.
Уровень B: придумать систему из трёх сигналов для умного дома (всё хорошо / внимание / авария) так, чтобы их нельзя было перепутать на слух. Обосновать выбор ритмов письменно.
Уровень C: прочитать раздел 4 THEORY.md и предложить схемотехническое решение, которое позволило бы плате проверять, исправен ли бузер. Обсуждается на следующем уроке.
Связь с курсом
| Что дальше | Где |
|---|---|
| Любая частота, мелодии, сирена | PassiveBuzzer |
| Машина состояний на более сложном примере | LED_middle |
| Звуковая индикация в реальном проекте | FoxHunter — зуммер «горячо-холодно» |
Связь с FoxHunter стоит проговорить: там ровно такой же приём — громкость и частота писка кодируют расстояние до цели. Урок про бузер — подготовка к проекту, который дети запомнят надолго.
Чек-лист педагога перед уроком
- Оба типа бузера проверены лично
- Схема с транзистором собрана как образец
- Serial-команды
0–4отработаны на реальной плате - Правило «звук по команде» проговорено до раздачи компонентов
- Готов контрпример с
beepBlocking()для демонстрации разницы - Карточки заданий A / B / C распечатаны
Презентация: активный бузер
Слайд 1: Один сигнал — простое управление
Активный бузер не нужно “раскачивать” переменным сигналом, как пассивный (tone()) —
внутри уже есть генератор. Драйверу достаточно digitalWrite() на один пин
(подробности физики — THEORY.md).
Слайд 2: Неблокирующая работа
Все сигналы строятся без delay() — через машину состояний в
update(), которая сравнивает millis() с моментом
последнего переключения. Это значит, что пока бузер пищит, loop() продолжает
опрашивать датчики и читать Serial.
Слайд 3: Один писк или готовый паттерн
beep(durationMs)— включить на заданное время и выключиться самому (ActiveBuzzer.cpp:28-36).playPattern(Pattern::Alert)— прерывистая тревога до явногоturnOff().playPattern(Pattern::Confirm)— два коротких писка подтверждения.
Проверить все три можно прямо в тестовом стенде — команды 1/3/4 в
main.cpp.
Слайд 4: Защита от нулевой длительности
beep(0) ничего не делает вместо того, чтобы включить бузер навсегда —
см. проверку в ActiveBuzzer.cpp:29. Без неё случайный
ноль в коде ученика “подвесил” бы бузер во включённом состоянии.
Слайд 5: Что бузер не умеет
У бузера нет обратной связи — программа не может узнать, оборван ли провод или
работает ли сам излучатель. Поэтому в этом драйвере (в отличие от сенсоров с
шиной) нет isAlive() — подробнее в THEORY.md, раздел 4.