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



    Меня в свое время очень впечатлил этот пост о создании светомузыкального устройства на микроконтроллере в подарок любимой. И однажды пришло мое время сделать такой подарок. Учитывая отличия от автора упомянутого проекта в навыках и инструментарии; будучи сильно ограничен во времени подготовки (3-4 дня), я пошел другим путем и разработал свое музыкальное устройство для установки в купленную в сувенирном магазине шкатулку. Оно отличается более простой схемой и легкостью изготовления. В статье описываются подробности моего проекта и их мотивация. Осторожно, фотографии (всего около 1Мб).

    Схема



    Как видите, деталей очень мало. Питание в диапазоне +3..+4.8В от трех батареек типа AAA подходит без применения стабилизаторов как микроконтроллеру D1 (PIC16F753), так и усилителю DA1 (TDA7052A). Данная микросхема усилителя является уникальной в своем роде, потому что среди своих аналогов она требует минимальное количество внешних элементов. Применение усилителя мощности необходимо: при попытке подключить выход микроконтроллера напрямую к динамику, достаточную громкость получить не удастся.

    Для работы усилителя необходим конденсатор C1 емкостью 220мкФ. Без конденсатора нельзя: если внутреннее сопротивление источника питания недостаточно мало, то звучать будет тихо и с сильными искажениями. Также необходим конденсатор C4 для развязки аудиосигнала по постоянному току. Подстроечным резистором R2 регулируется громкость. R1 ограничивает диапазон регулировки. Совместно с конденсатором C3 он также образует фильтр низких частот. В принципе C3 можно не ставить. Я поначалу так и хотел сделать, но потом мне показалось, что для уменьшения искажений звука лучше убрать из него ультразвуковые частоты, поставив C3.

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

    Пару слов о выборе микроконтроллера. Самый главный критерий — диапазон напряжения питания. Когда батарея почти разряжена, напряжение на ней проседает до 3В (по 1В на элемент). В свежем же состоянии напряжение может подниматься до +4.8В и даже более. К сожалению, более современные 16-битные микроконтроллеры, имеющие высокую скорость и много памяти, обычно требуют питание в диапазоне +2.7..+3.6В. Чтобы понизить напряжение, пришлось бы применять стабилизатор, причем не любой, а с малым падением напряжения (Low Drop-out), учитывая напряжение на батарее под конец ее службы. Я решил не усложнять. Из контроллеров фирмы Microchip (с ними у меня больше всего опыта и имеется программатор), поэтому, подходят только 8-битные. Также можно было бы использовать 16-битные из серии PIC24F. В следующей музыкальной шкатулке я, наверное, так и сделаю. Все-таки PIC16F753 очень уж тесноват как по скорости, так и по объему памяти. Но зато у него имеется встроенный 9-битный ЦАП, что очень подходит для синтеза звука.

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

    Сборка


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

    Печатную плату я не делал. Дома нет для этого условий, а на заводе заказывать — слишком долго и дорого. Поэтому собирал схему на макетной плате. Удалось вырезать лобзиком кусок платы по размерам шкатулки. Размеры и форма предопределили компоновку деталей. Вот фотка на промежуточных стадиях сборки:

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

    Вид с обратной стороны платы. Как видите, длинные или пересекающиеся соединения выполнены проводом МГТФ, а короткие — обрезанными ножками от конденсаторов и резисторов. После проверки работоспособности схемы на тестовой прошивке можно приступать к разработке и отладке основной программы. Подробнее о ней ниже.

    После того, как прошивка полностью отлажена, отключаем программатор, перепаиваем динамик и ставим выключатель. Последняя проверка.

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

    Прорезаем ножиком дырку для выключателя. Шилом протыкаются дырочки над динамиком. Далее приклеиваем выключатель к картонке и динамик на штатное место платы:

    Окончательный вид открытой шкатулки:


    Программа для PIC и подготовка музыки


    1. Синтез звука

    Имея 9-битный ЦАП, в принципе, можно получить достаточно сложный звуковой сигнал, однако в случае PIC16F753 возможности ограничены из-за малого размера памяти программ микроконтроллера — всего 2048 слов. Как показывает опыт, даже простая программа-проигрыватель, написанная на ассемблере и оптимизированная по размеру кода, занимает около 1000 слов, так что для нот остается совсем немного. И совсем ничего не остается для хранения сэмплов при использовании такого метода синтеза звука, как Wavetable. Использованию же таких мощных методов, как FM-синтез, препятствует недостаточная скорость процессора и отсутствие в нем аппаратного умножителя. Поэтому остается только синтез прямоугольников — симметричных, либо с переменной скважностью. Второй вариант дает некоторое разнообразие тембров — см., например, сборник «This is Tritone 2» (также имеется на Youtube). Этот метод я и реализовал в шкатулке. Удалось реализовать полифонический звук: 4 независимых звуковых канала. Можно управлять громкостью каждого канала.

    Находим частоту, соответствующую нужной ноте, по формуле равномерной темперации: f = 440*2^(n/12), где n — номер ноты в полутонах, n=0 соответствует «ля» первой октавы. Так как у нас 4 канала, то нужно одновременно генерировать 4 сигнала и суммировать их перед выводом. Наиболее распространенное решение — использовать для всех каналов общую частоту дискретизации. При этом процессор через равные промежутки времени вычисляет выходной отсчет для каждого канала. Полученные значения суммируются и подаются на ЦАП.

    Желаемые периоды прямоугольных сигналов, в общем случае, не являются кратными периоду дискретизации. Скажем, для ноты «ля» второй октавы у нас n=12, f=880 Гц. При частоте дискретизации Fs=27777.8Гц каждый период сигнала должен длиться ~31.57 выходных отсчетов, что нереализуемо. Здесь есть три выхода:
    1. Округлить период до целого числа отсчетов. При этом получаемый период будет отличаться от заданного, т.е. музыка будет фальшивить.
    2. Варьировать длительность периода в пределах плюс-минус одного отсчета так, чтобы средний период получаемого сигнала был равен 1/f. С точки зрения теории обработки сигналов это эквивалентно интерполяции методом ближайшего соседа. В результате в звуке возникают существенные негармонические искажения, в спектре появляются пики на посторонних частотах. На слух сигнал просто становится «грязным».
    3. Провести интерполяцию по Шеннону. Этот подход исключает фальшь и дает наилучшее качество звука, но в 8-битных микроконтроллерах неприемлем из-за сложности вычислений.

    Так что на практике можно выбирать между вариантами 1) и 2). Оба они используются при программном синтезе многоканальной музыки на 1-битном звуковом выходе в таких компьютерах, как ZX Spectrum. Я лично предпочитаю вариант 1). При достаточно высокой частоте дискретизации, на не слишком высоких нотах, округление частоты незначительно, и фальшь практически незаметна.

    Частота дискретизации должна быть дольной от тактовой частоты процессора и достаточно низкой, чтобы процессор успел провести все необходимые вычисления для каждого выходного отсчета. С другой стороны, она должна быть по возможности высокой, чтобы уменьшить фальшь и расширить диапазон воспроизводимых нот. Для работы программы-плеера необходима таблица с периодами каждой ноты. Для расчета этой таблицы и вычисления отклонения получаемых частот сигнала от желаемых была написана
    программа на Матлабе
    fs = 2e6/72;
    
    notes = -24:26;
    f = zeros(size(notes));
    d = zeros(size(notes));
    fa = zeros(size(notes));
    ndifs = zeros(size(notes));
    for i=1:length(notes)
        f(i) = 440*2^(notes(i)/12);
        k = round(fs/f(i));
        fa(i) = fs/k;
        na = 12*log2(fa(i)/440);
        ndifs(i) = na-notes(i);
        d(i) = k;
        fprintf('%10.1f    %10.1f    %3d   %4.2f\n',f(i),fa(i),notes(i),ndifs(i));
    end
    plot(ndifs);
    ylim([-0.5 0.5]);
     fprintf('\n\n');
     for i=1:length(notes)
         fprintf('\tretlw\tH''%02X''\n',d(i));
     end
    


    Для каждой ноты программа вычисляет период сигнала в отсчетах на выбранной частоте дискретизации, округляет его до целого и производит обратный пересчет в номер ноты. В этих логарифмических единицах и оценивается отклонение, график которого выводится на экран:

    Можно поэкспериментировать, меняя частоту дискретизации, то есть количество тактов процессора, приходящихся на один ее период. Эмпирически я подобрал коэффициент 72, который дает минимально достижимые отклонения нот в заданном диапазоне.
    2. Архитектура прошивки

    У PIC16F753 имеется три таймера, но только таймер 2 можно запрограммировать на генерацию прерываний с заданным периодом. С его помощью получаем прерывания на частоте дискретизации звука, т.е. каждые 72 такта процессора. Процедура обработки прерываний вычисляет очередное значение для вывода на ЦАП. Чтобы избежать искажений звука, необходимо обновлять уровень на ЦАП через строго равные промежутки времени. Так как вычисления могут занимать различное время в зависимости от состояния программы, здесь есть два варианта. Первый — «подравнять» все ветки вычислений, чтобы они исполнялись за одинаковое число тактов. Второй — сразу вывести в ЦАП значение, рассчитанное во время обработки предыдущего прерывания, а потом уже рассчитать значение для вывода в следующем прерывании. Я избрал второй путь. При этом процедура обработки прерывания выполняется каждый раз за разное время, но зато между прерываниями остается в среднем больше процессорного времени для фоновых вычислений.

    По прерываниям работает генерация стационарных сигналов — прямоугольников неизменной частоты, скважности и амплитуды. Эти параметры хранятся в соответствующих ячейках памяти. При работе прошивки прерывания никогда не запрещаются. Это обеспечивает отсутствие в звуке каких-либо неоднородностей и разрывов, за исключением моментов переключения параметров генерации. Получается такой же режим работы, как если бы в системе был звуковой чип, наподобие Atari Pokey или AY-3-8910: эти чипы тоже формируют на каждом канале стационарные сигналы до тех пор, пока процессор не изменит значения параметров во внутренних регистрах этих чипов.

    Обновление параметров генерации осуществляется процедурами, работающими в фоновом режиме (т.е. между прерываниями). Здесь я задействовал таймер-1 для обеспечения периодичности вызова процедуры обновления параметров — 50Гц. Такая же или близкая частота используется для этих целей в музыкальных проигрывателях на 8-битных компьютерах.

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

    3. Подготовка музыки

    Чип-музыку надо в чем-то редактировать, и на сегодняшний день один из наиболее легких путей — это использовать Open Modplug Tracker. Нужно подготовить несколько сэмплов, которые звучат хотя бы приблизительно похоже на звучание чипа, и создать с их помощью музыку в трекере, используя не более 4 каналов. При этом также нельзя пользоваться спецэффектами трекера, кроме тех, которые реализованы в нашем чип-плеере. В результате создается трекерный файл в формате .it. Я также написал программу-конвертор, которая конвертирует ноты из it-файла в формат, распознаваемый моей прошивкой PIC16F753. Конвертор ругается, если встретит в it-файле ноты за пределами диапазона или неподдерживаемые прошивкой команды. Инструменты из it-файла полностью игнорируются конвертором. Они нужны только для контроля звучания музыки во время редактирования.

    Сэмплы прямоугольников различной скважности, которые нужны во время редактирования музыки, я сгенерировал специальными программами на Матлабе. Но это было проделано давно в рамках другого проекта — конверсия музыки с ZX Spectrum, так что сейчас я просто взял инструменты из тех старых модулей и сделал на их базе музыку для шкатулки.

    В результате работы конвертора создается текстовый файл в формате ассемблера PIC. Его содержимое нужно скопировать в конец исходника прошивки и скомпилировать. В результате получится прошивка в виде hex-файла с нужной музыкой.

    К сожалению, у меня нет таланта композитора или аранжировщика, поэтому удалось лишь завести кусок известной вещи В. Моцарта. Часть возможностей плеера при этом даже осталась неиспользованной. Было бы несложно добавить в плеер шумовые эффекты и многое другое, но опять-таки, где взять человека, который сможет на них сделать красивое звучание?

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

    Исходники


    Полный исходный текст прошивки, программы-конвертора музыки, а также it-файл с той музыкой, которую я использовал в данной шкатулке, можно скачать с Github.
    AdBlock has stolen the banner, but banners are not teeth — they will be back

    More
    Ads

    Comments 28

      +6
      Обычно всё же музыкальные шкатулки начинают проигрывать музыку автоматически при открывании. Вручную включать шкатулку странно.
      Корявый вид схемы несколько удивил.
        +3
        Выключатель я бы заменил на фото-резистор\диод\транзистор, крышечку открыл, музычка зазвучала.
        Чутка опоздал.
          +8
          Можно просто геркон поставить. А в крышку — небольшой магнит.
            0
            Проблема — найти нормально замкнутый геркон.
              0
              Да не такая уж и проблема. Я недавно в радиоларьке их горсть всяких-разных видел.
                0
                А если действительно проблема в данной локации — то можно попробовать обойтись и нормально-разомкнутым, магнит поставить рядом с герконом в корпус, а в крышку — кусочек железа, чтобы при закрывании замыкал магн. поле и т.о. отпускал геркон.
                  0
                  Как вариант переключающие можно взять, они более распространены.
                0
                (Буду обновлять комментарии)
                +1
                А агрегат-то занял 2/3 глубины шкатулки (глубину крышки не считаю, ее там, кажется, и нет почти). И шкатулка почти перестала выполнять свою основную функцию. Проклятые батарейки. Вместо них бы аккумулятор плоский или «таблеток» насыпать. Это вам тоже в качестве идеи для последующих творений, наравне с герконом.

                Кстати, в крышке какого-нибудь тайника нет? А то высота слабо совпадает с ее глубиной на фото, вряд ли металл такой толстый там.
                  0
                  Глубина крышки миллиметра 4 или даже 5. Если бы ее не было — не закрывалось бы, выключатель бы мешал. Конечно, схема подлежит миниатюризации. Можно поставить батарейки поменьше, пьезодинамик, развести плату, использовать планарные элементы. Но тогда все это было бы нельзя собрать за 3-4 дня (вместе с разработкой прошивки). Сюда же относится рисование схемы от руки.

                  Батарейки AAA для такой схемы — это, конечно, из пушки по воробьям. Если принять их емкость порядка 700мА*ч — то их хватит на несколько десятков часов непрерывной работы схемы, из предположения, что она потребляет порядка 20мА (реальный ток не измерял). Никто не будет слушать шкатулку такое время. Батарейки помрут от саморазряда через несколько лет.
                  +1
                  К черту линейку! Только карандаш — только хардкор!
                    0
                    Однако, те кто прошел старую школу черчения могут рисовать достаточно ровно даже без линейки. Видимо у кого-то не было институтского черчения, либо его спустили на тормозах…
                      0
                      Не всем же быть Пикассо. Программирование умею, электронику умею, чертить и рисовать от руки — из рук вон плохо. Прошу извинять. В институте черчения не было — немного даже жалею об этом сейчас. Жалею — потому что оно нужно. Немного — потому что, наверно, вылетел бы из-за черчения с такими талантами к нему :)
                        +2
                        А с линейками тоже дефицит?
                          0
                          Была бы схема посложнее или для нужд серийного производства — нарисовал бы ровненько в САПРе. А так — схема рождается в голове и рисуется быстро от руки. Для сборки достаточно. Для понимания, надеюсь, тоже. Делюсь всем, что имею.
                          0
                          Paint тоже не умеете?
                            +2
                            Паинтом еще сложнее чем от руки с линейкой. Уж лучше какой-нибудь SprintLayout…
                            0
                            Дак, там эти таланты прививают а не отбраковывают. Только упорный труд, только хардкор… десятки часов проведенных с карандашом в руках…
                            Я как раз из той партии выпускников когда уже заканчивали давить на черчение в виду широкого развития всевозможных CAD-систем. Поэтому, шрифт по ГОСТу рисовать от руки не умею… Но все же, относительно короткие линии ровными получаются.
                        +1
                        Лет 10-12 назад «музыкализировал» шкатулку простейшей схемой на микросхеме УМС-8 (где зашиты 3 мелодии, тогда еще были популярны брелки на ней). Габариты схемы были очень маленькие (питание от часовой батарейки), поэтому все прекрасно разместилось под бархатной тряпочкой, которой с внутренней стороны оббил шкатулку. Под крышку разместил микровыключатель, чтобы начинало играть при открытии крышки. Шкатулка функционирует до сих пор :)
                          +1
                          УМС-ки даже работали от солнечной батарейки из калькуляторов — можно запихать это все в шкатулку и при открытии из шкатулки играла музыка… Использовался пьезо динамик от убитой игры «ну погоди».
                            +1
                            УМС-8 работали начиная от 1.2В, УМС-7 требовали минимум 2.5В
                            Что самое интересное, УМС-8 это белорусская разработка, они потом чип УМС 8-08 ставили в свои наручные часы.
                            –2
                            Самокат из брусочков (tm)
                              +2
                              Идея зачет, реализация не айс. Надо плату -ЛУТ, детали СМД, батарейки заменить на плоский литий ионный аккум, датчик открывания крышки повесить на оптику.
                                +3
                                Аккумулятор там не нужен, хватило бы AG13 или AG11 даже жестко паяных.

                                Во вторых, если химичить что-то с датчиками отличными от геркона или механического контакта(тяга от крышки и подпружиненый контакт) то появится необходимость в дежурном питании, а это будет сильно разряжать батарейку если не минимизировать потребление — а это и время и ресурсы и неоправданное усложнение конструкции.
                                  +1
                                  Совершенству нет предела. Если хотите повторить проект, улучшив его — вам и карты в руки. Моя реализация привлекательна тем, что она доступна большему числу людей, не владеющих ЛУТ, имеющих меньше навыков или инструментов для пайки и монтажа механических конструкций. То же касается и оптики. Выше уже сказали, в чем тут проблема: требуется дежурное питание, идет постоянный разряд батарейки. Также лишние детали, больше пайки. Все это увеличивает «порог вхождения». При использовании экзотических батареек также возрастают сложности с их заменой или зарядкой. Также это удорожает конструкцию.
                                  0
                                  Кстати, можно было использовать микропереключатель типа МП-3
                                  image
                                  закрепленный возле крепления крышки, а на крышке приклеить маленький толкатель — крышка закрыта он нажимает на переключатель и отключает схему.

                                  Такое же можно было сделать с тактовой кнопкой у которой есть переключающая секция, есть варианты с длинным штоком — можно было бы вообще без модификации крышки обойтись.
                                    0
                                    Всё равно не эстетично получилось… на мой взгляд объём полезного пространства в шкатулке уменьшился, его практически нет!!! А если учесть, что там будет что-то лежать — оно будет мешать вкл/выкл.

                                    Если времени в обрез, лучше сделать что-то попроще, но качественней, или вообще купить.

                                    p.s. многие шкатулки заводятся «ключом»
                                      0
                                      Основная идея этого поста было не хвастовство, а поделиться с сообществом схемой, программой и идеями. Разве вы не видите, что у схемы есть большой потенциал миниатюризации? И по эстетике — как сделаете, так и будет.

                                    Only users with full accounts can post comments. Log in, please.