Indholdsfortegnelse:

RGB LED Matrix: 5 trin
RGB LED Matrix: 5 trin

Video: RGB LED Matrix: 5 trin

Video: RGB LED Matrix: 5 trin
Video: How does an RGB LED Matrix work? 2024, November
Anonim
Image
Image
Hardware design
Hardware design

Søg Instructable, og du kan finde mange LED -matrixprojekter. Ingen af dem var helt, hvad jeg ville, hvilket var at udforske interaktionerne mellem hardware og software design for at producere noget og producere det endelige produkt i en pæn print med en driver, som lad mig tegne til "LED-skærmen" ved hjælp af højt niveau konstruerer (f.eks. at tegne en streg i modsætning til at indstille bestemte pixels). Denne del var vigtig for mig, da mange af LED -matrixdriverne er bare ben og ikke giver meget i vejen for programmatisk at skabe et billede eller en animation. Dette betyder ikke, at du ikke kan oprette billeder og animationer med de andre drivere, bare at du bliver nødt til at udføre mere gentaget arbejde fra projekt til projekt.

Så jeg satte mig for at opnå min vision. Det første trin var at designe hardware. Dette var nok den mest udfordrende for mig, da min baggrund er mere software. Igen var der mange færdigbagte designs, og jeg brugte dem bestemt til inspiration, men jeg ville lære gennem at gøre, så jeg prototyperede en 4x4-matrix på et brødbræt. Jeg lærte meget gennem den proces, da mine første par iterationer ikke virkede. Men jeg lavede hardware design, der fungerede, hvilket igen gav mig mulighed for at begynde at udvikle en driver.

Jeg valgte Arduino som min driverplatform, fordi den er bredt tilgængelig og har masser af referencer online. Selvom karriereerfaring tillod mig at komme til en fungerende version af en driver mere glat end min hardwareindsats, var der stadig masser af iterationer, mens jeg optimerede driverens ydeevne for ATMega -mikrokontrolleren og udviklede en programmerings -API, som jeg kunne lide.

Denne instruktionsbog dokumenterer designet og nogle vigtige erfaringer fra mit projekt. Flere oplysninger om dette projekt kan findes på mit websted her, inklusive fulde sæt, du kan købe til at bygge din egen RGB LED -matrix.

Trin 1: Hardware Design

Det primære mål med mit hardware design var at skabe en række RGB LED'er, som jeg kunne programmere, men jeg ville heller ikke bruge mange penge. Den fremgangsmåde jeg besluttede mig for var at bruge 74HC595 skifteregistre til at styre lysdioderne. For at minimere antallet af nødvendige skiftregistre, arrangerede jeg RGB -lysdioderne i et matrixlayout, hvor de fælles anoder blev bundet sammen i rækker, og de røde, grønne og blå katodeledninger blev bundet sammen i kolonner. For 4x4 -matricen lignede kredsløbsdiagrammet det vedlagte kredsløbsdiagram.

En ting, du vil bemærke med det samme, er, at i betragtning af matrixkredsløbet er der nogle LED -belysningskonfigurationer, der ikke kan udføres, mens alle de ønskede LED'er er tændt på samme tid. For eksempel kan matricen ikke samtidig tænde to lysdioder, der er diagonale fra hinanden, fordi strømforsyning af både rækker og kolonner får de to modsatte lysdioder til at lyse på den vinkelrette diagonal til de ønskede lysdioder. For at omgå dette, vil vi bruge multiplexing til at scanne gennem hver række. Der er masser af ressourcer på nettet, der dækker teknikken til multiplexering, jeg vil ikke prøve at replikere dem her.

Da jeg bruger almindelige anode -LED'er, betyder det, at rækkerne giver positiv effekt, og kolonnerne synker til jorden. Den gode nyhed er, at 74HC595 -skifteregistrene både kan kilde og synke strøm, men den dårlige nyhed er, at de har en grænse for, hvor meget strøm de kan skaffe eller synke. Individuelle stifter på 74HC595 har en maksimal strømforbrug på 70 mA, men det er bedst at beholde mindre end 20 mA. De enkelte farver i vores RGB LED'er har hver en 20 mA -trækning. Det betyder, at 74HC595 ikke direkte kan drive en hel række lysdioder, hvis jeg ønsker at tænde dem alle.

Så i stedet for at tænde for rækken direkte, vil 74HC595 i stedet drive en transistor for hver række, og transistoren vil tænde eller slukke for strømmen til rækken. Da designet bruger en fælles anode -LED, vil switch -transistoren være PNP. Hvis vi brugte en fælles katod -LED, ville switch -transistoren være NPN. Bemærk, at ved brug af en PNP -transistor til at køre en række bliver skiftregisterets indstilling for at tænde den nu lav, da en PNP -transistor har brug for en negativ spænding mellem emitteren og basen, som tillader positiv strøm at strømme ind i række.

En anden ting at overveje er det ønskede bitlayout af skiftregisterne. Det er blandt skiftregisterne, hvilke bits styrer hvilke rækker eller kolonner i matrixen. Det design, jeg sendte med, er, hvor den første bit, eller "den mest betydningsfulde bit", der blev sendt til daisy -kædede skiftregistre, styrer kolonnen med lysdioder i det røde element, den anden bit styrede den første kolums grønne element, den tredje bit styrede den første kolonnen blå element, den fjerde bit styrer den anden kolonnen røde element, … dette mønster gentages på tværs af kolonnerne fra venstre til højre. Derefter styrer den næste bit, der sendes, den sidste eller nederste række, den næste den anden til sidste række, … dette gentages indtil den sidste bit, der sendes, eller "mindst signifikante bit", styrer den første eller øverste række i matrixen.

Endelig var jeg nødt til at bestemme, hvilke modstande jeg ville bruge til hver af LED'erne i RGB LED. Selvom du kunne bruge standardformlen, der kombinerer fremspænding og ønsket strøm til at beregne den nødvendige modstand, fandt jeg ud af, at indstilling af hver LEDs strøm til 20 milliampere resulterede i en off-white farve, når alle de røde, grønne og blå lysdioder var tændt. Så jeg begyndte at se det i øjnene. For meget rødt i det hvide betød at øge den røde LEDs modstand ohm for at reducere strømmen. Jeg gentog udskiftning af modstande med forskellige ohm, indtil jeg fandt en kombination, der frembragte en hvid farve, som jeg følte var rigtig. Den sidste kombination var 180 Ω for den røde LED, 220 Ω for den grønne LED og 100 Ω for den blå LED.

Trin 2: Hardwarekonstruktion - brødbræt

Hardwarekonstruktion - brødbræt
Hardwarekonstruktion - brødbræt
Hardwarekonstruktion - brødbræt
Hardwarekonstruktion - brødbræt

Den første fase af hardware -konstruktøren var brødbrættet. Her lavede jeg en 4x4 matrix med RGB LED'erne. Denne matrix ville kræve 16 bit at styre, 12 for RGB -kolonnerne og 4 for hver række. To 74HC595 skifteregistre kan klare det hele. Jeg undersøgte og designede først et kredsløb, jeg troede ville fungere, og byggede det derefter på brødbrættet.

Formentlig den største udfordring ved opbygningen af brødbrættet var at styre alle ledninger. Jeg hentede et præformet trådkit til brødbrætter, men da var det lidt uhåndterligt. Et trick, som jeg fandt nyttig, var at oprette en "port" til tilslutning til Arduino -kortet. Det vil sige, i stedet for at forbinde stifterne på Arduino direkte til de forskellige IC -ben på brødbrættet, dedikerer et par rækker på brødbrættet til at være forbindelsespunktet for Arduinoen, og derefter tilslutter de relevante ID -ben til disse rækker. Til dette projekt behøver du kun fem forbindelser til Arduino: +5V, jord, data, ur og lås.

Da opbygningen af brødbrættet var færdig, havde jeg brug for at teste det. Men uden en slags driver til at sende de rigtige signaler til skifteregistrene, var jeg ikke i stand til at teste, om hardware -layoutet fungerede.

Trin 3: Design af driversoftware

Image
Image

I betragtning af min egen karriereerfaring med softwareudvikling var dette den del af projektet, som jeg nok var den mest klare om en vej at tage. Jeg undersøgte mange af de andre Arduino-baserede LED-matrixdrivere. Selvom der sikkert er gode drivere til rådighed, havde ingen helt det design, jeg ønskede. Mine designmål for chaufføren var:

  • Tilvejebring en API på højt niveau for programmæssigt at kunne oprette billeder og animationer. De fleste drivere, jeg så, var mere fokuseret på hårdkodede billeder. Da jeg også er en C ++ programmerer af fag, ville jeg bruge et godt objektorienteret design til at implementere og styre aktiviteterne ved at tegne til LED -matrixen.
  • Brug en dobbeltbufferet tilgang til at styre billedet på skærmen. Den ene buffer er det, der bliver trukket ind i programmet, mens den anden repræsenterer matrixpixelernes tilstand på et givet tidspunkt. Fordelen ved denne fremgangsmåde er, at du ikke er fuldstændig forpligtet til at gengive den næste frame -opdatering til skærmen fuldstændigt mellem multiplexingens opdateringscyklusser.
  • Brug PWM til at tillade mere end de syv primitive farver, en RGB kan gengive gennem simple kombinationer af de røde, grønne og blå elementer.
  • Skriv driveren sådan, at den "bare ville fungere" med RGB LED -matricer af forskellig størrelse, der fulgte min generelle tilgang til matrixdesign. Bemærk, at mens mit hardwaredesign bruger 74HC595 skiftregistre, ville jeg forvente, at min driver arbejder med en hvilken som helst skiftregistreringsstil til/fra -mekanisme, der er udlagt ved hjælp af et lignende bitlayout som mit hardware design. For eksempel ville jeg forvente, at min driver skulle arbejde med et hardwaredesign, der brugte DM13A -chips til at styre kolonnerne og en 74HC595 -chip til at styre rækkerne.

Hvis du vil gå direkte til at se på driverkoden, kan du finde den på GitHub her.

Den første iteration af min chauffør var lidt af en læringskurve om Arduino -platformens muligheder. Den mest oplagte begrænsning er RAM, som er 2K bytes for Arduino Uno og Nano. Det anbefales ofte ikke at bruge C ++ - objekter i et sådant scenario på grund af objekternes hukommelse. Jeg følte imidlertid, at hvis det blev gjort rigtigt, opvejes fordelen ved objekter i C ++ deres omkostninger (i RAM).

Den anden store udfordring var at finde ud af, hvordan vi implementerer pulsbreddemodulationen via skiftregisterne, så jeg kunne generere mere end de syv primitive farver på RGB LED. Efter at have programmeret i mange år på Linux -platforme, var jeg vant til at bruge konstruktioner som tråde til at styre processer, der kræver konsekvent timing. Timingen af skiftregisteropdateringsoperationen ender med at være temmelig kritisk, når man laver en driver til en LED -matrix, der bruger multiplexering. Årsagen er, at selvom multiplexering sker så hurtigt, at dine øjne ikke kan se de enkelte lysdioder blinke til og fra, kan dine øjne opfange forskelle i den samlede samlede tid, som nogen af lysdioderne er tændt. Hvis en række LED'er er konstant tændt i en længere periode end de andre, ser det lysere ud under multiplexeringen. Dette kan føre til ujævn lysstyrke i matrixen eller periodisk strobing af matrixen som helhed (dette sker, når en opdateringscyklus tager længere tid end de andre).

Da jeg havde brug for en konsekvent timemekanisme for at få skiftregisteropdateringer til at være samtykke, men Arduino formelt ikke understøtter tråd, var jeg nødt til at oprette min egen trådlignende mekanisme. Min første iteration af dette var simpelthen at oprette en loop -timer, der var afhængig af Arduino loop () -funktionen og ville affyre en handling, når a et bestemt tidsrum er gået siden sidste gang handlingen blev affyret. Dette er en form for "kooperativ multitasking". Det lyder godt, men i praksis viste dette sig at være inkonsekvent, når affyringshastigheden blev målt i mikrosekunder. Grunden til dette er, at hvis jeg havde to af disse loop -timere i gang, tog en af deres handlinger ofte lang nok tid til at få den anden handling til at affyre senere end ønsket.

Jeg fandt ud af, at løsningen på dette problem er at bruge Arduinos oprindelige urafbrydelsesmekanisme. Denne mekanisme giver dig mulighed for at køre en lille smule kode med meget konsekvente intervaller. Så jeg designede driverkoden omkring designelementet ved at bruge et urafbrydelse til at udløse koden til at sende matrixens skift registrerer den næste opdatering i multiplexcyklussen. For at gøre dette og lade opdateringer forekomme på skærmens billede for ikke at forstyrre en aktiv dumpning til skiftregistrene (noget vi ville kalde en "racetilstand"), brugte jeg en tilgang til at have to buffere til skiftregistrets bits, en til skrivning og en til læsning. Når brugeren opdaterer matrixbilledet, sker disse handlinger i skrivebufferen. Når disse operationer er afsluttet, afbrydes afbrydelser midlertidigt (det betyder, at urafbrydelsen ikke kan udløses), og skrivebufferen byttes med den tidligere læsebuffer, og det er ikke den nye læsebuffer, så tolkene genaktiveres. Når uret derefter afbryder, hvilket angiver, at det er tid til at sende den næste bitkonfiguration til skiftregistrene, læses disse oplysninger fra den aktuelle læsebuffer. På denne måde sker der aldrig nogen skrivning til en buffer, der muligvis læses fra i løbet af et urafbrydelse, hvilket kan ødelægge de oplysninger, der sendes til skifteregistrene.

Design af resten af driveren var et relativt ligetil tilfælde af objektorienteret design. For eksempel oprettede jeg et objekt til at styre skiftregisterbit -billedet for enhver given skærmtilstand. Ved at indkapsle koden vedrørende bit image management var oprettelsen af den førnævnte tvillingebuffer -tilgang i sig selv en ligetil øvelse. Men jeg skrev ikke denne Instructable for at prise dyderne i objektorienteret design. Andre designelementer inkluderer konceptet med en Glyph og et RGB -billede. En Glyph er en grundlæggende billedkonstruktion, der ikke har nogen medfødt farveinformation. Du kan tænke på det som et sort -hvidt billede. Når Glyph trækkes til LED -skærmen, gives der farveoplysninger for at angive, hvordan de "hvide" pixels skal farves. Et RGB -billede er et billede, hvor hver pixel har sine egne farveoplysninger.

Jeg opfordrer dig til at gennemgå Arduino -skitseeksemplerne og gennemse driveroverskriftsdokumentationen for at blive fortrolig med, hvordan du bruger driveren til at oprette billeder og animationer på en RGB LED -matrix.

Trin 4: LED Ghosting

LED Ghosting
LED Ghosting
LED Ghosting
LED Ghosting

I en LED -matrix er "ghosting" fænomenet med en LED i matrixen, der lyser, når den ikke ønskes, normalt et meget reduceret niveau. Mit originale hardwaredesign var modtageligt for spøgelser, især i den sidste række. Årsagen til dette skyldes to ting: transistorer slukker ikke med det samme og parasitisk kapacitans i RGB -lysdioderne.

Da vi scanner gennem rækkerne, skyldes det, at transistorer ikke straks slukker, den foregående række i scanningscyklussen stadig er delvist drevet, når den næste række tændes. Hvis en given kolonne, der var slukket i den foregående række, tændes for ny, når den nye række får strøm, lyser LED'en for den kolonne i den foregående række en lille smule, mens den forrige ræks switch -transistor stadig er i gang med at dreje af. Det, der får transistoren til at tage en mærkbar tid at slukke, er mætning i transistorens bund. Dette får transistorens kollektor-emittersti til at fortsætte med at lede, når strøm fjernes fra basen, i det mindste indtil mætningen forsvinder. I betragtning af at vores multiplexende opdateringscyklus bevirker, at rækker med vilje tændes i en periode målt i mikrosekunder, kan den tid, den foregående ræks mættede transistor forbliver ledende, være en mærkbar brøkdel af det. Som et resultat kan dit øje opfatte den meget lille tid, som den forrige ræks LED er tændt.

For at løse transistormætningsproblemet kan der tilføjes en Schottky -diode til transistoren mellem basen og kollektoren for at forårsage lidt tilbagestrøm til basen, når transistoren er tændt, hvilket forhindrer transistoren i at blive mættet. Dette vil igen få transistoren til at slukke hurtigere, når strøm fjernes fra basen. Se denne artikel for en grundig forklaring af denne effekt. Som du kan se på billedet i dette afsnit, er spøgelsen uden diode ganske mærkbar, men tilføjelse af dioden til kredsløbet for hver række fjerner spøgelsen betydeligt.

RGB -lysdioder er modtagelige for et andet fænomen kaldet parasitisk kapacitans. Hovedårsagen til dette er det faktum, at hver af de tre farve -lysdioder i RGB LED -enheden hver har forskellige fremspændinger. Denne forskel i fremspændinger kan forårsage effekten af elektrisk kapacitans mellem hver af de enkelte LED -farver. Da der opbygges en elektrisk ladning i LED -enheden, når den er tændt, når strømmen fjernes, skal parasitkapacitansen aflades. Hvis denne LED -kolonne ellers er tændt for en anden ræks strømforsyning, vil den parasitære ladning aflades gennem denne søjle -LED og få den til at lyse kortvarigt. Denne effekt forklares pænt i denne artikel. Løsningen er at tilføje en afladningssti for denne parasitiske ladning andet end gennem selve LED'en og derefter give LED'en tid til at aflade, før kolonnen tændes igen. I mit hardware design opnås dette ved at tilføje en modstand til hver ræks strømledning, der forbinder styrke til jord. Dette vil bevirke, at der trækkes mere strøm, når rækken drives, men giver en udladningssti for den parasitiske kapacitans, når rækken ikke drives.

Det er dog værd at bemærke, at jeg i praksis synes, at effekten af parasitisk kapacitans er knap mærkbar (hvis du leder efter det, kan du finde det), og derfor overvejer jeg at tilføje denne ekstra modstand som valgfri. Effekten af den langsomme slukningstid for mættede transistorer er meget stærkere og mærkbar. Ikke desto mindre, hvis du inspicerer de tre fotos, der er angivet i dette afsnit, kan du se, at modstandene fuldstændigt fjerner enhver spøgelse, der stadig opstår ud over den langsomme transistors slukketider.

Trin 5: Endelig fremstilling og næste trin

Image
Image

Den sidste fase af dette projekt var for mig at oprette et printkort (PCB). Jeg brugte open source -programmet Fritzing til at designe mit printkort. Selvom der var mange gentagne opgaver at udføre for at layoute 100 lysdioder på et 10x10 bord, fandt jeg faktisk denne fase af projektet mærkeligt tilfredsstillende. At finde ud af, hvordan hver elektrisk vej ville blive lagt ud, var som et puslespil, og at løse det puslespil skabte en følelse af præstation. Da jeg ikke er indstillet til at fremstille printkortene, brugte jeg en af de mange online -ressourcer, der laver små kørsler af brugerdefineret printkort. Lodning af delene var ret ligetil, da mit design brugte alle dele gennem hullet.

På tidspunktet for skrivningen af denne Instructable har jeg følgende planer for mine mine RGB LED Matrix -projekter:

  1. Fortsæt med at forbedre driveren på API-laget for at muliggøre mere funktionalitet på højt niveau til programmøren, især tekstrulning.
  2. Opret større matrixdesign, f.eks. 16x16 eller endda 16x32.
  3. Udforsk brug af MOSFET'er i stedet for BJT'er til skift af rækken
  4. Udforsk brug af DM13As konstantstrømdrivere frem for 74HC595'er til kolonneskift
  5. Opret drivere til andre mikrokontrolplatforme, såsom Teensy, ODROID C2 eller Raspberry Pi.

Bemærk, at både hardwaredesign og driver er blevet frigivet under GPL v3 open source -licensen på dette GitHub -lager. Desuden, da selvom PCB -fabrikanterne laver "små kørsler" af mit PCB -design, får jeg stadig langt mere, end jeg personligt har brug for. Så jeg sælger fulde sæt til mine forskellige RGB LED matrix designs (PCB og alle dele inkluderet) fra min hjemmeside her.

Anbefalede: