Proiectarea Unei Aplicatii Informatice Privind Simularea Prezentei Tobelor

INTRODUCERE

Instrumentele de percuție sunt printre cele mai vechi instrumente muzicale folosite de om in diverse scopuri, cel mai des pentru distracție drept suport muzical. Acestea sunt foarte ușor de folosit și nu necesită mult studiu pentru a putea cânta. În prezent, cele mai răspândite intstrumente de percuție sunt seturile de tobe acustice folosite în majoritatea melodiilor și în majoritatea genurilor muzicale. Însă, odată cu dezvoltarea tehnologiei s-au dezvoltat și instrumentele muzicale, acestea începând să folosească din tehnologia nou apărută.

O alternativă a setului de tobe acustice este setul de tobe electrice. Acestea sunt mai ieftine și pot ocupa un spațiu mai restrâns și un mare avantaj îl reprezintă faptul că pot minimiza sunetul produs prin folosirea unor căști, astfel, doar cel ce le va purta va auzi sunetul produs.

Scopul acestui proiect este să ofere o alternativă pentru cele 2 tipuri de seturi menționate. Pentru a minimiza atât spațiul ocupat cât și sunetul produs și costul, setul de tobe este virtual. Simularea prezenței tobelor în jurul celui ce folosește un astfel de set este realizată prin folosirea a două camere video, care urmăresc vârful bețelor toboșarului, poziționate astfel încât planurile vizuale bidimensionale ale acestora să formeze un spațiu tridimensional în care sunt ”prezente” tobele.

Motivul alegerii temei este unul personal deoarece când am început facultatea a trebuit să locuiesc în căminele studențești, nefiind din același oraș. Practicarea hobby-ului meu a încetat pentru că nu aveam la dispoziție spațiul, atât în timpul funcționării cât și de depozitare, necesar pentru un set de tobe, chiar și unul electric, și zgomotul produs nu ar fi fost permis. Astfel a apărut ideea pentru acest proiect care ar rezolva problemele de spațiu și zgomot. Desigur, proiectul ar avea limitări, lipsa răspunsului tactil fiind principalul neajuns, însă cei care ar folosi acest proiect sunt obișnuiți cu ”air-drumming” (a cânta la un set de tobe inexistent, în aer). În schimb, este oferit feedback vizual de către monitorul unde sunt afișate tobele și auditiv de la boxele, sau căștile, în momentul în care o tobă este lovită.

PROIECTE SIMILARE EXISTENTE

Având în vedere simplitatea unui set de tobe și răspândirea acestuia ca și instrument muzical există, dar și dezavantajele aferente unui set de tobe real, există proiecte care simulează unul încercând să ofere o experiență cât mai aproape de cea adevărată.

Un prim exemplu este proiectul lui Daniel Lélis Baggio[1] care folosește o aplicație cu camera web. Aceasta desemnează anumite regiuni ale ecranului ca fiind asociate unui anumit sunet, iar acel sunet este redat cât timp mâna sau un alt obiect se află în acea zonă a ecranului trece prin ea. Această metoda permite redarea sunetelor de tobe prin detectarea mișcarii, însă nu într-un mod similar cu cel al unui set adevărat. O variantă mai bună ar fi una care ține cont de locația utilizatorului și anumite mișcări ale acestuia.

Fig. 2.1 Demonstrație a aplicației cu camera web

Un produs care a încercat să reproducă capabilitățile air-drumming-ului este Wii Music Drums[2]. Acest produs face parte din jocul Wii Music care cuprinde mai multe instrumente. Pentru a cânta la tobe folosind acest produs, utilizatorul are nevoie de placa Wii Fit ca și cele 2 pedale și de Wiimote și Nunchuck ca și cele 2 bețe. Pentru a cânta la diferite tobe, utilizatorul selectează diferite butoane pe telecomandă. Aceasta nu este air-drumming adevărat deoarece nu contează unde lovește în aer utilizatorul, sunetul fiind determinat de butoanele de pe telecomandă.

Un alt produs, care folosește o tehnologie recent apărută, este aplicația AirBeats pentru Leap Motion[3]. Aceasta necesită cumpărarea aplicației și a dispozitivului Leap Motion, un produs hardware care recunoaște mâinile și degetele mâinii poziționate deasupra sa și le folosește ca și controale în aplicații. Principalul dezavantaj al aplicației este faptul ca nu poziționează tobele în spațiul 3D ca un set de tobe adevărat. În schimb este ca o tableta cu 6 zone pe care utilizatorul le poate lovi pentru a produce diferite sunete. Interfața cu utilizatorul este foarte bine realizată oferind multe facilități, precum alegerea sunetului pentru fiecare tobă în parte și posibilitatea de înregistra muzica creată.

Fig. 2.2 Aplicația Airbeats

DrumChuk[4] este un proiect care transformă telecomenzile Wiimote și Nunchuk în bețe virtuale de tobe. Aplicația produce sunete în funcție de viteza de mișcare și unghiurile de mișcare ale celor doua telecomenzi. Deși bazat pe Wii și nu pe Kinect, prezintă potential pentru un set de tobe virtual asemănător cu unul adevărat. O diferență între acest sistem și cel bazat pe Kinect este faptul că nu trebuie lovit un anumit loc pentru a produce un anumit sunet de tobă, ci alegerea este realizată de rotația telecomenzii, așadar, lovituri multiple în același loc pot produce sunete diferite. Acest lucru permite folosirea aplicației în spații restrânse, în timp ce Kinect necesită o zonă largă pentru a detecta toate mișcările.

”Airdrumming with Kinect”[5], folosește urmărirea scheletică oferită de Kinect pentru a detecta mișcările unei persoane. Anumite zone sunt mapate unor anumite tobe și redă sunetul specific zonei când utilizatorul face o mișcare de coborâre a mâinii prin acea zonă.

Fig. 2.3 Detectarea scheletului uman folosind Kinect în aplicația ”Airdrumming with Kinect”

O altă aplicație cu Kinect este Moto[6]. Aceasta permite utilizatorului să selecteze mai întâi un instrument, iar dacă sunt alese tobele afișează zonele desemnate pentru diferite tobe. Aceste zone urmăresc utilizatorul și produc sunet doar dacă acesta face o mișcare de coborâre cu mâna.

Fig. 2.4 Demonstrație a aplicației ”Moto”

”Virtual Drums”[7] reprezintă un proiect cu funcționalitatea asemănătoare ceea ce se dorește a se realiza, fiind însă implementat software . Pentru realizarea setului de tobe sunt folosite 2 camere video configurate astfel încât să ușureze procesul de detectare a bețelor, care au fost, de asemenea, modificate pentru a permite folosirea proiectului în condiții de iluminare variate și detectarea acestora indiferent de culorile din fundal. Cele doua camere oferă informații legat de poziția bețelor și utilizând algoritmi matematici se detectează poziția în 3D.

Fig. 2.5 Proiectul ”Virtual Drums”

Caracteristicile proiectului includ: prețul scăzut al componentelor, dimensiuni reduse, poate fi stocat într-un spațiu mic, tobele pot fi configurate, pot fi adăugate sau poziționate în funcție de preferințe.

METODOLOGIA DE PROIECTARE

Fig. 3.1 Metodologia de proiectare

Pornind de la specificațiile proiectului au fost create modulele hardware (RTL – Register Transfer Level), scrise in limbajul Verilog. Acestea au fost testate atât individual, pentru a li se verifica funcția, cât și împreună pentru a testa dacă comunicarea dintre module este realizată corect și sunt respectate condițiile de temporizare. Mediul testare folosit este ModelSim PE [anonimizat] de la Mentor Graphics.

Având la dispoziție și un procesor ARM, o parte din specificații au fost rezolvate software folosind limbajul de programare C si biblioteci specifice plăcii de dezvoltare pentru configurarea si controlarea perifericelor. De asemenea, procesorul comunică cu partea hardware, FPGA-ul, rezultând, astfel, un sistem hibrid software – hardware, care lucrează împreună și realizează funcțiile proiectului.

Pentru sunetele de tobe, mai întâi, folosind un microfon au fost înregistrate sunete pentru diferite tobe și salvate in format WAV. Apoi, utilizând un script Python au fost extrase valorile întregi ale eșantioanelor sunetelor, urmând ca un alt script să le prelucreze și să creeze fișiere C cu eșantioanele fiecărui sunet.

După crearea și testarea fisierelor Verilog acestea sunt adăugate într-un proiect în softul PlanAhead Design and Analysis Tool, care trece proiectul prin etapele de sinteză, implementare si generare de fișier BIT. PlanAhead oferă integrare cu XPS (Xilinx Platform Sudio), care permite introducerea procesorului în proiect și configurarea acestuia în funcție de necesitățile proiectului.

Ultimul pas constă în utilizarea SDK-ului (Software Development Kit) care conține bibliotecile specifice driver-elor procesorului, dar și fișierele C ale proiectului. Acestea sunt compilate și este creat fișierul ELF. Ultimele etape constau în descărcarea fișierului BIT pe placa de dezvoltare si rularea aplicației în SDK.

FUNDAMENTE TEORETICE

I2C

Inter-Integrated Circuit (IIC sau I2C) este o magistrală sincronă multi-master ce funcționează pe principiul master-slave. A fost dezvoltat de Philips (acum NXP Semiconductors) pentru a crea o interfață simplă și eficientă între diverse circuite integrate.[8]

Generalități:

Sunt necesare doar 2 fire: o linie de date (SDA, Serial Data, sau SDL, Serial Data Line) și o linie pentru semnalul de ceas (SCL, Serial Clock Line)

Fiecare dispozitiv conectat la magistrală are o adresă unică și există o relație master/slave tot timpul; dispozitivele master pot funcționa ca master-transmițători sau master-receptori

Transfer de date serial, bidirecțional, pe 8 biți la viteza de 100kbit/s în mod standard sau 400kbit/s în mod extins

Fig. 4.1 Conectarea dispozitivelor la cele 2 linii

Transferul de date este inițiat de master. Cele 2 linii, SDA și SCL, sunt conectate la tensiunea pozitivă prin rezistoare de pull-up, astfel în momentul în care liniile sunt libere acestea sunt la nivelul HIGH (1 logic). Semnalul de start al transferului este reprezentat de o tranziție a semnalului SDA din HIGH in LOW în timp ce SCL este menținut HIGH. După semnalul de start SDA mai poate realiza tranziții doar când SCL este LOW, astfel în momentul în care SCL este HIGH valoarea de pe linia de date este considarată validă. După trimiterea a 8 biți masterul așteaptă confirmarea de la slave care trage linia SDA în starea LOW pe durata bitului 9. După semnalul de start primul octet transmis reprezintă adresa unui dispozitiv conectat formată din 7 biți (10 la I2C extins), și bitul ce indică direcția, 1 dacă se dorește o operație de citire si 0 pentru cea de scriere. După următorii 2 octeți masterul semnalează oprirea transferului prin condiția de stop, SDA trece din starea LOW în starea HIGH în timp ce SCL este HIGH.[8]

Fig. 4.2 Transfer de date prin I2C

I2S

Inter Integrated Circuit Sound (I2S) este o magistrală special creată de Philips (acum NXP Semiconductors) pentru a standardiza modul de transfer a datelor audio in sistemele complexe cu circuite integrate cu funcții speciale pentru audio.

Magistrala folosește 3 linii seriale, o linie pentru semnalul de ceas, SCK, una pentru linia de date, SD, și cea pentru semnalul de selecție a canalului, WS. Datele sunt multiplexate în timp pe 2 canale, canalul fiind ales în funcție de valoarea semnalului de selecție.[9]

Fig. 4.3 Transferul unui cuvânt prin I2S

Frecvența semnalului de ceas este de următoarea formula:

(4.2.1)

unde: FS – frecvența de eșantionare a sunetului; N – numărul de biți al eșantionului; C – numărul de canale audio.[9]

VGA

Video Graphics Array (VGA) este o interfață analogică între un monitor si un calculator care a fost răspândită înainte de apariția standardului DVI (Digital Visual Interface). În prezent, din motive de compatibilitate, majoritatea laptop-urilor și calculatoarelor au port VGA, însă, cele moderne au renunțat la acest standard în favoarea celor digitale, DVI. În mod oficial, termenul VGA se referă la rezoluția de 640×480 pixeli cu 16 sau 256 culori, însă se pot realiza și rezoluții mai mari și o paletă de culori mult mai mare.

Fig. 4.4 Portul VGA

Configurația pinilor:

Temporizarea semnalelor de sincronizare este bazată pe modul funcționare al monitoarelor cu tub catodic, acestea conținând un tub electronic care emite un fascicul de electroni. Fasciculul baleiază ecranul din colțul stânga sus si parcurge ecranul linie cu linie. Dupa această parcurgere orizontală fasciculul trebuie să se întoarcă în partea stângă a ecranului pentru a parcurge următoarea linie. În acest timp de întoarcere semnalul de culoare nu este valid. După ce este parcurs tot ecranul fasciculul se întoarce in colțul din stânga sus pentru o nouă parcurgere, un nou cadru. Frecvența cu care este scanat ecranul este numită frecvență de reîmprospătare.[10]

Cunoscând rata de reîmprospătare a imaginii și rezoluția se calculează timpii necesari pentru ca semnalele de sincronizare să fie corect furnizate. Conform Figurii X, trebuie respectate anumite intervale de timp atât pentru sincronizarea orizontală cât și pentru cea verticală, forma de undă având aceeași formă, dar cu durate de timp diferite.

Fig. 4.5 Temporizarea semnalelor de sincronizare

TS (Sync pulse time) = timpul total al unei perioade a semnalului de sincronizare;

Tdisp (Display time) = timpul în care sunt furnizate semnalele de culoare pentru fiecare pixel;

Tpw (Pulse width time) = durata impulsului negativ de sincronizare;

Tfp (Front porch time) = timpul de pre-sincronizare;

Tbp (Back porch time) = timpul de post-sincronizare.

Pe durata Tpw , Tfp și Tbp trebuie să nu fie afișată informație, se transmite 0 (culoarea negru).

Folosind un ceas de 25MHz pentru pixeli, rezoluția de 480 x 640 (480 pixeli pe linie, 640 linii într-un cadru) și frecvența de reîmprospătare de 60Hz pot fi folosite următoarele valori pentru timpii menționați.[10]

Tabel 4.1 Valorile timpilor pentru rezoluția de 480×640

Formatul audio WAVE

Waveform Audio File Format (WAVE, sau WAV ca și extensia fișierelor) este un format audio standard creat de Microsoft si IBM pentru stocarea digitală a fișierelor audio. WAVE are la bază formatul RIFF (Resource Interchange File Format), care reprezintă o metodă de a stoca datele binare în bucăți mari („chunks”). Sunetele sunt eșantionate cu o anumite frecvență (ex: 48KHz sau 44,1KHz) și folosind un număr de biți multiplu de 8. [11]

Un fișier WAVE este compus din următoarele câmpuri:

Tabel 4.2 Câmpurile unui fișier WAVE

Tabel 4.3 Câmpurile unui fișier WAVE

Un exemplu de fișier WAVE cu octeți în format hexazecimal:

Fig. 4.6 Exemplu de fișier WAVE cu valorile câmpurilor

Componentele imaginii

O imagine este un ansamblu în plan bidimensional a unor elemente numiți pixeli ce poartă informație. Aceștia conțin date referitoare la culoarea și intensitatea luminii din acel punct al imaginii. Astfel, având o mulțime de pixeli se poate reprezenta o imagine reală, însă numărul de pixeli și cantitatea de informație pe care o poartă sunt esențiale pentru ca imaginea să arate cât mai natural.

Pentru a reda o imagine informația pixelilor poate reprezenta mai multe aspecte, cum ar fi luminanța, intensitatea luminoasă, sau crominanța, cantitatea de culoare, în funcție de spațiul de culoare ales. Spațiul de culoare este un grup de valori numerice asociat fiecărui pixel care oferă informație asupra anumitor elemente ce compun culoarea pe care le conține. Câteva exemple de spații de culoare sunt: RGB, YCbCr, HSV, etc.[12]

În spațiul de culoare RGB (Red, Green, Blue) fiecare pixel are câte o valoare numerică pentru fiecare dintre cele 3 culori primare, roșu, verde și albastru. Acesta este un spațiu de culoare aditiv deoarece culorile se obțin prin combinarea celor 3 culori de bază, spre exemplu culoarea galben este formată din culorile roșu si verde.

Pentru a stoca informațiile de culoare ale pixelilor pot fi folosite mai multe variante, în funcție de memoria disponibilă sau calitatea dorită a imaginii. RGB 888 folosește 3 octeți pentru fiecare pixel, 1 octet pentru fiecare culoare primară. RGB 565 și RGB 555 folosesc doar 2 octeți pentru reprezentarea culorilor, câte 5 biți pentru roșu si albastru și 6 sau 5 biți pentru verde. Astfel cu RGB 888 pot fi reprezentate 224 nuanțe de culoare pentru fiecare pixel însă este nevoie de 1 octet de memorie în plus față de RGB 565 sau 555 care au 216, respectiv 215, nuanțe.[13]

Fig. 4.7 Spațiul aditiv de culoare RGB

În spațiul YCbCr fiecare pixel din imagine conține informație despre luminanță, Y, care descrie intensitatea luminoasă, și crominanță, Cb și Cr, care descriu cromatica punctului.

Fig. 4.8 Imagine color și componentele Y, Cb, Cr

Un avantaj al acestui spațiu de culoare este faptul că se poate ține cont de faptul că ochiul uman este mai sensibil la modificări ale luminozității unei imagini decât ale crominanței.[14] Astfel, spațiul YCbCr poate fi reprezentat în mai multe formate, 4:4:4, 4:2:2, etc. Formatul 4:4:4 oferă cele mai multe informații, fiecare pixel transmite valorile pentru toate cele 3 componente, însă având în vedere particularitatea ochiului, formatul 4:2:2 este mai eficient doarece fiecare 2 pixeli împart valorile de crominanță și astfel nu este necesară transmiterea crominanței decât la fiecare 2 pixeli.

Fig. 4.9 Informația de luminanță și crominanță a fiecărui pixel în cele 2 formate

FPGA

FPGA-ul (Field Programmable Gate Array) este un dispozitiv semiconductor, un circuit integrat, care este bazat în jurul unei matrici de blocuri logice configurabile, CLB (Configurable Logic Block) conectate prin interconexiuni programabile. FPGA-urile pot fi reprogramate în funcție de necesitatea aplicației după fabricarea acestora. Acesta este principala diferență dintre un FPGA și un ASIC (Application Specific Integrated Circuit), care sunt manufacturate special pentru o anumită funcție. De asemenea, FPGA-urile permit proiectanților să modifice proiectul în stadii foarte avansate, chiar și după ce produsul a fost fabricat.[15]

Fig. 4.10 Structura unui FPGA

CLB-urile reprezintă unitatea logică de bază într-un FPGA. Fiecare CLB constă dintr-o matrice de întrerupătoare cu 4, 6 intrări, circuite de selecție, multiplexoare, si bistabile. Matrice de întrerupătoare este foarte flexibilă și poate fi configurată pentru a se ocupa de logică combinațională, registre de deplasare sau memorii RAM.

Fig. 4.11Structura unui CLB

În timp ce CLB-urile furnizează capabilitățile logice, rutele flexibile de interconectare conectează semnalele dintre CLB-uri și spre și de la intrările și ieșirile (I/O) circuitului. Rutarea poate fi în mai multe moduri, în funcție de semnal. Pentru a reduce complexitatea proiectului, programul realizează interconxiunile fără ajutorul proiectantului, dacă acesta nu dorește altfel.[15]

În prezent FPGA-urile furnizează suport pentru multe standarde de I/O-uri, astfel funcționând ca o interfață ideală pentru sistem. I/O-urile într-un FPGA sunt grupate în bancuri, fiecare banc putând să suporte un anumit standard. De asemenea, FPGA-urile conțin blocuri de memorie internă, BRAM (Block RAM), care permite accesarea unei memorii în interiorul proiectului. Aceste memorii pot fi configurate în funcție de necesitate.[16]

Fig. 4.12 Metodologia de proiectare (Xilinx)

Proiectarea unui circuit pentru un FPGA trece printr-un anumit flux specifi care ține cont de posibilitatea de revenire asupra proiectului. Inițial, sunt necesare datele proiectului, specificațiile, care specifică funcționalitatea. Având în vedere aceste specificații sunt create fișierele HDL (Hardware Description Language), care modelează circuitele logice necesare pentru funcționarea proiectului. Acestea sunt scrise în unul din limbajele de descriere hardware, Verilog sau VHDL. Acest set de fișier este testat prin simulări pentru a verifica modul de funcționare. Dacă proiectul este validat în urma simulării atunci trece prin etapa de sinteză, unde un program software analizează fișierele HDL și detectează structurile de bază ce pot fi folosite pentru realizarea funcțiilor. În această etapă se realizează diverse optimizări pentru ca proiectul să ocupe o arie cât mai mică pe circuitul integrat, să folosească cât mai puține elemente ale FPGA-ului. Sinteza generează un netlist, un fișier ce conține instanțe de primitive și conexiuni. Acest netlist trece printr-o etapă de implementare care plasează fiecare componentă a circuitului într-o anumită zonă fizică a FPGA-ului, ținând cont de constrângerile impuse de circuit, dar și de proiectant. După implementare este generat un fișier bitstream care este descărcat pe circuitul FPGA folosind o interfață serială, iar proiectul poate fi testat, iar procesul se poate relua în cazul în care sunt necesare modificări.[16]

ALGORITMI

Intersectarea planurilor a doua camere

O funcționalitate importantă a proiectului reprezintă detectarea mișcărilor bețelor în spațiul 3D din jurul utilizatorului pentru a simula un set de tobe cât mai bine. Acest lucru este realizat prin folosirea a doua camere video poziționate în așa fel încât planurile lor să se intersecteze perpendicular având astfel o coordonată spațială comună, care împreună cu celelalte 2 formează coordonatele X, Y, Z necesare.

În figura se poate observa modul în care sunt așezate camerele. Există mai multe posibilități de aranjare pentru a obține rezultatul dorit, o cameră în fața toboșarului și una în partea dreaptă sau stângă sau o cameră în față și cea de-a doua în partea de jos. Pentru a minimiza spațiul ocupat a fost aleasă varianta a doua.

Astfel cele două camere au în comun axa X, mișcarile orizontale fiind detectate de ambele camera, însă camera poziționată în față detectează mișcările verticale, iar cea de jos mișcările față-spate. Combinând coordonatele obținute se poate determina poziția în planul 3D.

O condiție importantă la această metodă este faptul că cele 2 camere trebuie sa fie foarte bine aliniate pentru o sincronizare cât mai bună.

Binarizarea imaginii după culoare

Pentru a ușura procesul de detectare a bețelor acestea au un obiect sferic în vârf colorat cu o anumită culoare. Bețele au culori diferite pentru a putea detecta mișcarile individuale ale fiecărui băț.

Astfel, în momentul în care camerele trimit informația pixelilor, acea informație de culoare este comparată cu anumite valori, care pot fi modificate pentru a testa diferite configurații, și dacă culoarea pixelul se încadrează în limitele dorite atunci este scris în memorie cu valoarea 1, altfel va avea valoarea 0. După primirea și procesarea unui cadru imaginea din memorie va fi o imagine binară, doar cu valori de 1 (culoarea alb) și 0 (culoarea negru).

Fig. 5.1. Binarizarea imaginii a. cantitatea de roșu b. cantitatea de verde c. cantitatea de albastru d. obiectul verde este evidențtiat

Filtrarea

În urma procesării culorii pixelilor ar trebui să se obțină o imagine cu o zonă de forma obiectului de culoare albă, iar restul imaginii să fie complet neagră. Acest lucru nu se întâmplă întotdeauna deoarece pot exista puncte care deși nu fac parte din obiectul ce se dorește a fi detectat au aceeași culoare cu acesta și vor fi validați. Din acest motiv este necesară o filtrare a imaginii.

Fig. 5.2 Rezultatele filtrării a. Imaginea originală b. Filtrare 3×3 c. Filtrare 5×5 d. Filtrare 7×7

Filtrarea este realizată cu un filtru de tip median. Acest tip de filtru este compus dintr-o fereastră ce se mișcă pe imagine și modifică valoarea pixelului din origine în funcție de valorile pixelilor din fereastră. Fereastra aleasă are dimensiunile de 5×5 pixeli, dimensiunea aleasă după testare în Simulink a dimensiunilor 3×3, 5×5, 7×7. În testele efectuate fereastra de 3×3 nu filtra suficient, pe când cele de 5×5 și 7×7 au avut rezultate mai bune. Trebuie ținut cont însă și de complexitatea implementării și viteza cu care poate filtra imaginea, motiv pentru care a fost aleasă fereastra de 5×5.

Detectarea poziției obiectului

Pentru detectarea poziției obiectului sunt calculate sumele pentru numărul de pixeli validați, valoarea 1 din memorie pentru fiecare linie și fiecare coloană. Practic, după filtrarea imaginii sunt adunate valorile fiecărei linii și fiecărei coloane și stocate în memorie.

Fig. 5.3 Detectarea obiectului prin calcularea sumelor

Având aceste sume, se determină cele mai mari valori pentru linii și pentru coloane, iar pozițiile unde apar aceste maxime sunt considerate coordonatele punctului în acea imagine.

RESURSE HARDWARE ȘI SOFTWARE

Placa de dezvoltare ZYBO

Caracteristici

Fig. 6.1 Placa de dezvoltare ZYBO

ZYBO (ZYnq BOard) este o placă de dezvoltare, ce permite implementarea de proiecte ce conțin atât parte de circuite digitale cât și software încorporat. Are la bază un circuit integrat AP SoC (All Programmable System-on-Chip) care integrează un procesor dual-core ARM Cortex-A9 cu logică FPGA Xilinx seria 7. [10]

Circuitul integrat Zynq 7010 AP SoC oferă următoarele facilități:

Procesor dual-core Cortex-A9 cu frecvența de 650MHz

Controller de memorie DDR3 cu 8 canale DMA (Direct Memory Access)

Controller pentru periferice cu lărgime de bandă largă: 1G Ethernet, USB 2.0, SDIO

Controller pentru periferice cu lărgime de bandă îngustă: SPI, UART, CAN, I2C

Logică reprogamabilă:

4.400 felii logice, fiecare cu 4 LUT-uri (Look Up Table) cu 6 intrări si 6 bistabile

240 KB block RAM rapid

80 de circuite DSP

Ceas intern de peste 450MHz

Convertor analog digital (XADC)

Placa de dezvoltare ZYBO are următoarele facilități:

AP SOC-ul ZYNQ XC7Z010-1CLG400C

Memorie DDR3 512MB

Port HDMI

Port VGA cu 16 biți per pixel

PHY Ethernet trimod (1Gbit/100Mbit/10Mbit)

Slot pentru card MicroSD

Memorie EEPROM externă

Codec audio

Memorie Flash Serială 128Mb

Programare prin JTAG

GPIO: 6 butoane, 4 întrerupătoare, 5 LED-uri

6 conectori PMOD

AP SoC-ul este divizat in 2 părți distincte: Sistemul de procesare, PS (Processing System) și Logica Programabilă, PL (Programmable Logic). [10]

Fig. 6.2 Arhitectura sistemului Zynq

Partea PL este un FPGA, ce poate fi configurat de proiectant, care conține însă și câteva porturi dedicate și magistrale strâns legate de PS. Astfel acestea pot comunica cu ușurință.

Partea PS include mai multe componente, APU (Application Processing Unit), care include 2 procesoare Cortex-A9, AMBA (Advanced Microcontroller Bus Architecture) Interconnect, controller de memorie DDR3, și alte controllere pentru diverse periferice care au intrările și ieșirile multiplexate pe 54 de pini dedicați ai procesorului, numiți pini de intrare/ieșire multiplexați, MIO (Multiplexed I/O). [10]

Portul VGA

Placa ZYBO folosește 18 pini logici programabili pentru a crea un port de ieșire analogic VGA. Aceasta înseamnă 16 biți pentru adâncimea de culoare și cele 2 semnale standard de sincronizare, HS (Horizontal Sync) și VS (Vertical Sync).

Fig. 6.3 Circuitul analogic VGA al ZYBO

Conversia din digital în analogic se realizează folosind o scară de rezistențe R-2R. Circuitul din figura produce trepte de semnale de culoare cu valori între 0V, complet închis, si 0.7V, complet deschis. Având 5 biți pentru roșu și albastru și 6 biți pentru verde pot fi redate 65.536 (32x32x64) de culori diferite, câte una pentru fiecare combinație de 16 biți.[10]

Pentru a folosi portul VGA trebuie creat un controller video în logica programabilă pentru a genera semnalele de sincronizare și de a furniza semnalele de culore la momente corecte de timp.

Surse de ceas

Sistemul de procesare al plăcii ZYBO are PLL-uri (Phase Locked Loop) dedicate capabile să genereze pâna la 4 ceasuri de referință, fiecare având frecvența configurabilă, care pot fi folosite pentru partea de logică programabilă. Există, însă, și un ceas extern de 125MHz legat printr-un pin direct la PL. Astfel, logica poate fi folosită independent de PS, pentru aplicațiile care nu necesită procesorul.[10]

Intrări/Ieșiri de bază

Placa ZYBO include 4 comutatoare glisante, 4 butoane cu apăsare și 4 LED-uri conectate la partea de PL. De asemenea, mai sunt încă 2 butoane cu apăsare și un LED conectate direct la PS. Butoanele și comutatoarele sunt conectate prin rezistențe în serie pentru a preveni daune cauzate de scurt circuite create din inadvertență (se poate întâmpla dacă un pin al unui buton este setat, din greșeală, ca pin de ieșire). Butoanele cu apăsare sunt comutatoare temporare care în mod normal generează un semnal jos, logic 0, când sunt libere și semnal înalt, logic 1, când sunt apăsate. Comutatoarele glisante furnizează semnal constant, 0 sau 1 logic, în funcție de poziție. [10]

Fig. 6.4 ZYBO GPIO

LED-urile sunt conectate cu anodul la Zynq cu rezistențe serie de 330Ω, și se aprind când este aplicată o tensiune înaltă la pinul acestora.

LED-ul și celelalte 2 butoane cu apăsare legate direct la PS sunt accesate doar printr-un controller GPIO.

Audio

Un codec audio SSM2603 de Analog Devices furnizează procesarea audio integrată pentru ZYBO. Acesta permite înregistrare stereo și redare la frecvențe de eșantionare de la 8kHz la 96kHz.

Pe partea analogică, codecul este conectat la 3 jack-uri audio standard de 3,5 mm. Acestea sunt 2 intrări: un microfon mono și o intrare de linie stereo, și o ieșire audio stereo.

Interfața digitală a codecului este legată la partea de logică programabilă a Zynq. Datele audio sunt transferate utilizând protocolul I2S. Configurarea codecului este realizată folosind I2C. Pentru a folosi codecul cu parametrii diferiți de cei standard, acesta trebuie să fie configurat prin I2C.[10]

Tabel 6.1 Semnalele codecului audio

Interfața I2S a codecului conține, pe lângă semnalele standard, de ceas, BCLK, selecția canalului audio, PBLRC (RECLRC pentru înregistrare), si datele, PBDAT (RECDAT), și semnalele MCLK, ceasul principal și MUTE, semnalul ce permite codecului să activeze datele recepționate pentru a fi redate.

Fig. 6.5 Transferul unui eșantion către pe canale audio

Semnalul digital de oprire a sunetului, MUTE, este activ în 0 logic și are un rezistor legat la masă, astfel încât dacă codecul nu este folosit semnalul să fie tras la 0 și să dezactiveze sunetul. Pentru a activa ieșirea codecului semnalul trebuie să primească valoarea 1 logic.

Conectori Pmod

Conectorii Pmod sunt conectori 2×6, unghi drept, mamă, spațiere de 100 mil compatibili cu pini 2×6 standard. Fiecare Pmod cu 12 pini furnizează 2 semnale de 3,3V, pinii 6 și 12, 2 semnale de masă, pinii 5 și 11, și 8 semnale logice.[10]

Fig. 6.6 Conector Pmod

Camera OV7670

CameraChipTM OV7670 este un senzor de imagine CMOS care furnizează funcționalitatea completă a unei camere VGA cu un singur cip și procesare de imagine într-un singur pachet. OV7670 oferă imagini într-o gamă variată de formate controlată prin SCCB (Serial Camera Control Bus), compatibil cu I2C.[17]

Camera are o matrice de imagine ce poate funcționa la viteze de pâna la 30 de cadre pe secundă în format VGA cu control complet al utilizatorului asupra calității imaginii și formatării. Toate funcțiile necesare procesării de imagine, incluzând controlul expunerii, gamma, echilibrul de alb, saturarea culorilor, etc., sunt, de asemenea, configurabile prin interfața SCCB.

Caracteristici:

Sensibilitate înaltă la operare în medii slab iluminate

Nivel de tensiune scăzut în funcționare pentru aplicații portabile

Standard SCCB compatibil cu I2C

Suportă rezoluțiile VGA (640×480), CIF (352×288) pentru formatele RGB (RGB565/555), YUV(4:2:2) și YcbCr (4:2:2)

Funcții automate de control a imaginii: AEC (Automatic Exposure Control), AGC (Automatic Gain Control), AWB (Automatic White Balance), ABF (Automatic Band Filter), și ABLC (Automatic Black-Level Calibration)

Control al calității imaginii incluzând saturarea culorii, nuanța, gamma, etc. [18]

Tabel 6.2 Interfața camerei

Fig. 6.8 Diagrama bloc funcțională

Pentru a funcționa camera trebuie să primească ceasul de referință, XCLK. În funcție de acesta generează celelalte semnale care sunt sincronizate cu PCLK, care are aceeași frecvență cu XCLK. Semnalele își schimbă valorile doar pe frontul negativ al PCLK, iar pe frontul pozitiv poate fi citită valoarea.[17]

Fig. 6.9 Transferul unui cadru de imagine

Sincronizarea pixelilor este realizată utilizând semnalele de sincronizare pe verticală, VSYNC, și cel pe orizontală, HREF. Pulsul pozitiv al VSYNC indică terminarea unui cadru, o imagine. Pulsul pozitiv al HREF indică faptul că valorile de pe date sunt valorile valide ale pixelilor. Pentru rezoluția de 640×480 (480 de linii a câte 640 pixeli) temporizarea pentru un cadru este reprezentată in figura.[17]

Fig. 6.10 Transferul unei linii dintr-un cadru

Începând cu primul front pozitiv al PCLK când HREF este în starea logică 1 sunt transmiși octeți de informație a pixelilor, începând cu pixelul din stânga sus a imaginii și terminând cu cel din dreapta jos. Fiecare pixel are nevoie de 2 octeți pentru a fi descris complet. În figura este exemplificată transmisia pentru formatul RGB565. Cei 16 biți de culoare sunt împărțiți în 2 octeți, mai întâi este transmisă informația pentru roșu, 5 biți, și cei mai semnificativi 3 biți pentru verde, iar apoi următorii 3 biți pentru verde și cei 5 biți pentru albastru. Astfel, pentru informația de culoare a unui pixel sunt necesare 2 perioade ale ceasului PCLK.

PlanAhead

PlanAhead este o unealtă software pentru proiectare și analiză a proiectelor cu FPGA. Aceasta oferă un mediu integrat și intuitiv pentru întreg procesul de implementare FPGA. Folosind PlanAhead se pot îmbunătăți performanțele circuitului proiectului prin analiza surselor RTL, a proiectului sintetizat sau a rezultatelor implementării.[18]

Folosind PlanAhead se crează un proiect cu setările, încă de la început, conform cipului FPGA folost. Astfel în prima etapă a creării proiectului trebuie ales cipul pe care se va implementa design-ul. Pe placa de dezvoltare ZyBo este prezent cipul Zynq-7000 xc7z010clg400.

Fig. 6.11 Alegerea tipului de circuit integrat

Fereastra principală a programului oferă acces la etapele proiectării, sinteză, implementare, generare de fișier .bit, la consolă, unde pot fi scrise comenzi de program și pot fi vizualizate mesajele de eroare sau atenționare din timpul rulării unei etape, la rapoartele rezultate în urma sintezei sau implementării, dar și la structura și ierarhia fișierelor RTL.

Fig. 6.12 Fereastra principală PlanAhead

Proiectul trebuie trecut prin fiecare etapă până la crearea fișierului BIT. Prima etapă este cea de sinteză unde softul analizează fiecare fișier RTL și crează schema finală, cu toate modulele legate între ele, folosind componente primitive specifice FPGA-ului Xilinx. Această schemă poate fi vizualizată în PlanAhead și poate fi analizată pentru a detecta eventuale erori ale sistemului.

Fig. 6.13 Schema rezultată după sinteză

Cea de-a doua etapă este cea de implementare a proiectului unde fiecare componentă din schema rezultată după sinteză este poziționată pe o locație fizică a FPGA-ului și se verifică dacă există suficient spațiu, dacă proiectul poate fi implementat pe cipul selectat. Din acest motiv este important pasul în care se alege cipul, pentru că implementarea este specifică fiecărui tip de cip.

După etapa de implementare poate fi vizualizată harta cu proiectul implementat pe FPGA. În această etapă sunt create și rapoarte cu procentul de utilizare a resurselor FPGA-ului și a constrângerilor de timp, unde se pot vizualiza căile unde au loc violări de timp.

Fig. 6.14 Plasarea componentelor pe FPGA

Pentru a folosi și procesorul ARM prezent pe placa de dezvoltare acesta trebuie adăugat în proiect ca și o sursă încorporată și integrat cu restul fișierelor prin instanțierea acestuia în fișierul top al proiectului.

Configurarea procesorului este realizată folosind unealta software XPS. Aceasta permite activarea driver-elor perifericelor disponibile, I2C, CAN, USB, etc., în funcție de necesitățile proiectului și modificarea componentelor parametrizabile ale procesorului, cum ar fi cele 4 PLL-uri ce pot furniza ceasuri către FPGA.

Fig. 6.15 Configurarea procesorului în XPS

În cazul în care proiectul folosește și procesorul atunci este nevoie ca după generarea fișierului BIT, acesta împreună cu descrierea hardware a sistemului, configurația procesorului, să fie exportată către unealta de programare software, SDK.

SDK-ul este un mediu de programare având la bază platforma Eclipse. Având la dispoziție bibliotecile cu funcțiile primitive ale perifericelor SDK-ul permite programarea si configurarea acestora pentru a fi folosite în proiect.

Fig. 6.16 Fereastra principală a SDK-ului

După crearea fișierelor sursă, C, acestea sunt compilate și este creat un fișier de tipul ELF (Executable and Linkable Format) care conține intrucțiunile pentru procesor în limbaj de asamblare. Înainte de rularea codului, FPGA-ul este programat prin descărcarea fișierului BIT pe placă prin intermediul SDK-ului. Apoi, este descărcat și fișierul ELF care este rulat pe procesor. Pot fi afișate erori sau diverse mesaje, funcții de printare în codul sursă cu mesaje pentru a ajuta la verificarea programului, în consola SDK-ului ce primește, și poate și trimite, date prin intermediul interfeței UART.

O altă caracteristică a SDK-ului este debugger-ul cu care se poate verifica programul rulat pe procesor adăugând puncte de oprire în anumite puncte ale programului, iar la fiecare pas se pot vizualiza valorile variabilelor folosite ajutând, astfel, la testarea funcționalității corecte sau la depistarea erorilor.

Python

Python este un limbaj de programare de nivel înalt cu o aria foarte mare de utilizare. Caracteristica principală a limbajului constă în faptul că pune mare accent pe modul în care este aranjat codul, pentru a fi cât mai ușor de citit, alineatul având rolul de a grupa codul, rol care este atribuit acoladelor în majoritatea limbajelor de programare. Un avantaj important al limbajului este faptul că, spre deosebire de alte limbaje sunt necesare mai puține linii de cod pentru a realiza o funcție ce ar fi complicat de implementat în alte limbaje.[19]

Python dispune de o mare varietate de biblioteci de funcții specializate pe anumite domenii, procesare de text, expresii regulate, procesare de imagini, aplicații web, aplicații multimedia, baze de date, etc. Pentru procesarea audio Python are la dispoziție biblioteca wave.

Bibilioteca wave conține următoarele funcții pentru citirea unui fișier audio:

wave.open (file[,mode]) – deschide fișierul dat ca parametru; modul specifică dacă este deschis pentru a fi citit sau scris; returnează un obiect de tip wave_read sau wave_write în funcție de modul ales;

wave_read.close() – închide instanța deschisă;

wave_read.getnchannels() – returnează numărul de canale audio (1, pentru mono, 2 pentru stereo) ;

wave_read.getsampwidth() – returnează lățimea unui eșantion în octeți;

wave_read.getframerate() – returnează frecvența de eșantionare;

wave_read.getnframes() – returnează numărul de eșantioane audio;

wave_read.getcomptype() – returnează tipul de compresie folosit;

wave_read.getcompname() – returnează numele compresiei folosite;

wave_read.getparams() – returnează un grup de parametrii; este echivalentă cu apelarea celorlalte funcții get*();

wave_read.readframes(n) – citește și returnează n eșantioane audio ca și șiruri de octeți.[20]

Astfel folosind funcțiile din Python se pot accesa eșantioanele unui fișier WAV și se pot procesa după cerințele proiectului.

PROIECTAREA

Funcționalitatea proiectului

Fig. 7.1 Schema bloc a sistemului

Modul de funcționare este următorul:

Cele 2 camere OV7670 sunt conectate la Pmod-urile plăcii de dezvoltare ZYBO

Camerele furnizează imagini care sunt captate de FPGA; imaginile sunt în format RGB 565 și în momentul în care este primit un pixel, valorile celor 3 culori sunt comparate cu un set de limite pentru filtrarea anumitor culori, v xz

Imaginea binarizată rezultată este filtrată cu un filtru median cu ferestra de 5×5

Imaginea filtrată este procesată pentru a detecta obiectul folosind algoritmul prezentat în

Folosind coordonatele obiectului din cadre succesive se verifică dacă s-a efectuat o mișcare de lovire a unei tobe

Dacă se detectează o lovire atunci procesorul este anunțat pentru a trimite modulului ce se ocupă cu redarea audio eșantioanele pentru sunetul tobei lovite

Pe monitorul VGA pot fi vizualizate pozițiile tobelor în ambele planuri, dar și imaginile binarizate în urma procesării culorilor sau filtrării.

Simulare Simulink

O primă etapă a proiectului a fost testarea funcționalității proiectului în mediul de simulare Simulink, o unealtă ce face parte din programul Matlab și care conține biblioteci cu numeroase componente ce pot fi folosite pentru a testa diverse sisteme.

Fig. 7.2 Schema bloc a simulării

Pentru a simula setul de tobe am folosit imaginile provenite de la camera web a laptopului care au trecut printr-un proces asemănător cu cel dorit pentru acest proiect. Mai întâi imaginile trec printr-un filtru de culoare care crează o imagine binară, cu valori doar de 1, pentru pixelii care au fost validați, adică au culoarea corespunzătoare și 0, pixelii ce nu au culoarea corespunzătoare.

Fig. 7.3 Binarizarea prin compararea valorilor culorilor cu constante

Imaginea rezultată este filtrată cu un filtru median cu fereastra de 5×5 și originea în centru. Următorul pas este calcularea sumelor și detectarea pozițiior maximelor acelor sume. Astfel, este detectată poziția aproximativă a obiectului, iar dacă obiectul este detectat într-o anumită zonă a ecranului este emis un sunet.

Fig. 7.4 a. Opțiunile pentru filtrare b. Configurarea blocului de calcul al sumei

În urma simulării proiectului funcționalitatea procesării a fost validată, metoda de detectare a obiectului fiind una viabilă.

Proiectarea Hardware

Modulul virtual_drum_top

Fig. 7.5 Schema bloc a modulului

Fig. 7.6 Interfața modulului virtual_drum_top

Modulul virtual_drum_top este modulul principal care leagă modulele audio_top, responsabil cu redarea sunetelor, virtual_drum, care se ocupă cu procesarea imaginilor, system, interfața cu procesorul și communication, care împarte și unește semnale pentru a ușura comunicarea dintre FPGA și procesor. De asemenea, acesta face legătura sistemului cu exteriorul cipului, cu perifericele.

Lista porturilor este următoarea:

Interfața cu GPIO-urile: LEDS_o, reset_i, switches_i

Interfața cu camerele: PCLK_i, XCLK_i, VSYNC_i, HREF_i, DATA_front_i, DATA_bottom_i, RESET_o, PWDN_o, SCL1_o, SDA1_o

Interfața cu portul VGA: VGARed_o, VGAGreen_o, VGABlue_o, VGAHSync_o, VGAVSync_o

Interfața cu codecul audio: MCLK_o, BCLK_o, MUTE_o, PBDAT_o, PBLRC_o, ac_scl, ac_sda

Aceste semnale vor fi detaliate ulterior când vor fi prezentate modulele care le folosesc.

Modulul communication

Fig. 7.7 Interfața modulului communication

Tabel 7.1 Lista de semnale ale modulului communication

Acest modul primește semnalele audio_control_fpga_arm_i, drum_hit_number_i, drum_hit_fpga_arm_i, și le unește într-o singură magistrală de 6 biți, gpio_to_arm_o, care este citită de procesor și o va despărți în semnalele componente. De asemenea, desparte magistrala gpio_from_arm_i în semnalele componente audio_control_arm_fpga_o, audio_sample_o, drum_hit_arm_fpga_o, care vor fi trimise către modulele corespunzătoare.

Această legare a semnalelor este utilă deoarece este mai simplu de transferat între FPGA și procesor un semnal de dimensiune mai mare.

Modulul audio_top

Fig. 7.8 Interfața modulului audio_top

Fig. 7.9 Schema bloc a modulului audio_top

Modulul audio_top are doar rolul de a îngloba modulele audio_controller și communication_ protocol.

Lista porturilor este următoarea:

Semnalele de ceas și reset asincron: clk_i și reset_i

Interfața audio: MUTE_o, PBLRC_o, PBDAT_o, BCLK_i, sample_i

Interfața protocolului de comunicație: audio_control_i, audio_control_o

Modulul audio_controller

Fig. 7.10 Interfața modulului audio_controller

Fig. 7.11 Lista porturilor modulului audio_controller

Acest modul are rolul de a serializa eșantioanele sunetelor primite de la procesor conform protocolului I2S. Un numărător descrescător de la 23 la 0 este folosit pentru ști ce bit al eșantionului trebuie trimis, iar PBLRC_o își inversează valoarea de fiecare dată când acest numărător ajunge la 0.

Când PBLRC_o, are valoarea 0 atunci eșantionul este trimis către canalul stând, iar când este 1 este trimis către canalul drept. Un nou eșantion este trimis mai întâi pe canalul stâng, așadar, pentru ca procesorul să aibă timp suficient pentru a pregăti următorul eșantion, acest lucru este cerut, printr-un puls al get_next_sample_o, când eșantionul curent este trimis pe canalul drept.

Semnalul MUTE_o, are valoarea 1.

Valoarea ceasului BCLK_i este calculată folosind formula (4.2.1), cu valorile , rezultând frecvența de 2,304MHz. Acest ceas este folosit pentru sincronizarea semnalelor către codecul audio.

Modulul communication_protocol

Fig. 7.12 Interfața modulului communication_protocol

Tabel 7.2 Lista porturilor modulului communication_protocol

Funcționarea acestui modul este ca a unui automat cu 3 stări cu intrările start_i și arm_fpga_i și ieșirea fpga_arm_o.

Tabel 7.3 Stările automatului pentru protocolul de comunicație

Fig. 7.13 Diagrama de stări pentru protocolul de comunicație

Acest protocol este folosit pentru ca modulul audio_controller să anunțe procesorul când trebuie trimis un nou eșantion și modulul virtual_drum când o tobă este lovită. Este necesar deoarece cele două componente nu funcționează cu același ceas și nu sunt sincronizate, iar cele două module nu ar ști când procesorul ar recepționa semnalul de atenționare.

Modulul virtual_drum

Fig. 7.14 Interfața modulului virtual_drum

Fig. 7.15 Schema bloc a modulului virtual_drum

Modulul virtual_drum conectează modulele responsabile cu afișarea pe portul VGA, detectarea lovirii unei tobe și cu controlarea celor două camere.

Lista porturilor este următoarea:

– Semnalele de ceas și reset asincron: clk_i și reset_i

– Interfața cu camerele: PCLK_i, XCLK_i, VSYNC_i, HREF_i, DATA_front_i, DATA_bottom_i, RESET_o, PWDN_o, SCL1_o, SDA1_o

– Interfața cu portul VGA: VGARed_o, VGAGreen_o, VGABlue_o, VGAHSync_o, VGAVSync_o

– Semnalele pentru comunicația cu procesorul: drum_hit_fpga_arm_o, drum_hit_arm_fpga_i, drum_o, drum_hit_o

– Semnalele de control: rgb_limits_i, selection_i

Modulul VGA_controller

Fig. 7.16 Interfața modulului vga_controller

Fig. 7.17 Schema bloc a modulului vga_controller

Modulul vga_controller instanțiază modulul vga_driver și îi furnizează ceasul de 25MHz și valorile pixelilor din memorie.

Pentru generarea ceasului de 25MHz din cel 125MHz este folosit următorul fragment de cod:

parameter[9:0] INPUT_CLK = 125;

parameter[4:0] CLK25 = 25;

parameter[3:0] CLK_COUNTER = (INPUT_CLK / CLK25);

parameter[3:0] CLK_COUNTER_NEG = CLK_COUNTER / 2;

always @(posedge clk_i or posedge reset_i)

if (reset_i) clk_counter <= 1'b0; else

clk_counter <= (clk_counter == CLK_COUNTER – 1'b1)?

1'b0 : clk_counter + 1'b1;

assign clk_transition = (clk_counter == CLK_COUNTER_NEG – 1'b1) || (clk_counter == CLK_COUNTER – 1'b1);

always @(posedge clk_i or posedge reset_i)

if (reset_i) clk25_o <= 1'b0; else

if (clk_transition) clk25_o <= ~clk25_o;

Este calculat numărul de perioade ale ceasului de 125MHz necesar pentru a genera o perioadă de ceas de 25MHz. Apoi semnalul clk25_o este inversat de fiecare dată când trece un anumit număr de perioade de ceas.

Semnalele pentru cititrea din memorie sunt generate în funcție de semnalele hcounter_o și vcounter_o (cap 7.3.8.). Semnalul enable_read_vga_o validează adresa de cititre din memorie, address_read_vga_o, iar următoarea perioadă de ceas este disponibilă data din acea locație. Acest semnal este activ cât timp sunt afișate date pe monitor.

Adresa de citire este incrementată de fiecare dată când hcounter_o își schimbă valoarea și este activ enable_read_vga_o. După ce este afișat un cadru adresa este resetată la 0.

Modulul vga_driver

Fig. 7.18 Interfața modulului vga_driver

Tabel 7.4 Lista porturilor modulului vga_driver

Modulul generează semnalele pentru funcționarea corectă a portului VGA.

Conform tabelului () o linie este formată din 800 de perioade de ceas, iar un cadru este format din 521 de linii. Numărătorul hcounter_o este incrementat la fiecare perioadă de ceas și este resetat când ajunge la valoarea 799 (de la 0 la 799 sunt 800 de perioade), iar numărătorul vounter_o este incrementat de fiecare dată când hcounter_o se resetează și revine la valoarea 0 când ajunge la valoarea 520.

Conform figurii 4.5 semnalele de sincronizare sunt inactive o perioadă de timp egală cu Tpw. Astfel, VGAHSync_o este inactiv cât timp hcounter_o este mai decât 96, iar VGAVSync_o este inactiv cât timp vcounter_o este mai mic decât 2.

Semnalele de culoare primesc valori diferite de 0 (corespunde culorii negru) doar când numărătoarele sunt între limitele impuse de tabelul 4. pentru a fi în perioada de timp în care se pot trimite valori pixelilor de pe ecran.

Modulul vga_memory_controller

Fig. 7.19 Interfața modulului vga_memory_controller

Proiectarea Software

Scripturi Python

Scriptul read_drums.py

În urma înregistrării sunetelor de tobe au rezultat fișiere tip WAV ce conțin valorile eșantionelor necomprimate ale acelui sunet. Folosind un script Python cu funcțiile bibliotecii wave au putut fi extrase acele valori și convertite în numere întregi.

Primul pas este de a deschide fișierul WAV și fișierul în care se vor scrie valorile.

wav = wave.open("drum10.wav", 'r')

sound_samples = open (drum10.txt', 'w')

Pentru că fișierele audio sunt mai lungi decât este necesar trebuie ca un anumit număr de eșantioane să fie sărite până se ajunge la sunetul înregistrat. Determinarea acestui punct s-a realizat prin vizualizarea în programul WavePad Sound Editor a formei de undă. Astfel se alege timpul, în milisecunde, de unde începe sunetul, time_to_skip. Se citesc eșantioanele timp de 500ms, iar frecvența de eșantionare fiind 48KHz rezultă că vor rezulta 24000 de valori. Aceste valori pot fi schimbate în cazul în care se doresc mai multe eșantioane sau dacă este folosită altă frecvență.

time_to_skip = 1668

time_to_keep = 500

samples_per_ms = 48

Este declarată o variabilă de tip array cu valori de tip întregi care va stoca eșantioanele extrase din sunet.

data = array.array('i')

Este determinat numărul de octeți al unui eșantion.

width = wav.getsampwidth()

Apoi este sărit un anumit de eșantioane, iar din acel punct sunt stocate datele corecte.

skip_samples = wav.readframes(time_to_skip * samples_per_ms)

data = wav.readframes(time_to_keep * samples_per_ms)

Deoarece datele stocate sunt sub formă de octeți individuali, acestea trebuie grupate câte width. Și pentru a obține valoarea întreagă a eșantionului este apelată funcția bin_to_int pentru fiecare grup de octeți.

data = [data[i:i+width] for i in xrange(0, len(data), width)]

data = [bin_to_int(s,width) for s in data]

Funcția ce convertește octeții în numere întregi este următoarea:

def bin_to_int(bin,n):

as_int = 0

for char in bin[::-1]:

as_int <<= 8

as_int += ord(char)

if (as_int & (1 << n*8 – 1) ):

as_int = -((as_int ^ ((1<<n*8-1) |((1<<n*8-1)-1)))+1)

return as_int

Funcția primește ca parametrii grupul de octeți al eșantionului și numărul de octeți pe care este reprezentat un eșantion. Mai întâi octeții sunt așezați în format big-endian pentru a putea calcula valoarea întreagă. Apoi este comparat bitul cel mai semnificativ al valorii obținute cu ’1’, ceea ce ar indica faptul că numărul este negativ. În acest caz as_int trebuie să fie convertit în număr întreg negativ.

La final datele sunt scrise într-un fișier pentru a fi prelucrate ulterior.

Scriptul sample.py

Pentru a ușura procesul de scriere a eșantioanelor în fișierele C a fost folosit scriptul sample.py .

Programare procesor

Întrucât circuitul integrat Zynq conține atât circuitul FPGA cât și un procesor ARM s-a ales o proiectare hibridă hardware-software. Astfel, anumite procese sunt efectuate de procesor. Un avantaj al folosirii procesorului este faptul că folosind programul SDK se poate realiza o legătură între utilizator și sistem prin terminalul programului și se poate crea un soft pentru a permite comunicarea între aceștia.

Funcția principală a procesorului este de a furniza eșantioane circuitului FPGA când este anunțat.

Procesorul citește mereu valoarea de pe intrarea GPIO care are următorul format: bitul 5 reprezintă semnalul de trimitere a următorului eșantion, bitul 4 semnalul de atenționare că o tobă a fost lovită, iar ultimii 4 biți reprezintă numărul tobei care a fost lovită.

Următorul fragment de cod citește intrarea și împarte magistrala în părțile componente.

GPIO_input_value = XGpio_DiscreteRead(&sample_control, 2);

audio_control_fpga_arm = ( GPIO_input_value >> 5 );

drum_hit_fpga_arm = ( GPIO_input_value >> 4 ) & 0x01;

drum_hit = ( GPIO_input_value & 0x0F );

Semnalele audio_control_fpga_arm și drum_hit_fpga_arm provin de la modulul communication_protocol, care așteaptă confirmarea de la procesor. Așadar a fost introdus protocolul și în software, însă sunt necesare doar 2 stări, IDLE și ACK. Când este primit un semnal de atenționare se trece din starea IDLE în starea ACK, iar în momentul în care circuitul FPGA recepționează confirmarea și trece semnalul de control în 0 starea trece înapoi în IDLE.

switch ( current_state ){

case IDLE: { if ( control_to_arm == 1) next_state = 1; }

break;

case ACK: { if ( control_to_arm == 0 ) next_state = 0; }

break;

}

De fiecare dată când este lovită o tobă are loc o etapă de inițializare a unor variabile ce vor fi specifice acelei tobe:

drums_hit_number, reprezintă numărul tobei care a fost lovită și este folosit pentru a alege sunetul specific acelei tobe

drums_memory_offset,poziția în memorie de unde încep să fie inserate eșantioanele

drums_index,numărul eșantionului curent

drums_memory_section, reprezintă secțiunea de eșantioane ce a fost scrisă în memorie

Pot fi active maxim 4 sunete de tobe în același timp, iar această limită este verificată prin drums_hit[4] care inițial are valoarea 0 pe toate pozițiile ceea ce înseamnă că toate pozițiile sunt libere. Când este lovită o tobă drums_hit este parcurs într-o buclă for, iar prima poziție care are valoarea 0, însemnând că este liberă, va fi folosită pentru toba respectivă și va primi valoarea 1. Variabila drums_active urmărește câte tobe sunt active la un moment dat.

if ( new_drum_hit == 1 ) {

xil_printf("DRUM HIT\n");

for (i = 0; i < 4; i++ ){

if ( drums_hit[i] == 0 ){

drums_hit_number[i] = drum_hit;

drums_memory_offset[i] = i * 10000;

drums_index[i] = 0;

drums_hit[i] = 1;

drums_memory_section[i] = 1;

drum_section_check[i] = 0;

drums_active ++;

xil_printf("drum_hit = %d\n", drum_hit);

break; }

new_drum_hit = 0; } }

Concluzii

Bibliografie

[1] “Realtime webcam virtual drum – draft version”, Daniel Lelis Baggio,

https://www.youtube.com/watch?v=QJvKT-NId9M (23.04.2014)

[2] “Wii Music drums”, Nintendo,

https://www.youtube.com/watch?v=Xa_cTiMUjJQ (23.04.2014)

[3] “AirBeats for Leap Motion”, Handwavy,

https://www.youtube.com/watch?v=fU4ZWAPwvcM (23.04.2014)

[4] “DrumChuk – Wii Drums for Mac”, TheFranklinKite,

https://www.youtube.com/watch?v=iQe6-WjcKw0 (23.04.2014)

[5] “Airdrumming with Kinect (Brought to you by ‘Hex on the Beach’)”, Aayush,

http://vimeo.com/74565829 (23.04.2014)

[6] “Moto Prototype Demo”, MotoKinect,

https://www.youtube.com/watch?v=Vxhp-XG3jd0 (23.04.2014)

[7] “Virtual Drums”, Matthieu Aubry, Julien Rouviere, Xavier Maurice,

http://www.virtual-drums.com/ (23.04.2014)

[8] Curs “Sisteme electronice încorporate”, Mihai Romanca

http://vega.unitbv.ro/~romanca/EmbSys/Electronica%20Aplicata-2013-2014/12-I2C-bus.pdf

[9] “I2S bus specification”, Philips Semiconductors,

https://www.sparkfun.com/datasheets/BreakoutBoards/I2SBUS.pdf

[10] “ZYBO Reference Manual”, Digilent,

http://www.digilentinc.com/Data/Products/ZYBO/ZYBO_RM_B_V6.pdf

[11] “WAVE PCM soundfile format”,

https://ccrma.stanford.edu/courses/422/projects/WaveFormat/

[12] “Culoarea”, curs “Tehnologii Multimedia”

http://ctmtc.utcluj.ro:8080/sites/curs_tm/Documente%202011/01%20Curs/02_Culoare1_7Mar2011.pdf

[13] “Afișaje video”, curs “Interfețe și periferice”, Petre Ogruțan,

vega.unitbv.ro/~ogrutan/materiale%202011/3-Afisaje%20video%20si%20controllere.ppt

[14] “Standardul MPEG pentru codarea semnalelor TV”, curs “Radio și Televiziune”,

http://vega.unitbv.ro/~nicolaeg/TV-TSTC%20si%20EA%202013-2014/Cursul%20TV/Curs%2011.pdf

[15] Xilinx

http://www.xilinx.com/fpga/index.htm

[16] Xilinx

http://www.xilinx.com/fpga/asic.htm

[17] OV7670 Datasheet, OmniVision,

http://www.voti.nl/docs/OV7670.pdf

[18] Xilinx,

http://www.xilinx.com/tools/planahead.htm

[19] “General Python FAQ”, Python

https://docs.python.org/2/faq/general.html

[20] Biblioteca wave

https://docs.python.org/3/library/wave.html

Bibliografie

[1] “Realtime webcam virtual drum – draft version”, Daniel Lelis Baggio,

https://www.youtube.com/watch?v=QJvKT-NId9M (23.04.2014)

[2] “Wii Music drums”, Nintendo,

https://www.youtube.com/watch?v=Xa_cTiMUjJQ (23.04.2014)

[3] “AirBeats for Leap Motion”, Handwavy,

https://www.youtube.com/watch?v=fU4ZWAPwvcM (23.04.2014)

[4] “DrumChuk – Wii Drums for Mac”, TheFranklinKite,

https://www.youtube.com/watch?v=iQe6-WjcKw0 (23.04.2014)

[5] “Airdrumming with Kinect (Brought to you by ‘Hex on the Beach’)”, Aayush,

http://vimeo.com/74565829 (23.04.2014)

[6] “Moto Prototype Demo”, MotoKinect,

https://www.youtube.com/watch?v=Vxhp-XG3jd0 (23.04.2014)

[7] “Virtual Drums”, Matthieu Aubry, Julien Rouviere, Xavier Maurice,

http://www.virtual-drums.com/ (23.04.2014)

[8] Curs “Sisteme electronice încorporate”, Mihai Romanca

http://vega.unitbv.ro/~romanca/EmbSys/Electronica%20Aplicata-2013-2014/12-I2C-bus.pdf

[9] “I2S bus specification”, Philips Semiconductors,

https://www.sparkfun.com/datasheets/BreakoutBoards/I2SBUS.pdf

[10] “ZYBO Reference Manual”, Digilent,

http://www.digilentinc.com/Data/Products/ZYBO/ZYBO_RM_B_V6.pdf

[11] “WAVE PCM soundfile format”,

https://ccrma.stanford.edu/courses/422/projects/WaveFormat/

[12] “Culoarea”, curs “Tehnologii Multimedia”

http://ctmtc.utcluj.ro:8080/sites/curs_tm/Documente%202011/01%20Curs/02_Culoare1_7Mar2011.pdf

[13] “Afișaje video”, curs “Interfețe și periferice”, Petre Ogruțan,

vega.unitbv.ro/~ogrutan/materiale%202011/3-Afisaje%20video%20si%20controllere.ppt

[14] “Standardul MPEG pentru codarea semnalelor TV”, curs “Radio și Televiziune”,

http://vega.unitbv.ro/~nicolaeg/TV-TSTC%20si%20EA%202013-2014/Cursul%20TV/Curs%2011.pdf

[15] Xilinx

http://www.xilinx.com/fpga/index.htm

[16] Xilinx

http://www.xilinx.com/fpga/asic.htm

[17] OV7670 Datasheet, OmniVision,

http://www.voti.nl/docs/OV7670.pdf

[18] Xilinx,

http://www.xilinx.com/tools/planahead.htm

[19] “General Python FAQ”, Python

https://docs.python.org/2/faq/general.html

[20] Biblioteca wave

https://docs.python.org/3/library/wave.html

Similar Posts

  • . Aplicatie Online Pentru Recrutarea Si Facilitarea Comunicatiei Intre Membrii Programului

    I. Tema lucrării Se cere implementarea unei aplicații online pentru recrutarea și facilitarea comunicației între membrii unei companii multinationale. Aplicația oferă următoarele facilități: permite căutarea (după nume, prenume, țara și orașul în care aceștia își desfășoară activitatea, precum și cateva din datele lor personale); permite vizualizarea si actualizarea datelor personale: nume, prenume, locul si data…

  • Auditarea Sistemului Informatic

    Capitolul 1 Auditul sistemelor informatice, componentă a sistemului de audit Definirea și conceptul auditului sistemelor informatice În literatura și practica se întâlnesc termenii de auditul sistemelor informaționale, auditul sistemelor informatice sau auditul informatic (auditul IT), Diferența conceptuală dintre acești termeni este dată pe de o parte de conținutul și nivelul la care se desfășoară activitatea…

  • Arhitectura Magazinelor Online

    1.Intoducere 1.1            Internetului în lume Internetul poate fi considerat un mediu, o infrastructura ce ofera agentilor economici, spre exemplu, abilitatea de a se face cunoscuti atât clientilor cât si posibililor parteneri de afaceri, de a accesa informatia usor si rapid. Ce este internetul? Sunt multe definitii pentru acest mediu. Este considerat, în primul rând, ca si…

  • Xml Tehnologii

    CUPRINS Întroducere………………………………………………………………………………3 Capitolul I: EXtensible Markup Language (XML)…………………………………..4 1. XML – EXtensible Markup Language………………………………………………4 1.1. Tehnologiile XML……………………………………………………………..5 Elementele specifice limbajului XML……………………………………8 1.2. Documente XML……………………………………………………………..9 1.2.1. Regulile de creare a documentului XML…………………………………11 1.2.2. Documente bine formatate și documente valide………………………….13 1.2.3. Sintaxa documentelor XML………………………………………………13 1.2.3.1. Simbolurile speciale…………………………………………………….14 1.2.3.2. Începutul unui element și tag-ul de sfîrșit………………………………14 1.2.3.3. Atribute………………………………………………………………….16…

  • Aplicatie Software Pentru Evidenta Resurselor Umane Dintr O Firma

    1. INTRODUCERE Managementul competitiv al resurselor umane reprezintă un factor esențial pentru succesul oricărei firme. Datorită importanței factorului uman în asigurarea succesului competițional al fimei, funcția de resurse umane s-a amplificat cu un număr sporit de activități. Pentru un management eficace al resurselor umane este nevoie de informații pertinente și oportune. Rolul asigurării acestor informații…