Музыка на ардуино

Музыкальная шкатулка на Arduino

Наш следующий проект на контроллере Arduino – музыкальная шкатулка. Программный скетч для Ардуино прилагается, так что вы легко сможете добавить свои мелодии, даже не имея больших познаний в программировании Ардуино. Принцип работы устройства очень прост — при открытии шкатулка будет играть приятную мелодию, при закрытии шкатулки воспроизведение мелодии прекращается. Для данного проект потребуется сама плата Arduino и минимум деталей: динамик, потенциометр (переменный резистор), сопротивление на 10кОм, батарейки АА, кнопка и транзистор КТ503А или любой другой маломощный n-p-n транзистор, например КТ315.

Звук – колебательное движение частиц упругой среды, распространяющееся в виде волн в газообразной, жидкой или твёрдой средах. Если сказать просто — это колебания волн. В динамике колеблется мембрана. В зависимости от частоты колебания мы слышим звук разной тональности. От глубины хода мембраны зависит громкость. Управляют мембраной за счёт подаваемого напряжения.
В платах Arduino для вывода звука на динамик используются цифровые или аналоговые выходы. Для воспроизведения мелодии необходимо подавать последовательно звуки определенной частоты и длительности. Для генерации звуков определенной частоты и длительности в Arduino используется функция tone():
tone(pin,frequency,duration);

Функция tone() генерирует на выводе pin прямоугольный сигнал частоты frequency с коэффициентом заполнения 50%. Третий (необязательный) параметр функции duration позволяет задавать длительность сигнала. Если длительность сигнала не указана, звук будет генерироваться до вызова функция noTone().
Обычно в примерах по генерации звуков на Arduino для воспроизведения звука используется пьезоэлектрический излучатель, но к сожалению громкость звука при этом недостаточна. Поэтому Мы для воспроизведения звука мы будем использовать маленький динамик.

В качестве контроллера Arduino я использовал Arduino Pro Mini, которая отличается малым размером и очень удобна при использовании на плате. Можно использовать любую плату Ардуино, например, подойдет наиболее популярная Arduino Uno. Соберем схему, показанную на рисунке 1 (схема соединений на рисунке 2).

Рис. 1. Принципиальная схема музыкальной шкатулкиРис. 2. Схема подключения компонентов к Arduino

Для написания скетча нам понадобятся значения частот для нот 1 и 2 октавы и обозначения для каждой ноты (см. таблицу 1).

Таблица 1. Таблица нот

Теперь подберем мелодию, которую будет воспроизводить музыкальная шкатулка. Желательно найти мелодию, записанную на нотном стане. Я выбрал простую мелодию – «В траве сидел кузнечик» (ноты на рисунке 3).

Рисунок 3. Мелодия «В траве сидел кузнечик» на нотном стане.

Теперь приступим к написанию скетча. Потенциометр в схеме (рисунок 1) присутствует для подбора нужного темпа мелодии. Темп может принимать значения от MIN_TEMPO до MAX_TEMPO. Для вычисления подобранного темпа используем функцию map(), которая преобразует значение на аналоговом входе A0 в значение подобранного темпа.
tempo=map(analogRead(PIN_POT),0,1024,MIN_TEMPO,MAX_TEMPO);

Занесем в массив melody последовательность воспроизводимых нот, список длительностей нот занесем в массив duration, при этом длительность целой ноты равна 32, половинной 16, и т.д. до 1/32 – длительность1. Данные с обозначением нот занесем в массив notes, а данные с частотами для соответствующих нот занесем в массив frequency. Паузу обозначим символом ‘*’.

// МЕЛОДИЯ – массив нот и массив длительностей char melody={‘A’, ‘E’,’A’,’E’,’A’, ‘U’,’G’,’G’,’G’, ‘E’,’U’,’E’,’G’, ‘A’,’A’,’A’,’A’, ‘E’,’A’,’E’,’A’, ‘U’,’G’,’G’,’G’, ‘E’,’U’,’E’,’G’, ‘A’,’A’, ‘H’,’H’,’H’,’H’,’H’, ‘c’,’c’,’c’,’c’,’c’, ‘c’,’H’,’A’,’U’, ‘A’,’A’,’A’,’A’, ‘H’,’H’,’H’,’H’,’H’, ‘c’,’c’,’c’,’c’,’c’, ‘c’,’H’,’A’,’U’, ‘A’, ‘*’ }; int bb={4, 4,4,4,4, 4,4,4,4, 4,4,4,4, 4,4,4,4, 4,4,4,4, 4,4,4,4, 4,4,4,4, 8,8, 4,2,2,4,4, 4,2,2,4,4, 4,4,4,4, 4,4,4,4, 4,2,2,4,4, 4,2,2,4,4, 4,4,4,4, 4,64 }; // массив для наименований нот в пределах двух октав char names={‘c’,’r’,’d’,’s’,’e’,’f’,’t’,’g’,’u’,’a’,’b’, ‘h’,’C’,’R’,’D’,’S’,’E’,’F’,’T’,’G’,’U’,’A’,’B’, ‘H’,’F’}; // массив частот нот int tones={261,277,293,311,329,349,370,392,415,440,466, 494, 523,554,587,622,659,698,740,784,830,880,932,988};

В цикле loop() мы проверяем отжатие кнопки (открытие шкатулки). По отжатию кнопки начинается проигрывание мелодии понотно, вызывая процедуру playNote(), в которую передает обозначение текущей ноты и продолжительность. Процедура playNote() находит по обозначению ноты значение соответствующей частоты и вызывает для проигрывания ноты функцию tone(). Продолжительность звучания ноты – это базовая нотная длительность (32 – для целой, 16 – для полуноты, 8 – для четвертной и т.д.) умноженная на значение темпа произведения – temp. Значение temp устанавливается по значению потенциометра, и подбирается при отладке, в работе не меняется. Для лучшего звучания музыкального отрезка после воспроизведения каждой ноты делаем небольшую паузу delay(beats*tempo+tempo). По нажатии кнопки при воспроизведении мелодии, воспроизведение прекращается. При нажатии клавиш обязательно использовать процедуру проверки на дребезг debounce(boolean last).

Запустим Arduino IDE. Создадим новый скетч и внесем в него содержимое листинга 1.

// МЕЛОДИЯ – массив нот и массив длительностей char melody={‘A’, ‘E’,’A’,’E’,’A’, ‘U’,’G’,’G’,’G’, ‘E’,’U’,’E’,’G’, ‘A’,’A’,’A’,’A’, ‘E’,’A’,’E’,’A’, ‘U’,’G’,’G’,’G’, ‘E’,’U’,’E’,’G’, ‘A’,’A’, ‘H’,’H’,’H’,’H’,’H’, ‘c’,’c’,’c’,’c’,’c’, ‘c’,’H’,’A’,’U’, ‘A’,’A’,’A’,’A’, ‘H’,’H’,’H’,’H’,’H’, ‘c’,’c’,’c’,’c’,’c’, ‘c’,’H’,’A’,’U’, ‘A’, ‘*’ }; int bb={4, 4,4,4,4, 4,4,4,4, 4,4,4,4, 4,4,4,4, 4,4,4,4, 4,4,4,4, 4,4,4,4, 8,8, 4,2,2,4,4, 4,2,2,4,4, 4,4,4,4, 4,4,4,4, 4,2,2,4,4, 4,2,2,4,4, 4,4,4,4, 4,64 }; // подключить динамик к pin 8 #define PIN_SPEAKER 8 // переменные — темп воспроизведения, ноты, длительности int tempo,notes,beats; #define MIN_TEMPO 20 #define MAX_TEMPO 100 // пин подключения потенциометра #define PIN_POT A0 // пин подключения кнопки // при отжатии — включить проигрывание мелодии // при нажатии прекратить // пин подключения потенциометра #define PIN_BUTTON 5 // Переменная для сохранения текущего состояния кнопки int tekButton = LOW; // Переменная для сохранения предыдущего состояния int prevButton = LOW; // Переменная для сохранения количества проигрываний int countPlay = 0; void setup() { // Сконфигурировать контакт динамика как выход pinMode(PIN_SPEAKER, OUTPUT); // Сконфигурировать контакт кнопки как вход pinMode (PIN_BUTTON, INPUT); } void loop() { tekButton = debounce(prevButton); if (prevButton == HIGH && tekButton == LOW) // если отжатие… { // получить темп воспроизведения tempo=map(analogRead(PIN_POT),0,1024,MIN_TEMPO,MAX_TEMPO); for(int i=0;i<sizeof(melody);i++) { notes=melody; beats=bb; if (notes == ‘*’) tone(PIN_SPEAKER,0, beats*tempo); // пауза else playNote(notes, beats*tempo); // воспроизвести ноту // пауза между нотами delay(beats*tempo+tempo); // проверить на нажатие tekButton = debounce(prevButton); if (prevButton == LOW && tekButton == HIGH) } i=sizeof(melody); // если нажатие — прекратить tekButton == LOW; } prevButton = tekButton; // получить темп воспроизведения tempo=map(analogRead(PIN_POT),0,1024,MIN_TEMPO,MAX_TEMPO); } } prevButton = tekButton; } // // процедура проигрыша ноты void playNote(char note, int duration) { // массив для наименований нот в пределах двух октав char names={‘c’,’r’,’d’,’s’,’e’,’f’,’t’,’g’,’u’,’a’,’b’, ‘h’,’C’,’R’,’D’,’S’,’E’,’F’,’T’,’G’,’U’,’A’,’B’, ‘H’,’F’}; // массив частот нот int tones={261,277,293,311,329,349,370,392,415,440,466, 494, 523,554,587,622,659,698,740,784,830,880,932,988}; for (int i = 0; i < sizeof(tones); i++) { if (names == note) { tone(PIN_SPEAKER,tones,duration); } } } // Функция сглаживания дребезга. Принимает в качестве // аргумента предыдущее состояние кнопки и выдает фактическое. boolean debounce(boolean last) { // Считать состояние кнопки, boolean current = digitalRead(PIN_BUTTON); if (last != current) // если изменилось… { delay(5); // ждем 5 мс // считываем состояние кнопки current = digitalRead(PIN_BUTTON); // возвращаем состояние кнопки return current; } }

После загрузки скетча и настройки потенциометром скорости воспроизведения мелодии все упаковываем в шкатулку (рисунки 4, 5, 6) и дарим маме или любимой девушке.

Рис. 4. Собранная схема музыкальной шкатулки

Собранную схему музыкальной шкатулки необходимо поместить в корпус. Для этого я использовал сундучок, купленный в китайском магазине.

Рис. 5. Сундучок — корпус музыкальной шкатулки

Монтажная схема

Соберите схему согласно монтажной схеме.

При подключении динамика к выводам Arduino необходимо использовать токоограничивающие резисторы. Каждый вывод Arduino может выдать ток не более 40 мА (0,04 А). Воспользовавшись законом Ома, вычислим минимальное сопротивление токоограничивающего резистора:

  • U = I * R;
  • R = U / I = 5 / 0,04 = 125 Ом;

Но т.к. динамик имеет также сопротивление(обмотка провода катушки электромагнита), для примера возьмем 8 Ом, то получим минимальное сопротивление токоограничивающего резистора равным:

  • R = 125 — 8 = 117 Ом;

Ближайший номинал резистора равен 150 Ом, его и будем использовать в нашей схеме.

Чтобы регулировать громкость звучания мелодии, воспользуемся переменным резистором на 10 кОм, включив его последовательно с подобранным токоограничивающим резистором. Обратите внимание, что мы используем только крайний и средний вывод потенциометра. Крайний вывод соединен с токоограничивающим резистором, а средний с одним из выводов динамика.

При повороте ручки потенциометра громкость воспроизведения будет изменяться вследствие изменения сопротивления цепи.