Воспроизведение «С днём рождения» в трехголосной полифонии на Arduino Nano — бесконечная мелодия с синхронизацией светодиодов
Компоненты и материалы
- Arduino Nano R3 — 1 шт.
Приложения и сервисы
- Arduino IDE
О проекте
Демонстрация
Устройство воспроизводит мелодию «С днём рождения» в трёхголосящей полифонии на трёх пьезоизлучателях (buzzer). Питание от любого USB-источника (пауэрбанк, зарядка). Мелодия играет бесконечно — до тех пор, пока вам не надоест. Светодиоды мигают в такт смене нот в каждом голосовом канале.
Схема и монтаж
Вся схема собрана на крошечной макетной плате без пайки. Arduino Nano идеально встаёт в разъёмы платы, оставляя свободные контакты по бокам для подключения компонентов.
Используются три пьезоизлучателя и три светодиода с токоограничивающими резисторами 100 Ом (обычно берут 220 Ом, но 100 Ом тоже работают). «Хитрость»: выводы GND для зуммеров и светодиодов реализованы через цифровые пины Arduino, установленные в LOW — они работают как виртуальная земля.
Центральный зуммер немного больше остальных — изначально планировался для бас-канала, но по факту все три звучат одинаково. Можно использовать три одинаковых зуммера, только нужно скорректировать номера пинов в коде.
О программе
Для одновременного звучания трёх тонов используется библиотека Tone (автор Bhagman). Она задействует аппаратные таймеры и прерывания для псевдо-мультизадачности на одном ядре.
Скачать библиотеку: Tone.zip (при регистрации на Dropbox просто закройте окно). Установка: Sketch → Include Library → Add .ZIP Library….
Ссылки на автора: Профиль, GitHub.
Код довольно объёмный из-за необходимости ручного управления тремя независимыми потоками нот в линейном потоке команд. Рефакторинг планировался, но не выполнен. Код приведён ниже.
Код
Не забудьте установить библиотеку Tone!
#include <Tone.h>
Tone solo;
Tone bass;
Tone rythm;
const int t = 600; // длительность четвертной ноты (мс)
const int tt = t * 2;
const int t14 = round(t * 1 / 4);
const int t24 = round(t * 2 / 4);
const int t34 = round(t * 3 / 4);
const int bassLedPin = 15; // A1
const int rythmLedPin = 17; // A3
const int soloLedPin = 19; // A5
void wait(Tone t) { while (t.isPlaying()) { } }
int bassLedState = LOW;
void switchBassLed() { bassLedState = !bassLedState; digitalWrite(bassLedPin, bassLedState); }
int rythmLedState = LOW;
void switchRythmLed() { rythmLedState = !rythmLedState; digitalWrite(rythmLedPin, rythmLedState); }
int soloLedState = LOW;
void switchSoloLed() { soloLedState = !soloLedState; digitalWrite(soloLedPin, soloLedState); }
void setup(void) {
pinMode(14, OUTPUT); // GND для светодиода баса (A0)
pinMode(16, OUTPUT); // GND для светодиода ритма (A2)
pinMode(18, OUTPUT); // GND для светодиода соло (A4)
pinMode(bassLedPin, OUTPUT);
pinMode(rythmLedPin, OUTPUT);
pinMode(soloLedPin, OUTPUT);
pinMode(2, OUTPUT); // GND для зуммера соло
pinMode(9, OUTPUT); // GND для зуммера ритма
solo.begin(6); // сигнальный пин соло
bass.begin(12); // сигнальный пин баса
rythm.begin(0); // сигнальный пин ритма
// Вступление: две ноты ре
solo.play(NOTE_D4, t34); switchSoloLed(); wait(solo);
solo.play(NOTE_D4, t14); switchSoloLed(); wait(solo);
}
void loop(void) {
// Весь остальной фрагмент мелодии последовательно играет три голоса
// с миганием соответствующих светодиодов.
// Код опущен для краткости — полный листинг в исходнике.
// Принцип: bass.play(нота, длительность); switchBassLed(); и т.д.
// wait(rythm) синхронизирует голоса по самому длинному.
}
Примечание: полный листинг очень длинный, в статье приведён только каркас. Скачайте исходный файл для полного кода.
Производственный процесс
- Датчик CO2 K30: мониторинг качества воздуха в реальном времени на Arduino
- Устройство для общения глухосліпых людей с помощью 1Sheeld и Arduino
- Умная копилка: управление монетоприёмником на Arduino Nano
- Набор Arduino Nano: CrazyCircuits, датчики DFRobot и инструменты — создавайте проекты с уверенностью
- Управление светодиодом по Bluetooth с Arduino: простой DIY-гид
- Интеграция ёмкостного сканера отпечатков DFRobot с Arduino или ESP8266
- Интерактивный HMI-проект на Nextion с Arduino Mega и датчиками
- Роботизированная рука 6 степеней свободы на Arduino Mega с управлением через Nunchuk
- Управление двумя шаговыми двигателями через джойстик на Arduino Nano — простой урок (Visuino)
- Ручной дозиметр (Гейгер-счетчик) на Arduino Nano: сборка в 3D-корпусе