Генерация музыкальных тонов на Arduino: полный спектр 88 клавиш пианино
Компоненты и материалы
| Arduino UNO | ×1 |
| Динамик 0.25 Вт, 8 Ом | ×1 |
| Резистор 150–220 Ом | ×1 |
Программное обеспечение
- Arduino IDE
О проекте
Проект демонстрирует генерацию квадратных волн для воспроизведения нот полноразмерного пианино (88 клавиш, ноты 1–88). В отличие от стандартной функции tone(), ограниченной 31 Гц, здесь используется программная генерация задержек на микросекундном уровне, что позволяет воспроизводить даже самые низкие ноты (A0 = 27.5 Гц).
Проблема стандартной tone()
Функция tone(pin, freq) использует таймеры и не работает ниже 31 Гц. Нижние 9 клавиш пианино (A0–F#1) имеют частоты 27.5–46.25 Гц — они недоступны для tone().
Решение: программная генерация
Период волны T = 1/f (в микросекундах). Полупериод (половина периода) задаёт задержку между переключениями пина HIGH/LOW. Для частоты 27.5 Гц период ≈ 36364 мкс, полупериод ≈ 18182 мкс — это превышает лимит delayMicroseconds() (16383 мкс).
Обход ограничения delayMicroseconds()
Используется цикл с накоплением задержек: если нужная задержка > 16000 мкс, выполняется несколько вызовов delayMicroseconds(16000) плюс остаток.
Алгоритм расчёта частоты
Номер клавиши n (1–88) → частота f = 440 * 2^((n-49)/12) Гц (A4 = 440 Гц, клавиша 49). Код вычисляет это в реальном времени без таблиц.
Схема подключения
Динамик подключен к GND и пину 12 через резистор 150–220 Ом (ограничение тока). Пин 12 переключается HIGH/LOW с рассчитанными задержками.
Код (компактная версия)
const int speakerPin = 12;
void playNote(int key) { // key = 1..88
float freq = 440.0 * pow(2.0, (key - 49) / 12.0);
long halfPeriod = 500000 / freq; // микросекунды
int cycles = freq * 0.5; // играть 0.5 сек
for (int i = 0; i < cycles; i++) {
digitalWrite(speakerPin, HIGH);
delayMicrosecondsClamped(halfPeriod);
digitalWrite(speakerPin, LOW);
delayMicrosecondsClamped(halfPeriod);
}
}
void delayMicrosecondsClamped(unsigned long us) {
while (us > 16000) { delayMicroseconds(16000); us -= 16000; }
delayMicroseconds(us);
}
void setup() { pinMode(speakerPin, OUTPUT); }
void loop() {
// Пример: гамма до мажор (клавиши 40..52)
for (int k = 40; k <= 52; k++) { playNote(k); delay(100); }
delay(2000);
}
Полный прокомментированный код доступен по ссылке в описании видео автора.
Особенности
- Код вмещается на одном экране (без комментариев).
- Работает на уровне микросекунд — высокая точность тона.
- Позволяет обучать основкам цифрового синтеза звука.
Производственный процесс
- Создание потрясающей системы Ambilight для монитора на Arduino
- Создание универсального ИК-пульта на Arduino: пошаговое руководство
- Создание настраиваемой «бьющейся» клавиши на Arduino: пошаговое руководство
- Подключение Arduino Mega к GPS-модулю NEO‑6M: пошаговое руководство
- Крестики-нолики на Arduino с матрицей MAX7219 и картонным корпусом
- Сборка вольтметра на Arduino с дисплеем Nokia 5110 — Пошаговое руководство
- Голосовое управление бытовыми приборами: Bluetooth-управление через Google Assistant
- Подключение Arduino к NMEA-0183: пошаговое руководство
- Автоматическая дверь на Arduino с ультразвуковым датчиком HC-SR04
- Создание Bluetooth-управляемой машины на Arduino: полное DIY-руководство