Приводим подробное описание программы для Arduino воспроизводящей музыку. Так же, даются основы нотной грамотности, и математические и физические принципы музыкальных нот.
Перечислим концепции лежащие в основе музыкальной программы для Arduino:
- Звуки в электронных устройствах и, в том числе, в Arduino можно извлекать с помощью громкоговорителя (динамика).
- Громкоговоритель создаёт в воздухе звуковую волну, если к нему подвести электрические колебания низкой (звуковой) частоты от генератора.
- Для извлечения звуковым генератором одной ноты, генератор должен выдавать изменяющийся во времени электрический сигнал синусоидальной формы. В крайнем случае, подойдёт электрический сигнал прямоугольной формы. От формы электрического сигнала и его скважности зависит тембр звучания ноты. От частоты повторения импульсов зависит высота тона звука, то есть музыкальная нота.
- Частота повторения электрических импульсов и частота звуковых колебаний воздуха измеряется в Герцах. Но ещё задолго до того как люди научились измерять физические параметры звука, звукам определённой частоты дали названия музыкальных нот. Ноте Ля первой октавы соответствует звуковая волна частотой 440 Гц.
- 1 Гц — это одно колебание в секунду. Человек может слышать звуковые колебания в диапазоне частот от 20 Гц до 20 кГц. Но с возрастом, у человека верхняя граница этого диапазона существенно снижается. Слух животных отличается от слуха человека. Например, слон слышит звуки в более низком диапазоне частот чем человек, а собаки слышат более высокие звуки.
- Колебания воздуха с частотой ниже 20 Гц называются инфразвуком, а колебания с частотой выше 20 кГц называются ультразвуком.
- В программе должны быть предусмотрены команды управления воспроизведением (вперёд, назад, стоп, по номеру, повтор, повтор всего).
- Человек дал названия только семи звукам. Это музыкальные ноты до, ре, ми, фа, соль, ля, си. Но звук с частотой 440 Гц люди считают очень похожим на звук с частотой 880 Гц. Оба звука называют нотой ля. Нота ля с частотой 880 Гц воспринимается на слух более высокой чем нота ля с частотой 440 Гц. Так же обстоят дела и с остальными нотами.
- Весь слышимый нами звуковой диапазон разбит на октавы, содержащие все семь нот. Нота с частотой 440 Гц — это нота ля первой октавы. Но та с частотой 880 Гц — это нота ля второй октавы
Кажется, с концепцией определились.
Возможная техническая реализация.
Длительность ноты.
Пусть WDT (Watchdog) отвечает за длительность ноты. Распишем коды длительностей:
Длительность | Сек | Команда | Код команды | Код 3 бита | Инверсный код |
---|---|---|---|---|---|
1/64 | 0.015625 | WDTCSR = (1 << WDIE ); | 0b01000000 | 000 | 7 |
1/32 | 0 .03125 | WDTCSR = (1 << WDP0) | (1 << WDIE ); | 0b01000001 | 001 | 6 |
1/16 | 0.0625 | WDTCSR = (1 << WDP1) | (1 << WDIE ); | 0b01000010 | 010 | 5 |
1/8 | 0.125 | WDTCSR = (1 << WDP0) | (1 << WDP1) | (1 << WDIE ); | 0b01000011 | 011 | 4 |
1/4 | 0.25 | WDTCSR = (1 << WDP2) | (1 << WDIE ); | 0b01000100 | 100 | 3 |
1/2 | 0.5 | WDTCSR = (1 << WDP0) | (1 << WDP2) | (1 << WDIE ); | 0b01000101 | 101 | 2 |
1 | 1 | WDTCSR = (1 << WDP1) | (1 << WDP2) | (1 << WDIE ); | 0b01000110 | 110 | 1 |
Конец | 111 | 0 |
Табл. 1. Коды длительностей нот.
; ***** WATCHDOG *********************
; WDTCSR - Watchdog Timer Control Register
.equ WDP0 = 0 ; Watch Dog Timer Prescaler bit 0
.equ WDP1 = 1 ; Watch Dog Timer Prescaler bit 1
.equ WDP2 = 2 ; Watch Dog Timer Prescaler bit 2
.equ WDE = 3 ; Watch Dog Enable
.equ WDCE = 4 ; Watchdog Change Enable
.equ WDP3 = 5 ; Watchdog Timer Prescaler Bit 3
.equ WDIE = 6 ; Watchdog Timeout Interrupt Enable
.equ WDIF = 7 ; Watchdog Timeout Interrupt Flag
Лист. 1. Биты регистра WDTCSR микроконтроллера ATmega328
Частота ноты.
Пусть 16-ти битный таймер отвечает за частоту ноты (высоту тона).
В м-к ATmega328 один 16-ти битный таймер-счётчик - это "Timer/Counter1". Timer/Counter1 (ТС1) может работать в режиме генератора частоты.
Таймер-счётчик ТС1 микроконтроллера, работая в режиме СТС (сравнение и сброс таймера при совпадении, один из четырёх режимов), ведёт подсчёт тактовых импульсов до совпадения с числом, заданным программистом в любом из регистров совпадения(OCR1A или OCR1B). В случае совпадения, сигнал, на выходе счётчика меняется на противоположный и счёт начинается сначала. Таймер/счётчик TC1 имеет выходы на порты микроконтроллера PB1 и PB2 (9 и 10 pin Arduino или 15 и 16 pin м-к ATmega328-PU). Таймер-счётчик приводятся в действие от системного тактового генератора, работающего на частоте 16 МГц. Если записать в регистр совпадения 0, Таймер-счётчик делит частоту на входе на 2. Если мы хотим получить с помощью таймера-счётчика, заданную частоту, мы должны записать в 16-ти битный регистр совпадения (OCR1A или OCR1B) коэффициент деления, который можно вычислить по формуле, Формуле. 1.
Формула. 1. Коэффициент деления ТС1,
В datashit на м-к ATmega328 в формуле 1 записано (1+k), но это в нашей задаче не принципиально.
Частота любой музыкальной ноты F может быть вычислена по формуле Ф.2, где N порядковый номер ноты.
Формула. 2. Частота любой музыкальной ноты.
Нота ЛЯ первой октавы имеет порядковый номер 48 и её частота, вычисленная по этой формуле равна 440 Гц. В октаве 7 нот (ДО, РЕ, МИ, ФА, СОЛЬ, ЛЯ, СИ), однако, они распределены по частоте неравномерно. На фортепианной клавиатуре вы видели что есть белые и чёрные клавиши. Белые клавиши мы уже перечислили, это основные ноты. Чёрные клавиши дополняют белые так, что все ноты в октаве, а их теперь 12, распределяются по частоте равномерно, следуя математическому закону по Формуле.2.
Перечислим все 12 нот одной октавы: ДО ДО# РЕ РЕ# МИ ФА ФА# СОЛЬ СОЛЬ# ЛЯ ЛЯ# СИ Знак # читается как диез и ставится на нотной линейке перед нотой или в начале строки. Отменяется знаком бекар ????. Теперь должно быть понятно, что нота ЛЯ второй октавы имеет номер 60 и её частота 880 Гц. Очевидно, что частота двух одноименных нот из соседних октав отличается в ровно 2 раза. Эти ноты воспринимаются на слух, как очень похожие, только одна выше другой. В программе на языке Си для Ардуино, чтобы извлечь желаемую ноту, мы должны будем записать (присвоить) в 16-ти битный регистр совпадения (OCR1A или OCR1B) коэффициент деления вычисленный для этой ноты.
Для автоматизации расчёта коэффициентов деления для всех нот мы воспользовались электронной таблицей Google документы (Можно использовать LibreOffice Calc). В результате получилась таблица табл. 2.
A | B | C | D | E | F | |
---|---|---|---|---|---|---|
1 | № | N | Октава | Нота | F Gz | К дел. |
2 | 1 | 27 | 0 | До | 131 | 61156 |
3 | 2 | 28 | 0 | До# | 139 | 57724 |
4 | 3 | 29 | 0 | Ре | 147 | 54484 |
5 | 4 | 30 | 0 | Ре# | 156 | 51426 |
6 | 5 | 31 | 0 | Ми | 165 | 48540 |
7 | 6 | 32 | 0 | Фа | 175 | 45815 |
8 | 7 | 33 | 0 | Фа# | 185 | 43244 |
9 | 8 | 34 | 0 | Соль | 196 | 40817 |
10 | 9 | 35 | 0 | Соль# | 208 | 38526 |
11 | 10 | 36 | 0 | Ля | 220 | 36364 |
12 | 11 | 37 | 0 | Ля# | 233 | 34323 |
13 | 12 | 38 | 0 | Си | 247 | 32396 |
14 | 13 | 39 | 1 | До | 262 | 30578 |
15 | 14 | 40 | 1 | До# | 277 | 28862 |
16 | 15 | 41 | 1 | Ре | 294 | 27242 |
17 | 16 | 42 | 1 | Ре# | 311 | 25713 |
18 | 17 | 43 | 1 | Ми | 330 | 24270 |
19 | 18 | 44 | 1 | Фа | 349 | 22908 |
20 | 19 | 45 | 1 | Фа# | 370 | 21622 |
21 | 20 | 46 | 1 | Соль | 392 | 20408 |
22 | 21 | 47 | 1 | Соль# | 415 | 19263 |
23 | 22 | 48 | 1 | Ля | 440 | 18182 |
24 | 23 | 49 | 1 | Ля# | 466 | 17161 |
25 | 24 | 50 | 1 | Си | 494 | 16198 |
26 | 25 | 51 | 2 | До | 523 | 15289 |
27 | 26 | 52 | 2 | До# | 554 | 14431 |
28 | 27 | 53 | 2 | Ре | 587 | 13621 |
29 | 28 | 54 | 2 | Ре# | 622 | 12856 |
30 | 29 | 55 | 2 | Ми | 659 | 12135 |
31 | 30 | 56 | 2 | Фа | 698 | 11454 |
32 | 31 | 57 | 2 | Фа# | 740 | 10811 |
33 | 32 | 58 | 2 | Соль | 784 | 10204 |
34 | 33 | 59 | 2 | Соль# | 831 | 9631 |
35 | 34 | 60 | 2 | Ля | 880 | 9091 |
36 | 35 | 61 | 2 | Ля# | 932 | 8581 |
37 | 36 | 62 | 2 | Си | 988 | 8099 |
38 | 37 | 63 | 3 | До | 1047 | 7645 |
39 | 38 | 64 | 3 | До# | 1109 | 7215 |
40 | 39 | 65 | 3 | Ре | 1175 | 6810 |
41 | 40 | 66 | 3 | Ре# | 1245 | 6428 |
42 | 41 | 67 | 3 | Ми | 1319 | 6067 |
43 | 42 | 68 | 3 | Фа | 1397 | 5727 |
44 | 43 | 69 | 3 | Фа# | 1480 | 5405 |
45 | 44 | 70 | 3 | Соль | 1568 | 5102 |
46 | 45 | 71 | 3 | Соль# | 1661 | 4816 |
47 | 46 | 72 | 3 | Ля | 1760 | 4545 |
48 | 47 | 73 | 3 | Ля# | 1865 | 4290 |
49 | 48 | 74 | 3 | Си | 1976 | 4050 |
Табл. 2. Коэффициенты деления для всех нот.
В табл. 2 в ячейку E2 мы вставили формулу =ОКРУГЛТ(27,5*2^(B2/12); 1) и растянули её на всю колонку E. В ячейку F2 мы вставили формулу =ОКРУГЛТ(8000000/(27,5*2^(B2/12)); 1) и растянули её на всю колонку F.
На основании табл. 2 мы можем составить массив коэффициентов деления {61156, 57724, 54484, 51426, 48540, 45815, 43244, 40817, 38526, 36364, 34323, 32396, 30578, 28862, 27242, 25713, 24270, 22908, 21622, 20408, 19263, 18182, 17161, 16198, 15289, 14431, 13621, 12856, 12135, 11454, 10811, 10204, 9631, 9091, 8581, 8099, 7645, 7215, 6810, 6428, 6067, 5727, 5405, 5102, 4816, 4545, 4290, 4050}.
С таким же успехом, можно использовать 12 коэффициентов деления, но тогда прерывания будут выполнятся дольше, за счёт лишних операций по вычислению коэффициентов деления.
Замечание, так как мы планируем использовать в любом музыкальном произведении только 31 ноту (2,5 октавы), то у нас будет необходимость транспонировать, повышать или понижать тональность произведения, что мы легко сможем сделать сдвигая цифры в колонке A вверх или вниз.
Управление таймером-счётчиком TC1.
void setup() {
// инициализация Timer/Counter-1
pinMode (9, OUTPUT); // PB1/OC1A как Output порт
TCCR1A = 0;
TCCR1B = 0;
TCCR1B &= ~((1 << CS10) | (1 << CS11) | (1 << CS12)); // Таймер остановлен.
TCCR1B |= (1 << WGM12); // CTC режим.
TCCR1A &= ~((1 << COM1A1) | (1 << COM1A0) | (1 << COM1B1) | (1 << COM1B0)); // Порты PB1/PB2 от OC1A/OC1B отключены.
TCCR1A = TCCR1A & ~(1 << COM1A0) | (1 << COM1A1); // Порт PB1 подключен к OC1A и обнуляется при совпадении.
TCCR1A = TCCR1A & ~(1 << COM1A1) | (1 << COM1A0); // Порт PB1 подключен к OC1A и инвертируется при совпадении.
OCR1A = 18182; // установка регистра совпадения. Нота Ля 440 Гц.
TCCR1B |= (1 << CS10); // запуск с таймера с делителем на 1.
}
void loop() {
}
Лист. 2. Программное управление таймером счётчиком TC1.
Рис. 1. Осциллограмма снятая на 9 ножке платы Arduino Nano.
Принципиальная электрическая схема.
В программе лист. 2 мы организовали подключение выхода таймера-счётчика TC1 на порт микроконтроллера PB1, который, в свою очередь, подключён к pin 9 платы Arduino NANO или UNO.
Рис. 2. Принципиальная электрическая схема музыкального автомата.
На принципиальной электрической схеме рис. 2 однокаскадный импульсный усилитель на транзисторе 2N2222 своим входом подключён к pin 9 платы Arduino, а нагрузкой этого усилителя является высокоомный динамик. У транзистора 2N2222 типичный коэффициент усиления по току в схеме с общим эмиттером равен 300. В ключевом режиме работы ток коллектора транзистора примерно равен 5/30=0,16 Ампер. Где 5 Вольт напряжение питания схемы, а 30 Ом сопротивление динамика. Сопротивлением открытого транзистора можно пренебречь. Для полного открывания транзистора ток базы этого транзистора должен быть не менее 0,16/300=0,00055 Ампер. Где 0,16 Ампер ток коллектора транзистора, а 300 коэффициент усиления по току. Ограничивающий ток базы резистор должен быть не более 4,5/0,00055=8100 Ом. Где 4,5 Вольт напряжение единичного импульса на выходе микроконтроллера.
Например, Вы не нашли высокоомный динамик, типичное сопротивление маломощных динамиков 8 Ом, и такой у Вас есть. Задача: рассчитать сопротивление резистора в цепи базы транзистора. 5/8=0,625А. 0,625/300=0,002А. 4,5/0,02=2160 Ом.
Нотная грамотность.
Хороший программист, создавая свой программный продукт для целей автоматизации какого либо рода деятельности человека в производстве, науке или искусстве должен разбираться в этой области на уровне специалиста. Создавая программу музыкального автомата, программист должен, как минимум, изучить музыкальную нотацию. Не плохо было бы подтянуть себя по сольфеджио.
Рис. . Основы музыкальной нотации.
Размещение массива данных в Flash-памяти м-к.
Если хранить коды нот в динамической памяти, то мы сможем записать в м-к всего 1-2 мелодии. Flash память программ в м-к может хранить в десятки раз больше мелодий, но доступ к данным в Flash памяти специфичен. Перепишем программу лист. 4 так, что-бы массивы данных размещались в Flash памяти.
В пьесе Генрика Ибсена «Пер Гюнт» под эту мелодию Грига, Горный Король и его тролли вступают в Тронную пещеру Горного Короля. Действие происходит в мистической, таинственной атмосфере.
Музыкальный автомат, исполняющий мелодию, собран на Arduino Nano v.3 ядром которой является микроконтроллер ATMEL ATmega328P AU. Музыкальный автомат так же содержит усилитель на транзисторе 2N2222 включённом по схеме с общим эмиттером. В коллектор транзистора включён громкоговоритель с сопротивлением постоянному току 30 Ом. Громкоговоритель (динамик) помещён в ракушку рапана и приклеен к ней термоклеем так, чтобы не было щелей. Ракушка рапана используется нами не только как декоративный элемент. Динамик в ракушке представляет из себя акустическую колонку. Звук в такой акустической системе получается мягче и существенно громче.
Рис. 1. Принципиальная электрическая схема музыкального автомата.
Рис. 2. Акустическая система (колонка) собранная из громкоговорителя и ракушки рапана.
Рис. 3.Фрагмент Сюиты Эдварда Грига “В пещере Горного Короля”.
Программа для музыкального автомата разработана на языке C в среде Arduino.
#define si3 OCR1A=4050;
#define lad3 OCR1A=4290;
#define la3 OCR1A=4545;
#define sod3 OCR1A=4816;
#define so3 OCR1A=5102;
#define fad3 OCR1A=5405;
#define fa3 OCR1A=5727;
#define mi3 OCR1A=6067;
#define red3 OCR1A=6428;
#define re3 OCR1A=6810;
#define dod3 OCR1A=7215;
#define do3 OCR1A=7645;
#define si2 OCR1A=8099;
#define lad2 OCR1A=8581;
#define la2 OCR1A=9091;
#define sod2 OCR1A=9631;
#define so2 OCR1A=10204;
#define fad2 OCR1A=10811;
#define fa2 OCR1A=11454;
#define mi2 OCR1A=12135;
#define red2 OCR1A=12856;
#define re2 OCR1A=13621;
#define dod2 OCR1A=14431;
#define do2 OCR1A=15289;
#define si1 OCR1A=16198;
#define lad1 OCR1A=17161;
#define la1 OCR1A=18182;
#define sod1 OCR1A=19263;
#define so1 OCR1A=20408;
#define fad1 OCR1A=21622;
#define fa1 OCR1A=22908;
#define mi1 OCR1A=24270;
#define red1 OCR1A=25713;
#define re1 OCR1A=27242;
#define dod1 OCR1A=28862;
#define do1 OCR1A=30578;
#define si0 OCR1A=32396;
#define lad0 OCR1A=34323;
#define la0 OCR1A=36364;
#define sod0 OCR1A=38526;
#define so0 OCR1A=40817;
#define fad0 OCR1A=43244;
#define fa0 OCR1A=45815;
#define mi0 OCR1A=48540;
#define red0 OCR1A=51426;
#define re0 OCR1A=54484;
#define dod0 OCR1A=57724;
#define do0 OCR1A=61156;
#define d2 delay(1000);
#define d4 delay(500);
#define d8 delay(250);
#define d16 delay(125);
#define p8 TCCR1B = 0b00001000;delay(250);TCCR1B = 0b00001001;
#define p64 TCCR1B = 0b00001000;delay(7);TCCR1B = 0b00001001;
void setup() {
pinMode (9, OUTPUT);
pinMode (10, OUTPUT);
TCCR1A = 0b01010000;
//TCCR1B = 0b00001010; // Делитель на 8, на выходе 1.000 MGz
TCCR1B = 0b00001001; // Делитель на 0, на выходе 8.000 MGz
DDRD = 0b11111111;
mi0 d8 fad0 d8 so0 d8 la0 d8 si0 d8 so0 d8 si0 d4
lad0 d8 fad0 d8 lad0 d4 la0 d8 fa0 d8 la0 d4
mi0 d8 fad0 d8 so0 d8 la0 d8 si0 d8 so0 d8 si0 d8 mi1 d8
re1 d8 si0 d8 so0 d8 si0 d8 re1 d2
mi1 d8 fad1 d8 so1 d8 la1 d8 si1 d8 so1 d8 si1 d4
lad1 d8 fad1 d8 lad1 d4 la1 d8 fa1 d8 la1 d4
mi1 d8 fad1 d8 so1 d8 la1 d8 si1 d8 so1 d8 si1 d8 mi2 d8
re2 d8 si1 d8 so1 d8 si1 d8 re2 d2
PORTD = 0b00000000;
TCCR1B = 0b00001000; // Осанов
digitalWrite (9, LOW);
digitalWrite (10, LOW);
pinMode (9, INPUT);
pinMode (10, INPUT);
}
void loop() {
}
Рис. 4. Листинг программы для светомузыкального автомата на Arduino
Скетч использует 2152 байт (7%) памяти устройства. Всего доступно 30720 байт. Глобальные переменные используют 9 байт (0%) динамической памяти, оставляя 2039 байт для локальных переменных. Максимум: 2048 байт.
Массив кодов нот песенки Jingle Bells, не содержит повторяющихся частей. Но, практически, любая песня содержит куплет и припев и, как правило, ноты всех куплетов не отличаются друг от друга, а у припева, и подавно.
Рис. 4.
Рис. 5.