Inhoudsopgave:
- Stap 1: Pulsbreedtemodulatie voor het mengen van kleuren
- Stap 2: Praten met schuifregisters en LED's
- Stap 3: Schematisch:
- Stap 4: C++-broncode
- Stap 5: Voltooide gadget
- Stap 6: Toepassing: CPU-belastingsmonitor voor Linux met Perl
- Stap 7: Toepassing: praten met andere modules met I²C
- Stap 8: Toepassing: "Game Cube":-)
- Stap 9: Afbeeldingen / animaties weergeven op de matrix - Snelle hack
- Stap 10: Interactieve besturing van opgeslagen animaties
- Stap 11: Live video tonen
- Stap 12: Bijna gratis meer licht
2025 Auteur: John Day | [email protected]. Laatst gewijzigd: 2025-01-13 06:57
Dit display is gebaseerd op een 8x8 RGB LED Matrix. Voor testdoeleinden was het aangesloten op een standaard Arduino-bord (Diecimila) met behulp van 4 schuifregisters. Nadat ik het aan het werk had gekregen, permatiseerde ik het op een fabbed PCB. De schuifregisters zijn 8-bits breed en kunnen eenvoudig worden gekoppeld aan het SPI-protocol. Pulsbreedtemodulatie wordt gebruikt om de kleuren te mengen, daarover later meer. Een deel van het RAM-geheugen van de MCU wordt gebruikt als framebuffer om het beeld vast te houden. Het video-RAM wordt geparseerd door een interruptroutine op de achtergrond, zodat de gebruiker andere nuttige dingen kan doen, zoals praten met een pc, knoppen en potentiometers lezen. Meer informatie over "Arduino": www.arduino.cc
Stap 1: Pulsbreedtemodulatie voor het mengen van kleuren
Pulsbreedtemodulatie - WAT ?Pulsbreedtemodulatie is in wezen het vrij snel in- en uitschakelen van de stroomtoevoer naar een elektrisch apparaat. Het bruikbare vermogen is het resultaat van het wiskundige gemiddelde van de blokgolffunctie over het interval van één periode. Hoe langer de functie in de AAN-stand staat, hoe meer vermogen u krijgt. PWM heeft hetzelfde effect op de helderheid van LED's als een dimmer op AC-verlichting. De taak die voor ons ligt is om op een goedkope en gemakkelijke manier de helderheid van 64 RGB-LED's (= 192 enkele LED's!) afzonderlijk te regelen, zodat men de hele spectrum van kleuren. Er mogen bij voorkeur geen flikkeringen of andere storende effecten zijn. De niet-lineaire perceptie van helderheid die door het menselijk oog wordt vertoond, wordt hier niet in aanmerking genomen (het verschil tussen 10% en 20% helderheid lijkt "groter" dan tussen 90% en 100%). Afbeelding (1) illustreert het werkingsprincipe van het PWM-algoritme. Stel dat de code een waarde van 7 krijgt voor de helderheid van LED (0, 0). Verder weet hij dat er maximaal N stappen in helderheid zijn. De code voert N lussen uit voor alle mogelijke helderheidsniveaus en alle benodigde lussen om elke afzonderlijke LED in alle rijen te onderhouden. Als de lusteller x in de helderheidslus kleiner is dan 7, gaat de LED aan. Als deze groter is dan 7, gaat de LED uit. Door dit zeer snel te doen voor alle LED's, helderheidsniveaus en basiskleuren (RGB), kan elke LED afzonderlijk worden aangepast om de gewenste kleur weer te geven. Metingen met een oscilloscoop hebben aangetoond dat de verversingscode van het scherm ongeveer 50% CPU-tijd kost. De rest kan worden gebruikt om seriële communicatie met een pc te doen, knoppen te lezen, met een RFID-lezer te praten, I. te verzenden2C-gegevens naar andere modules…
Stap 2: Praten met schuifregisters en LED's
Een schuifregister is een apparaat waarmee gegevens serieel en een parallelle uitgang kunnen worden geladen. De omgekeerde werking is ook mogelijk met de juiste chip. Op de arduino website staat een goede tutorial over schuifregisters. De LED's worden aangestuurd door 8-bit schuifregisters van het type 74HC595. Elke poort kan ongeveer 25 mA stroom leveren of laten zinken. De totale stroom per gezonken of aangevoerde chip mag niet hoger zijn dan 70 mA. Deze chips zijn extreem goedkoop, dus betaal niet meer dan ongeveer 40 cent per stuk. Aangezien LED's een exponentiële stroom-/spanningskarakteristiek hebben, moeten er stroombeperkende weerstanden zijn. Gebruikmakend van de wet van Ohm: R = (V - Vf) / IR = beperkende weerstand, V = 5V, Vf = LED's voorwaartse spanning, I = gewenste stroom Rode LED's hebben een voorwaartse spanning van ongeveer 1,8 V, blauw en groen bereik van 2,5 V tot 3,5 V. Gebruik een eenvoudige multimeter om dat te bepalen. Voor een goede kleurweergave moet men rekening houden met een aantal zaken: spectrale gevoeligheid van het menselijk oog (rood/blauw: slecht, groen: goed), efficiëntie van de LED bij een bepaalde golflengte en stroom. In de praktijk neemt men gewoon 3 potmeters en stelt deze in tot de LED goed wit licht geeft. Uiteraard mag de maximale LED-stroom niet worden overschreden. Wat hier ook belangrijk is, is dat het schuifregister dat de rijen aanstuurt, stroom moet leveren aan 3x8 LED's, dus je kunt de stroom beter niet te hoog opdrijven. Het is me gelukt met begrenzingsweerstanden van 270Ohm voor alle LED's, maar dat hangt natuurlijk af van het merk van de LED-matrix. De schuifregisters zijn gekoppeld aan SPI-serieel. SPI = Serial Peripheral Interface (Afbeelding (1)). In tegenstelling tot de seriële poorten op pc's (asynchroon, geen kloksignaal), heeft SPI een kloklijn nodig (SRCLK). Dan is er een signaallijn die het apparaat vertelt wanneer de gegevens geldig zijn (chipselectie / vergrendeling / RCLK). Ten slotte zijn er twee datalijnen, de ene heet MOSI (master out slave in), de andere heet MISO (master in slave out). SPI wordt gebruikt om geïntegreerde schakelingen te koppelen, net als I2C. Dit project heeft MOSI, SRCLK en RCLK nodig. Daarnaast wordt ook de activeringslijn (G) gebruikt. Een SPI-cyclus wordt gestart door de RCLK-lijn naar LAAG te trekken (Afbeelding (2)). De MCU verzendt zijn gegevens op de MOSI-lijn. De logische toestand ervan wordt bemonsterd door het schuifregister aan de stijgende flank van de SRCLK-lijn. De cyclus wordt beëindigd door de RCLK-lijn terug naar HOOG te trekken. Nu zijn de gegevens beschikbaar bij de uitgangen.
Stap 3: Schematisch:
Afbeelding (1) laat zien hoe de schuifregisters zijn aangesloten. Ze zijn in serie geschakeld, zodat gegevens in deze keten kunnen worden verschoven en er ook doorheen. Daarom is het eenvoudig om meer schuifregisters toe te voegen.
Afbeelding (2) toont de rest van het schema met de MCU, connectoren, kwarts … Het bijgevoegde PDF-bestand bevat het hele werk, het beste om af te drukken.
Stap 4: C++-broncode
In C/C++ moet men gewoonlijk een prototype van functies maken alvorens ze te coderen.#include int main(void);void do_something(void);int main(void) { do_something();}void do_something(void) { /* comment */ }De Arduino IDE vereist deze stap niet, omdat functieprototypes automatisch worden gegenereerd. Daarom zullen functieprototypes niet verschijnen in de hier getoonde code. Afbeelding (1): setup() functionImage (2): spi_transfer() functie met hardware SPI van de ATmega168-chip (werkt sneller) Afbeelding (3): framebuffercode met een timer1 overflow-interrupt. Stukjes code die een enigszins cryptische uitstraling hebben voor beginners, bijv while(!(SPSR & (1<<SPIF))) {} gebruikt de MCU-registers rechtstreeks. Dit voorbeeld in woorden: "terwijl de SPIF-bit in register SPSR niet is ingesteld, doe niets". Beginners hoeven hier niet bang voor te zijn.
Stap 5: Voltooide gadget
Nadat ik alle problemen had opgelost en de code had laten werken, hoefde ik alleen maar een PCB-lay-out te maken en deze naar een fantastisch huis te sturen. Het ziet er zo veel schoner uit:-)Afbeelding (1): volledig gevulde controllerkaartAfbeelding (2): voorkant van de kale PCBAfbeelding (2): achterkantEr breken connectoren uit PORTC en PORTD van de ATmega168/328-chip en 5V/GND. Deze poorten bevatten de seriële RX-, TX-lijnen, de I2C-lijnen, digitale I/O-lijnen en 7 ADC-lijnen. Deze is bedoeld voor het stapelen van schilden aan de achterkant van het bord. De afstand is geschikt voor het gebruik van perfboard (0,1 inch). De bootloader kan worden geflitst met behulp van de ICSP-header (werkt met USBtinyISP van adafruit). Zodra dat is gebeurd, gebruikt u gewoon een standaard FTDI USB/TTL seriële adapter of iets dergelijks. Ik heb ook een jumper voor automatisch resetten en uitschakelen toegevoegd. Ik heb ook een klein Perl-script gemaakt (zie mijn blog), dat auto-reset met FTDI-kabels mogelijk maakt, wat meestal niet uit de doos werkt (RTS versus DTR-lijn). Dit werkt op Linux, misschien op MAC. Printplaten en een paar DIY KIT's zijn beschikbaar op mijn blog. SMD-solderen vereist! Zie de PDF-bestanden voor bouwinstructies en bronnen voor LED-matrices.
Stap 6: Toepassing: CPU-belastingsmonitor voor Linux met Perl
Dit is een zeer eenvoudige belastingsmonitor met een geschiedenisplot. Het is gebaseerd op een Perl-script dat elke seconde het "laadgemiddelde" van het systeem verzamelt met behulp van iostat. Gegevens worden opgeslagen in een array die bij elke update wordt verschoven. Nieuwe gegevens worden bovenaan de lijst toegevoegd, de oudste invoer wordt eruit geduwd. Meer gedetailleerde informatie en downloads (code…) zijn beschikbaar op mijn blog.
Stap 7: Toepassing: praten met andere modules met I²C
Dit is slechts een proof of principle en verreweg niet de eenvoudigste oplossing voor deze klus. I. gebruiken2C maakt directe adressering van maximaal 127 "slave"-kaarten mogelijk. Hier is het bord aan de rechterkant in de video de "master" (die alle overdrachten initieert), het linkerbord is de slaaf (wacht op gegevens). l2C heeft 2 signaallijnen nodig en de gebruikelijke stroomlijnen (+, -, SDA, SCL). Omdat het een bus is, zijn alle apparaten er parallel op aangesloten.
Stap 8: Toepassing: "Game Cube":-)
Gewoon een gekke gedachte. Deze past ook in de houten behuizing die op de intropagina wordt getoond. Het heeft 5 knoppen op de achterkant die kunnen worden gebruikt voor het spelen van een eenvoudig spel. HET EINDE?
Stap 9: Afbeeldingen / animaties weergeven op de matrix - Snelle hack
Het heeft dus maar 8x8 pixels en een paar kleuren beschikbaar. Gebruik eerst iets als Gimp om je favoriete afbeelding te verkleinen tot precies 8x8 pixels en sla het op als ".ppm" onbewerkt formaat (niet ASCII). PPM is gemakkelijk te lezen en te verwerken in een Perl-script. Het gebruik van ImageMagick en de opdrachtregeltool "converteren" zal niet goed werken. Upload de nieuwe Arduino-code en gebruik vervolgens het Perl-script om te uploaden naar de controller. De flikkering is gewoon een mismatch tussen LED-verversing en de framesnelheid van mijn camera. Nadat de code een beetje is bijgewerkt, werkt deze behoorlijk pittig. Alle afbeeldingen worden live via serieel overgedragen zoals u ze ziet. Langere animaties kunnen worden opgeslagen in een externe EEPROM, zoals bij verschillende spoke-pov boards.
Stap 10: Interactieve besturing van opgeslagen animaties
Waarom zou u de microcontroller alle plezier laten beleven? Bij de Arduino-cultus draait alles om fysiek computergebruik en interactie, dus voeg gewoon een potentiometer toe en neem de controle over! Het gebruik van een van de 8 analoog naar digitaal converter-ingangen maakt dat heel eenvoudig.
Stap 11: Live video tonen
Het gebruik van een Perl-script en een paar modules maakt het vrij eenvoudig om quasi live video op X11-systemen te tonen. Het is gecodeerd op Linux en werkt mogelijk ook op MAC's. Het werkt als volgt: - verkrijg de positie van de muiscursor - leg een doos met NxN-pixel vast in het midden van de cursor - schaal de afbeelding naar 8x8 pixel - stuur het naar het LED-bord- herhalen
Stap 12: Bijna gratis meer licht
Met slechts twee stappen kan de helderheid behoorlijk worden verhoogd. Vervang de 270Ω-weerstanden door 169Ω-weerstanden en draag nog een 74HC595-schuifregister op IC5.