Persistence of vision

by donpedro

Proiectul a fost realizat în perioada de vară, în cadrul unei colaborări între Microchip şi laboratorul InGeAr, din cadrul Universităţii POLITEHNICA din Bucureşti. Ţinem să mulţumim pe această cale mentorilor din cadrul echipei Microchip, în special mentorului nostru, Horia Boicu pentru îndrumarea şi răbdarea de care a dat dovadă.

Articolul de faţă prezintă o aplicaţie complexă – un sistem de afişaj bazat pe efectul optic “persistenţa viziunii” – pentru realizarea căruia am trecut printr-un proces de învăţare spectaculos, experienţă din care vom încerca în cele ce urmează să vă împărtăşim câteva aspecte.

Autori:
Vladimir Oltean – olteanv@gmail.com
Iulian Calciu – iuliancalciu@gmail.com
Alexandra Marinescu – alexa.alyas@yahoo.com
Alexandra Ştefănescu – s.alexandra.stefanescu@gmail.com

Principiul de funcţionare şi prezentare generală

Pentru a înţelege mai bine fenomenul de “persistenţă a viziunii” trebuie amintit faptul că ochiul nu funcţionează precum o cameră foto, în sensul că vederea nu se rezumă la lumina care loveşte un mediu. Creierul trebuie să proceseze datele vizuale transmise de ochi şi să construiască o imagine coerentă a realităţii. Astfel, pentru ochi nu există un frame rate, ci întregul sistem ochi-creier funcţionează precum o colecţie de senzori de detecţie a mişcării, a detaliilor, precum şi a modelelor, iar înregistrările acestor senzori se combină pentru a crea o experienţă vizuală.
Încă din secolul al XIX-lea au existat invenţii optice care puteau reda “persistenţa viziunii”. Ele se pot enumera astfel: taumatropul – disc conţinând mai multe imagini ce se învârte cu rapiditate; stroboscopul şi praxinoscopul – pe o fâşie de hârtie, în interiorul unui cilin­dru sunt desenate secvenţe repre­zen­tând mişcarea. Astăzi, majoritatea desenelor ani­mate sau a animaţiilor sunt create bazându-se pe aceast mecanism.
Dorind să aflăm mai multe despre acest fenomen remarcabil, nu doar la nivel teoretic, ci şi practic, ne-am hotărât să ne construim un astfel de dispozitiv.
Susţinuţi de laboratorul Ingear, un centru unde studenţii pasionaţi de hardware, electronică şi robotică au posibilitatea de a lucra la astfel de proiecte, precum şi de Microchip Tehnology, am reuşit să ne asamblăm propiul PoV. Filmuleţe cu acesta în mişcare se pot găsi pe pagina de Facebook “eap.ingear”.

Layout şi design mecanic

Dispozitivul este format dintr-o plăcuţă principală dreptunghiulară, centrată pe axul vertical al unui motor şi care se învârte odată cu acesta. De extremităţile sale laterale se află, prinse câte două L-uri metalice, alte două plăcuţe, perpendiculare pe plăcuţa principală. Împreună, acestea formează un ansamblu în formă de T.

Plăcuţele laterale au fiecare câte 16 LED-uri intercalate pe verticală. Astfel, rezoluţia verticală este fixată la 32 de “pixeli”, cu liniile pare afişate de una din plăcuţe, iar cele impare afişate de cealaltă. Rezoluţia orizontală, pe de altă parte, este reglabilă, el făcând “stretch” la imaginea din memorie, astfel încât să umple 360 de grade cu ea.
Cea mai mare dificultate mecanică întâmpinată a fost aceea de a centra placa principală, motiv pentru care am renunţat la baterie (vezi Design electronic). Pentru centrare, am folosit următoarea metodă: pui placa principală pe un ax orizontal şi o loveşti încet, aşteptând să se oprească. Dacă aceasta oscilează, înseamnă că nu este centrată. O placă centrată în mod corect ar trebui să se stabilizeze fără oscilaţii în orice poziţie şi nu cu partea mai grea în jos. Pentru centrare am folosit fie repoziţio­narea diverselor componente, fie adău­garea de fludor pe planul de masă al părţii mai uşoare.

Design electronic

POV-ul se foloseşte de două alimentări separate, una de putere (pentru motor) şi una pentru logică. Deşi planul iniţial a fost ca tensiunea de alimentare a motorului să fie controlată prin PWM cu un algoritm de tip PID, pe parcurs am considerat acest lucru inutil, cu toate complicaţiile aferente.

Astfel, în starea ac­tua­lă, motorul DC se foloseşte de două surse reglabile de tensiune montate în paralel.
Cât despre alimentarea circuitelor logice, planul iniţial a fost de asemenea diferit, şi anume de a monta o baterie pe placa prin­cipală, cât mai aproape de centru. Cu pro­blemele de stabilitate menţionate mai sus, am renunţat la baterie, şi am adoptat soluţia energiei transmise prin perii (detalii în cele ce urmează).
Nu este vorba de “brushed DC motor”, ci chiar de două perii care fac contact prin frecare pe două inele circulare de pe placa principală, cu centrul în gaura pentru axul motorului. “Periile” sunt în fapt nişte arcuri metalice, izolate electric de alimentarea motorului, dar fixate mecanic de carcasa acestuia, pe care plasăm o tensiune electrică. Prin faptul că periile fac contact cu pistele de pe placă, tensiunea de alimentare se poate transmite fără a fi nevoie de o baterie. În practică, contactul dintre perii şi placă este departe de a fi perfect, rezultând un zgomot foarte mare pe alimentare. Drept urmare, controlerul se resetează, adică dioda Zener şi comparatorul din interiorul lui depistează că s-a ajuns sub tensiunea de prag critică funcţionării sale corecte (frecvenţa de ope­rare a unui circuit CMOS este propor­ţională cu tensiunea de alimentare!) şi se resetează.
O metodă de combatere a pagubelor produse de aceste variaţii este folosirea unor condensatoare pentru a filtra zgomotele produse de perii. Ca valoare efectivă, această tensiune de alimentare a logicii este în jurul valorii de 8 – 8.5V şi trece prin două stabilizatoare liniare: un 7805 şi un NCP1117DT33G, care aduc tensiunea la 5V, respectiv 3.3V.

Singura componentă care foloseşte alimentarea de 3.3V este modulul de Bluetooth (chip-ul RN42), toate celelalte fiind legate la 5V (aşa cum am menţionat şi mai sus, asta îi permite şi controlerului să ruleze la o frecvenţă mai mare).
Plăcuţele laterale, aşa cum spuneam, sunt conectate de main board printr-un cablu panglică cu 6 fire: VCC, GND, SIN, SCLK, BLANK şi XLAT. Mai multe detalii despre transmisia serială vor fi la

capitolul de programare, însă este suficient să spunem că aceste fire sunt solicitate de către driver-ul de LED-uri, un TLC5947 de la Texas Instruments. Acesta este construit propriu-zis ca un registru de shiftare pe 288 de biţi, grupaţi ca 24 seturi de câte 12. Astfel pot fi controlate până la 24 de LED-uri în paralel, iar fiecare set de 12 biţi reprezintă o va­loare PWM de la 0 la 4095, din care se poate regla intensitatea individuală a acestora. Driver-ul trebuie să alimenteze toate LED-urile la o sursă de curent constant, implementată ca o oglindă de curent a curentului de referinţă, setabil pe pinul Iref, prin modificarea rezistenţei Rref (2.4kOhmi rezultă un curent de 20mA).
Pentru depistarea unei rotaţii la 360 de grade, folosim un senzor Hall care reacţionează la câmpul magnetic al celor doi magneţi plasaţi pe bara fixă de lângă motor.
Ca principiu, senzorul furnizează la ieşire o tensiune de aproximativ 0.45V atunci când este activat de polul Nord al unui magnet şi 0V când este activat de polul Sud. Deoarece tensiunea de ieşire manifestă fenomenul de remanenţă, chiar şi după ce se înlătură din câmpul magnetic, este nevoie şi de al doilea magnet pentru a asigura o tranziţie din “low” în “high”. Pentru a ajuta senzorul, am mai folosit şi un amplificator operaţional, LM324, pentru a aduce tensiunea de ieşire în starea “high” la un nivel logic acceptabil. Bucla de reacţie a op-amp-ului este reglabilă printr-un mini-potenţiometru.

Schema electrică a fost realizată în Eagle şi a fost concepută ca un PCB two-sided, cu trasee de putere cu grosimea de 1mm, iar cele pentru logică de 0.4mm. Package-urile folosite au fost SMD pentru toate compo­nentele (mai puţin condensatoarele electrolitice folosite pentru filtrarea curentului transmis prin perii).
Comunicaţia dintre microcontroler şi Bluetooth este un subiect demn de abordat, atât prin natura sa electronică, cât şi de programare.
Logic, ele sunt conectate printr-o interfaţă UART (Universal Asynchronous Receiver/ Transmitter), un protocol bazat pe standardul serial RS232, dar adaptat la nivele logice scăzute (standardul prevede între -3 şi -12V pentru “1” şi între +3 şi +12V pentru “0”). Din această interfaţă, noi nu vom folosi decât firele de Rx, Tx şi GND, pentru o comunicaţie full duplex între Bluetooth şi microcontroler. Din punct de vedere electric, este interesantă interconectarea unui dispozitiv de 5V cu unul de 3.3V: dinspre controler am folosit un divizor de tensiune rezistiv, iar în sens invers ne-am bazat pe tensiunea de prag de 2.5V şi marginea de zgomot bună a chip-urilor CMOS, legând direct ieşirea RN42-ului la intrarea microcontrolerului.

Programare

Şi pentru că a venit vorba despre microcontroler, adică inima proiectului, am folosit chip-ul dsPIC30F4011 de la Microchip, un DSP de 16 biţi care poate rula până la 120MHz.
Programarea a avut loc în IDE-ul MPLAB X de la Microchip, în limbajul C. Au existat tentative de a introduce cod în limbaj de asamblare, însă pasajele respective au fost înlocuite, nefiind critică execuţia lor. Compilatorul folosit a fost varianta gratuită de XC16, fără optimizări.
Clocking-ul controlerului este în mod implicit setat pe un oscilator RC intern, ce rulează la 8MHz (comparabil cu Intel 80286 din 1982!). Din motiv că această viteză nu este suficientă (pixelii apar ca dungi orizontale), am decis să folosim un oscilator extern de quartz de 6MHz. Apoi, folosind circuitul încorporat de PLL (Phase-Locked Loop) al microcontrolerului, am multiplicat această frecvenţă de 16 ori, obţinând o frecvenţă de oscilaţie efectivă de 96MHz.
Temporizarea instrucţiunilor la familia de procesoare PIC, ca la majoritatea arhitecturilor RISC, este una foarte simplă, un ciclu de instrucţiune completându-se la fiecare 4 cicli de ceas. Astfel se obţine:

Fpri = 6 MHz, PLL = 16x
Fosc = Fpri * PLL
Fcy = Fosc / 4

Cunoscând şi faptul că pipeline-ul acestui procesor este unul de asemenea foarte simplu, în 2 etape, ajungem la concluzia că el rulează la 24MIPS, sau începe o instrucţiune nouă la fiecare 41.6 nanosecunde.

Instruction Flow – 1-Word, 1-Cycle

Acestea fiind spuse, programul se bazează pe următorul algoritm: instalează o întrerupere de Change Notification pe pinul la care se află legat senzorul Hall, apoi cronome­trează intervalul dintre două activări succesive ale acestuia. Acest interval reprezintă durata unei rotaţii complete la 360 de grade. Dacă dorim să afişăm toate coloanele imaginii în acest timp, înseamnă că fiecare coloană trebuie afişată la un interval egal cu durata împărţită la numărul de coloane.
Timing-ul unei noi afişări se face prin intermediul unei alte intreruperi, de Timer 1. Pentru a cronometra întreruperile de senzor Hall, folosim un timer de 32 de biţi (Timer2/3 concatenate), pentru a creşte raza intervalului măsurat la o valoare teoretică de 232 * 41ns, adică aproximativ 176 secunde, păstrând în acelaşi timp rezoluţia de 41 de nanosecunde, cu un prescaler de 1:1.
Putem acum detalia transmisia serială a datelor atunci când se doreşte afişarea unei noi coloane. Metoda folosită se numeşte “bit banging” şi este de o complexitate deosebit de joasă.

Practic, aceasta presupune legarea pinilor de transmisie SIN/SOUT şi SCLK (serial in/out şi serial clock, linii ce caracte­ri­zează, de altfel, interfaţa I2C), direct la porturile de uz gene­ral ale microcontrolerului. În acest mod, ele pot fi setate în mod direct, prin instrucţiuni de tipul SOUT = 1; SCLK = 1; SCLK = 0; fără a avea un control deosebit de mare asupra factorului de umplere al ceasului rezultat prin alternarea liniei de SCLK. Dacă acest lucru ar fi fost strict necesar, ar fi fost nevoie ca numărul de instrucţiuni executat de procesor după SCLK = 1; să fie fix acelaşi ca cele executate după SCLK = 0; iar acest lucru este foarte greu de controlat, dacă nu imposibil, atât timp cât programarea are loc în C şi nu în asamblare (nu putem fi siguri de codul maşină în care transformă compilatorul codul nostru).
Driver-ul de LED-uri funcţionează în felul următor: la fiecare front pozitiv al liniei SCLK, datele din registrul de shiftare se mută cu o poziţie mai la dreapta, pentru a-i face loc noului bit (citit de pe linia de SIN) în poziţia de MSB (Most Significant Bit). Transmisia se opreşte la frontul pozitiv al liniei XLAT (latch data), prin care biţii sunt copiaţi din shift register în latch-urile de control ale LED-urilor.

Acestea se aprind pe palierul negativ al liniei BLANK şi rămân aprinse până la un front negativ al acesteia. Linia de GND forţează ca plăcuţele laterale şi cea principală să aibă masa comună şi impiedică formarea buclelor de masă (ground loops).
Un ultim aspect ce a mai rămas de discutat este stocarea imaginilor în memorie. O scurtă privire în arhitectura acestui procesor ne indică o construcţie de tip Harvard, cu spaţiul de date diferit de spaţiul de cod. Mai precis, zona de program este mapată peste o memorie EEPROM de 144KB, iar zona de date peste o memorie flash de 4KB, de departe insuficient pentru a stoca o imagine cu adâncimea de culoare de 12 biţi, cât ne permite driver-ul de LED-uri. Din acest motiv, am adoptat pentru o repre­zentare mult comprimată a imaginii, ea fiind spartă în două matrice şi reprezentată pe coloane, fiecare fiind un număr pe 16 biţi (1 bit = 1 pixel). Transmisia se face simultan pentru ambele plăcuţe laterale, cu men­ţiunea că la oricare moment de timp, plăcuţa a doua afişează coloana diametral opusă faţa de prima (ele sunt mereu la 180 de grade una faţă de cealaltă).

Odată ce bitul corespunzător este pus pe linia de SOUT, ceasul (SCLK) este basculat de 12 ori, pentru a produce numărul “000…0” sau “111..1”, adică 0 sau 4095 (minim sau maxim). Am redus astfel adâncimea culorii de la 12 biţi la 1 bit.
Chiar şi aşa, memoria de 4KB este insuficientă pentru stocarea a mai mult de o imagine la un moment de timp. Metoda actuală de schimbare a imaginii este prin reprogramare cu o nouă matrice hard-codată, însă o aplicaţie pentru modulul de Bluetooth este în lucru.
Generarea imaginilor se face pe calculator în editorul de text preferat (imaginile actuale au fost create în Vim), folosind ceva ce nu diferă prea mult de ASCII art, apoi sunt convertite printr-un mic program în cod ce poate fi inserat direct în programul POV-ului.

Planuri şi modificări viitoare

În momentul actual, arcurile periilor produc un contact sub-optimal cu placa, ceea ce duce la resetări neplăcute ale controlerului. Acestea vor fi înlocuite cu perii noi, din cărbuni, care dau rezultate mai bune în condiţii de uzură şi protejează inelele de cupru de pe placa centrală.
Cum spuneam mai sus, un software care să comunice cu POV-ul pentru transmisia imaginii prin Bluetooth va fi gata odată cu upgrade-urile mecanice. Menghina care îl susţine în momentul de faţă va fi de asemenea înlocuită cu un suport adecvat.

Acestea fiind spuse, fiţi pregătiţi pentru un nou episod cu POV-ul şi peripeţiile prin care va trece, în numărul următor din Electronica Azi Hobby!

S-ar putea să vă placă și