PIC16F1503. Тачка на прокачку — 1. Звук

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

В результате детский автопарк пополнился вот таким вот чудом китайской инженерии. Джип, с «люстрой» и лебедкой!



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

В результате долгих переговоров было решено, что простая смена батареек — это уже не модно. Ведь все настоящие водители тюнят свои машины в специальных студиях, после чего ездят на машинах, которых ни у кого нет. Вот и я взял машину в студию «Всё Моё» для тюнинга…

Что первым делом необходимо сделать? Правильно, оценить, какой объем работ свалился на нас. Разбираем машину.


Внутри три светодиода (синих, ярких, дешевых), пищалка и неизвестный безкорпусный микроконтроллер класса «китайская сопля». Все это питается от 3х батареек LR4 (емкость в районе 20мАч), поэтому не удивительно, что машина так быстро умерла. Все это великолепие запускается кнопкой, которая в лучших традициях китайского автопрома заедает и закусывает.

В общем, тут надо менять все. Ну или почти все. На что?

Конечно, я был бы не против воткнуть внутрь машинки STM32F4, но оценочная плата внутрь не залезет, а разводить под это печатную плату откровенно лень. Порывшись в ящиках, обнаружил демоплату на PIC16F1503. До 16 мегагерц, 3 килобайта флеша и аж 128 байт памяти. Самое оно для машинки!

Если вы пожелаете повторить мои упражнения, то искать надо по словам PIC-H1503 (это сам микроконтроллер) и PIC-KIT3 (это программатор) от Olimex. Так же будет необходимо скачать и установить MPLAB X Ide и XC8 с сайта microlab. В отличии ОТ, поддерживаются Windows, Linux и OS X.

С чего необходимо начать тюнинг? Правильно, начнем как все, с звука. Громче нам не надо, нам надо что бы пиликало «по-полицейски» и не громко.

Достаем из машинки «пищалку» и пытаемся понять, что это такое. Не найдя никаких опознавательных знаков, цепляем к омметру. Омметр показывает 15Ом. Значит, микродинамик: если бы омметр показал «обрыв», то это пьезопищалка.

Подключать динамик напрямую к ножке микропроцессора бессмысленно (15 ом на 3 вольтах дадут ток в 200мА, что явно не понравится микроконтроллеру, которому 20 за глаза), поэтому делаем простую схему на первом попавшемся NPN транзисторе.



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

Теперь осталось понять, как нам извлечь звук. Из школьного курса физики мы знаем, что звук — это колебания воздуха. А динамик переводит колебания электричества в колебания воздуха. Значит нам надо поколебать динамик. Но динамик у нас подключен напрямую к микроконтроллеру, а тот умеет выдавать только «1» (есть на ножке) и «0» (ничего нет). Да, даже (даже? да это редкость) у этого микроконтроллера есть аж 5ти битный ЦАП (аудиофилы тащатся от однобитных, если что. смаил), но это не спортивно.

Спасает нас опять физика: даже если подать «1» на динамик, магнит не мгновенно подтянет диффузор, как и после «0» он его отпустит не мгновенно.

Самое простое это написать код вроде такого
while(1)
{
  dinamikON();
  pause(1);
  dinamikOFF();
  pause(1);
}


Если паузы считаются в миллисекундах, то в динамике мы получим «писк» в 500Гц. И меняя длительность пауз можно получить вполне себе приличный звук. В чем проблема? Проблема в том, что нам нужно будет постоянно отвлекаться на «ножкодрыганье».

Но в любом приличном микроконтроллере есть такая штука, как PWM, он же ШИМ (что это? легко ищется в той же википедии, с картинками и долгими объяснениями). Есть она и в пике. Открываем MPLAB, создаем новый проект и с помощью Code Configurator (Менюшка Tools-Embedded. Может потребоваться сначала поставить в Plugins) добавляем новый PWM.



Я взял PWM4 исключительно из-за удобства ножки. Так как PWM в пике не может без таймера, посмотрим и на его.



Так как пока ничего не понятно, просто нажмем «Generate Code» и попробуем запустить полученное. Как обычно, ничего не должно произойти — программы нет. Если у вас вылезла ошибка про VDD, то надо в Run-Project Configuration-PICKit3-Power поставить галочку напротив Power target Cirсuit. Просто можно программировать платы «в работе», а тока от программатора не всегда хватит для питания схемы.

Набираем первый код. Все делается в main.c, там я блоки разделил комментариями.

uint16_t count;
        for(count=0; count<1024; count++)
        {
            PWM4_LoadDutyValue(count);
            __delay_ms(10);
        }


Закачиваем и подключаем осциллограф одним входом к выходу микроконтроллера (синяя линия) и другим к динамику (красная).



Итак, что же мы видим? Синяя линия — это результат работы ШИМа. Заполнение от 0 до 100% и скачком снова на ноль. А вот красная линия где-то на середине заполнения отдаленно похожа на синусоиду. Скажу честно, это отдаленность получена путем прицепления конденсатора в 0,47 мкФ параллельно транзистору, для красивой гифки. Реальную картину можно увидеть ниже.

Уберем конденсатор.

Видите пики на красном? Это динамик на «обратном ходу» работает как генератор и легко накидывает целый вольт при питании от 3х. В принципе при соблюдении некоторых условий легко можно спалить схему. Но у нас эти пики никому не мешают, поэтому ставить кондер или нет — ваше дело. Я поставил ради красоты.

Снова поставим. Оно уже было, но эта картинка в статике.

Сменим на 0,1мкф. Просто для сравнения и отображения влияния емкости на звук :)


В принципе мы уже получили писк в 15 килогерц, но кому он нужен, кроме комаров? Значит надо крутить частоту. Частота у ШИМа зависит от таймера, а как часто будет «тикать» таймер, зависит от счетчика, который устанавливается при каждом запуске таймера.

То есть алгоритм работы таймера выглядит примерно так
— Запускаем таймер.
— Таймер тикнул и уменьшил счетчик.
— Счетчик в ноле? Если нет, то снова тикаем. Если да — генерируем прерывание.

Обработчик прерывания:
— ОЙ! Таймер тикнул!
— Сбросить таймер заново


И вот запуск ШИМа как раз у нас подцеплен к прерыванию таймера. А мы можем крутить как частоту «входа тиканья» (prescaler в настройках), так и величину счетчика.

Меняем код (оно же stage2)

uint8_t count;

for(count=0;count<256;count++)
  {
    PWM4_LoadDutyValue(count*2);
    TMR2_LoadPeriodRegister(count);
     __delay_ms(100);
  }



Смотрим на красивую красную линию и видим, что получается нечто отдаленное на синусоиду, причем изменяющуюся по частоте. Да и ухо подтверждает. То, что нам надо!

Зачем я меняю заполнение ШИМа, предлагаю подумать самостоятельно. Но в принципе если мысленно продолжить график и затормозить изменение одного параметра, то все становится ясно. Особо продвинутые могут увидеть аналогичную картинку в каком-нибудь эмуляторе, например proteus

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

Прибиваем count в 255

А теперь ставим в 10


Обратите внимание на правый верхний угол, где указывается шаг сетки. У меня «на глаз» получился диапазон примерно 300-5000Гц. Вполне. И по черепу «ездить» не будет. Перфекционисты могут воспользоваться частотомером, или подсчитать реальное значение из тактовой частоты и прескалеров.

А вот дальше у меня возникли проблемы. Какого-либо понимания, как должно оно звучать у меня нет. Грубо говоря, в музыке чукча читатель, но никак не писатель.

С трудом пополам нашел, какие частоты каким нотам соответствуют, нашел какую-то нотную запись «в лесу родилась елочка»…

Подсчитал задержки, написал

#define do 243 //523Hz
#define re 239 //587
#define mi 236 //659
#define fa 231 //739
#define sol 229 //783
#define la 224 //880
#define si 218 //987
// and again +523Hz

const uint8_t elka[29]={do,la,la,sol,la,fa,do,do,do,la,la,si,sol,do,do,re,re,si,si,si,la,sol,fa,do,la,la,sol,la,fa};

void play(uint8_t p)
{
    // 255 - 3ms period - 300Hz
    // 10 - 0,2ms - 5000Hz
    PWM4_LoadDutyValue(p*2);
    TMR2_LoadPeriodRegister(p);
}
....
uint8_t count;

for (count = 0; count < 29; count++) {
  play(elka[count]);
   __delay_ms(300);
  PWM4_LoadDutyValue(0);
  TMR2_LoadPeriodRegister(0);
   __delay_ms(50);
}


Скомпилировал, запустил. Нет, мелодия угадывается без проблем, но все не так. Путем подбора резисторов и конденсаторов добился «почти синусоиды-пилы» на выходе, но ухо слышит разницу.

В итоге пока остановился на обычном двухтональном сигнале: «высокий-низкий». Классический полицейский «вау-вау», известный всем по голливудским фильмам, у меня не получился. И гугл в ответ на «police sirene tones code programm example» выдает что угодно, только не то что надо.

Помогите, плиз? В какой последовательности там пиликанье идет?

В принципе, мы уже подошли к тому, что бы следующим шагом взять и воспроизвести обычный wav. То есть не мучаться с тонами и прочим. Просто записать звук, перевести его в удобоваримую форму и проиграть. Как делали в свое время разные ScreamTracker'ы.

Проблема только одна: полсекунды звука в формате PCM, моно, с дискретизацией 8КГц занимает около килобайта. А у меня всего три с половиной килобайта. Не пойдет. Но ознакомиться с принципами и примерами можно просто введя гуглу «pic pcm sound». И прямо с первой ссылки будут и исходники и сами программы.

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

Но звук — это половина дела. Хороший свет — тоже отличительный признак настоящего тюнинга :) Но это чуть позже.

Как обычно, готовые проект для MPLAB со всеми штуками можно забрать тут
Поделиться публикацией
Ой, у вас баннер убежал!

Ну. И что?
Реклама
Комментарии 18
  • НЛО прилетело и опубликовало эту надпись здесь
      0
      Не, оно само так получилось :) Я бы папе другую игрушку взял, типа вертолетика или квадрокоптера… Хотя стоп, где-то один у нас уже валяется… :)
      • НЛО прилетело и опубликовало эту надпись здесь
          +2
          Есть и танк, и малинка и датчики… присосок нет и кота. Есть кошка и лазерный модуль :)
            +2
            Танк, самонаводящий кота на маму.
      +2
      Имхо интервал между нотами — кварта (2.5 тона). Чтобы представить, как это звучит — вспомните первые 2 ноты любого марша или гимна («Со-юз» во всем известном гимне).
        0
        Абсолютно верно. А кварту как аккорд, а не интервал, раньше можно было услышать в метро — в вагоне акустика фоном гудела одну ноту на довольно приятной консонирующей частоте. А за секунду до слов «осторожно, двери закрываются» к основному тону подмешивался звук на 2.5 тона выше, который звучал все время, пока автоинформатор говорил.
        0
        Частоты соседних полутонов отличаются в корень 12 степени из 2 раз. Полная октава (12 полутонов) — это как раз изменение частоты в 2 раза. Ля первой октавы — 440 герц.
          +3
          Ехххх. Молодежь. 3 кила это уже нынче мало. В свое время нам дядька делал дверной звонок с 20 мелодиями и все они помещались в 2кб РФку.
          Разные тона вы уже научились генерить, осталось табличку сделать и мелодий из midi'шек накидать.
            +3
            (кряхтя и высыпая песок) Дык, оно этого, разбаловалися, да. Да и окромя мелодий мне ишшо кучку всякого туда запихать надо.

            А так — сейчас 10% занято, так что куда пихать мелодии есть :)
              0
              было время :) КР580ВИ53
                0
                Это мажорство! :) ЦАП на резисторах на ВВ55 — вот хардкор :)
                  0
                  тогда уж ИР23. ВИ53 не жрёт процессорное время на дрыганье
                0
                А, были ли у «дядьки» свои детки?
                0
                Ожидал увидеть в конце статьи Xzibit =))) с фоткой до прокачки, и после -))))
                  0
                  Полицейское пиликанье — лучше всего найти какой-нибудь американский фильм с полицией, и посмотреть в аудиоредакторе частоты, последовательность и длительность.
                  А «в лесу родилась елочка» звучит не совсем правильно потому, что не учитываются длительности нот. Тут может быть два подхода:
                  1) добавить длительность к каждой ноте
                  2) сделать ноту минимальной длительности, а длинные ноты делать повторением нужное число раз
                  3) сделать ноту «пауза», во время которой ничего не играется
                  Например, во 2 случае массив будет выглядеть так:
                  {do,la,la,sol,la,fa,do,do,do,la,la,si,sol,do,do,do,do,re,re,si,si,la,sol,fa,do,la,la,sol,la,fa,fa,fa};
                  А в 3 случае массив будет выглядеть так:
                  {do,la,la,sol,la,fa,do,do,do,la,la,si,sol,do,p,p,do,re,re,si,si,la,sol,fa,do,la,la,sol,la,fa,p,p};
                  Да, и правильно в данном случае называть ноту не si, а sib потому что там си-бемоль при ключе, и вместо каждой ноты си должна играться си-бемоль (правильная ли частота в массиве с частотами я правда не проверял).
                    0
                    Не, там все хуже. В следующей статье объяснения сейчас напишу :)
                    0
                    Как сам-отец плюсую неистово. За цикл про FreeRTOS отдельное спасибо.

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

                    Самое читаемое