Jingle Bells на Arduino: код и 4 рождественские песни для зуммера
Код Jingle Bells для Arduino, а также We Wish You a Merry Christmas, Silent Night и Deck the Halls на пассивном зуммере: таблица нот, темп и плеер на millis со светодиодами.
Чтобы сыграть Jingle Bells на Arduino, нужны только пассивный зуммер и функция tone(): ты записываешь частоту и длительность каждой ноты в массив, а Arduino по очереди отправляет их на зуммер. В этой статье есть точные массивы нот и длительностей для Jingle Bells, We Wish You a Merry Christmas, Silent Night и Deck the Halls, снятые с нотной записи, а не подобранные на слух. Все четыре мелодии — традиционные произведения, которым больше ста лет, поэтому их можно использовать в любом проекте, не беспокоясь об авторских правах.
Начнём с короткого скетча на одну песню, затем перейдём к музыкальной шкатулке, которая по очереди играет все четыре песни, мигает двумя светодиодами в такт нотам и переключает песни кнопкой. Второй скетч использует millis() вместо delay(), поэтому во время песни он продолжает выполнять другие задачи: опрашивать кнопки и датчики или управлять светодиодной лентой. В конце мы перенесём те же мелодии на сенсорную рождественскую открытку на ESP32 и на MicroPython для Raspberry Pi Pico.

Какой нужен зуммер: активный или пассивный?
У активного зуммера внутри есть собственный генератор: подай на него 5 V, и он всегда пищит на одной высоте, так что мелодию сыграть не может. Пассивный зуммер работает как крошечный динамик: он звучит с той частотой, с которой пин Arduino включается и выключается. Отличить их легко: на мгновение коснись зуммером батарейки на 3–5 V. Непрерывный писк — значит активный, одиночный щелчок — пассивный. На активных моделях обычно есть белая наклейка и закрытое дно, а у пассивных снизу видна зелёная плата. Подробности — в статье Что такое зуммер?.
| Характеристика | Активный зуммер | Пассивный зуммер |
|---|---|---|
| Встроенный генератор | Есть | Нет |
| Играет мелодии? | Нет, только один тон | Да, любую ноту через tone() |
| Команда управления | digitalWrite() (вкл/выкл) | tone(пин, частота, длительность) |
| При касании батарейки | Непрерывный писк | Одиночный щелчок |
| Самый громкий диапазон | Фиксированный (обычно 2–2,5 kHz) | Примерно 2–4 kHz (резонанс) |
Подключение: зуммер, два светодиода и кнопка
| Деталь | Arduino Uno | ESP32 | Raspberry Pi Pico |
|---|---|---|---|
| Пассивный зуммер + | D8 | GPIO 25 | GP15 |
| Пассивный зуммер − | GND | GND | GND |
| Светодиод 1 (с резистором 220 Ω) | D6 | GPIO 26 | GP14 |
| Светодиод 2 (с резистором 220 Ω) | D7 | GPIO 27 | GP13 |
| Кнопка (вторая ножка на GND) | D2 | GPIO 4 | GP2 |
| Сенсорная фольга | - | GPIO 32 (T9) | - |
Частоты нот: 14 нот из этих рождественских песен
В западной музыке каждая октава делится на 12 полутонов, и подъём на один полутон умножает частоту на корень 12-й степени из 2, то есть примерно на 1,0595. Опорная нота Ля (A4) — 440 Hz; частота ноты с MIDI-номером n равна f = 440 × 2^((n − 69) / 12). Например, До5 (C5) — это MIDI 72: 440 × 2^(3/12) = 523,25 Hz. Подъём на октаву ровно удваивает частоту, поэтому До6 — 1047 Hz. Маленькие пассивные зуммеры звучат слабо ниже 500 Hz, поэтому мы перенесли все четыре песни в 5-ю и 6-ю октавы; в таблице перечислены все ноты, которые использует код.
| Нота | Название | Частота (Hz) | Константа в коде |
|---|---|---|---|
| B4 | Си | 494 | NOTE_B4 |
| C5 | До | 523 | NOTE_C5 |
| D5 | Ре | 587 | NOTE_D5 |
| E5 | Ми | 659 | NOTE_E5 |
| F5 | Фа | 698 | NOTE_F5 |
| F#5 | Фа-диез | 740 | NOTE_FS5 |
| G5 | Соль | 784 | NOTE_G5 |
| A5 | Ля | 880 | NOTE_A5 |
| A#5 / Bb5 | Си-бемоль | 932 | NOTE_AS5 |
| B5 | Си | 988 | NOTE_B5 |
| C6 | До | 1047 | NOTE_C6 |
| D6 | Ре | 1175 | NOTE_D6 |
| E6 | Ми | 1319 | NOTE_E6 |
| F6 | Фа | 1397 | NOTE_F6 |
Темп и длительности нот
Вместо того чтобы писать каждую длительность в миллисекундах, мы взяли за единицу самую короткую ноту — восьмую: 1 — восьмая, 2 — четверть, 3 — четверть с точкой, 4 — половинная, 6 — половинная с точкой, 8 — целая нота. Темп — это число четвертей в минуту (BPM); четверть длится 60 000 / BPM миллисекунд, а восьмая — вдвое меньше. При 120 BPM четверть длится 500 мс, а восьмая — 250 мс. Чтобы изменить скорость песни, достаточно поменять длительность восьмой, не трогая массивы. Каждая нота звучит 90% своей длительности, а последние 10% — тишина, поэтому повторяющиеся ноты (как три Ми в Jingle Bells) не сливаются в один долгий звук.
| Песня | Размер | Темп | Восьмая (мс) | Четверть (мс) | Число нот |
|---|---|---|---|---|---|
| Jingle Bells (припев) | 4/4 | 120 BPM | 250 | 500 | 51 |
| We Wish You a Merry Christmas | 3/4 | 150 BPM | 200 | 400 | 30 |
| Silent Night | 3/4 | 75 BPM | 400 | 800 | 46 |
| Deck the Halls | 4/4 | примерно 130 BPM | 230 | 460 | 68 |
Первый скетч: припев Jingle Bells
- Подключи вывод + пассивного зуммера к D8, а второй вывод — к GND.
- Открой Arduino IDE, вставь код ниже и выбери плату Arduino Uno.
- Загрузи код: припев прозвучит один раз сразу после запуска платы. Чтобы послушать ещё раз, нажми кнопку сброса (reset).
- Если звучит слишком медленно или слишком быстро, измени EIGHTH_MS: при 200 мелодия играет быстрее, при 300 — медленнее.
1// Jingle Bells nakaratı - pasif buzzer D8 / Jingle Bells chorus - passive buzzer on D8
2#define NOTE_C5 523
3#define NOTE_D5 587
4#define NOTE_E5 659
5#define NOTE_F5 698
6#define NOTE_G5 784
7
8const int BUZZER_PIN = 8; // pasif buzzer + ucu / passive buzzer + lead
9const int EIGHTH_MS = 250; // 120 BPM: dörtlük 500 ms, sekizlik 250 ms / quarter 500 ms, eighth 250 ms
10
11const int melody[] = {
12 NOTE_E5, NOTE_E5, NOTE_E5, NOTE_E5, NOTE_E5, NOTE_E5,
13 NOTE_E5, NOTE_G5, NOTE_C5, NOTE_D5, NOTE_E5,
14 NOTE_F5, NOTE_F5, NOTE_F5, NOTE_F5, NOTE_F5, NOTE_E5, NOTE_E5, NOTE_E5, NOTE_E5,
15 NOTE_E5, NOTE_D5, NOTE_D5, NOTE_E5, NOTE_D5, NOTE_G5,
16 NOTE_E5, NOTE_E5, NOTE_E5, NOTE_E5, NOTE_E5, NOTE_E5,
17 NOTE_E5, NOTE_G5, NOTE_C5, NOTE_D5, NOTE_E5,
18 NOTE_F5, NOTE_F5, NOTE_F5, NOTE_F5, NOTE_F5, NOTE_E5, NOTE_E5, NOTE_E5, NOTE_E5,
19 NOTE_G5, NOTE_G5, NOTE_F5, NOTE_D5, NOTE_C5
20};
21// süreler sekizlik cinsinden: 1 = sekizlik, 2 = dörtlük, 3 = noktalı dörtlük, 4 = ikilik, 8 = birlik
22// lengths in eighths: 1 = eighth, 2 = quarter, 3 = dotted quarter, 4 = half, 8 = whole
23const byte beats[] = {
24 2, 2, 4, 2, 2, 4,
25 2, 2, 3, 1, 8,
26 2, 2, 3, 1, 2, 2, 2, 1, 1,
27 2, 2, 2, 2, 4, 4,
28 2, 2, 4, 2, 2, 4,
29 2, 2, 3, 1, 8,
30 2, 2, 3, 1, 2, 2, 2, 1, 1,
31 2, 2, 2, 2, 8
32};
33
34void setup() {
35 int count = sizeof(melody) / sizeof(melody[0]); // 51 nota / 51 notes
36 for (int i = 0; i < count; i++) {
37 int duration = beats[i] * EIGHTH_MS;
38 tone(BUZZER_PIN, melody[i], duration * 9 / 10); // notalar arasında %10 boşluk / 10% gap between notes
39 delay(duration);
40 }
41 noTone(BUZZER_PIN);
42}
43
44void loop() {
45 // bir kez çalar; tekrar için reset tuşuna bas / plays once, press reset to replay
46}Скетч хранит два параллельных массива: melody содержит частоты нот, а beats — длительность каждой ноты в восьмых, в том же порядке. Для каждой ноты цикл запускает звук через tone() и ждёт полную длительность ноты с помощью delay(). Если tone() получает длительность третьим аргументом, звук прекращается сам; так как мы передаём 90% длительности ноты, между нотами остаётся короткий вдох. В обоих массивах должно быть одинаковое число элементов: если добавить ноту в один и забыть длительность в другом, мелодия поедет, и зазвучат случайные значения памяти за концом массива. Пробелы в массивах совпадают с тактовыми чертами, поэтому ноты легко сверять с нотной записью.
Массивы нот для всех четырёх песен
В таблице ниже указаны тональность каждой песни и ноты её первой строки; это пригодится при проверке кода на слух. Тире (–) — тактовая черта, точка (.) — нота с точкой. We Wish You a Merry Christmas начинается с затакта (anacrusis): первая До5 — одна четверть перед первым тактом. Silent Night медленная и широкая, поэтому последнюю До5 мы держим 12 восьмых, то есть два полных такта. Единственный диез в Deck the Halls — Фа-диез (F#5) в восходящем пассаже «фа-ла-ла».
| Песня | Тональность | Ноты первой строки | Обрати внимание |
|---|---|---|---|
| Jingle Bells | до мажор | Ми Ми Ми – Ми Ми Ми – Ми Соль До. Ре – Ми | Четверть с точкой + восьмая на «all the way» |
| We Wish You a Merry Christmas | фа мажор | До – Фа Фа Соль Фа Ми – Ре Ре Ре | Размер 3/4, используется Си-бемоль (A#5) |
| Silent Night | до мажор (на октаву выше) | Соль. Ля Соль – Ми – Соль. Ля Соль – Ми | Медленный темп, половинные с точкой |
| Deck the Halls | до мажор | Соль. Фа Ми Ре – До Ре Ми До | Восьмые в «фа-ла-ла», Фа-диез (F#5) |
Плеер рождественских песен на millis со светодиодами (4 песни + кнопка)
Теперь соберём все четыре песни в один скетч. Ноты хранятся в структуре Note из пар {частота, длительность} и лежат во флеш-памяти благодаря PROGMEM; у Uno всего 2 КБ ОЗУ, поэтому читать 195 нот из флеша, а не держать их в ОЗУ, — хорошая привычка. Светодиоды меняются местами на каждой ноте, кнопка на D2 работает со встроенной подтяжкой, а нажатие переключает на следующую песню. Когда песня заканчивается, наступает пауза 1,5 с, затем начинается следующая.
1// 4 Noel şarkısı: millis ile çalar, LED'ler notaya göre yanar, buton sonraki şarkıya geçer
2// 4 Christmas songs: millis-based player, LEDs follow the notes, button skips to the next song
3#define REST 0
4#define NOTE_B4 494
5#define NOTE_C5 523
6#define NOTE_D5 587
7#define NOTE_E5 659
8#define NOTE_F5 698
9#define NOTE_FS5 740
10#define NOTE_G5 784
11#define NOTE_A5 880
12#define NOTE_AS5 932
13#define NOTE_B5 988
14#define NOTE_C6 1047
15#define NOTE_D6 1175
16#define NOTE_E6 1319
17#define NOTE_F6 1397
18
19#if defined(ESP32)
20const int BUZZER_PIN = 25; // ESP32 pinleri / ESP32 pins
21const int LED_PINS[2] = {26, 27};
22const int BUTTON_PIN = 4;
23#else
24const int BUZZER_PIN = 8; // Arduino Uno pinleri / Arduino Uno pins
25const int LED_PINS[2] = {6, 7};
26const int BUTTON_PIN = 2;
27#endif
28
29struct Note { uint16_t freq; uint8_t len; }; // len: sekizlik sayısı / length in eighths
30
31// Jingle Bells (Do majör, 4/4) / (C major, 4/4)
32const Note JINGLE[] PROGMEM = {
33 {NOTE_E5,2},{NOTE_E5,2},{NOTE_E5,4}, {NOTE_E5,2},{NOTE_E5,2},{NOTE_E5,4},
34 {NOTE_E5,2},{NOTE_G5,2},{NOTE_C5,3},{NOTE_D5,1}, {NOTE_E5,8},
35 {NOTE_F5,2},{NOTE_F5,2},{NOTE_F5,3},{NOTE_F5,1}, {NOTE_F5,2},{NOTE_E5,2},{NOTE_E5,2},{NOTE_E5,1},{NOTE_E5,1},
36 {NOTE_E5,2},{NOTE_D5,2},{NOTE_D5,2},{NOTE_E5,2}, {NOTE_D5,4},{NOTE_G5,4},
37 {NOTE_E5,2},{NOTE_E5,2},{NOTE_E5,4}, {NOTE_E5,2},{NOTE_E5,2},{NOTE_E5,4},
38 {NOTE_E5,2},{NOTE_G5,2},{NOTE_C5,3},{NOTE_D5,1}, {NOTE_E5,8},
39 {NOTE_F5,2},{NOTE_F5,2},{NOTE_F5,3},{NOTE_F5,1}, {NOTE_F5,2},{NOTE_E5,2},{NOTE_E5,2},{NOTE_E5,1},{NOTE_E5,1},
40 {NOTE_G5,2},{NOTE_G5,2},{NOTE_F5,2},{NOTE_D5,2}, {NOTE_C5,8}
41};
42
43// We Wish You a Merry Christmas (Fa majör, 3/4) / (F major, 3/4)
44const Note WE_WISH[] PROGMEM = {
45 {NOTE_C5,2},
46 {NOTE_F5,2},{NOTE_F5,1},{NOTE_G5,1},{NOTE_F5,1},{NOTE_E5,1}, {NOTE_D5,2},{NOTE_D5,2},{NOTE_D5,2},
47 {NOTE_G5,2},{NOTE_G5,1},{NOTE_A5,1},{NOTE_G5,1},{NOTE_F5,1}, {NOTE_E5,2},{NOTE_C5,2},{NOTE_C5,2},
48 {NOTE_A5,2},{NOTE_A5,1},{NOTE_AS5,1},{NOTE_A5,1},{NOTE_G5,1}, {NOTE_F5,2},{NOTE_D5,2},{NOTE_C5,1},{NOTE_C5,1},
49 {NOTE_D5,2},{NOTE_G5,2},{NOTE_E5,2}, {NOTE_F5,6}
50};
51
52// Silent Night (Do majör, 3/4, bir oktav yukarı) / (C major, 3/4, one octave up)
53const Note SILENT[] PROGMEM = {
54 {NOTE_G5,3},{NOTE_A5,1},{NOTE_G5,2}, {NOTE_E5,6}, {NOTE_G5,3},{NOTE_A5,1},{NOTE_G5,2}, {NOTE_E5,6},
55 {NOTE_D6,4},{NOTE_D6,2}, {NOTE_B5,6}, {NOTE_C6,4},{NOTE_C6,2}, {NOTE_G5,6},
56 {NOTE_A5,4},{NOTE_A5,2}, {NOTE_C6,3},{NOTE_B5,1},{NOTE_A5,2}, {NOTE_G5,3},{NOTE_A5,1},{NOTE_G5,2}, {NOTE_E5,6},
57 {NOTE_A5,4},{NOTE_A5,2}, {NOTE_C6,3},{NOTE_B5,1},{NOTE_A5,2}, {NOTE_G5,3},{NOTE_A5,1},{NOTE_G5,2}, {NOTE_E5,6},
58 {NOTE_D6,4},{NOTE_D6,2}, {NOTE_F6,3},{NOTE_D6,1},{NOTE_B5,2}, {NOTE_C6,6}, {NOTE_E6,6},
59 {NOTE_C6,2},{NOTE_G5,2},{NOTE_E5,2}, {NOTE_G5,3},{NOTE_F5,1},{NOTE_D5,2}, {NOTE_C5,12}
60};
61
62// Deck the Halls (Do majör, 4/4) / (C major, 4/4)
63const Note DECK[] PROGMEM = {
64 {NOTE_G5,3},{NOTE_F5,1},{NOTE_E5,2},{NOTE_D5,2}, {NOTE_C5,2},{NOTE_D5,2},{NOTE_E5,2},{NOTE_C5,2},
65 {NOTE_D5,1},{NOTE_E5,1},{NOTE_F5,1},{NOTE_D5,1},{NOTE_E5,3},{NOTE_D5,1}, {NOTE_C5,2},{NOTE_B4,2},{NOTE_C5,4},
66 {NOTE_G5,3},{NOTE_F5,1},{NOTE_E5,2},{NOTE_D5,2}, {NOTE_C5,2},{NOTE_D5,2},{NOTE_E5,2},{NOTE_C5,2},
67 {NOTE_D5,1},{NOTE_E5,1},{NOTE_F5,1},{NOTE_D5,1},{NOTE_E5,3},{NOTE_D5,1}, {NOTE_C5,2},{NOTE_B4,2},{NOTE_C5,4},
68 {NOTE_D5,3},{NOTE_E5,1},{NOTE_F5,2},{NOTE_D5,2}, {NOTE_E5,3},{NOTE_F5,1},{NOTE_G5,2},{NOTE_D5,2},
69 {NOTE_E5,1},{NOTE_FS5,1},{NOTE_G5,2},{NOTE_A5,1},{NOTE_B5,1},{NOTE_C6,2}, {NOTE_B5,2},{NOTE_A5,2},{NOTE_G5,4},
70 {NOTE_G5,3},{NOTE_F5,1},{NOTE_E5,2},{NOTE_D5,2}, {NOTE_C5,2},{NOTE_D5,2},{NOTE_E5,2},{NOTE_C5,2},
71 {NOTE_A5,1},{NOTE_A5,1},{NOTE_A5,1},{NOTE_A5,1},{NOTE_G5,3},{NOTE_F5,1}, {NOTE_E5,2},{NOTE_D5,2},{NOTE_C5,4}
72};
73
74struct Song { const Note* notes; uint8_t count; uint16_t eighthMs; };
75const Song SONGS[] = {
76 {JINGLE, sizeof(JINGLE) / sizeof(Note), 250}, // 120 BPM
77 {WE_WISH, sizeof(WE_WISH) / sizeof(Note), 200}, // 150 BPM
78 {SILENT, sizeof(SILENT) / sizeof(Note), 400}, // 75 BPM
79 {DECK, sizeof(DECK) / sizeof(Note), 230} // yaklaşık 130 BPM / about 130 BPM
80};
81const uint8_t SONG_COUNT = sizeof(SONGS) / sizeof(Song);
82const unsigned long SONG_GAP_MS = 1500; // şarkılar arası sessizlik / silence between songs
83
84uint8_t song = 0;
85int noteIndex = -1; // -1: şarkı başlamadı / song not started
86unsigned long noteStart = 0;
87unsigned long noteLength = 0;
88bool lastButton = HIGH;
89unsigned long lastPress = 0;
90
91void ledsOff() {
92 digitalWrite(LED_PINS[0], LOW);
93 digitalWrite(LED_PINS[1], LOW);
94}
95
96void startNote() {
97 Note n;
98 memcpy_P(&n, &SONGS[song].notes[noteIndex], sizeof(Note)); // flash'tan oku / read from flash
99 noteLength = (unsigned long)n.len * SONGS[song].eighthMs;
100 if (n.freq != REST) {
101 tone(BUZZER_PIN, n.freq, noteLength * 9 / 10); // %10 boşluk / 10% gap
102 digitalWrite(LED_PINS[noteIndex % 2], HIGH); // LED'ler sırayla / LEDs alternate
103 digitalWrite(LED_PINS[(noteIndex + 1) % 2], LOW);
104 } else {
105 noTone(BUZZER_PIN);
106 ledsOff();
107 }
108 noteStart = millis();
109}
110
111void nextSong() {
112 noTone(BUZZER_PIN);
113 ledsOff();
114 song = (song + 1) % SONG_COUNT;
115 noteIndex = 0;
116 startNote();
117}
118
119void setup() {
120 pinMode(LED_PINS[0], OUTPUT);
121 pinMode(LED_PINS[1], OUTPUT);
122 pinMode(BUTTON_PIN, INPUT_PULLUP); // buton GND'ye / button to GND
123 noteIndex = 0;
124 startNote();
125}
126
127void loop() {
128 unsigned long now = millis();
129
130 // Buton: düşen kenar + 250 ms kilit / button: falling edge + 250 ms lockout
131 bool button = digitalRead(BUTTON_PIN);
132 if (lastButton == HIGH && button == LOW && now - lastPress > 250) {
133 lastPress = now;
134 nextSong();
135 }
136 lastButton = button;
137
138 // Nota süresi doldu mu? / has the note finished?
139 if (now - noteStart >= noteLength) {
140 noteIndex++;
141 if (noteIndex < SONGS[song].count) {
142 startNote();
143 } else if (noteIndex == SONGS[song].count) { // şarkı bitti: ara ver / song over: pause
144 ledsOff();
145 noteLength = SONG_GAP_MS;
146 noteStart = now;
147 } else {
148 nextSong(); // aradan sonra sıradaki şarkı / next song after the pause
149 }
150 }
151}Сердце кода — проверка времени внутри loop(): если millis() − noteStart превысило длительность ноты, запускается следующая нота; если нет, loop продолжает работу без ожидания. Так кнопка опрашивается на каждом проходе, и ни одно нажатие не теряется; с delay() кнопка вообще не реагировала бы во время последней 4,8-секундной ноты Silent Night. memcpy_P() копирует ноту из флеша во временную переменную в ОЗУ. Когда песня заканчивается, noteIndex равен числу нот, и это значение используется как состояние «паузы»; когда пауза истекает, вызывается nextSong(). Скомпилированный скетч занимает на Uno около 3,9 КБ флеш-памяти и 67 байт ОЗУ. Почему мы выбрали millis(), а не delay(), подробнее рассказано в статье millis и delay: в чём разница.
Рождественские песни на ESP32: сенсорная рождественская открытка
Скетч плеера выше компилируется на ESP32 без изменений: блок #if defined(ESP32) автоматически переключает пины на GPIO 25, 26, 27 и 4. В версиях 2.x и 3.x ядра ESP32 есть tone(), которая за кадром использует модуль ШИМ LEDC. Пины ESP32 выдают 3,3 V, поэтому звук немного тише, чем на Uno. Короткий скетч ниже использует сенсорные пины ESP32: коснись звезды из алюминиевой фольги, подключённой к GPIO 32, и зазвучит первая строка Jingle Bells, а светодиод загорится. При запуске код измеряет значение без касания и сам задаёт порог; подробнее о сенсорных пинах — в статье Сенсорные пины ESP32.
1// ESP32 dokunmatik Noel kartı: folyo yıldıza dokununca Jingle Bells çalar
2// ESP32 touch Christmas card: touch the foil star and Jingle Bells plays
3const int BUZZER_PIN = 25; // pasif buzzer / passive buzzer
4const int LED_PIN = 26; // yıldızın LED'i / star LED
5const int TOUCH_PIN = 32; // T9: folyoya giden kablo / T9: wire to the foil
6
7const int EIGHTH_MS = 250;
8const int melody[] = {659, 659, 659, 659, 659, 659, 659, 784, 523, 587, 659}; // E E E, E E E, E G C D E
9const byte beats[] = {2, 2, 4, 2, 2, 4, 2, 2, 3, 1, 8};
10int threshold = 0;
11
12void setup() {
13 Serial.begin(115200);
14 pinMode(LED_PIN, OUTPUT);
15 long sum = 0;
16 for (int i = 0; i < 20; i++) { // dokunmadan ortalama al / average while untouched
17 sum += touchRead(TOUCH_PIN);
18 delay(20);
19 }
20 threshold = (sum / 20) * 7 / 10; // eşik: ortalamanın %70'i / threshold: 70% of the average
21 Serial.printf("Esik / threshold: %d\n", threshold);
22}
23
24void loop() {
25 if (touchRead(TOUCH_PIN) < threshold) { // dokununca değer düşer / the value drops when touched
26 digitalWrite(LED_PIN, HIGH);
27 for (int i = 0; i < 11; i++) {
28 int duration = beats[i] * EIGHTH_MS;
29 tone(BUZZER_PIN, melody[i], duration * 9 / 10);
30 delay(duration);
31 }
32 noTone(BUZZER_PIN);
33 digitalWrite(LED_PIN, LOW);
34 delay(1000); // art arda tetiklenmesin / avoid instant retrigger
35 }
36}Рождественские песни на Raspberry Pi Pico с MicroPython
У Pico нет tone(), но ту же работу делает machine.PWM: freq() задаёт частоту ноты, а duty_u16(32768) — коэффициент заполнения 50%, при котором зуммер звучит громче всего. duty_u16(0) выключает звук. Скрипт по очереди играет две песни; нажми кнопку на GP2, и текущая песня прервётся, а начнётся следующая. Две другие песни можно добавить в том же формате с числами из скетча для Arduino: частоты и длительности полностью совпадают. Если MicroPython в новинку, начни с установки Thonny из статьи Что такое Raspberry Pi Pico?.
1# Raspberry Pi Pico (MicroPython): Jingle Bells + We Wish You a Merry Christmas
2from machine import Pin, PWM
3import time
4
5buzzer = PWM(Pin(15)) # pasif buzzer GP15 / passive buzzer on GP15
6leds = [Pin(14, Pin.OUT), Pin(13, Pin.OUT)]
7button = Pin(2, Pin.IN, Pin.PULL_UP) # buton GP2 -> GND / button GP2 -> GND
8
9C5, D5, E5, F5, G5, A5, AS5 = 523, 587, 659, 698, 784, 880, 932
10
11JINGLE = [(E5,2),(E5,2),(E5,4),(E5,2),(E5,2),(E5,4),(E5,2),(G5,2),(C5,3),(D5,1),(E5,8),
12 (F5,2),(F5,2),(F5,3),(F5,1),(F5,2),(E5,2),(E5,2),(E5,1),(E5,1),
13 (E5,2),(D5,2),(D5,2),(E5,2),(D5,4),(G5,4),
14 (E5,2),(E5,2),(E5,4),(E5,2),(E5,2),(E5,4),(E5,2),(G5,2),(C5,3),(D5,1),(E5,8),
15 (F5,2),(F5,2),(F5,3),(F5,1),(F5,2),(E5,2),(E5,2),(E5,1),(E5,1),
16 (G5,2),(G5,2),(F5,2),(D5,2),(C5,8)]
17WE_WISH = [(C5,2),(F5,2),(F5,1),(G5,1),(F5,1),(E5,1),(D5,2),(D5,2),(D5,2),
18 (G5,2),(G5,1),(A5,1),(G5,1),(F5,1),(E5,2),(C5,2),(C5,2),
19 (A5,2),(A5,1),(AS5,1),(A5,1),(G5,1),(F5,2),(D5,2),(C5,1),(C5,1),
20 (D5,2),(G5,2),(E5,2),(F5,6)]
21SONGS = [(JINGLE, 250), (WE_WISH, 200)] # (notalar, sekizlik ms) / (notes, eighth ms)
22
23def play(notes, eighth_ms):
24 for i, (freq, length) in enumerate(notes):
25 duration = length * eighth_ms
26 leds[i % 2].on()
27 leds[(i + 1) % 2].off()
28 if freq:
29 buzzer.freq(freq)
30 buzzer.duty_u16(32768) # %50 doluluk = en yüksek ses / 50% duty = loudest
31 time.sleep_ms(duration * 9 // 10)
32 buzzer.duty_u16(0) # %10 sessizlik / 10% silence
33 time.sleep_ms(duration // 10)
34 if button.value() == 0: # basılırsa şarkıyı kes / stop the song on press
35 break
36 for led in leds:
37 led.off()
38
39song = 0
40while True:
41 play(*SONGS[song])
42 song = (song + 1) % len(SONGS)
43 time.sleep_ms(1500)Как сделать звук громче и лучше
- Транзистор и динамик: подключи пин через резистор 1 kΩ к базе NPN-транзистора (2N2222, BC337), динамик — между 5 V и коллектором, а эмиттер — к GND. Маленький динамик на 8 Ω звучит намного полнее зуммера; последовательный резистор 47–100 Ω ограничивает ток.
- Диапазон резонанса: маленькие пьезозуммеры громче всего звучат около 2–4 kHz. Перенос мелодии на октаву выше заметно прибавляет громкости, хотя и не так сильно, как транзистор.
- Эффект корпуса: если поместить зуммер в картонную коробку или ёлочный шар отверстием наружу, звук естественным образом усилится.
- Чтобы сделать тише: в проекте, который работает ночью, поставь последовательно с зуммером резистор 100–470 Ω: громкость упадёт, а мелодия не исказится.
- Только один голос: на Uno tone() выдаёт звук только на одном пине одновременно. Для аккордов или двухголосной музыки лучше подходит MP3-модуль вроде DFPlayer Mini; варианты сравниваются в статье Музыкальные проекты на Arduino.
Частые проблемы и решения
| Проблема | Причина | Решение |
|---|---|---|
| Всегда один и тот же писк | Используется активный зуммер | Поставь пассивный зуммер: при касании батарейки он должен щёлкнуть |
| Мелодию не узнать, ноты сдвинуты | Массивы melody и beats разной длины | Уравняй число элементов и проверь такт за тактом |
| Повторяющиеся ноты сливаются в один долгий звук | Между нотами нет тишины | Сделай длительность в tone() равной 90% ноты |
| Светодиод на D3 или D11 мерцает | tone() использует Timer2 | Перенеси светодиод на другой пин, например D6 или D7 |
| Одно нажатие пропускает несколько песен | Дребезг контактов кнопки | Лови спадающий фронт и добавь блокировку на 250 мс |
| Ошибка 'tone' was not declared (не объявлена) на ESP32 | Очень старое ядро ESP32 (1.x) | Обнови до 2.x или 3.x в «Менеджере плат» (Boards Manager) |
| На Pico звук не прекращается после песни | Не вызвана duty_u16(0) | Вызывай duty_u16(0) после каждой ноты и в конце |
Идеи проектов с рождественскими песнями
- Детектор Санта-Клауса: когда PIR-датчик замечает движение перед камином, играет Jingle Bells; сборка описана в статье Детектор Санта-Клауса.
- Музыкальная ёлка: пока звучит песня, цвета на ленте WS2812B меняются в такт нотам; как собрать саму ёлку, смотри в статье Светодиоды для новогодней ёлки.
- Мелодия в полночь: когда новогодний таймер обратного отсчёта дойдёт до нуля, пусть звучит We Wish You a Merry Christmas.
- Дверной звонок: весь декабрь при нажатии кнопки звонка вместо обычного «динь-дон» играет первая строка Deck the Halls.
- Кнопочное пианино: сыграй эти ноты своими руками на восьми кнопках; схема и код — в статье Пианино на Arduino. Больше сезонных идей — в подборке Рождественские проекты на Arduino.
Если хочется сыграть первую мелодию на зуммере, бесплатные проекты с зуммером в приложении BlueGrays проведут от первого писка до управления частотой и полной мелодии государственного гимна; в каждом есть схема подключения, пошаговая сборка и готовый к запуску код. С навыками, полученными там, четыре рождественские песни из этой статьи легко добавить в свою музыкальную шкатулку или рождественскую открытку.
Частые вопросы
Как сыграть Jingle Bells на Arduino?
Подключи вывод + пассивного зуммера к D8, а второй вывод — к GND, затем запиши частоты нот в один массив, а их длительности — в другой. В цикле для каждой ноты вызывай tone(8, частота, длительность) и жди delay(длительность). Припев начинается с Ми Ми Ми, Ми Ми Ми, Ми Соль До Ре Ми, а при 120 BPM восьмая длится 250 мс.
Может ли активный зуммер играть рождественские песни?
Нет. Внутри активного зуммера генератор с фиксированной частотой, и он пищит на одной высоте, что бы на него ни подавали. Для мелодий нужен пассивный зуммер, пьезодиск или маленький динамик, управляемый через транзистор.
Как пользоваться функцией tone() в Arduino?
tone(пин, частота) выдаёт на пин меандр с заполнением 50% и звучит, пока не будет вызвана noTone(пин). Если передать третьим аргументом миллисекунды, звук сам прекратится по истечении этого времени. На Uno tone() использует Timer2, поэтому во время звучания ШИМ на D3 и D11 не работает.
Как сделать зуммер громче?
Самый действенный способ — управлять NPN-транзистором с пина через резистор 1 kΩ и питать через транзистор маленький динамик от 5 V. Без транзистора тоже помогает перенос мелодии на октаву выше, ведь пьезозуммеры громче всего звучат около 2–4 kHz. Звук усиливается и если поместить зуммер в замкнутый объём, например в коробку.
Может ли Arduino делать что-то ещё, пока играет песня?
Пока играет мелодия, написанная с delay(), Arduino больше ничего делать не может. Если проверять окончание каждой ноты через millis(), loop() возвращается без ожидания, и опрос кнопок, управление светодиодами или чтение датчиков продолжают работать, пока звучит песня.
Есть ли tone() у Raspberry Pi Pico?
В MicroPython нет tone(), но ту же работу делает machine.PWM. У объекта PWM(Pin(15)) нота задаётся через freq(частота), а заполнение 50% — через duty_u16(32768); duty_u16(0) выключает звук. Частоты нот точно такие же, как на Arduino.
Что собрать после прочтения
Все проекты
Работа с зуммером
Интересно, как дверной звонок или сигнализация издают звук? Arduino заставляет маленький зуммер пищать через короткие промежутки: пик, пауза, пик, пауза. Ты видишь, как электричество превращается в зв

Настройка частоты зуммера
Ты управляешь звуком зуммера четырьмя кнопками: одна включает звук, другая выключает, а две оставшиеся делают его выше или ниже. Удерживай кнопку вверх или вниз, и высота звука меняется шаг за шагом,

Гимн Турции на зуммере
Нажми кнопку, и маленький зуммер начнёт нота за нотой играть Государственный гимн Турции. Arduino играет каждую ноту нужной высоты и длительности, исполняет два куплета гимна от начала до конца и ждёт

Мелодии с ИК-пультом и зуммером
Собери музыкальную шкатулку, которая играет мелодии по кнопкам пульта от телевизора. Инфракрасный приёмник ловит сигнал пульта; одна кнопка играет на зуммере весёлую мелодию из видеоигры, другая — зна

Простое пианино на зуммере и кнопках
Собери своё маленькое пианино из восьми кнопок. Каждая кнопка — одна нота, от низкой к высокой: до, ре, ми, фа, соль, ля, си и верхнее до. Нота звучит через зуммер, пока ты держишь кнопку, и замолкает

Мелодия на зуммере с ESP32
Воспроизведение простой мелодии (Twinkle Twinkle Little Star) на пассивном зуммере. Ноты играются функциями tone() и noTone(), как в Arduino, — ESP32 работает с тем же синтаксисом в Arduino Core 3.0+. Нужен пассивный зуммер (активный мелодию не сыграет).

Тест времени реакции на Arduino со звуковым сигналом: измерь рефлексы в миллисекундах (LCD + зуммер + 3 светодиода)
Насколько быстрые у тебя рефлексы? Нажми кнопку: красный светодиод говорит приготовиться, жёлтый — внимание, и начинается случайное ожидание от 1,5 до 3,5 секунды. Как только загорится зелёный светодиод и пискнет зуммер, нажми снова; время реакции в миллисекундах появится на I2C LCD, а под ним — лучший и средний результат сессии. Нажмёшь до зелёного — на экране TOO EARLY! и звук проигрыша. Удержание кнопки — новый игрок, и у всех одинаковый порядок ожиданий.
Другие статьи
Приложение BlueGrays
Собери эту схему шаг за шагом в телефоне
Схема подключения, код и список деталей на одном экране. 200+ проектов на Arduino, ESP32 и Pico готовы к сборке.
Наведи камеру телефона
Наведи камеру на код — откроется магазин приложений на телефоне.
или открыть магазин

