Найти тему

"Шарманку" программируете? ‒ Arduino, Bascom-AVR и восемь простых мелодий. Часть 2

Оглавление

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

А сейчас остановимся подробнее на вопросах программирования простых монофонических мелодий посредством Bascom-AVR, исполняемых впоследствии микроконтроллером ATmega328P с платы Arduino.

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

Для удобства повторю табличку расчета параметров команды Sound, пересчитанную под тактовую частоту кристалла 16 мГц. Первоначальный вариант данной таблицы под частоту кристалла 8 мГц приводился в статье Василия Рубашки.

[Скачать таблицу в формате Excel]

-2

И, пожалуй, продолжим...

6. Где брать любимые мелодии?

Музыкантам хорошо ‒ они ноты знают. И даже умеют читать их с листа.

А где же брать мелодии таким дилетантам как я, которым нотная грамота совсем не грамота и, к тому же, и "медведь на ухо наступил"?

Ну, конечно-же, в Интернете!

Ведь скачивали же вы рингтоны для сотовых в начале двухтысячных. А может даже и набирали их вручную, пользуясь причудливой кодировкой.

Давайте попробуем освежить позабытые и почти утерянные знания.

Только необходимо учитывать, что сейчас, всё-таки не 2005-й, и большинства тех сайтов, ломящихся от рингтонов, уже нет, а те, что остались, перешли на сплошную полифонию и на MP3-формат. Нам же нужны монофонические мелодии от сотовых.

В дополнение к мелодиям от Siemens из основательного источника, упоминавшегося в первой части статьи

AN #155 - Digital Melody Player - Simple digital melody player for AVR By Rubashka Vasiliy , Ukraine

из свеженайденного, современного и наиболее информационно-насыщенного, коды монофонических мелодий для сотовых телефонов можно найти, например, здесь: Коды мелодий для Nokia Composer

Или здесь: Монофонические мелодии на телефон Nokia 1100

И даже здесь: Fryazino.NET Forum - Музыка - Мелодии на nokia 3310

Хотя конечно есть и другие подобные сайты, Интернет, ведь большой, словно океан.

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

Источник данного замечательного пояснения: https://habr.com/ru/post/245917/
Источник данного замечательного пояснения: https://habr.com/ru/post/245917/

А, наверное, одно их самых лаконичных и точных, встреченных мной, дополнений такое:

Источник лаконичного и точного дополнения: https://www.cyberforum.ru/audio-soft/thread39030.html
Источник лаконичного и точного дополнения: https://www.cyberforum.ru/audio-soft/thread39030.html

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

А если кого накроет волной ностальгии, то вот ещё:

Nokia - Инструкция по программированию мелодий

Инструкция по вводу мелодий для телефона Nokia

Вооруженный найденными сакральными знаниями я бодро двинулся по всем перечисленным сайтам в поиске тех самых мелодий, заветные коды которых горячо и трепетно набивал в телефон далёкой морозной зимой 2003-го с бумажной распечатки, что давно утеряна в суматохе лет.

Но на пятой просмотренной странице мешанины цифр и букв понял, что дело это гиблое и вспомнил про старенький Nokia 3310, лежавший скромно в шкафу.

-5

Достал, зарядил, включил, зашел в режим синтезатора мелодий.

Все они были там, все семь, целёхонькие, не потускневшие ни на байт.

-6

Несколько минут корпения, пыхтения, внимательности и высовывания языка от усердия и вот они, повторно оцифрованы вручную и представлены на ваше обозрение:

[Символы диеза # здесь заменены на слово "Диез", так как Дзен воспринимает решётки как теги].

Modern Talking ‒ Cheri Cheri Lady
8e1 8g1 8a1 8c2 8a1 16- 4a1 16- 8e1 8g1 8a1 8c2 8b1 16- 4b1 16- 8e1 8g1 8a1 8c2 8a1 16- 4a1 16- 8g1 8e1 8e1 16c2 4a1
Mелодия из кинофильма "Игрушка"
8b1 8g2 8Диезd2 8Диезf2 4e2 4- 8b1 8e2 8d2 8d2 4c2 4- 8a1 8Диезf2 8e2 8e2 4Диезd2 4- 8b1 8g2 8Диезf2 8Диезf2 4e2 4- 8e2 8Диезf2 8g2 8b2 4a2 8e2 8b2 8a2 8- 8d2 8a2 4g2 8d2 8a2 8g2 8- 8c2 8g2 4Диезf2 8f2 8g2 8Диезf2 8Диезd2 8Диезf2 2e2
ABBA ‒ Happy New Year
16e1 16f1 16g1 16- 4e2 16e1 16f1 16g1 16- 4d2 16e1 16Диезf1 16Диезg1 16- 8c2 8c2 8c2 16b1 4a1
Мелодия из кинофильма "Буратино"
16b1 16d2 16b1 16d2 16b1 16d2 8e2 4b1 4- 16Диезa1 16b1 16d2 16g2 8b2 16a2 16g2 16Диезf1 16g1 16b1 16d2 8g2 16Диезf2 16e2
16b1 16c2 16b1 16c2 16b1 16c2 8e2 4a1 4- 16Диезg1 16a1 16c2 16e2 8a2 16g2 16Диезf2 16f1 16Диезf2 16a1 16d2 8Диезf2 16e2 16d2
Кино ‒ Пачка сигарет
8c2 8e2 8b2 8a2 8e2 8c2 8c2 8g2 8e2 8c2 8d2 8d2 8a2 8Диезf2 8c2 8b1
8b1 8b2 8a2 8e2 8c2 8c2 8g2 8e2 8b1 8c2 8c2 8a2 8Диезf2 8c2 8b1 8b1
Мелодия из мультфильма "Чунга-чанга"
8a1 8c2 16e2 16- 4e2 8- 8e2 16- 16d2 8e2 8f2 2e2 4- 8a2 8c2 8b1
4b1 8- 8b1 16- 16c2 8d2 8e2 2c2 4- 8a1 8c2 16e2 16- 4e2 8- 8e2
16- 16d2 8e2 8f2 2e2 4- 8a2 8c2 8b1 4b1 8- 8b1 16- 16c2 8d2 8e2
2a1
Кино ‒ Звезда по имени Солнце
8g2 8g2 2e2 4- 8b1 8b1 2b1 4- 8b1 8b1 8d2 8d2 8- 8d2 4d2 4e2
2b1 4- 8b1 8b1 8a1 8a1 8- 8a1 8a1 8a1 8- 8b1 2a1 4- 8a1 8a1
8- 8a1 8a1 8a1 4b1 2a1

7. Конвертация любимых мелодий

По-настоящему, по-айтишному, хорошо бы написать отдельную программу-конвертер, разбирающую код за кодом и одним махом переводящую мелодии из кодировки Nokia Composer в массив параметров команды Sound Bascom-AVR. И это, в общем-то, вполне реально.

Но учитывая, что самих [любимых] мелодий немного, на перевод пары-тройки десятков нот каждой уходит минут по двадцать, а операцию эту проделать нужно всего лишь один раз, я сделал конвертацию вручную.

Вооружился таблицей и...

8e1 ‒ 165, 4044
8g1 ‒ 196, 3402
8a1 ‒ 220, 3030
...
16‒ ‒ 3333, 100
...
8Диезf2 ‒ 370, 1802
...

... И так нота за нотой.

Потом загрузил в Bascom-AVR, прослушал.

Если слишком медленно ‒ откорректировал длительность, поделив пополам.

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

При конвертации и прослушивании немного подкорректировал последовательность мелодии "Звезда по имени Солнце" группы "Кино", добавив короткие паузы между соседними одинаковыми нотами, чтобы они не сливались.

В результате появился вот такой вариант программы. Скачать исходный текст можно отсюда.

-7

Если на вашем устройстве текст программ на скриншотах читается не слишком отчетливо, можно открыть увеличенную картинку, просто щёлкнув на ней мышью. Или открывать такие картинки в соседней вкладке браузера.

Текст программы вполне рабочий, пищит исправно, услаждая слух.

Вот только уместилось в этот файл всего три мелодии, а с четвёртой мелодией Bascom-AVR компилировать код отказался.

Сработало ограничение демонстрационной бесплатной версии, допускающей не более 4096 байт готового кода.

Но идти на поводу ограничений, установленных бездушным алгоритмом ‒ не наш метод.

Приступаем к программной оптимизации.

8. Оптимизация программного кода ‒ попытка номер один.

Если посмотреть на исходный код нашей программы внимательнее, можно видеть, что при меняющихся параметрах нот сама команда Sound повторяется множество раз.

А нельзя ли отделить данные от командного кода, вызывая Sound в цикле и подавая на неё раз за разом очередные параметры?

Получится ли тогда сократить размер программы, уместив в неё и остальные 5 мелодий?

В следующем варианте программы, исходный текст которой можно скачать отсюда, такая попытка была сделана.

-8

Длительности и периоды нот были вынесены в отдельные наборы данных с помощью команды DATA.

Знак процента пришлось добавить к каждому из значений для указания его целочисленности, это синтаксическое требование Bascom-AVR для описания последовательностей данных.

-9

В цикле, своем для каждой из мелодий, эти данные считываются последовательно. Итого в программе получилось 8 циклов, имеющих примерно такой вид:

-10

Команда Lookup считывает из последовательности данных с меткой Delays.. или Notes.. очередное число с порядковым номером, определяемым счётчиком цикла.

Кстати, здесь же появилась возможность ускорять-замедлять мелодию не редактированием данных с длительностями, а командной корректировкой.

Размер кода программы, вмещающий в себя все восемь мелодий уменьшился до 2640 байт. Но в коде ещё остались повторяющиеся конструкции ‒ почти одинаковые циклы, отдельные для каждой мелодии.

Можно ли снизить их количество?

9. Оптимизация программного кода ‒ попытка номер два.

Да, можно.

Я стремился свести восемь повторяющихся программных циклов к одному, но, кажется, в Bascom-AVR отсутствуют конструкции для строчной макроподстановки [по крайней мере найти такие мне не удалось] и получилось это лишь частично.

Данные при этом пришлось представить в виде длинной-длинной последовательности, точнее даже двух.

Одна длинная последовательность для нот, вторая для их длительностей.

Для определения местоположения конкретной мелодии в такой последовательности потребовался ещё один массив данных, содержащий количество нот в нужной мелодии.

-11

И предварительный цикл для расчета начальной и конечной ноты каждого музыкального фрагмента

-12

Обернув основную логику

  • расчета номеров начальной и конечной нот музыкального фрагмента
  • цикла исполнения найденной ноты

ещё одним, внешним циклом, перебирающим номера мелодий от 1 до 8 получим очередной вариант программы, скачать исходный код которой можно здесь.

-13

В нём однократно проигрываются все восемь мелодий друг за другом с двухсекундными паузами между ними.

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

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

10. Беру управление на себя

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

На данном этапе, после завершения отладки программы, отключив предварительно USB-кабель от компьютера, можно будет подключить к тестовому стенду отдельный блок питания, выдающий на выходе напряжение 5 вольт. Для снижения пульсаций и уменьшения наводок желательно добавить на шину питания тестового стенда электролитический конденсатор 1000 мкФ х 16V.

Нам потребуется обработка нажатий всего двух кнопок: кнопки запуска-остановки проигрывания мелодии и кнопки выбора мелодии.

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

Если понятие прерываний для вас является новым, то, для пояснения, наверное, хорошим примером будет сравнить это со звонком вашего телефона.
Представьте, что вы пользуетесь телефоном с неисправным звонком.
В этом случае вам постоянно приходится держать телефон при себе, прикладывая к уху, чтобы удостовериться, что вам кто-то звонит [или не звонит].
На выполнение других дел времени у вас практически не остается, вы заняты прослушиванием телефона беспрерывно.
Осознав это вы относите телефон в ремонт, получаете его исправным и дальше спокойно занимаетесь любимыми делами.
А при необходимости, услышав звонок, вы ненадолго отвлекаетесь на ответ и продолжаете заниматься любимыми делами.
В данном случае звонок телефона ‒ это ваше прерывание.

Аналогично работают и прерывания в микроконтроллере.

В процессе работы микроконтроллера он выполняет бесконечный цикл основной программы.

При поступлении сигнала на определенный вывод [вывод прерывания] происходит активация прерывания.

Микроконтроллер переключается на выполнение подпрограммы обработки прерывания, а завершив её отработку возвращается к выполнению основной программы.

В нашем случае используется прерывание INT0, именно поэтому тактовые кнопки подключены через развязывающие диоды к порту PD2 микроконтроллера [выводу D2 платы Arduino]. При замыкании какой-либо кнопки на катоде одного из диодов устанавливается низкий уровень. На выводе 32 микроконтроллера [вывод порта PD2] возникает сигнал, инициирующий процесс программной обработки прерывания.

О таком способе я когда-то узнал из статьи

Обработка большого количества кнопок на одном прерывании

сайта AVR project ‒ Проекты на микроконтроллерах AVR

Там ещё много подобных полезных идей по работе с микроконтроллерами. Очень хороший сайт, заходите, не пожалеете.

Для настройки прерывания в начале программы используется следующая последовательность команд

'Настройка прерывания по нажатию кнопок
Config PinD.2 = Input 'Вход D2 Int0 - PD2 - вывод D2 Arduino Nano
Config Int0 = Falling 'Прерывание по нисходящему фронту
On Int0 Button 'При возникновении прерывания обращаемся к процедуре обработки с именем Button
Enable Interrupts 'Разрешаем прерывания
Enable Int0

Здесь указана метка процедуры обработки прерывания Button, на которую осуществляется переход при возникновении прерывания.

Немногим ранее конфигурируем выводы портов PB2 и PB3 на входящие сигналы от кнопок

Config PinB.2 = Input 'Кнопка KeyMelodySet для выбора мелодии - PB2 - вывод D10 Arduino Nano
Config PinB.3 = Input 'Кнопка KeyStartStop запуска-остановки проигрывания - PB3 - вывод D11 Arduino Nano

Участок кода для проигрывания отдельной мелодии по указанному номеру вынесен в отдельную подпрограмму PlayMelody.

-14

Основной цикл программы состоит теперь всего из нескольких строк и выглядит так:

-15

А подпрограмма обработки прерывания по нажатию кнопок имеет следующий вид:

-16

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

Полный исходный текст окончательной программы можно скачать по этой ссылке.

-17

И что же останется сделать после её компиляции?

Конечно же слушать!

[В реальности звук более чистый, чем на данном видео, да и качество видео оставляет желать лучшего. Но, что есть ‒ то есть].

А наслушавшись вдоволь ‒ запрограммировать ещё мелодий хороших и разных. Своих, любимых. Теперь вы тоже это умеете.

04 мая 2020 года.

С уважением, Ваш @mp42b.

Предыдущие статьи по данной теме:

1. Про температурные датчики MTH02, их функциональные аналоги и Arduino

2. Arduino, Bascom-AVR и трёхцветный светодиод Piranha. Помигаем? ‒ Тестовый стенд

3. Бегут и переливаются: Arduino, Bascom-AVR и светодиоды WS2812B

4. "Шарманку" программируете? ‒ Arduino, Bascom-AVR и восемь простых мелодий. Часть 1

-18