Scopul proiectului este realizarea unui dispozitiv de afisare bazat pe fenomenul de inertie a retinei (Persistence of Vision).
Dispozitivul consta din:
Prin rotirea cu viteza mare (minim 16 rot/s) a baretei de LED-uri si sincronizand momentele de aprindere/stingere a acestora cu pozitia baretei dispozitivul va crea iluzia existentei unui afisaj de forma circulara alcatuit din 18*360 = 6480 LED-uri.
In mare, dispozitivul este alcatuit din doua parti:
Deoarece viteza de rotatie a placutei este mare, dispozitivul va trebui echilibrat cat mai bine(atat static cat si dinamic). O echilibrare imperfecta va avea drept consecinta aparitia unor vibratii mari si de aici imposibilitatea obtinerii unor imagini clar definite.
De aceea intreaga proiectare a dispozitivului a fost facuta in ideea obtinerii unui ansamblu cat mai usor (si rigid totodata) si a unei echilibrari cat mai bune.
Astfel placa de test facuta pentru prima etapa a proiectului s-a dovedit a fi inutilizabila pentru proiectul propru-zis datorita incarcarii cu componente inutile scopului urmarit (headere pentru extensii, interfata seriala).
O problema spinoasa a fost cea a asigurarii alimentarii placii (aflata in miscare de rotatie). Solutia (triviala) de alimentare din baterie amplasata pe placa ar fi ingreunat mult ansamblul mobil si ar fi condus la probleme majore de echilibrare, facand-o astfel nefezabila. Solutia adoptata in final a fost aceea de preluare a alimentarii pentru placa din alimentarea motorului prin intermediul colectorului acestuia. Tot in ideea de a nu ingreuna inutil placa am luat decizia de a pune interfetele de programare SPI si USB pe mici placute de extensie conectabile la placa mama prin headere.
Schema bloc:
De fiecare data cand in miscarea sa de rotatie placa trece prin dreptul pozitiei de referinta senzorul magnetic genereaza o intrerupere. Astfel se poate afla durata unei rotatii complete iar prin impartirea acesteia la 360 se determina durata necesara parcurgerii unui grad. Generand o intrerupere la parcurgerea fiecarui grad vom sti in permanenta in ce pozitie ne aflam si putem astfel comanda aprinderea/stingerea LED-urilor in functie de ceea ce dorim sa fie afisat.
Receptorul in infrarosu este folosit pentru a prelua semnalele emise de la telecomanda. De fiecare data cand este receptionat un semnal valid este activata o intrerupere iar semnalul este analizat, in final microcontroller-ul obtinand comanda care a fost transmisa.
A fost folosita o telecomanda Sony (RM-W100) care foloseste protocolul de comunicatie SIRCS (Sony IR Control System).
Protocolul SIRCS foloseste pentru transmiterea informatiei procedeul de modulatie in latime (PWM) a unei purtatoare avand frecventa de 38KHz. Fiecare pachet este alcatuit din 12 biti si un bit de start. Fiecare dintre acestia este caracterizat printr-o anumita latime care este multiplu al unei durate de baza T=0.6ms. Astfel un bit 0 are o latime de 0.6ms urmata de o pauza de 0.6ms, un bit 1 are o latime de 1.2ms urmata de o pauza de 0.6ms iar bitul de start are o latime de 2.4ms urmata de o pauza de 0.6.ms
Cei 12 biti care alcatuiesc un pachet sunt transmisi incepand cu LSB. Astfel primii 7 biti reprezinta codul comenzii iar urmatorii 5 reprezinta adresa (tipul de aparat: TV, DVD player etc)
Astfel peentru pachetul reprezentat mai sus comanda este 0010011 iar adresa este 000001.
Deoarece informatiile gasite in faza de documentare referitor la codurile alocate tastelor au fost contradictorii am decis sa obtin pe cont propriu aceste coduri. Pentru aceasta a trebuit sa construiesc un dispozitiv de receptie simplu, care atasat la calculator sa imi permita sa captez impulsurile generate de telecomanda. Pentru afisarea impulsurilor am folosit programul kWinLIRC, varianta pentru Windows a LIRC (Linux Infrared Remote Control) avand si facilitati de osciloscop.
unde:
IC1 = 7805, stabilizator 5V
IC2 = TSOP1738 , receptor IR
D1 = 1N4148
C1 = 4.7uF
R1 = 4.7K
iar configuratia conectorului DB9 este:
1 = DCD (Carrier Detect)
2 = RXD (Receive Data)
3 = TXD (Transmit Data)
4 = DTR (Data Terminal Ready)
5 = GND (Ground)
6 = DSR (Data Set Ready)
7 = RTS (Request To Send)
8 = CTS (Clear To Send)
9 = RI (Ring Indicator)
Minidispozitivul rezultat:
Rezultatul afisat de kWinLIRC la apasarea tastei “2” a telecomenzii:
deci comanda este 0000001 iar adresa este 00001.
Repetand operatia de mai inainte pentru toate tastele telecomenzii RM-W100 pe care le voi utiliza in continuare in cadrul proiectului am obtinut urmatoarele rezultate (in ordinea MSB first):
Tasta | Adresa | Comanda | Utilizare |
---|---|---|---|
1 | 00001 | 0000000 | introducere 1 |
2 | 00001 | 0000001 | introducere A,B,C sau 2 |
3 | 00001 | 0000010 | introducere D,E,F sau 3 |
4 | 00001 | 0000011 | introducere G,H,I sau 4 |
5 | 00001 | 0000100 | introducere J,K,L sau 5 |
6 | 00001 | 0000101 | introducere M,N,O sau 6 |
7 | 00001 | 0000110 | introducere P,Q,R,S sau 7 |
8 | 00001 | 0000111 | introducere T,U,V sau 8 |
9 | 00001 | 0001000 | introducere W,X,Y,Z sau 9 |
0 | 00001 | 0001001 | introducere spatiu sau 0 |
Mute | 00001 | 0010100 | stergere caracter (in mod TEXT CUSTOM) |
_ /_ _ | 00001 | 0011101 | memorare caracter (in mod TEXT CUSTOM) |
Last channel | 00001 | 0111011 | avans rapid timp |
Menu up | 00001 | 1110100 | selectare mod TEXT FIX; la apasare repetata comuta intre cele 3 texte |
Menu right | 00001 | 0110011 | selectare mod CEAS DIGITAL |
Menu down | 00001 | 1110101 | selectare mod TEXT CUSTOM |
Menu left | 00001 | 0110100 | selectare mod CEAS ANALOGIC |
Lista de piese:
Denumire | Cantitate | Comentarii |
---|---|---|
microcontroller ATMEGA 16P | 1 | |
arie Darlington ULN2803A | 1 | |
stabilizator 5V 7805 CT | 1 | |
senzor Hall TLE4905L | 1 | nu am gasit decat TLE4935L care este bipolar, deci va trebui sa folosesc doi magneti |
receptor IR TSOP 1738 | 1 | nu am gasit decat TSOP 31238 (aceeasi frecventa, 38KHz |
tranzistor FET canal N IRFZ45 | 1 | |
tranzistor BC547 | 1 | |
dioda Zener 3V3 | 2 | |
dioda Zener 5V1 | 2 | |
punte redresoare 1A | 2 | |
LED verde (high brightness) | 17 | |
LED rosu (high brightness) | 1 | |
Quartz 16MHz | 1 | |
rezistenta 58 ohm | 18 | |
rezistenta 100 ohm | 2 | |
rezistenta 2K2 | 1 | |
rezistenta 4K7 | 2 | |
rezistenta 10K | 2 | |
rezistenta 15K | 1 | |
condensator 15p | 2 | |
condensator 100n | 2 | |
condensator electrolitic 1000u/16V | 2 | |
condensator electrolitic 10u/16V | 1 | |
soclu microcontroller | 1 | |
conector jack | 1 | |
conector USB-B | 1 | |
conector DB9 mama | 1 | |
placa test | ||
motor 12V cc | 1 | de la instalatia de spalare a parbrizului Dacia |
rulment | 1 | |
magnet | 1 | din cei folositi la mobila pentru inchizatorile magnetice |
Deoarece reusita proiectului depindea foarte mult de faptul daca voi reusi sau nu sa preiau alimentarea pentru placa mobila din alimentarea motorului, inca de la inceput m-am concentrat asupra acestei probleme.
Motorul utilizat:
Motorul demontat:
Ideea a fost sa lipesc fire pe sectiunile colectorului, fire pe care apoi sa le scot in exteriorul motorului trecandu-le prin capacul acestuia.
Pentru aceasta capacul a trebuit modificat in sensul largirii gaurii centrale astfel incat pe capac sa poata fi montat un rulment cu diametrul interior suficient de mare pentru a permite trecerea tubului de protectie a firelor.
Capacul initial:
Capacul modificat:
Rotorul cu firele lipite la sectiunile colectorului si trecute prin tubul de protectie:
Motorul modificat cu firele de alimentare de la colector scoase in exterior:
Avand rezolvata problema alimentarii placii mobile, in continuare am putut sa trec la proiectarea electrica.
Deoarece colectorul este alcatuit din 8 sectiuni grupate in 4 faze, in timpul miscarii de rotatie se obtine un sistem 4-fazat de tensiuni:
Din cele patru faze disponibile, in continuare nu voi folosi decat doua faze neadiacente (as fi putut folosi si o singura faza dar ondulatiile datorate consumului de curent al celor 18 LED-uri (aproximativ 800mA) ar fi fost mai mari si ar fi trebuit sa maresc valoarea condensatorului de filtrare, in caz contrar existand riscul ca microcontroler-ului sa nu i se asigure cei 5V necesari functionarii stabile).
Schema electrica a sursei de tensiune este urmatoarea:
Tot pe placa mobila se afla si:
Explicatii:
Schema modulelor de extensie:
In urma realizarii efective au fost obtinute urmatoarele:
Placa mobila (fata cu componente):
Placutele de extensie (programare SPI si programare USB):
Dispozitivul asamblat:
In partea opusa microcontroller-ului se poate observa contragreutatea amplasata pentru echilibrare. Chiar si asa echilibrarea nu este perfecta, de aceea pentru amortizarea vibratiilor intregul dispozitiv va fi amplasat pe un manson din buret:
Implementarea software a fost facuta utilizand limbajul C si WinAVR cu compilatorul avr-gcc pentru Windows.
Bootloaderul utilizat a fost bootloaderul HID cu temporizare de 10 secunde.
Incarcarea bootloaderului a fost facuta utilizand placuta de extensie SPI si avrdude.
Functii implementate:
1. Rutina de tratare a intreruperii generate de senzorul magnetic la trecerea prin pozitia de referinta (INT2)
ISR(INT2_vect)
Calculeaza timpul necesar parcurgerii unui arc de cerc cu marimea de 1 grad in functie de timpul scurs intre doua treceri succesive prin pozitia de referinta.
2. Rutina de tratare a intreruperii generate la parcurgerea unui unghi de 1 grad.
ISR(TIMER1_COMPA_vect)
Apeleaza functia Display() pentru desenare
3. Rutina de tratare a intreruperii generata la aparitia unui front crescator pe intrarea de captura (ICP este conectat la receptorul IR)
ISR(TIMER1_CAPT_vect)
Analizeaza impulsurile provenite de la telecomanda si captate de catre receptorul IR si decodifica comanda.
4. Rutina de tratare a intreruperii generata de overflow la Timer0
ISR(TIMER0_OVF_vect)
De fiecare data cand trece un timp egal cu o secunda apeleaza functia Time().
5. void Time(unsigned char)
Actualizeaza secundele, minutele si orele in concordanta cu timpul care a trecut.
6. void Display(void)
Comanda aprinderea/stingerea corespunzatoare a LED-urilor in functie de ceea ce trebuie afisat in momentul si la pozitia unghiulara respectiva.
7. void CopyData(int Value)
Functie ajutatoare care converteste valorile numerice ale secundelar, minutelor si orelor in format alfanumeric pentru a fi afisate in modul de functionare CEAS DIGITAL. Incarca din tabela matricele de puncte care definesc caracterele respective.
8. void CopyDot(void)
Functie ajutatoare care incarca din tabela matricea de puncte care defineste caracterul ”:”
9. void CopyText(int Value)
Functie ajutatoare care incarca din tabela matricea de puncte care defineste caracterul alfanumeric care trebuie afisat in modurile de functionate TEXT FIX si TEXT CUSTOM.
10. void loadTextCust()
Functie ajutatoare care construieste textul custom in functie de tastele apasate pe telecomanda si totodata construieste matricea de puncte corespunzatoare necesara pentru afisare in modul TEXT CUSTOM.
11. void loadTextFix()
Functie ajutatoare care construieste matricea de puncte pentru intregul text fixat care trebuie afisat in modul TEXT FIX.
In main() se fac configurarile iar apoi se ruleaza in bucla asteptand apasarea tastelor telecomenzii pentru comutarea intre diferitele moduri de afisare:
int main() { PORTA = 0x00; DDRA =0xFF; //PA0...PA7 ca iesire PORTB &=~(1<<PB2); //fara rezistenta de pull-up DDRB &= ~(1<<PB2); // PB2 (INT2) ca intrare PORTD |= (1<<PD0); //LED17 (rosu) ON DDRD |= (1<<PD0); //PD0 ca iesire si LED17 (rosu) ON PORTD &= ~(1<<PD6);//fara rezistenta de pull-up DDRD &= ~(1<<PD6); //PD6 (ICP) ca intrare //INT2 MCUCSR &= ~(1<<ISC2);//INT2 genereaza intrerupere pe falling edge GICR |= (1<<INT2);//INT2 enable //Timer0 TCCR0 |= (1<<CS02)|(1<<CS00);//prescaler 1024 TIMSK |= (1<<TOIE0); //interrupt enable on Timer0 overflow //Timer1 TCCR1B |= (1<<CS11)|(1<<CS10); //prescaler 64 TCCR1B |= (1<<ICES1); //Input Capture on rising edge TIMSK |= (1<<OCIE1A)|(1<<TICIE1);//interrupt enable on Timer1 Compare Match A & interrupt enable on Timer1 Input Capture Hrs = 0; Min = 0; Sec = 0; Mode = ANALOG; sei(); while(1) { for (i=0;i<200;i++); if ( LatchedIrData == 0xbb ) Time(TRUE); //tasta Last Program if ( LatchedIrData == 0xb3 ) Mode = DIGITAL; //tasta Menu right if ( LatchedIrData == 0xb4 ) Mode = ANALOG; //tasta Menu left if ( LatchedIrData == 0xf4 ) { Mode = TEXT_FIX; loadTextFix(); } //tasta Menu up if ( LatchedIrData == 0xf5 ) Mode = TEXT_CUSTOM; //tasta Menu down if ( Mode == TEXT_CUSTOM ) loadTextCust(); else { lastChr = 0; validChr = 0; lenTextCust = 0; } LatchedIrData = 0; }
In faza finala dispozitivul este perfect functional, indeplinind in totalitate cerintele impuse.
Un film reprezentand dispozitivul in timpul functionarii poate fi vazut aici
Dispozitivul de afisare in modul de functionare ceas analogic:
Dispozitivul de afisare in modul de functionare ceas digital:
Dispozitivul de afisare in modul de functionare text fix (primul text):
Dispozitivul de afisare in modul de functionare text fix (al doilea text):
Dispozitivul de afisare in modul de functionare text fix (al treilea text):
Dispozitivul de afisare in modul de functionare text custom in timpul introducerii clsicului “HELLO WORLD”:
Proiectul a reprezentat o buna ocazie de a exersa lucrul cu timere si intreruperi iar faptul ca in final am obtinut un dispozitiv perfect functional a reprezentat o mare satisfactie.
Un aspect mai putin placut a fost reprezentat de prelucrarile mecanice pe care a trebuit sa le fac pentru adaptarea motorului pentru scopul urmarit.
Daca ar fi sa refac proiectul as incerca sa maresc “rezolutia” marind numarul de LED-uri si folosind LED-uri miniatura. De asemenea as incerca sa folosesc un alt motor deoarece cel utilizat acum se incalzeste destul de mult la functionare prelungita (ceea ce este normal, intrucat a fost facut pentru a functiona pe durate mici, specifice unui spalator de parbriz).
Proiecte similare:
Transmisia/Receptia in IR si Protocolul SIRCS:
make-an-infrared-remote-control-for-pc.html
Datasheet-uri: