Innehållsförteckning:

RGB LED Matrix: 5 steg
RGB LED Matrix: 5 steg

Video: RGB LED Matrix: 5 steg

Video: RGB LED Matrix: 5 steg
Video: AmazingChina: Modular & Flexible LED TV Wall 2024, Juli
Anonim
Image
Image
Hårdvarudesign
Hårdvarudesign

Sök Instructable, och du kan hitta många LED -matrisprojekt. Ingen av dem var riktigt vad jag ville, det vill säga att utforska interaktionerna mellan hårdvara och mjukvarudesign för att producera något, och producera slutprodukten i ett snyggt kretskort med en drivrutin som vi kan dra till "LED-skärmen" med hjälp av hög nivå konstruerar (t.ex. att dra en linje i motsats till att ställa in specifika pixlar). Den här delen var viktig för mig, eftersom många av LED -matrisdrivrutinerna är bara ben och inte ger så mycket programmässigt att skapa en bild eller animering. Det betyder inte att du inte kan skapa bilder och animationer med de andra drivrutinerna, bara att du skulle behöva göra mer repetitivt arbete från projekt till projekt.

Så jag bestämde mig för att uppnå min vision. Det första steget var att designa hårdvaran. Detta var förmodligen det mest utmanande för mig, eftersom min bakgrund är mer programvara. Återigen fanns det många förgräddade mönster, och jag använde dem verkligen som inspiration, men jag ville lära mig genom att göra, så jag prototypade en 4x4-matris på en brödbräda. Jag lärde mig mycket genom den processen, eftersom mina första iterationer inte fungerade. Men jag gjorde hårdvarudesign som fungerade, vilket i sin tur tillät mig att börja utveckla en drivrutin.

Jag valde Arduino som min drivrutinsplattform eftersom den är allmänt tillgänglig och har gott om referenser online. Medan karriärserfarenhet tillät mig att komma till en fungerande version av en förare mer smidigt än mina hårdvaruinsatser, fanns det fortfarande gott om iterationer medan jag optimerade förarens prestanda för ATMega -mikrokontrollen och utvecklade ett programmerings -API som jag gillade.

Denna instruktionsbok dokumenterar designen och några viktiga lärdomar från mitt projekt. Mer information om detta projekt finns på min webbplats här, inklusive kompletta kit som du kan köpa för att bygga din egen RGB LED -matris.

Steg 1: Hårdvarudesign

Det primära målet med min hårdvarudesign var att skapa en rad RGB -lysdioder som jag kunde programmera, men jag ville inte heller spendera mycket pengar. Metoden jag bestämde mig för var att använda 74HC595 skiftregister för att styra lysdioderna. För att minimera antalet skiftregister som behövs, ordnade jag RGB -lysdioderna i en matrislayout där de gemensamma anoderna var bundna i rader och de röda, gröna och blå katodledarna var bundna i kolumner. För 4x4 -matrisen såg kretsschemat ut som det bifogade kretsschemat.

En sak du kommer att märka direkt är att med tanke på matriskretsen finns det några LED -belysningskonfigurationer som inte kan göras med alla önskade lysdioder på samtidigt. Till exempel kan matrisen inte samtidigt tända två lysdioder som är diagonala från varandra eftersom strömförsörjning av både raderna och kolumnerna kommer att få de två motsatta lysdioderna att lysa på den vinkelräta diagonalen mot de önskade lysdioderna. För att komma runt detta kommer vi att använda multiplex för att skanna igenom varje rad. Det finns gott om resurser på webben som täcker tekniken för multiplexering, jag tänker inte försöka replikera dem här.

Eftersom jag använder vanliga anod -lysdioder betyder det att raderna ger positiv effekt och kolumnerna sjunker till marken. Den goda nyheten är att 74HC595 -skiftregistren kan både källa och sänka ström, men de dåliga nyheterna är att de har en gräns för hur mycket ström de kan källa eller sjunka. Enskilda stift på 74HC595 har en maximal strömförbrukning på 70 mA, men det är bäst att behålla mindre än 20 mA. De enskilda färgerna i våra RGB -lysdioder har cirka 20 mA dragning. Det betyder att 74HC595 inte direkt kan driva en hel rad lysdioder om jag vill slå på dem alla.

Så istället för att driva raden direkt, kommer 74HC595 istället att driva en transistor för varje rad, och transistorn kommer att slå på eller av strömmen som driver raden. Eftersom konstruktionen använder vanliga anod -lysdioder kommer omkopplingstransistorn att vara PNP. Om vi använde en vanlig katod -LED skulle omkopplingstransistorn vara NPN. Observera att när du använder en PNP -transistor för att driva en rad blir skiftregisterets inställning för att slå på den nu låg eftersom en PNP -transistor behöver en negativ spänning mellan sändaren och basen för att slås på, vilket gör att positiv ström kan strömma in i rad.

En annan sak att tänka på är den önskade bitlayouten för skiftregistren. Det vill säga bland skiftregistren vilka bitar styr vilka rader eller kolumner i matrisen. Designen jag skickade med är där den första biten, eller "mest signifikanta biten", som skickades till de daisy -kedjade skiftregistren styr kolumnen med lysdiodernas röda element, den andra biten styr den första kolumnens gröna element, den tredje biten styr den första kolumnens blått element, den fjärde biten styr den andra kolumnens röda element, … detta mönster upprepas över kolumnerna vänster till höger. Sedan styr nästa sända bit den sista eller nedre raden, den nästa den näst till sista raden, … detta upprepas tills den sista bit som skickas, eller "minst betydande bit", styr den första eller översta raden i matrisen.

Slutligen behövde jag bestämma vilka motstånd jag skulle använda för var och en av lysdioderna i RGB -lysdioden. Medan du kunde använda standardformeln som kombinerar framspänning och önskad ström för att beräkna det erforderliga motståndet, fann jag att inställningen av varje LED: s ström till 20 milliampar resulterade i en vitvit färg när alla röda, gröna och blå lysdioder var på. Så jag började ögonkula det. För mycket rött i vitt innebar att öka den röda lysdiodens motstånd ohm för att minska strömmen. Jag upprepade gånger bytte ut motstånd från olika ohm tills jag hittade en kombination som gav en vit färg som jag tyckte var rätt. Den sista kombinationen var 180 Ω för den röda lysdioden, 220 Ω för den gröna lysdioden och 100 Ω för den blå lysdioden.

Steg 2: Hårdvarukonstruktion - Brödbräda

Hårdvarukonstruktion - brödbräda
Hårdvarukonstruktion - brödbräda
Hårdvarukonstruktion - brödbräda
Hårdvarukonstruktion - brödbräda

Den första fasen av hårdvarukonstruktionen var brödbrädet. Här gjorde jag en 4x4 -matris med RGB -lysdioderna. Denna matris skulle kräva 16 bitar att styra, 12 för RGB -kolumnerna och 4 för varje rad. Två 74HC595 skiftregister klarar allt. Jag undersökte och konstruerade först en krets som jag trodde skulle fungera och byggde den sedan på brödbrädan.

Förmodligen den största utmaningen med brödbrädans konstruktion var att hantera alla trådar. Jag hämtade ett förformat trådkit för brödbrädor, men då var det lite otympligt. Ett trick som jag tyckte var till hjälp var att skapa en "port" för anslutning till Arduino -kortet. Det vill säga, i stället för att ansluta stiften på Arduino direkt till de olika IC -stiften på brödbrädet, ägna några rader på brödbrädan till att vara anslutningspunkten för Arduino och anslut sedan de relevanta ID -stiften till dessa rader. För detta projekt behöver du bara fem anslutningar till Arduino: +5V, jord, data, klocka och spärr.

När konstruktionen av brödbrädet var klar behövde jag testa den. Men utan någon form av drivrutin för att skicka rätt signaler till skiftregistren kunde jag inte testa om hårdvarulayouten fungerade.

Steg 3: Design av drivrutinsprogramvara

Image
Image

Med tanke på min egen karriärerfarenhet med mjukvaruutveckling, var detta den del av projektet som jag förmodligen var den mest tydliga om en väg att ta. Jag undersökte många av de andra Arduino-baserade LED-matrisdrivrutinerna. Även om det verkligen finns bra förare tillgängliga, hade ingen riktigt den design jag ville ha. Mina designmål för föraren var:

  • Ge ett API på hög nivå för att programmatiskt kunna skapa bilder och animationer. De flesta drivrutiner jag såg var mer fokuserade på hårdkodade bilder. Eftersom jag är en C ++ programmerare till yrket, ville jag också använda bra objektorienterad design för att implementera och hantera aktiviteterna för att rita till LED -matrisen.
  • Använd en dubbelbuffrad metod för att hantera bilden på skärmen. En buffert är vad som dras in i programmet, medan den andra representerar matrispixelns tillstånd vid varje givet ögonblick. Fördelen med detta tillvägagångssätt är att du inte behöver göra nästa bilduppdatering för skärmen fullständigt mellan uppdateringscyklerna för multiplexen.
  • Använd PWM för att tillåta mer än de sju primitiva färger som en RGB kan återge genom enkla kombinationer av de röda, gröna och blå elementen.
  • Skriv drivrutinen så att den "bara skulle fungera" med RGB LED -matriser av olika storlek som följde min allmänna matrisdesign. Observera att även om min hårdvarudesign använder 74HC595 -skiftregister, förväntar jag mig att min drivrutin arbetar med alla på/av -mekanismer för skiftregister som är utformade med en liknande bitlayout som min hårdvarudesign. Till exempel skulle jag förvänta mig att min förare skulle arbeta med en hårdvarudesign som använde DM13A -chips för att styra kolumnerna och ett 74HC595 -chip för att styra raderna.

Om du vill gå direkt till att titta på förarkoden kan du hitta den på GitHub här.

Den första iterationen av min förare var lite av en inlärningskurva om Arduino -plattformens möjligheter. Den mest uppenbara begränsningen är RAM, som är 2K byte för Arduino Uno och Nano. Användning av C ++ - objekt i ett sådant scenario rekommenderas ofta inte på grund av minneskostnader för objekt. Men jag kände att om det görs rätt, uppväger fördelen med objekt i C ++ deras kostnad (i RAM).

Den andra stora utmaningen var att ta reda på hur vi skulle implementera pulsbreddsmoduleringen via skiftregistren så att jag kunde generera mer än de sju primitiva färgerna på RGB LED. Efter att ha programmerat i många år på Linux -plattformar var jag van vid att använda konstruktioner som trådar för att hantera processer som kräver konsekvent timing. Tidpunkten för skiftregisteruppdateringsoperationen hamnar ganska kritiskt när man skapar en drivrutin för en LED -matris som använder multiplexing. Anledningen är att även om multiplexeringen sker så snabbt att dina ögon inte kan se de enskilda lysdioderna blinka på och av, kan dina ögon få skillnader i den totala sammanlagda tiden som någon av lysdioderna är på. Om en rad lysdioder konstant lyser under en längre tid än de andra kommer det att se ljusare ut under multiplexeringen. Detta kan leda till ojämn ljusstyrka i matrisen eller periodisk strobing av matrisen som helhet (detta inträffar när en uppdateringscykel tar längre tid än de andra).

Eftersom jag behövde en konsekvent tidsmekanism för att orsaka att skiftregisteruppdateringarna var samtycke, men Arduino formellt inte stöder tråd, var jag tvungen att skapa min egen trådliknande mekanism. Min första iteration av detta var att helt enkelt skapa en loop -timer som var beroende av Arduino loop () -funktionen och skulle avfyra en åtgärd när a en viss tid har gått sedan den senaste gången åtgärden avfyrades. Detta är en form av "kooperativ multitasking". Låter bra men i praktiken visade det sig vara inkonsekvent när avfyrningshastigheten mättes i mikrosekunder. Anledningen till detta är att om jag hade två av dessa loop -timers, tog en av deras handlingar ofta tillräckligt lång tid för att få den andra åtgärden att skjuta senare än önskat.

Jag fann att lösningen på detta problem är att använda Arduinos inbyggda klockavbrottsmekanism. Denna mekanism låter dig köra en liten bit kod med mycket konsekventa intervall. Så jag utformade förarkoden kring designelementet med att använda ett klockavbrott för att utlösa koden för att skicka matrisens skiftregister nästa uppdatering i multiplexcykeln. För att göra detta och tillåta uppdateringar av skärmbilden för att inte störa en aktiv dumpning till skiftregistren (något vi skulle kalla ett "rasvillkor") använde jag en metod för att ha dubbla buffertar för skiftregisterbitarna, en för att skriva och en för att läsa. När användaren uppdaterar matrisbilden sker dessa operationer till skrivbufferten. När dessa operationer är klara avbryts avbrottet tillfälligt (det betyder att klockavbrottet inte kan avfyras) och skrivbufferten byts ut mot den tidigare läsbufferten och det är inte den nya läsbufferten, då aktiveras tolkarna igen. När sedan klockan avbryter, vilket indikerar att det är dags att skicka nästa bitkonfiguration till skiftregistren, läses den informationen från den aktuella läsbufferten. På detta sätt uppstår aldrig skrivning till en buffert som för närvarande kan läsas från under ett klockavbrott, vilket kan skada informationen som skickas till skiftregistren.

Att designa resten av föraren var ett relativt enkelt fall av objektorienterad design. Till exempel skapade jag ett objekt för att hantera skiftregisterbitbilden för ett givet skärmläge. Genom att kapsla in koden för bitbildhantering var det en enkel övning att skapa den ovannämnda metoden med dubbla buffertar. Men jag skrev inte detta Instructable för att hylla dygderna i objektorienterad design. Andra designelement inkluderar konceptet Glyph och RGB -bild. A Glyph är en grundläggande bildkonstruktion som inte har någon medfödd färginformation. Du kan se det som en svartvit bild. När Glyph dras till LED -skärmen ges färginformation för att indikera hur de "vita" pixlarna ska färgas. En RGB -bild är en bild där varje pixel har sin egen färginformation.

Jag uppmuntrar dig att granska exempel på Arduino -skisser och granska dokumentationen för förarhuvudet för att bli bekant med hur du använder föraren för att skapa bilder och animationer på en RGB LED -matris.

Steg 4: LED Ghosting

LED Ghosting
LED Ghosting
LED Ghosting
LED Ghosting

I en LED -matris är "ghosting" fenomenet att en LED i matrisen lyser när den inte önskas, vanligtvis en mycket reducerad nivå. Min ursprungliga hårdvarudesign var känslig för spökbilder, framför allt på den sista raden. Orsaken till detta beror på två saker: transistorer stängs inte av direkt och parasitisk kapacitans i RGB -lysdioderna.

När vi skannar igenom raderna, på grund av det faktum att transistorer inte stängs av direkt, drivs den föregående raden i skanningscykeln fortfarande delvis när nästa rad slås på. Om en given kolumn som var avstängd i den föregående raden slås på igen när den nya raden får ström, kommer lysdioden för den kolumnen i den föregående raden att lysa en liten stund medan den föregående radens växlingstransistor fortfarande håller på att vridas av. Det som får transistorn att ta en märkbar tid att stänga av är mättnad i basen av transistorn. Detta gör att transistorns kollektor-emitterbana fortsätter att leda när strömmen avlägsnas från basen, åtminstone tills mättnaden försvinner. Med tanke på att vår multiplexuppdateringscykel gör att rader avsiktligt sätts på under en tidsperiod mätt i mikrosekunder, kan den tid som den föregående radens mättade transistor förblir ledande vara en märkbar bråkdel av det. Som ett resultat kan ditt öga uppfatta den mycket lilla tid som LED -lampan för föregående rad är tänd.

För att åtgärda transistormättnadsproblemet kan en Schottky -diod läggas till transistorn mellan basen och kollektorn för att orsaka lite återström till basen när transistorn är på, vilket förhindrar att transistorn blir mättad. Detta kommer i sin tur att transistorn stängs av snabbare när strömmen tas bort från basen. Se denna artikel för en fördjupad förklaring av denna effekt. Som du kan se på bilden i det här avsnittet är spökningen ganska märkbar utan dioden, men att lägga till dioden i kretsen för varje rad avlägsnar betydligt spökningen.

RGB -lysdioder är mottagliga för ett annat fenomen som kallas parasitisk kapacitans. Grundorsaken till detta är det faktum att var och en av de tre färg -lysdioderna i RGB LED -enheten har olika framspänningar. Denna skillnad i framspänningar kan orsaka effekten av elektrisk kapacitans mellan var och en av de enskilda LED -färgerna. Eftersom en elektrisk laddning byggs upp i LED -enheten när den drivs, när strömmen tas bort, måste parasitkapacitansen urladdas. Om den LED -kolumnen annars är på för en annan rads strömförsörjning, kommer parasitladdningen att laddas ut genom den kolumnens LED och få den att lysa kort. Denna effekt förklarar fint i denna artikel. Lösningen är att lägga till en urladdningsväg för denna parasitiska laddning annat än genom själva lysdioden, och sedan ge LED -lampan tid att ladda ur innan kolonnen drivs igen. I min hårdvarudesign uppnås detta genom att lägga till ett motstånd till varje rad kraftledning som ansluter styrka till mark. Detta kommer att leda till att mer ström dras när raden drivs, men ger en urladdningsbana för parasitkapacitansen när raden inte drivs.

Det är dock värt att notera att i praktiken tycker jag att effekten av parasitisk kapacitans är knappt märkbar (om du letar efter det kan du hitta det), och därför anser jag att det är frivilligt att lägga till detta extra motstånd. Effekten av långsam avstängningstid för mättade transistorer är mycket starkare och märkbar. Men om du inspekterar de tre bilderna i det här avsnittet kan du se att motstånden helt tar bort alla spökbilder som fortfarande uppstår utöver de långsamma transistorns avstängningstider.

Steg 5: Slutlig tillverkning och nästa steg

Image
Image

Den sista fasen av detta projekt var för mig att skapa ett kretskort (PCB). Jag använde open source -programmet Fritzing för att designa mitt PCB. Även om det var många repetitiva uppgifter att utföra för att lägga upp 100 lysdioder på ett 10x10 -kort, tyckte jag faktiskt att denna fas av projektet var märkligt tillfredsställande. Att räkna ut hur varje elektrisk väg skulle läggas ut var som ett pussel, och att lösa det pusslet skapade en känsla av prestation. Eftersom jag inte är inställd på att tillverka kretskort, använde jag en av de många online -resurser som gör små körningar av anpassat kretskort. Lödning av delarna var ganska rakt fram eftersom min design använde alla delar genom hålet.

När jag skriver den här instruktionsboken har jag följande planer för mina RGB LED Matrix -projekt:

  1. Fortsätt att förbättra drivrutinen på API-lagret för att möjliggöra fler funktioner på hög nivå för programmeraren, framför allt textrullning.
  2. Skapa större matrisdesigner, till exempel 16x16 eller till och med 16x32.
  3. Utforska att använda MOSFET istället för BJT för radomkoppling
  4. Utforska att använda DM13As konstantströmdrivrutiner snarare än 74HC595s för kolumnbytet
  5. Skapa drivrutiner för andra mikrokontrollplattformar, till exempel Teensy, ODROID C2 eller Raspberry Pi.

Observera att både maskinvarudesign och drivrutin har släppts under GPL v3 -öppen källkodslicens på detta GitHub -arkiv. Eftersom även om kretskortstillverkarna gör "små körningar" av min PCB -design, får jag fortfarande mycket mer än jag personligen behöver. Så jag säljer hela kit för mina olika RGB LED -matrisdesigner (PCB och alla delar ingår) från min webbplats här.

Rekommenderad: