![]() | |
| |
![]() | |
Het doel van het project was het ontwikkelen van een 3 dimensionale monitor. Dit is gerealiseerd door een LED kubus van 10^3 leds te bouwen. Op deze manier hebben we een monitor van 10*10*10 pixels. Op deze monitor kunnen dan verschillende applicaties geïmplementeerd worden. De aansturing is een embedded systeem wat luistert naar een bepaalt protocol. Verschillende applicaties zouden dan allerlei projectie in de kubus kunnen weergeven. Voor de applicatie zijn verschillende ideeën:
| |
![]() | |
Mechanische opbouw LED's Omdat het praktisch onmogelijk is alle LED's afzonderlijk aan te sturen, maken we gebruik van een techniek die multiplexen genoemd wordt. Dit houd in dat we de LED's niet continue aansturen, maar schakelen tussen de verschillende LED's. De traagheid van het menselijke oog zorgt ervoor dat het lijkt alsof de led continue brand. Een nadeel hiervan is dat elke LED slechts een klein gedeelte van de tijd kan branden (1 / multiplex aantal), en dus minder fel lijkt. Om dit probleem gedeeltelijk te compenseren worden de LED's aangestuurd met een hogere stroom. We moeten hierbij wel rekening houden dat deze stroom te hoog is om de LED's continue mee aan te sturen. Dit zou er voor zorgen dat de LED's doorbranden. Om dit te voorkomen is er een controller toegevoegd, welke controleert of de LED's wel op de juiste frequentie en tijdsduur worden aangestuurd. Is dit niet het geval schakelt de controller alle LED's uit.De kubus is opgebouwd uit 10 vlakken van 10 * 10 LED's. Deze vlakken zijn zo gemonteerd dat het een uniforme constructie wordt van 10 * 10 * 10 LED's. In onderstaand figuur is als voorbeeld een 3 * 3 * 3 kubus weergegeven. De uiteindelijke kubus is 30 * 10 * 10. Elke RGB-led beschouwen we namelijk als 3 losse LED's. ![]() Als we een LED willen laten branden, moeten er twee punten aangestuurd worden. De "vlak selectie lijn", en de individuele led lijn. De "vlak selectie" lijn selecteert een enkel vlak in de kubus, waarna de individuele stuurlijn (verder LED selectie lijn genoemd) de gewenste LED selecteert. Om in bovenstaande kubus de middelste LED te laten branden moeten dus "vlak selectie 2" en "led2 rij2" aangestuurd worden. Aanstuurstrap LED Elke LED wordt aangestuurd door twee MOSFET's, een P-type en een N-type. Deze schakelen de LED respectievelijk over de positieve en negatieve kant. Het is niet zo dat er voor elke LED daadwerkelijk twee MOSFET's geplaatst zijn. Omdat we multiplexen kunnen we met minder uit. De P-type MOSFET's zijn voor het selecteren van de Vlakken. Deze transistoren schakelen het gehele vermogen van de kubus, en moeten hierom gekoeld worden (zie warmte huishouding). De N-type MOSFET schakelt 1 led tegelijkertijd. Hierdoor kan er een veel kleiner type gebruikt worden, en is er geen koel element nodig. ![]() De waarde van weerstand R is afhankelijk van de kleur van de LED. De rode LED heeft namelijk een lagere spanningsval dan de groene en blauwe LED. De waarde van R kunnen we voor de 3 verschillende kleuren berekenen. De waarde van de weerstand hangt af van de spanningsval van de LED, de gewenste stroom door de led, en de weerstand van de twee aanstuur MOSFET's. Omdat deze waardes niet direct af te leiden zijn (deze zijn batch afhankelijk voor de verschillende onderdelen), bepalen we de weerstand door de stroom te meten door een van de gebruikte LED's via een variabele weerstand. Zorg dat de waarden binnen de specs van de LED's vallen zolang we op 1 Khz een duty cycle van maximaal 10% aanhouden. De LED's continue laten branden op deze stroom veroorzaakt blijvende schade! Led aansturing / rij selectie Om de individuele LED datalijnen aan te kunnen sturen, zijn er 300 datalijnen nodig. Omdat dit teveel is om rechtstreeks op de controller te doen, maken we gebruik van een demultiplexer op de aanstuurprint. Deze Demultiplexer maakt het mogelijk om 40 datalijnen om te zetten in 300 stuurlijnen voor de LED's.Om dit mogelijk te maken heeft ieder vlak een stukje logica welke op een centrale bus is aangesloten. Deze bus bestaat uit 30 datalijnen. Door de overige 10 datalijnen te gebruiken om een rij te selecteren, kunnen we iedere rij los aansturen, en komen we op 10 * 30 = 300 stuurlijnen. De logica welke op deze bus wordt aangesloten bestaat uit zogenaamde latches. Deze componenten zorgen ervoor dat we kunnen selecteren dat de data op de bus wel of niet aan de LED stuur trappen word doorgegeven. De latches worden aangestuurd met de LE (Latch enable) lijn. Als deze lijn hoog is geven de latches de data op de ingang direct door op de uitgang. Als we de LE lijn laag maken dan blijft de data op de uitgangen hetzelfde, onafhankelijk van de data op de ingangen. Door de latches langs te lopen, de gewenste data erop zetten, en ze dan te "latchen", kunnen we alle rijen van de gewenste data voorzien, en sturen we dus 300 datalijnen aan via 40 stuurlijnen. In onderstaand schema is de hardware voor een vlak weergegeven. Deze hardware is voor alle vlakken hetzelfde. De LED1_r LED10_b aansluitingen zitten aan de gezamenlijke bus. De LE aansluiting is voor elke rij apart. De uitgangen van de latches (latch_r1..latch_b10) zitten aangesloten op de led selectie van de LED stuurtrappen. ![]() Vlak selectie De LED kubus is opgebouwd uit 10 vlakken. Deze vlakken worden één voor één ingeschakeld op een frequentie van 1 kHz. De aansturing van deze vlakken wordt gedaan via een zogenaamde 4-to-16 decoder. Deze decoder maakt van een 4 bit binaire waarde, een van de 16 uitgangspinnen laag (alle uitgangen zijn geïnverteerd). Het gebruik van deze decoder heeft twee voordelen: [list=1] • Er zijn 4 datalijnen nodig voor de vlak selectie i.p.v. 10 • De decoder dwingt af dat er nooit 2 vlakken tegelijk aangezet worden. Dit mag absoluut niet gebeuren, aangezien dit een stoompiek veroorzaakt (10 * 20A = 200A) waardoor de hele print kapot gaat). Verder kunnen we met de decoder via de "enable kubus" lijn de gehele kubus uitzetten. Als deze lijn laag is gaan alle uitgangen naar een hoge impedantie staat. Nu zorgen de pull-up weerstanden bij de P-type MOSFET's ervoor dat deze uitgeschakeld worden. De decoder heeft twee van deze enable ingangen. De eerste kan gebruikt worden om de kubus gemakkelijk uit te schakelen. De tweede wordt aangestuurd door een aparte processor op de print. Deze processor zal de kubus uitschakelen als deze een fout ontdekt. (zie kubus safeguard). De kubus wordt uitgeschakeld als één of twee van de enable lijnen hoog is. Kubus safeguard Om ervoor te zorgen dat een fout in de aansturing geen schade veroorzaakt aan de kubus is er een controller welke controleert of er geen fouten zijn. Vind deze controller een fout dan schakelt hij de kubus uit, en geeft weer via een LED op de print dat er een fout is opgetreden. De controller controleert op twee punten:
Warmte huishouding Het opgenomen vermogen door de aansturings print wordt vooral gebruikt door de LED aansturingstrap. We moeten hier dus goed kijken wat er niet effectief gebruikt wordt, en omgezet wordt in warmte.We gaan uit van het slechtste geval, en gaan er vanuit dat alle LED's vol branden. Er zijn drie punten waar warmteontwikkeling plaats vind. De P-type MOSFET, de N-type MOSFET en de weerstand. De warmte ontwikkeling is afhankelijk van de stroom en de weerstand. De stroom weten we en verschild per kleur. De weerstand is ook bekend dus kunnen we de warmteontwikkeling berekenen: P = I2 * R Samenvatting aansturing De kubus wordt aangestuurd met behulp van latches. Er is per Z-laag één latch, elke latch kan daardoor worden gebruikt om de bijbehorende Z-laag in te stellen. Als de aardelijnen van alle LEDs permanent op de aarde zouden zijn aangesloten, zouden alle LEDs die boven elkaar zitten dezelfde waarde hebben (ze zijn immers allemaal op dezelfde poort van dezelfde latch aangesloten). Om die reden is er een multiplexer geplaatst waarmee een Y-laag geselecteerd kan worden. Door nu eerst alle latches in te stellen op de waarden voor een bepaalde Y-laag en vervolgens die Y-laag te selecteren zijn de instellingen alleen op die laag zichtbaar. Als dit proces herhaald wordt voor elke laag en dit gebeurt op een voldoende hoge snelheid (1000Hz), dan lijkt het voor het menselijk oog alsof alle lagen tegelijk branden met hun eigen instellingen. Nadeel hierbij is dat elke LED slechts een klein gedeelte van de tijd kan branden (1 / hoogte_kubus); om dit probleem gedeeltelijk te compenseren worden de LEDs aangestuurd met een stroom die onder normale omstandigheden te hoog zou zijn. Het programmeren van de latches gebeurt ook via een multiplexer, hiermee kan een latch worden geselecteerd, zodat die ingesteld kan worden. Zie 'Pseudocode' voor een codefragment waar de kubusaansturing in uitgevoerd wordt.In plaats van éénkleurs-LEDs zijn RGB-LEDs gebruikt; deze kunnen worden gezien als drie losse LEDs met één gezamenlijke aarde. Het enige verschil is dan ook dat de latches drie keer zoveel poorten moeten hebben. Data buffering Alle I/O poorten op de aansturing print zijn gebufferd. Dit is om verschillende redenen gedaan:
| |
![]() | |
De bouw:De aanstuurprint (PCB):Testing:Gebruik Codec: MJPG 320x240 10.00fps Movies: | |
Tweaker die aan dit project hebben gewerkt zijn: the12be, k0ewl en Neptunus Suggesties, opmerkingen en aanvullingen mogen altijd per PM, mail of topicpost bericht worden. |
Pseudocode
C:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
| //De afmetingen van de kubus. #define X_SIZE 10 #define Y_SIZE 10 #define Z_SIZE 10 //data bevat de ledwaarden. int data[X_SIZE][Y_SIZE][Z_SIZE]; void set_latchbit(int n, int bit, int value); void select_drainmux(int n); void select_latchmux(int n); //De y-loop stelt steeds eerst de latches in, //en selecteerd daarna de betreffende Y-laag. for(y = 0; y < Y_SIZE; y++) { //De z-loop stelt all latches in. for(z = 0; z < Z_SIZE; z++) { //De x-loop stelt de poorten van een latch in. for(x = 0; x < X_SIZE; x++) { set_latchbit(z, x, data[x][y][z]); } } select_drainmux(y); } //Stelt een poort van een latch in. void set_latchbit(int n, int bit, int value){ select_latchmux(n); latch_writebit(bit, value); } //Selecteert een Y-laag void select_drainmux(int n) { //disable all dmuxes except n } //Selecteert een latch. void select_latchmux(int n){ //disable all lmuxes except n } |