А знакома ли вам, уважаемые читатели данного блога, вот эта статья?
Квартирный звонок для своих
Быть может попадалась она вам на глаза среди бескрайних информационных просторов Дзена, быть может вы даже её бегло проглядывали?
Давно публиковалась она на канале, почти год назад. Много событий прошло с тех пор.
Сейчас даже кажется, что было это так же давно, как и штормящие 90-е, из которых родом та самая микросхема УМС для проигрывания простых мелодий.
И вот вспомнились недавно мне комментарии одного из читателей той статьи, Александра Тепаева, где упоминались им более современные технологии и захотелось из 90-х прыгнуть сразу на 15 или даже 20 лет вперёд.
Пусть хотя бы мысленно и пусть сегодня будет за окном не опустевшая от потоков машин и людей притихшая улица с редкими прохожими, передвигающимися короткими перебежками в режиме самоизоляции, а год 2005-й или 2007-й.
Чем же были интересны именно те годы? Да хотя бы тем, что о кризисе 2008-го тогда и не знали, равно как и о жарком лете пожаров 2010-го, или о долларе по 72 в декабре 2015-го или по 75 в прошлом месяце. Да и коронавирус-2020, вырвавшийся в мир на исходе 2019-го, что обрушил мировую экономику и более-менее привычный размеренный уклад жизни миллиардов людей на планете тогда тоже предвидеть мало кто мог.
А ещё год 2005-й примечателен тем, что именно в нём появилась технология с причудливым заморским названием ‒ Arduino.
Диковинное экзотическое слово, что-то жаркое, солнечное, небесно-синее, средиземноморское, игрушечное.
Вспоминается песенка из детского кинофильма, где длинноносый паренёк под заверения местных жуликов стремился сказочно разбогатеть, посадив несколько золотых в ямку, приговаривая заклинания "крекс-пекс-фекс" и надеясь купить потом папе-шарманщику новую куртку.
Кубики-модули электронного конструктора, минимум пайки и никакого травления печатных плат, цветные проводки да металлические скобочки для плат беспаечных-макетных. Никаких мудрёных программаторов и священнодействий с FUSE-битами.
Для серьезных электронщиков это всё несерьёзно, так, чепуха какая-то, развлечение для детей и школьников.
Многие до сих пор к технологии этой так и не привыкли, кого-то просто коробит название, кто-то относится вообще с пренебрежением.
Быть может просто не принимая во внимание, что на каждой подобной плате стоит поистине удивительная микросхема, можно сказать одно из достижений технического прогресса последних десятилетий, называемая довольно обыденно "микроконтроллер", применений которому в сегодняшней жизни трудно перечесть.
А вся технология с таким детским "Буратино"-итальянским названием рассчитана на максимально простое, дешёвое, быстрое и доступное освоение навыков для работы с подобными микроконтроллерами.
И не спрашивайте меня, почему я вдруг решил воспроизвести функциональность квартирного музыкального звонка с микросхемой из 90-х на элементной базе и по технологиям 2005-го. В сущности, почему бы и нет? Тем более, что времени на это, по крайней мере сегодня, у меня, как и у многих из нас, достаточно. И пока ещё можно тратить его, изучая что-то новое.
Статья для всех, кто изучает микроконтроллеры и учится их программировать. Для всех, кому это интересно. Каких-либо открытий и инноваций здесь нет, за исключением собственного полученного практического опыта.
Я постараюсь воспроизвести алгоритм работы устройства, как можно ближе к оригинальному.
Отличий будет всего два:
‒ Первое ‒ связано с возможностями Arduino, можно будет менять репертуар, дополняя прошивку новыми мелодиями по желанию.
‒ Второе ‒ конструкция будет реализована только в виде тестового стенда, собирать её окончательно я не буду. Так как есть ещё кое-какие задумки относительно неё, да и потом, зачем мне ещё один квартирный звонок?
1. По традиции немного скучной теории
Когда я только решил научиться извлекать из модуля Arduino какие-либо звуки я предположить не мог, насколько это окажется и простым и трудным делом одновременно.
Простым, потому что в Bascom-AVR, демонстрационную версию которого я использую для написания программ для Arduino, есть простая специальная команда
Sound Имя_порта, Длительность, Нота
Она предназначена для извлечения из микроконтроллера Arduino звука определенной тональности.
Казалось бы, чего проще, назначай нужный порт и выводи на него последовательность нот любимых мелодий.
Но на практике дело обстоит немного сложнее.
В отличие от других языков программирования Длительность и Нота в Bascom-AVR измеряются в абстрактных "попугаях", это просто числа размерностью в два байта, принимающие значения от 1 до 65535.
Более того, и длительность и частота извлекаемой ноты зависят от частоты тактового генератора микроконтроллера, для разных частот кристалла одинаковые значения "попугаев" будут звучать по разному.
В Интернете достаточно информации по данному вопросу, на сайте MSC Electronics [разработчика Bascom-AVR] я нашёл старинную, от 2007 года, статью Василия Рубашки
AN #155 - Digital Melody Player - Simple digital melody player for AVR
Статья очень подробная и основательная, поэтому решил опираться на неё и использовать в качестве базовой.
Как указано в статье, при расчете параметров команды Sound в Bascom-AVR для получения ноты нужной длительности и частоты используются следующие формулы:
Sound Speaker, Pulses, Periods
, где
Speaker ‒ порт для генерации звука
Pulses ‒ продолжительность звука (1-65535)
Periods ‒ частота звука (1-65535)
Periods = Abc[F_crystal / (k * F_nota)]
Pulses = Abc[(T_period * F_crystal) / (k * Periods)]
, где
F_crystal ‒ тактовая частота микроконтроллера, Гц
F_nota ‒ частота ноты, которую нужно получить, Гц
k = 12 ‒ константа, количество тактов, для которых формируется один период звучания
T_period ‒ длительность звучания, которую нужно получить, в секундах
Abc ‒ функция округления [усечения?] до целого числа
Вроде бы формулы несложные, но пересчитывать ноту за нотой слишком уж трудоёмко.
Вбивать раз за разом числа в табличку Excel для пересчета тоже затруднительно.
Поэтому автор той статьи просчитал необходимые параметры для нот с первой по третью музыкальные октавы самостоятельно и результаты представил в виде готовой таблицы.
Застали таблицы Брадиса в школе на уроках тригонометрии? Пользовались ими? Вот и мне немного напомнило, только данной таблицей пользоваться гораздо проще. Только знай, подставляй значение нужной ноты и ее длительности и получай параметры команды Sound.
Таблица рассчитана для микроконтроллера ATmega8, работающего на тактовой частоте 8 мГц.
Для ещё большего облегчения задачи автор представил готовые результаты в виде кодировки нескольких мелодий, и приложил также целую кучу популярных мелодий в кодировке монофонических рингтонов для старинных уже телефонов Siemens.
Мне захотелось повторить этот путь на практике, но для начала пришлось задуматься об "аппаратной составляющей" и собрать нужную схему.
2. "Железо" тестового стенда
Там же, в вышеуказанной статье, приведена простейшая схема для извлечения звука из микроконтроллера.
Она состоит из громкоговорителя и включенного последовательно с ним токогасящего резистора на 100 Ом, подключенных к выходу порта.
В документации по Bascom-AVR также приводится схема с включением в эту цепь электролитического конденсатора на 100 мкФ, для развязки по постоянному току.
Прикинем, очень приблизительно и грубо параметры схемы.
При напряжении логической 1 приблизительно в 4.2 Вольта на выходе порта и сопротивлении громкоговорителя 8 Ом, максимальный ток, протекающий через порт равен 4.2 В / 108 Ом = 38.9 мА. Это очень близко к предельно допустимому для отдельного порта значению в 40 мА.
Используем более безопасный резистор сопротивлением 180 Ом.
Тогда ток в цепи равен 4.2 В / 188 Ом = 22.3 мА
При таком токе на громкоговорителе будет падать 22.3 мА * 8 Ом = 178.4 милливольт.
Выходная мощность громкоговорителя при этом будет составлять 4 мВт, основная часть напряжения упадет на резисторе.
Чтобы повысить громкость и не подвергать опасности порт Arduino можно использовать дополнительный транзистор в качестве усилителя.
Я вспомнил старую схему квартирного звонка на УМС, и сделал аналогично.
При этом для регулировки уровня громкости сигнал на транзистор будет подаваться через потенциометр, переменный резистор сопротивлением 1 кОм.
Транзистор понадобится биполярный, кремниевый, структуры NPN.
Использовал BC547, но, в сущности, подойдет любой аналогичный малой или средней мощности. Например KT315, KT312 или KT3102.
Надо только соблюдать цоколевку при подключении.
Для включения-выключения "шарманки", а также для выбора нужной мелодии понадобится пара тактовых кнопок.
Кнопки будем подключать к портам PB2 и PB3 микроконтроллера.
Вместе с кнопками будем использовать два стандартных подтягивающих резистора по 10 кОм каждый.
Ещё понадобится пара кремниевых диодов для организации прерываний при опросе кнопок.
Тоже практически любые, что найдутся под рукой, хоть 1N4148, хоть 1N4001, хоть старые советские, например КД521.
Про диоды и прерывания расскажу подробнее позже.
Схема электрическая принципиальная нашей конструкции будет выглядеть так.
Ну а так как мы используем не столько микросхему микроконтроллера, сколько плату Arduino с ним, для большего удобства пригодится вот эта схема распиновки контактов, с сайта Распиновка платы Ардуино Нано (Arduino Nano Rev3.2) + схема
3. Сборка тестового стенда
Для сборки тестового стенда нам понадобятся следующие комплектующие и компоненты:
- Громкоговоритель мощностью 1‒3 Вт, сопротивлением 8 Ом, какой найдётся, главное, чтобы звучал приятно и не слишком искажал звук.
Для удобства подключения к плате я припаял к выводам громкоговорителя пару проводов с разъемами-иголками на концах.
Для защиты и сохранности диффузора громкоговорителя при отладке и сборке конструкции раньше мы завязывали их в тряпочку, сейчас завязал его в натянутый кусочек целлофана.
- Соединительный кабель USB ‒ mini USB для загрузки программ в Arduino с компьютера
- При небольшой громкости подавать питание на плату можно от USB-разъема компьютера через этот же кабель, прямо на плату Arduino, но лучше всё-таки не рисковать защитным диодом платы Arduino и по окончании прошивки питать схему от дополнительного переходника с USB-разъемом и пятью контактами. Или от чего-то подобного.
- Беспаечная макетная плата MB-102 или аналогичная, главное, чтобы количества контактных посадочных отверстий хватило
- Маломощный кремниевый биполярный транзистор, проводимости NPN, например BC547, KT315, КТ312, KT3102
- Переменный резистор сопротивлением 1 кОм
- Постоянные резисторы, один на 180 Ом, и две штуки по 10 кОм каждый
- Две тактовых кнопки
- Два кремниевых импульсных диода, например 1N4148, 1N4001, или КД521
- Ещё один соединительный провод с игольчатыми разъемами на обоих сторонах
- Прямоугольные скобки для соединения деталей на макетной плате
Соединительный провод с игольчатыми разъемами можно заменить отрезком обычного многожильного монтажного провода, залудив и толсто пропаяв зачищенные концы.
Прямоугольные скобки при необходимости можно согнуть и отрезать, отмерив по длине, из цветных скрепок из нержавеющей стали, продающихся в канцтоварах или любом киоске, в пластиковой изоляции или крашеных. Отогнутые концы нужно будет зачистить от изоляции или краски. Пользоваться вполне можно, только они немного жёсткие. Если не считать ручной работы, стоить это будет в несколько раз дешевле, чем покупать набор готовых скобок. Только нужно подобрать их по толщине отверстий беспаечной макетной платы.
Также прямоугольные скобки удобно делать из медного обмоточного провода диаметром 0.75 мм. Снять с него эмалевую изоляцию, хорошо зачистив, залудить припоем в сосновой канифоли, отрезать и согнуть концы под прямым углом. Он более мягкий, чем скрепки.
Кроме скобок отрезки такого медного облуженного провода удобно припаивать к выводам отдельных деталей, например к переменному резистору, чтобы закрепить его на плате.
Монтажная схема соединений деталей и компонентов, сделанная в программе Fritzing выглядит так. [Скачать монтажную схему в формате PDF]
А собранный по этой схеме тестовый стенд выглядит так.
При повторении сборки обращайте, пожалуйста, внимание на правильность подключения элементов к шинам питания. Макетная плата в программе Fritzing шины питания маркирует красно-синими цветами в другом порядке, по сравнению с моей платой, произведенной в Китае. Неизменным должен остаться принцип: синий ‒ минус, красный ‒ плюс. Так на своей плате и подключайте.
4. Программа первая моя, ...звуковая
Настала пора опробовать собранный тестовый стенд в работе. Для начала просто погудим.
Для этого выставим регулятор громкости в среднее положение.
Подключим Arduino к USB-порту компьютера с помощью кабеля.
Если Вы используете китайскую версию Arduino и если на компьютере корректно установлены драйвера для CH340, то в диспетчере устройств Windows должен появиться дополнительный COM-порт.
В редакторе Bascom-AVR наберём вручную или скачаем исходный код программы первого примера.
Если на вашем устройстве текст программ на скриншотах читается не слишком отчетливо, можно открыть увеличенную картинку, просто щёлкнув на ней мышью. Или открывать такие картинки в соседней вкладке браузера.
Откомпилируем и загрузим код в Arduino.
Как компилировать программы в Bascom-AVR и загружать полученную прошивку в Arduino можно подробно прочитать в этой статье:
Про температурные датчики MTH02, их функциональные аналоги и Arduino
Если предыдущие шаги выполнены правильно, после передачи прошивки в Arduino в громкоговорителе должен прозвучать короткий гудок.
Так же разово и коротко схема должна гудеть при повторной прошивке или при определении модели микроконтроллера. И при подаче напряжения питания тоже.
Если гудит исправно ‒ можно приступать к следующим шагам.
Если не гудит, но прошивка в Arduino уходит без ошибок - разбираемся с исправностью деталей и со схемой соединений, скорее всего что-то напутали при сборке схемы.
Если прошивка идет с ошибками, разбираемся со шнуром подключения и драйверами на компьютере, проверяем порт в диспетчере устройств и настройки Bascom-AVR, описанные в вышеупомянутой статье.
Если сообщения об ошибках выдаются в процессе компиляции ‒ ищем и исправляем их в тексте программы.
5. А что именно я слышу?
Как только из громкоговорителя раздались первые гудки, я не удержался и сразу же загрузил в Bascom-AVR коды из статьи, а именно отрывок мелодии Europe ‒ Final Countdown. Прямо как есть, один к одному. Помню эту песню из 90-х.
'Europe :: Final Countdown
Sound Speaker , 124 , 675 'H2(1/16)
Sound Speaker , 110 , 758 'A2(1/16)
Sound Speaker , 248 , 675 'H2(1/8)
Waitms 125 'P(1/16)
Sound Speaker , 165 , 1011 'E2(1/8)
Waitms 250 'P(1/8)
Waitms 125 'P(1/16)
Sound Speaker , 131 , 637 'C3(1/16)
Sound Speaker , 124 , 675 'H2(1/16)
Sound Speaker , 131 , 637 'C3(1/16)
Waitms 125 'P(1/16)
Sound Speaker , 124 , 675 'H2(1/16)
Waitms 125 'P(1/16)
Sound Speaker , 220 , 758 'A2(1/8)
Waitms 125 'P(1/16)
Waitms 250 'P(1/8)
Sound Speaker , 131 , 637 'C3(1/16)
Sound Speaker , 124 , 675 'H2(1/16)
Sound Speaker , 262 , 637 'C3(1/8)
Waitms 125 'P(1/16)
Sound Speaker , 165 , 1011 'E2(1/8)
Waitms 250 'P(1/8)
Waitms 125 'P(1/16)
Sound Speaker , 110 , 758 'A2(1/16)
Sound Speaker , 98 , 850 'G2(1/16)
Sound Speaker , 110 , 758 'A2(1/16)
Waitms 125 'P(1/16)
Sound Speaker , 98 , 850 'G2(1/16)
Waitms 125 'P(1/16)
Sound Speaker , 92 , 901 'Fis2(1/16)
Waitms 125 'P(1/16)
Sound Speaker , 110 , 758 'A2(1/16)
Waitms 125 'P(1/16)
Sound Speaker , 196 , 850 'G2(1/8)
Wait 2
Но здесь она проигралась настолько быстро, что я даже её не узнал. Пришлось скорректировать длительности нот, замедлив темп в 4 раза. Звучание стало вполне приемлемым, мелодия стала угадываться.
Изменение скорости проигрывания я связал с изменением тактовой частоты микроконтроллера, ведь я компилировал программу под частоту кристалла в 16 мГц. Но тактовая частота микроконтроллера, кроме формулы расчёта длительности, также учитывается и в формуле расчета тональности нот.
Почему же ноты остались узнаваемыми, ведь мелодию мне тоже удалось угадать?
Действительно ли я слышу ноты с нужными частотами или формула расчёта неверна?
Я задумался над этим и не придумал ничего лучше, как просто замерить частоты нескольких нот практически. Для этого подойдет любой частотомер или осциллограф, даже самый простой.
Даже программный USB-осциллографический пробник, подключенный к выходу порта Arduino, вроде такого:
А для проверки пригодится простейшая программа, исходный текст которой можно скачать здесь, выводящая на протяжении десяти секунд ноты Ля первой, второй и третьей октав.
На осциллограммах значение измеренной частоты отображается в левом нижнем углу.
По ним стало понятно, что частоты, указанные в первоначальной таблице при частоте кристалла в 16 мГц уплыли ровно в два раза.
Формула оказалась верна.
А мелодия казалась правильной и угадываемой потому, что двукратное изменение частоты нот смещает музыкальный ряд ровно на одну октаву.
Ля первой октавы - 440 Гц
Ля второй октавы - 880 Гц
Ля третьей октавы - 1720 Гц
Такая вот гармония муз.
На этих осциллограммах и в калибровочной нотной программе частоты и периоды уже подобраны под частоту кристалла 16 мГц.
С длительностями, указанными в таблице, так же не всё оказалось гладко. Поначалу я решил, что длительности даны в долях секунды, 1/1 = 1 секунда. Но в пояснении выше таблицы приводится соотношение 1/1 = 2 секунды. В настоящей же музыке всё, оказывается, устроено ещё круче. Если хотите подробности, то вам сюда и сюда.
Насколько я понял из прочитанного, жёстко к секундам длительность нот вообще не привязана и есть величина относительная.
Но, чтобы как-то всё-таки сориентироваться по времени, есть простой способ.
Произнесите обычным темпом фразу "и-раз-и-два-и-три-и-четыре" и замерьте время, на это потраченное. У меня оно составило 4 секунды.
Таким образом мы получили время для размера такта 4/4.
Многие популярные мелодии сегодняшних дней и прошлых лет имеют именно такой размер.
4/4 ‒ это столько длится целая нота. И уже эту ноту, не секунды, а именно ноту, мы разбиваем на доли: 1/2, 1/4 и т.д.
То есть, если очень упрощенно: нота длится 4 секунды, а 1/4 от неё ‒ секунду. Но для других размерностей такта может быть иначе.
Чтобы не держать в голове все эти поправки на быстродействие кристалла, частоты нот, периоды и длительности я скорректировал исходную таблицу под 16 мГц своей платы Arduino, добавив к ней несколько столбцов. [Скачать таблицу в формате Excel]
По ней, если нужно вычислить длительность звучания в секундах для какой либо частоты, берем значения из столбца голубого цвета, кратно умножая его на нужное количество секунд. А если конвертируем какую либо ноту в долях звучания - ориентируемся на столбцы длительности, расположенные правее.
Впрочем, если темп звучания отдельной мелодии покажется вам слишком быстрым или слишком медленным, вы всегда сможете сделать поправку, ориентируясь на один столбец левее или правее. Либо в уме или на калькуляторе разделить-умножить предлагаемое таблицей значение в два раза.
Отдельным моментом идет формирование пауз.
Я решил отказаться от использования для паузы команды Waitms и задействовать для однородности данных ту же команду Sound.
Для этого в параметре использую Period = 100, воспроизводя невоспроизводимый громкоговорителем звук. Это Соль Диез 6-ой октавы.
Если ваш громкоговоритель будет способен его воспроизвести, или вы способны будете его услышать в виде писка на пределе слышимости, попробуйте уменьшить значение периода ещё в два или 4 раза, до 50 или 25.
С учётом данных корректировок и изменений таблицы последовательность команд для воспроизведения мелодии-хита из 90-х группы Europe была пересчитана снова и теперь выглядит так:
'Europe :: Final Countdown
Sound Speaker, 248, 1350 'H2(1/16)
Sound Speaker, 220, 1515 'A2(1/16)
Sound Speaker, 496, 1350 'H2(1/8)
Sound Speaker, 1667, 100 '1/16 - Пауза
Sound Speaker, 330, 2022 'E2(1/8)
Sound Speaker, 3333, 100 '1/8 - Пауза
Sound Speaker, 1667, 100 '1/16 - Пауза
Sound Speaker, 262, 1274 'C3(1/16)
Sound Speaker, 248, 1350 'H2(1/16)
Sound Speaker, 262, 1274 'C3(1/16)
Sound Speaker, 1667, 100 '1/16 - Пауза
Sound Speaker, 248, 1350 'H2(1/16)
Sound Speaker, 1667, 100 '1/16 - Пауза
Sound Speaker, 440, 1515 'A2(1/8)
Sound Speaker, 1667, 100 '1/16 - Пауза
Sound Speaker, 3333, 100 '1/8 - Пауза
Sound Speaker, 262, 1274 'C3(1/16)
Sound Speaker, 248, 1350 'H2(1/16)
Sound Speaker, 524, 1274 'C3(1/8)
Sound Speaker, 1667, 100 '1/16 - Пауза
Sound Speaker, 330, 2022 'E2(1/8)
Sound Speaker, 3333, 100 '1/8 - Пауза
Sound Speaker, 1667, 100 '1/16 - Пауза
Sound Speaker, 220, 1515 'A2(1/16)
Sound Speaker, 196, 1700 'G2(1/16)
Sound Speaker, 220, 1515 'A2(1/16)
Sound Speaker, 1667, 100 '1/16 - Пауза
Sound Speaker, 196, 1700 'G2(1/16)
Sound Speaker, 1667, 100 '1/16 - Пауза
Sound Speaker, 184, 1802 'Fis2(1/16)
Sound Speaker, 1667, 100 '1/16 - Пауза
Sound Speaker, 220, 1515 'A2(1/16)
Sound Speaker, 1667, 100 '1/16 - Пауза
Sound Speaker, 392, 1700 'G2(1/8)
Wait 2
Чтобы не сильно перегружать вас информацией разрешите ненадолго прерваться.
В следующей части от теории и железа перейдём непосредственно к программированию данной конструкции.
Продолжим программировать музыку!
04 мая 2020 года.
С уважением, Ваш @mp42b.
Предыдущие статьи по данной теме:
1. Про температурные датчики MTH02, их функциональные аналоги и Arduino
2. Arduino, Bascom-AVR и трёхцветный светодиод Piranha. Помигаем? ‒ Тестовый стенд
3. Бегут и переливаются: Arduino, Bascom-AVR и светодиоды WS2812B