Zoals jullie in de kroeg wel konden lezen, heb ik bij Baco tien led-boards gekocht. Het idee is om daarmee een monochroom LED-display van 96x48 pixels te maken wat realtime bestuurd kan worden door de PC.

Het lijkt erop dat het board bedoeld is om in serie met z'n maatjes geschakeld te worden: zowel J1 als J2 lijken data te vervoeren. J1 doet dat echter naar de electronica toe, terwijl J2 meer van de electronica af vervoert. Na wat zoeken kwam ik uit op deze pinout:
Uiteindelijk heb ik een leuk klein printje gemaakt. Een schema ga ik hier niet posten, de belangrijkste connecties staan in de code. Een pic kan je wel van me krijgen:

Het ding is zo gemaakt dat het direct op de header past. De kabel die je ziet is voor het programmeren van de AVR.

De code ervan is downloadbaar en gelicenseerd onder de GPLv3.
• Connectie met de PC maken. Voor 1 board kan dat nog wel een standaard serieele verbinding zijn, maar 96px*48px*8bit*25fps=~1mbit aan data.
• Meerdere uCboards maken voor de andere 8 led-boards
• Spul fysiek aan elkaar vastmaken
• Plugin voor MPlayer of een andere video-afspeel-unit maken
De borden
De borden van Baco zijn blijkbaar uit een bestaand LED-display-iets; de naam 'comfuture ltd.' staat erop te lezen. Verder is er niet zo heel veel over bekend. Nou, dat word dus reverse-engineeren
Het lijkt erop dat het board bedoeld is om in serie met z'n maatjes geschakeld te worden: zowel J1 als J2 lijken data te vervoeren. J1 doet dat echter naar de electronica toe, terwijl J2 meer van de electronica af vervoert. Na wat zoeken kwam ik uit op deze pinout:
nc | 15 | 16 | GND |
LDAT | 13 | 14 | GND |
nc | 11 | 12 | GND |
UDAT | 9 | 10 | GND |
A2 | 7 | 8 | GND |
A1 | 5 | 6 | /OE |
A0 | 3 | 4 | STROBE |
CLK | 1 | 2 | GND |
Aansturen
Ok, hoe stuur je nu zo'n bord aan? Het kreng zelf is niet intelligent om zelf z'n beeld te behouden, wat betekent dat we een microcontroller nodig hebben om het beeld er tientallen of zelfs honderden keren per seconde heen te sturen. Hoe gebeurt dat? Ten eerste moet je weten dat het bord is onderverdeeld in een bovenste en een onderste helft. Deze twee helften hebben twee aparte data-ingangen, namelijk LDAT en UDAT. Het idee is dat daar ism CLK de regel die je wil weergeven ingeklokt word. In pseudo-code, geoptimaliseerd voor leesbaarheid, maak je zo een compleet beeld:code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
| while(1) { for y=0 to 8 { for x=0 to 32 { maak LDAT hoog als je op (x,y+8) een pixel wilt weergeven maak UDAT hoog als je op (x,y) een pixel wilt weergeven maak CLK laag maak CLK hoog } maak OE hoog (dit zet alle LEDs tijdelijk uit) maak STROBE laag maak STROBE hoog zet [A2..0] naar y maak OE hoog wacht een tijd, afhankelijk van de gewenste refreshrate } } |
Grijstinten
of eigenlijk roodtinten... Da's allemaal leuk als je wat tekst wil weergeven, maar wat nou als je verschillende intensiteiten wilt weergeven? Als je naar de hardware kijkt, zou je zeggen dat dat onmogelijk is: we kunnen alleen maar een led aan- of uitzetten. Door een smerig truukje is het toch mogelijk: als we het display niet honderd, maar bijvoorbeeld tienduizend keer per seconde verversen, kunnen we de LEDs gaan PWMmen. Het nadeel is wel dat dit redelijk opvalt: als een compleet bord met 50Hz naar je staat te knipperen, valt dat wel op. Daar is echter omheen te werken: als we ervoor zorgen dat elke pixel 90 graden uit fase knippert met z'n dichtbijzijnde buurman, valt het ineens een heel stuk minder op dat alles aan het knipperen is. Voor implementatiedetails, zie de sourcecode later in deze post.Hardware
Theorie is leuk natuurlijk, maar hoe gaat dat nou in de praktijk werken? Ten eerste is er een microcontroller nodig. Omdat we een redelijke snelheid willen halen ivm het grijstintenverhaal, is enkele tientallen mips aan processing-power toch wel gewenst. Ook zou meer dan een halve K aan RAM practisch zijn: op die manier kunnen we het huidige beeld gewoon in een array zetten waar de display-routine weer uit kan lezen. Al met al ben ik uitgekomen op een ATMega88: met z'n 1K aan SRAM is er genoeg geheugen voor een displaybuffer en met 20MHz (a ongeveer 1 mips per MHz) moet 'ie toch redelijk rap pixels uit kunnen spugen.Uiteindelijk heb ik een leuk klein printje gemaakt. Een schema ga ik hier niet posten, de belangrijkste connecties staan in de code. Een pic kan je wel van me krijgen:

Het ding is zo gemaakt dat het direct op de header past. De kabel die je ziet is voor het programmeren van de AVR.

Resultaat
De theorie die hierboven staat is omgezet in een net C-programmaatje en met avr-gcc geprogrammeerd. Naast de display-routine zit er een plaatje in en een plasma-functie die geleend is uit mijn demo voor het HD44780-microcontest.De code ervan is downloadbaar en gelicenseerd onder de GPLv3.
ToDo
• Intensiteit exponentieel maken. Door een eigenschap van het menselijk oog lijkt er veel verschil tussen de lagere intensiteiten te zitten en veel minder verschil tussen de hogere.• Connectie met de PC maken. Voor 1 board kan dat nog wel een standaard serieele verbinding zijn, maar 96px*48px*8bit*25fps=~1mbit aan data.
• Meerdere uCboards maken voor de andere 8 led-boards
• Spul fysiek aan elkaar vastmaken
• Plugin voor MPlayer of een andere video-afspeel-unit maken
Relaxen und watchen das blinkenlichten. | Laatste project: Ikea Frekvens oog