Съдържание:

Лазерен синтезатор на арфа на Zybo Board: 10 стъпки (със снимки)
Лазерен синтезатор на арфа на Zybo Board: 10 стъпки (със снимки)

Видео: Лазерен синтезатор на арфа на Zybo Board: 10 стъпки (със снимки)

Видео: Лазерен синтезатор на арфа на Zybo Board: 10 стъпки (със снимки)
Видео: Laser harp with omnichord style keyboard 2024, Юли
Anonim
Лазерен синтезатор на арфа на Zybo Board
Лазерен синтезатор на арфа на Zybo Board

В този урок ще създадем напълно функционална лазерна арфа, използваща IR сензори със сериен интерфейс, който ще позволи на потребителя да промени настройката и тона на инструмента. Тази арфа ще бъде римейк на 21 -ви век на вековния инструмент. Системата е създадена с помощта на платка за разработка Xilinx Zybo заедно с Vivado Design Suites. Какво ще ви е необходимо за завършване на проекта:

  • 12 IR сензора и излъчватели (повече или по -малко могат да се използват в зависимост от броя на низовете)
  • Zybo Zynq-7000 борд за разработка
  • Безплатен RTOS
  • Дизайн апартамент Vivado
  • Тел (за свързване на сензорите към платката)
  • 3 броя PVC тръба ((2) 18 инча и (1) 8 инча)
  • 2 PVC лакти

Стъпка 1: Вземете Zybo DMA Audio Demo на Digilent

Страната на FPGA на този проект се основава до голяма степен на демо проекта, намерен тук. Той използва директен достъп до паметта, за да изпраща данни директно от паметта, в която процесорът може да записва през AXI Stream към I2S аудио блок. Следните стъпки ще ви помогнат да стартирате и стартирате демонстрационния проект на DMA аудио:

  1. Може да се наложи нова версия на файла на дъската за платката Zybo. Следвайте тези инструкции, за да получите нови файлове на борда за Vivado.
  2. Следвайте стъпки 1 и 2 в инструкциите на тази страница, за да отворите демо проекта в Vivado. Използвайте метода Vivado, а не хардуерното предаване на SDK.
  3. Може да получите съобщение, че някои от вашите IP блокове трябва да бъдат актуализирани. Ако е така, изберете „Показване на състоянието на IP“и след това в раздела Състояние на IP изберете всички остарели IP и кликнете върху „Надстройка избрана“. Когато приключи и се появи прозорец с въпрос дали искате да генерирате изходен продукт, продължете и кликнете върху „Генериране“. Ако получите критично предупредително съобщение, игнорирайте го.
  4. Преминете от дизайна към раздела източници във Vivado, за да видите изходните файлове. Щракнете с десния бутон върху дизайна на блока „design_1“и изберете „Създаване на HDL обвивка“. Когато бъдете подканени, изберете „копиране на генерирана обвивка, за да разрешите потребителски редакции“. Ще бъде генериран файл с обвивка за проекта.
  5. Сега, когато тези критични стъпки, които по някакъв начин бяха пропуснати в другия урок, са завършени, можете да се върнете към предишния свързан урок и да продължите от стъпка 4 до края и да се уверите, че демонстрационният проект работи правилно. Ако нямате начин да въведете звук, за да може той да записва, просто запишете със слушалките си и слушайте 5-10 секунди размит звук, когато натиснете бутона за възпроизвеждане. Докато нещо излиза от жака за слушалки, когато натиснете бутона за възпроизвеждане, вероятно той работи правилно.

Стъпка 2: Направете някои промени във Vivado

Направете някои промени във Vivado
Направете някои промени във Vivado

Така че сега имате DMA аудио демонстрация на Digilent, която работи, но това изобщо не е крайната цел тук. Така че трябва да се върнем към Vivado и да направим някои промени, така че нашите сензори да могат да бъдат включени в заглавките на PMOD и да можем да използваме тяхната стойност от страна на софтуера.

  1. Отворете блоковата диаграма във Vivado
  2. Създайте GPIO блок, като щракнете с десния бутон върху празното място в блоковата диаграма и изберете „Добавяне на IP“от менюто. Намерете и изберете „AXI GPIO“.
  3. Щракнете двукратно върху новия IP блок и в прозореца за повторно персонализиране на IP отидете в раздела IP конфигурация. Изберете всички входове и задайте ширината на дванадесет, тъй като ще имаме 12 "струни" на нашата арфа и следователно се нуждаем от 12 сензора. Ако искате да използвате по -малко или повече сензори, коригирайте този номер по подходящ начин. Също така задайте активиране на прекъсване.
  4. Щракнете с десния бутон върху новия GPIO IP блок и изберете „стартиране на автоматизация на връзката“. Поставете отметка в полето AXI и натиснете добре. Това трябва да свърже AXI интерфейса автоматично, но да остави изходите на блока несвързани.
  5. За да освободите място за допълнителното прекъсване, щракнете двукратно върху IP блока xlconcat_0 и променете броя на портовете от 4 на 5. След това можете да свържете щифта ip2intc_irpt от новия GPIO блок към новия неизползван порт на блока xlconcat.
  6. Щракнете с десния бутон върху изхода „GPIO“на новия GPIO IP блок и изберете „направи външно“. Намерете къде отива линията и кликнете върху малкия страничен петоъгълник, а вляво трябва да се отвори прозорец, където можете да промените името. Променете името на „СЕНЗОРИ“. Важно е да използвате същото име, ако искате файлът с ограничения, който предоставяме, да работи, в противен случай ще трябва да промените името във файла с ограничения.
  7. Назад в раздела източници намерете файла с ограничения и го заменете с този, който предоставяме. Можете да изберете да замените файла или просто да копирате съдържанието на нашия файл с ограничения и да го поставите върху съдържанието на стария. Едно от важните неща, които прави нашият файл с ограничения, е да активира издърпващите резистори на заглавките на PMOD. Това е необходимо за конкретните сензори, които използвахме, но не всички сензори са еднакви. Ако вашите сензори изискват падащи резистори, можете да промените всеки екземпляр на „set_property PULLUP true“с „set_property PULLDOWN true“. Ако те изискват различна стойност на резистора от тази на платката, тогава можете да премахнете тези линии и да използвате външни резистори. Имената на пиновете са в коментарите във файла с ограничения и съответстват на етикетите в първата диаграма в схемите на Zybo страница, която можете да намерите тук. Ако искате да използвате различни pmod щифтове, просто съпоставете имената в ограничителния файл с етикетите в схематично. Използваме PMOD заглавки JE и JD и използваме шест пина за данни на всеки, като пропускаме пинове 1 и 7. Тази информация е важна, когато свързвате сензорите си. Както е показано на схемата, щифтове 6 и 12 на PMODS са VCC, а щифтове 5 и 11 са заземени.
  8. Регенерирайте HDL обвивката както преди и копирайте и презапишете старата. Когато това е направено, генерирайте поток от битове и експортирайте хардуер както преди и рестартирайте SDK. Ако ви попитат дали искате да замените стария хардуерен файл, отговорът е да. Вероятно е най -добре да затворите SDK, когато експортирате хардуер, така че да бъде правилно заменен.
  9. Стартирайте SDK.

Стъпка 3: Включете FreeRTOS

Следващата стъпка е да стартирате FreeRTOS на дъската Zybo.

  1. Ако все още нямате копие, изтеглете FreeRTOS тук и извлечете файловете.
  2. Импортирайте демото на FreeRTOS Zynq, намиращо се на FreeRTOSv9.0.0 / FreeRTOS / Demo / CORTEX_A9_Zynq_ZC702 / RTOSDemo. Процесът на импортиране е почти същият като при другия демонстрационен проект, но тъй като демонстрацията FreeRTOS Zynq разчита на други файлове в папката FreeRTOS, не трябва да копирате файловете в работното си пространство. Вместо това трябва да поставите цялата папка FreeRTOS в папката на вашия проект.
  3. Създайте нов пакет за поддръжка на борда, като отидете на "file" -> "new" -> "package support package". Уверете се, че е избрано самостоятелно и щракнете върху край. След малко ще се появи прозорец, поставете отметка в квадратчето до lwip141 (това спира едно от демонстрациите на FreeRTOS да не успее да се компилира) и натиснете OK. След като завършите с десния бутон върху проекта RTOSdemo и отидете на "свойства", отидете в раздела "препратки към проекта" и поставете отметка в квадратчето до новия bsp, който сте създали. Надяваме се, че ще бъде разпознат, но понякога Xilinx SDK може да е странен за подобни неща. Ако все още получавате грешка след тази стъпка, че xparameters.h липсва или нещо подобно, опитайте да повторите тази стъпка и може би да излезете и да стартирате отново SDK.

Стъпка 4: Добавете код за лазерна арфа

След като FreeRTOS е импортиран, можете да пренесете файловете от проекта за лазерна арфа в демото на FreeRTOS

  1. Създайте нова папка под папката src в демонстрацията на FreeRTOS и копирайте и поставете всички предоставени c файлове с изключение на main.c в тази папка.
  2. Сменете RTOSDemo main.c с предоставения main.c.
  3. Ако всичко е направено правилно, на този етап трябва да можете да стартирате кода на лазерната арфа. За целите на тестването, входът с бутони, използван в демонстрационния проект на DMA, сега се използва за възпроизвеждане на звуци без сензори (всеки от четирите основни бутона ще работи). Той ще свири низ всеки път, когато го натиснете, и ще преминете през всички струни в системата при множество натискания. Включете някои слушалки или високоговорители към жака за слушалки на платката Zybo и се уверете, че можете да чуете звуците на струните, които преминават, когато натиснете бутон.

Стъпка 5: За кода

Много от вас, които четете този урок, вероятно ще научите как да настроите аудио или да използвате DMA, за да направите нещо различно, или да създадете различен музикален инструмент. Поради тази причина следващите няколко раздела са посветени на описанието как работи предоставеният код във връзка с описания по -горе хардуер за получаване на работещ аудио изход с помощта на DMA. Ако разбирате защо има кодови части, тогава трябва да можете да ги коригирате за всичко, което искате да създадете.

Прекъсва

Първо ще спомена как се създават прекъсвания в този проект. Начинът, по който го направихме, беше като първо създадохме структура на векторна таблица за прекъсвания, която следи идентификатора, манипулатора на прекъсвания и препратка към устройството за всяко прекъсване. Идентификаторите на прекъсванията идват от xparameters.h. Манипулаторът на прекъсвания е функция, която написахме за DMA и GPIO, а прекъсването I2C идва от драйвера Xlic I2C. Препратката към устройството сочи към копия на всяко устройство, които инициализираме другаде. В края на функцията _init_audio цикъл преминава през всеки елемент от векторната таблица за прекъсване и извиква две функции, XScuGic_Connect () и XScuGic_Enable () за свързване и активиране на прекъсванията. Те се позовават на xInterruptController, който е контролер за прекъсване, създаден в FreeRTOS main.c по подразбиране. Така че по принцип ние прикрепяме всяко наше прекъсване към този контролер на прекъсвания, който вече е създаден за нас от FreeRTOS.

DMA

Кодът за инициализация на DMA започва в lh_main.c. Първо се декларира статичен екземпляр на структура XAxiDma. След това във функцията _init_audio () се конфигурира. Първо се извиква функцията за конфигуриране от демонстрационния проект, която е в dma.c. Това е доста добре документирано и идва директно от демонстрацията. Тогава прекъсването се свързва и активира. За този проект се изисква само прекъсване master-to-slave, тъй като всички данни се изпращат от DMA към контролера I2S. Ако искате да записвате аудио, ще ви е необходимо и прекъсване от slave-to-master. Прекъсването master-to-slave се извиква, когато DMA завърши изпращането на всички данни, които сте му казали да изпрати. Това прекъсване е изключително важно за нашия проект, тъй като всеки път, когато DMA завърши изпращането на един буфер от аудио проби, той трябва незабавно да започне да изпраща следващия буфер, в противен случай ще се появи звуково забавяне между изпращанията. Вътре в функцията dma_mm2s_ISR () можете да видите как се справяме с прекъсването. Важната част е близо до края, където използваме xSemaphoreGiveFromISR () и portYIELD_FROM_ISR (), за да уведомим _audio_task (), че може да инициира следващия DMA трансфер. Начинът, по който изпращаме постоянни аудио данни е чрез редуване между два буфера. Когато един буфер се предава към I2C блока, стойностите на другия буфер се изчисляват и съхраняват. След това, когато прекъсването идва от DMA, активният буфер се превключва и наскоро записаният буфер започва да се прехвърля, докато прехвърленият преди това буфер започва да се презаписва с нови данни. Ключовата част от функцията _audio_task е мястото, където се извиква fnAudioPlay (). fnAudioPlay () приема в DMA екземпляра, дължината на буфера и указател към буфера, от който ще се прехвърлят данни. Няколко стойности се изпращат към регистрите на I2S, за да се уведоми, че идват още проби. Тогава XAxiDma_SimpleTransfer () се извиква, за да започне прехвърлянето.

I2S аудио

audio.c и audio.h са мястото, където се извършва инициализацията на I2S. Кодът за инициализация на I2S е доста често срещан парче код, който се носи на много места, може да откриете леки вариации от други източници, но този трябва да работи. Това е доста добре документирано и не е нужно много да се променя за проекта за арфа. Аудио демонстрацията на DMA, от която идва, има функции за превключване към микрофонни или линейни входове, така че можете да ги използвате, ако имате нужда от тази функционалност.

Звуков синтез

За да опиша как работи синтеза на звук, ще изброя всеки от моделите на звука, използвани в разработката, които са довели до крайния метод, тъй като той ще ви даде представа защо се прави по начина, по който се прави.

Метод 1: Един период от синусови стойности се изчислява за всяка струна на съответната честота за музикалната нота на тази струна и се съхранява в масив. Например, дължината на масива ще бъде периодът на синусоидалната вълна в пробите, което е равно на # проби / цикъл. Ако честотата на дискретизация е 48 kHz и нотната честота е 100Hz, тогава има 48 000 проби/секунда и 100 цикъла/секунда, водещи до 4800 проби на цикъл, а дължината на масива ще бъде 4800 проби и ще съдържа стойностите на една пълна период на синусоида. Когато низът се възпроизвежда, буферът за аудио проба се запълва, като се вземе стойност от масива от синусоидални вълни и се постави в аудио буфера като проба, след което се увеличава индекса в масива от синусоиди, така че използвайки предишния ни пример в хода от 4800 проби един цикъл на синусоида се поставя в аудио буфера. Модулна операция се използва върху индекса на масива, така че винаги да пада между 0 и дължината, а когато индексът на масива надхвърли определен праг (като примерно 2 секунди на проби), низът се изключва. За да играете няколко струни едновременно, следете отделно индекса на масивите на всеки низ и добавете стойността от синусоидата на всяка струна заедно, за да получите всяка проба.

Метод 2: За да създадем по -музикален тон, започваме с предишния модел и добавяме хармоници към всяка основна честота. Хармоничните честоти са честоти, които са цяло число, кратно на основната честота. За разлика от това, когато две несвързани честоти се сумират заедно, което води до едновременно възпроизвеждане на два отделни звука, когато се добавят хармоници, той продължава да звучи само като един звук, но с различен тон. За да постигнем това, всеки път, когато добавяме стойността на синусоидата на местоположението (индекс на масива % дължина на масива) към аудио извадката, добавяме и (2 * индекс на масива % дължина на масива) и (3 * индекс на масива % дължина на масива) и т.н., въпреки че са желани много хармоници. Тези умножени индекси ще преминават през синусоидата при честоти, които са цяло кратно на първоначалната честота. За да се даде възможност за по -голям контрол на тона, стойностите на всеки хармоник се умножават по променлива, която представлява количеството на тази хармоника в общия звук. Например, фундаменталната синусоида може да има своите стойности, умножени по 6, за да стане по -скоро фактор в общия звук, докато петата хармоника може да има множител 1, което означава, че нейните стойности допринасят много по -малко за общия звук.

Метод 3: Добре, така че сега имаме много приятен тон на нотите, но все още има доста важен проблем: те свирят с фиксирана сила на звука за фиксирана продължителност. За да звучи изобщо като истински инструмент, силата на звука на струна трябва да намалява постепенно с течение на времето. За да се постигне това, масив се запълва със стойностите на експоненциално залязваща функция. Сега, когато се създават аудио образци, звукът, идващ от всеки низ, се изчислява както в предишния метод, но преди да бъде добавен към аудио извадката, той се умножава по стойността в индекса на масива на тези низове в масива с експоненциално разпадане. Това кара звука да се разсейва плавно с течение на времето. Когато индексът на масива достигне края на разпадащия се масив, низът се спира.

Метод 4: Тази последна стъпка е това, което наистина дава на струнните звуци реалистичния им звук. Преди те звучаха приятно, но ясно синтезирано. За да се опита да подражава по-добре на струнен арфа в реалния свят, на всеки хармоник се присвоява различна скорост на затихване. В истинските струни, когато струната се удари за първи път, има високо съдържание на високочестотни хармоници, което създава вида на скубещ звук, който очакваме от струна. Тези високочестотни хармоници са много кратко основната част на звука, звукът на струната се удря, но те се разпадат много бързо с по -бавните хармоници. За всеки хармоничен номер, използван в синтеза на звук, се създава масив от разпад, всеки със своя собствена скорост на затихване. Сега всеки хармоник може независимо да се умножи по стойността на съответния масив на разпадане в индекса на масива на струната и да се добави към звука.

Като цяло синтезът на звук е интуитивен, но изчислението е тежко. Съхраняването на целия струнен звук в паметта наведнъж би отнело твърде много памет, но изчисляването на синусоидата и експоненциалната функция между всеки кадър би отнело твърде дълго време, за да бъде в крак с скоростта на възпроизвеждане на аудио. В кода се използват редица трикове, за да се ускори изчислението. Цялата математика, с изключение на първоначалното създаване на таблици на синусоида и експоненциално разпадане, се извършва в целочислен формат, което изисква разпределяне на наличното числово пространство в 24 -битовия аудио изход. Например, таблицата на синусите е с амплитуда 150, така че да е гладка, но не толкова голяма, че много струни, които се играят заедно, могат да добавят над 24 бита. По същия начин стойностите на експоненциалната таблица се умножават по 80, преди да бъдат закръглени до цели числа и съхранени. Хармоничните тегла могат да приемат дискретни стойности между 0 и 10. Също така всички проби всъщност се удвояват и синусоидите се индексират с 2, което ефективно намалява наполовина честотата на дискретизация. Това ограничава максималната честота, която може да се играе, но беше необходимо, за да може текущият брой струни и хармоници да се изчисли достатъчно бързо.

Създаването на този звуков модел и привеждането му в действие отнеха значителни усилия от страна на процесора и би било невероятно трудно да го накарате да работи от страна на fpga от нулата във времевата рамка на този проект (представете си, че трябва да пресъздадете битовия поток всеки време на промяна на парче верилог за тестване на звука). Това обаче с fpga вероятно би могло да бъде по -добър начин да се направи това, евентуално елиминирайки проблема с невъзможността да се изчислят достатъчно бързо пробите и да се позволи да се изпълняват повече струни, хармоници и дори аудио ефекти или други задачи страна на процесора.

Стъпка 6: Окабеляване на сензорите

Окабеляване на сензорите
Окабеляване на сензорите

За създаването на струните използвахме IR сензори за прекъсване на лъча, които ще открият кога се свири струната. Поръчахме нашите сензори от следната връзка. Сензорите имат захранващ, заземен и кабел за данни, докато излъчвателите имат само захранващ и заземен проводник. Използвахме 3.3 V и земни щифтове от заглавията PMOD за захранване както на излъчвателите, така и на сензорите. За да захранвате всички сензори и излъчватели е необходимо да свържете паралелно всички сензори и излъчвател. Кабелите за данни от сензорите ще трябва да отидат на своя собствен pmod пин.

Стъпка 7: Конструиране на скелета

Изграждане на скелета
Изграждане на скелета

За да се създаде формата на арфата, трите парчета се използват като скелет за поставяне на сензорите и излъчвателите. На едно от двете 18 -инчови парчета PVC тръба подравнете сензорите и излъчвателите в последователен ред на 1,5 инча един от друг и след това ги залепете до тръбата. На другата 18 -инчова PVC тръба подравнете сензорите и излъчвателите в променлив ред, но не забравяйте да изместите реда (т.е. ако първата тръба е имала сензор първа, втората трябва първо да има излъчвател и обратно). Ще бъде необходимо да запоите по -дълги проводници върху проводниците за данни, захранване и заземяване, за да сте сигурни, че те ще могат да достигнат до платката.

Стъпка 8: Изграждане на дървен екстериор

Изграждане на дървен екстериор
Изграждане на дървен екстериор

Тази стъпка не е задължителна, но е силно препоръчителна. Екстериорът от дърво не само прави арфата да изглежда добре, но и предпазва сензорите и проводниците от повреда. Дървената рамка може да бъде създадена от кухи правоъгълен пръстен от дърво. Вътрешността на правоъгълника трябва да има отвор най-малко 1-1/2 инча, за да пасне на тръбата и скелета на сензора. След като рамката е изградена, пробийте два отвора, които ще позволят на проводниците от сензора и излъчвателите да излязат, за да ги свържат с платката.

*Забележка: Препоръчително е да добавите точки за достъп, за да можете да премахнете и поставите скелета на тръбата в случай, че е необходимо да се извърши ремонт или да се направят леки корекции.

Стъпка 9: Сглобяване на всички части

Сглобяване на всички парчета заедно
Сглобяване на всички парчета заедно

След като всички предишни стъпки приключат, е време да се конструира арфата. Първо поставете скелета на тръбата вътре в дървената външна част. След това включете проводниците за сензорите и излъчвателите в правилното място на платката. След това отворете SDK и щракнете върху бутона за отстраняване на грешки, за да програмирате платката. След като платката е програмирана, включете чифт слушалки или високоговорител. В зависимост от това кой сензор се озовава в кой pmod порт, струните на арфата ви вероятно ще бъдат извадени отначало. Тъй като може да бъде трудно да се определи кой проводник отива към кой сензор, когато са включени толкова много проводници, ние включихме начин за картографиране на номера на низове, за да прекъснем позициите на битове в софтуера. Намерете "static int sensor_map [NUM_STRINGS]" и коригирайте стойностите в масива, докато низовете свирят от най -ниския до най -големия по ред.

Менюто може да се използва чрез отваряне на сериен терминал (например RealTerm) и задаване на скоростта на предаване на 115200, а на дисплея - ANSI. Менюто може да се навигира с помощта на бутоните w и s за придвижване нагоре и надолу и бутоните a и d за промяна на стойностите.

Стъпка 10: ROCK OUT

След като арфата е напълно функционална. Овладейте арфата и слушайте сладкия звук на собствената си музика!

Препоръчано: