Acasă / Atelier / Microcontroler / ATMEL / Dispozitiv de afisare bazat pe fenomenul de inertie a retinei – POV (Persistence of Vision)

Dispozitiv de afisare bazat pe fenomenul de inertie a retinei – POV (Persistence of Vision)

Introducere

Scopul proiectului este realizarea unui dispozitiv de afisare bazat pe fenomenul de inertie a retinei (Persistence of Vision).

Dispozitivul consta din:

1.Bareta de 18 LED-uri rotita cu ajutorul unui motor
2.Moduri de afişare:

  • Ceas analogic
  • Ceas digital
  • Text fixat
  • Text custom

3.Recepţionarea si decodificarea comenzilor in IR primite de la o telecomana TV standard:

  • Selectarea modului de lucru (analogic/digital/text fixat/text custom)
  • Setarea orei
  • Introducerea de text custom de la telecomanda prin alocarea tastelor acesteia intr-o maniera similara tastaturii unui telefon mobil.

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.

Descriere generală
In mare, dispozitivul este alcatuit din doua parti:

  • Placa de circuit care contine microcontrolerul, LED-urile si celelalte componente
  • Motorul de curent continuu care antreneaza placa in miscare circulara

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:

Schema Bloc LED POV
Schema Bloc LED POV

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)

Primii 7 biti reprezinta codul comenzii iar urmatorii 5 reprezinta adresa

Primii 7 biti reprezinta codul comenzii iar urmatorii 5 reprezinta adresa
Primii 7 biti reprezinta codul comenzii iar urmatorii 5 reprezinta adresa

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.

Receptor date
Receptor date

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:

Dispozitiv
Dispozitiv

Rezultatul afisat de kWinLIRC la apasarea tastei “2” a telecomenzii:

Rezultat
Rezultat

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:

Motor utilizat
Motor utilizat

Motorul demontat:

Motor demontat
Motor 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.

Capac nemodificat
Capac nemodificat
Capacul modificat
Capacul modificat
Rotorul cu firele lipite la sectiunile colectorului si trecute prin tubul de protectie
Rotorul cu firele lipite la sectiunile colectorului si trecute prin tubul de protectie
Motorul modificat
Motorul modificat

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:

colector
Colector
Forme de unda
Forme de unda

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
Schema electrica a sursei de tensiune

Tot pe placa mobila se afla si:

Schema electrica LED POV
Schema electrica LED POV

Explicatii:

  • Pentru a evita interactiunea nedorita cu bootloader-ul (care utilizeaza intreruperile externe INT0 si INT1) senzorul magnetic TLE4935 a fost conectat la intreruperea externa INT2
  • Receptorul IR TSOP 31238 a fost conectat la intrarea de captura ICP
  • LED17 (rosu) este folosit pentru desenarea conturului exterior si va fi in stare ON in toate modurile de functionare
  • LED7…LED16 (verzi) sunt folosite pentru desenarea acului orar si vor fi folosite doar in modul de functionare CEAS ANALOGIC
  • LED0…LED6 (verzi) sunt folosite in toate celelalte moduri de functionare
  • Ordinea de amplasare fizica pe placa va fi (din centro spre exterior): LED16 ……. LED0 LED17
  • Pe placa au fost amplasate doar headere pentru conectarea interfetelor de programare, acestea fiind realizate ca module de extensie distincte, conectabile doar atunci cand este cazul

Schema modulelor de extensie:

Schema modulelor de extensie
Schema modulelor de extensie

In urma realizarii efective au fost obtinute urmatoarele:

Placa mobila (fata cu componente)
Placa mobila (fata cu componente)
Placutele de extensie (programare SPI si programare USB)
Placutele de extensie (programare SPI si programare USB)
Dispozitivul asamblat
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:

Manson din burete
Manson din burete

Software Design

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;

	}

Rezultate Obţinute
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:

Rezultate Obţinute
Rezultate Obţinute

Dispozitivul de afisare in modul de functionare ceas digital:

Rezultate Obţinute
Rezultate Obţinute

Dispozitivul de afisare in modul de functionare text fix (primul text):

Rezultate Obţinute
Rezultate Obţinute

Dispozitivul de afisare in modul de functionare text fix (al doilea text):

Rezultate Obţinute
Rezultate Obţinute

Descarca proiect pov1.

Sursa: http://elf.cs.pub.ro/pm/wiki/prj2010/amocanu/pov

Atașat acestui articol :

pov1
Filename : pov1.zip (94 KB)

Despre Ciprian

Am dezvoltat o pasiune pentru acest domeniu de cand eram foarte mic, cred ca aveam 6-7 ani, din cate imi amintesc, am invatat sa citesc din revistele Tehnium, cam astea erau preferatele mele la varsta respectiva. In plus, aveam o atractie pentru informatica fapt ce a dus la inscrierea mea la un liceu de informatica, iar pentru a continua cu pasiunea mea m-am inscris apoi la facultatea de electrotehnica...

9 Comentarii

  1. Vreau sa realizez un line follower robot, bazat pe acelasi uC, dar vreau sa stiu daca merge si aici adaptorul prezentat de tine (in articolul cu ceasul) adica sa plec de la pinii uC-ului la pin header si de la pin header la portul serial doar prin niste diode rezistenta si un tranzistor.La mine in documentatia care o am trebuie sa lucrez cu un pin header 2×5 care trebuie conectat la un adaptor de port paralel printr-un circuit integrat, si nu prea imi convine chestia asta. Intreb acest lucru pentru ca mi se pare cam ciudata schema adaptorului, pe forum acest adaptor se numeste USB asp si e mai greu de realizat decat cel pus de tine.

  2. Salut, as dori daca se poate cateva informatii legate de proiectul tau POV, vreau sa il construiesc si as avea nevoie de cateva informatii suplimentare.

  3. Ai cateva erori in program iar senzorul Hall TLE4953L nu mi-l arata in pe placa de proiectare arata doar rezistenta R19, nici jumper-ul nu il arata in placa de proiectare, folosesc programul Eagle, la fel a fost si la tine ? Am mai lasat un comentariu dar nu ai raspuns, adresa mea de email este: drawshade@yahoo.com te rog raspunde.

  4. Scuze „soclul” pentru jumper.

  5. Gramada Ciprian :
    Te rog pune niste poze cu ce vrei sa faci si te voi ajuta.

    Vreau sa realizez si eu acest ceas POV, dar nu am Atmega16 DIP pe „stoc”, am in schimb Atmega16 SMD si as vrea sa-l folosesc la acest proiect, ar iesi mult mai compacta „elicea” ceasului.
    Trebuie ceva modificari soft?
    Cele doua texte afisate, se pot modifica?
    In locul senzorului magnetic, se poate folosi (implementa in soft) o pereche emitaror-receptor IR dintr-un mouse ?
    Astept un raspuns referitor la aceste modificari, daca sunt posibile sau nu.

    P.S. Linkul-sursa -> http://elf.cs.pub.ro/pm/wiki/prj2010/amocanu/pov NU mai este valabil.

    • Pai diferenta dintre DIP (dual in-line package), adica pinii sunt mai lungi ca sa treaca prin PCB, acest tip prezinta o constructie ceva mai solida dar ca principiu de functionare este identic cu cel al SMD-urilor (surface-mount device). SMD-urile sunt lipite direct de PCB. Nu trebuiesc aduse modificari programului.

  6. Gramada Ciprian :
    Pai diferenta dintre DIP (dual in-line package), adica pinii sunt mai lungi ca sa treaca prin PCB, acest tip prezinta o constructie ceva mai solida dar ca principiu de functionare este identic cu cel al SMD-urilor (surface-mount device). SMD-urile sunt lipite direct de PCB. Nu trebuiesc aduse modificari programului.

    Aceasta diferenta o stiam si eu. Pe un site (nu dau nume) unde era prezentat un voltmetru, scria clar sa nu se foloseasca hex pentru DIP la SMD, de aceea am intrebat daca le pot inclocui.
    Am sa proiectez cablajul in functie de piesele mele, Atmega16 SMD (eventual LED-uri), am sa tin cont si de de pini lui Atmega16 SMD (porturi, etc) ca sa corespunda cu schema postata.
    In loc de senzorul magnetic, se poate folosi o pereche emitator-receptor IR din mouse? Eventual o schema de modificare/inlocuire
    Eu nu ma pricep la scriere/modificare soft pentru microcontroler si as mai avea o nelamurire, se poate folosi si alt tip de telecomanda, bineinteles prin modificarea softului. Am o telecomanda de receiver DIGI care sta degeaba si as vrea sa o pun la munca.
    Sau trebuie un anumit tip, care transmite printr-un anumit protocol, ex RC 5.

Lasă un răspuns

Adresa ta de email nu va fi publicată. Câmpurile obligatorii sunt marcate cu *

*