Table of Contents

Persistence of Vision Display

Autor: Carapcea Andrei-Antonio 336CA

Introducere

“Persistence of vision” (POV) reprezinta fenomenul ce caracterizeaza persistenta unor imagini pe retina. Este destul de similar cu comportamentul unui aparat foto cu un timp de expunere mai mare. Practic, daca un punct se misca suficient de rapid, acesta va fi perceput continuu pe retina pe intreaga traiectorie a lui.

Tema proiectului consta in realizarea unui display POV care se foloseste de aceasta iluzie optica pentru a afisa o anumita imagine cu ajutorul unor LED-uri dispuse pe o linie si se rotesc foarte repede.

Am ales acest proiect deoarece am vrut sa obtin mai multa experienta pe partea de hardware(sa invat sa lipesc fire, etc.) si pentru ca ofera un feedback vizual foarte placut. De asemenea, a fost o oportunitate buna de a aprofunda si cunostintele software, intrucat a fost necesar sa lucrez cu un timer si intreruperi.

Descriere generală

Proiectul are doua componente principale: componenta rotativa si componenta motoare care se ocupa cu rotirea efectiva.

Componenta rotativa este formata dintr-un rotor(un suport fizic pe care se monteaza celalalte componente), placuta Arduino cu o sursa de alimentare, LED-urile cu rezistente si un senzor magnetic Hall.

Pe langa componenta rotativa si cea motoare, mai exista si un magnet stationar. Senzorul Hall detecteaza momentul cand acesta trece pe langa magnet, oferind o modalitate de a calcula viteza de rotatie.

Schema bloc

Hardware design

Componente folosite

Sursa imagine Arduino Nano

Sursa imagine Senzor Hall

Sursa imagine magnet

Dispozitivul realizat

Procesul de realizare

Am ales sa folosesc un CD drept rotor pentru ca are o forma rotunda, ofera destul spatiu de montare si este in acelasi timp destul de compact.

Am ales sa folosesc bormasina drept componenta motoare pentru ca este suficient de puternica astfel incat sa roteasca tot dispozitivul fara probleme.

Initial am folosit un motoras DC de 9V, lipit pe o cutie de carton:

Desi motorul era suficient de puternic pentru a roti CD-ul cu LED-urile si cu placuta Arduino, atunci cand adaugam bateria de 9V nu mai facea fata si rotea destul de incet. O alta alternativa incercata a fost un ventilator de PC, insa nici el nu avea suficient cuplu.

Am ales sa montez led-urile pe o parte a CD-ului(partea din fata, cea pe care se vede efectul), iar pe cealalta parte(partea din spate) am montat restul componentelor.

Am invelit CD-ul in banda izolera neagra pentru a obtine un rezultat vizual mai bun. LED-urile se vad mai bine pe un fundal negru. Acesta este si motivul pentru care am pus celalalte componente pe fata din spate, pentru a nu influenta rezultatul vizual final.

Am dat 8 gauri prin CD, prin care am montat LED-urile. Pe partea din spate, le-am lipit pe o placuta de protitipare, alaturi de rezistente.

Apoi, am lipit firele care urmau sa se conecteze la arduino. Am montat Arduino pe o alta placuta de prototipare, intrucat nu mai era loc pe prima si am lipit firele ce leaga LED-urile. Dupa aceea, am lipit conexiunile cu senzorul Hall si am legat bateria cu intrerupatorul la placuta.

La final, am lipit toate componentele pe CD cu un pistol de lipit. Am adaugat cateva piulite suplimentare pentru stabilizarea CD-ului.

De altfel, una dintre cele mai mari probleme la un astfel de dispozitiv o reprezinta echilibrarea mecanica a partii rotative. Daca aceasta nu este echilibrata cum trebuie, este foarte probabil ca miscarea de rotatie sa nu fie lina si suficient de rapida.

In ceea ce priveste modul in care se fixeaza CD-ul pe bormasina, am folosit un surub cu o piulita. Piulita era un pic mai mica decat gaura de la CD, si de aceea am folosit si o saiba pe partea din spate. Pe partea din fata am folosit o garnitura de aragaz, pentru ca e formata dintr-un material mai moale si permite o mica ajustare a pozitiei CD-ului (initial am folosit tot o saiba, insa CD-ul statea un pic stramb).

Schema electrica

Software design

Am lucrat in Arduino IDE.

Sursa de inspiratie:

techydiy.org POV Display

Configurare display

Atunci cand linia de pixeli se roteste, aceasta urmareste traiectoria unui cerc. Acest cerc poate fi discretizat, eu am ales sa il impart in 64 de unghiuri egale. Astfel, fiecare unghi poate fi considerata o “coordonata” pentru LED-uri, avand o valoare asociata in fiecare din cele 64 din unghiuri.

Folosind 8 LED-uri, starea acestora la un moment de timp poate fi stocata intr-un octet, fiecare LED avand asociat un bit. Bitul cel mai nesemnificativ corespunde LED-ului din exterior, iar cel mai semnificativ LED-ului din interior. Astfel, pentru a stoca starea LED-urilor pe parcursul unei rotatii, este nevoie de un vector de 64 de octeti.

Un exemplu de configurare poate arata astfel:

byte config[64] ={
B01111111, //P
B00001001,
B00001001,
B00000110,
B00000000,
B01111111, // M
B00000010,
B00001100,
B00000010,
B01111111,
B00000000
};

Am gasit un header care ofera configurarea pentru fiecare caracter ASCII aici:

techydiy.org font.h

Astfel, se poate scrie orice caracter pe display-ul POV.

Modul de conectare

Pinout Arduino Nano:

Sursa Arduino Nano pinout

Am ales sa conectez LED-urile astfel incat sa ocupe fix portul PD (PD0-PD7 sau D2-D7 + D1, D0, adica RX0 si TX1). Astfel, pentru a modifica starea LED-urilor, se scrie direct valoarea retinuta in memorie in PORTD.

Senzorul magnetic Hall este conectat la D8, care are ICP1 (Input Capture Unit). ICP1 este folosit in cadrul timer-ului 1 pentru a calcula perioada de rotatie.

Timer1 si modul de functionare

Timer 1 este configurat astfel:

 // normal wave generation
 TCCR1A = 0;    
 // ICNC1 = input capture noise canceller
 TCCR1B |= (1 << ICNC1);
 // CS10 = prescaler 1
 TCCR1B |= (1 << CS10);
 // ICES1 = input capture edge select, 0 = falling edge, 1 = rising edge
 // in cazul de fata, atunci cand detecteaza un magnet, input-ul de la senzor trece de la Vcc la GND
 TCCR1B &= (0 << ICES1); // obs: nu este necesar intrucat era deja setat pe 0
 
 // input capture interrupt enable
 TIMSK1 = (1 << ICIE1);
 // enable output compare A match interrupt
 TIMSK1 |= (1 << OCIE1A);
 // timer overflow interrupt enable
 TIMSK1 |= (1 << TOIE1);
 

Timer 1 este folosit in modul urmator:

Acesta numara, pana cand senzorul Hall detecteaza un magnet, ceea ce produce un front descrescator pe pin-ul ICP1. In acel moment, se retine contorul curent al timer-ului in ICR1, si se intra in ISR-ul TIMER1_CAPT_vect. In acest ISR, se reseteaza counter-ul la 0 si indexul din vectorul de afisat. Se calculeaza perioada de rotatie impartind ICR1 la 64 (si tinand cont de cate overflow-uri s-au produs pana atunci), si pune aceasta valoare in registrul OCR1A.

Acum, pentru fiecare unghi din cele 64, se va intra pe ISR-ul TIMER1_COMPA_vect, unde se poate afisa starea curenta a LED-urilor si se poate incrementa indicele in vectorul de afisare. La final, se actualizeaza OCR1A pentru a genera o intrerupere la urmatorul unghi.

De asemenea, am folosit un “frame buffer” pentru a afisa textul. Astfel, nu apar artefacte atunci cand se actualizeaza configuratia display-ului si se afiseaza o configuratie incompleta.

Rezultate obținute

Proiectul a fost finalizat cu succes. Efectul se vede bine cu ochiul liber.

Am realizat niste poze cu o expunere mai lunga pentru a evidentia fenomenul de persistence of vision:

Ceas analogic:

PM 2021:

Afisare RPM curent:

Pe filmari, efectul nu se vede la fel de bine, intrucat depinde mult de FPS.

Am facut si o filmare slow-motion pentru a evidentia mai bine modul in care isi schimba starea LED-urie.

Filmare POV display slow motion

Filmare POV display ceas analogic

Filmare POV display afisare "Proiect PM", apoi "POV 2021"

Concluzii

Proiectul a fost interesant si are un rezultat satisfacator vizual.

A fost o experienta placuta pe partea de hardware si de software.

Cea mai dificila parte a proiectului este echilibrarea partii rotative, mai ales daca nu se foloseste un motor suficient de puternic.

Posibilitati de extindere a proiectului:

Download

PDF:

https://ocw.cs.pub.ro/courses/pm/prj2021/apredescu/pov-display?do=export_pdf

Cod:

pm-pov-display.zip

Bibliografie

techydiy POV display

Datasheet atmega328p