Innholdsfortegnelse:

RGB LED Matrix: 5 trinn
RGB LED Matrix: 5 trinn

Video: RGB LED Matrix: 5 trinn

Video: RGB LED Matrix: 5 trinn
Video: Aquarium Maintenance On Client Location - 4K Cinematic - Green Aqua 2024, Juli
Anonim
Image
Image
Maskinvaredesign
Maskinvaredesign

Søk Instructable, og du kan finne mange LED -matriseprosjekter. Ingen av dem var helt det jeg ønsket, det vil si å utforske samspillet mellom maskinvare- og programvaredesign for å produsere noe, og produsere sluttproduktet i en pen PCB med en driver som lar meg trekke til "LED-skjermen" ved hjelp av høyt nivå konstruerer (f.eks. å tegne en linje i motsetning til å sette bestemte piksler). Denne delen var viktig for meg, ettersom mange av LED -matrisedriverne er bare bein og ikke gir mye i veien for å programmere et bilde eller en animasjon. Dette betyr ikke at du ikke kan lage bilder og animasjoner med de andre driverne, bare at du må gjøre mer repetitivt arbeid fra prosjekt til prosjekt.

Så jeg satte meg for å oppnå visjonen min. Det første trinnet var å designe maskinvaren. Dette var sannsynligvis den mest utfordrende for meg, ettersom bakgrunnen min er mer programvare. Igjen var det mange ferdigbakte design, og jeg brukte dem absolutt som inspirasjon, men jeg ville lære gjennom å gjøre, så jeg prototyperte en 4x4-matrise på et brødbrett. Jeg lærte mye gjennom den prosessen, ettersom de første par iterasjonene mine ikke fungerte. Men jeg gjorde maskinvaredesign som fungerte, noe som igjen tillot meg å begynne å utvikle en driver.

Jeg valgte Arduino som min driverplattform fordi den er allment tilgjengelig og har mange referanser på nettet. Selv om karriereerfaring tillot meg å komme til en fungerende versjon av en driver mer glatt enn maskinvareinnsatsen min, var det fortsatt mange iterasjoner mens jeg optimaliserte driverytelsen for ATMega -mikrokontrolleren og utviklet et programmerings -API som jeg likte.

Denne instruksjonsboken dokumenterer designet og noen viktige erfaringer fra prosjektet mitt. Mer informasjon om dette prosjektet finner du på nettstedet mitt her, inkludert komplette sett du kan kjøpe for å bygge din egen RGB LED -matrise.

Trinn 1: Maskinvaredesign

Hovedmålet med maskinvaredesignet mitt var å lage en rekke RGB -lysdioder som jeg kunne programmere, men jeg ville heller ikke bruke mye penger. Tilnærmingen jeg bestemte meg for var å bruke 74HC595 skiftregistre for å kontrollere lysdiodene. For å minimere antall skiftregistre som trengs, arrangerte jeg RGB -lysdiodene i et matriselayout der de vanlige anodene ble bundet sammen i rader og de røde, grønne og blå katodeledningene ble bundet sammen i kolonner. For 4x4 -matrisen så kretsdiagrammet ut som det vedlagte kretsdiagrammet.

En ting du vil merke med en gang er at gitt matrisekretsen, er det noen LED -belysningskonfigurasjoner som ikke kan gjøres med alle de ønskede lysdiodene på samtidig. For eksempel kan ikke matrisen samtidig tenne to lysdioder som er diagonale fra hverandre fordi strømmen til både radene og kolonnene vil føre til at de to motsatte lysdiodene lyser på den vinkelrette diagonalen til de ønskede lysdiodene. For å omgå dette, bruker vi multipleksing for å skanne gjennom hver rad. Det er mange ressurser på nettet som dekker teknikken for multipleksing, jeg skal ikke prøve å replikere dem her.

Siden jeg bruker vanlige LED -anoder, betyr det at radene gir positiv effekt og kolonnene synker til bakken. Den gode nyheten er at 74HC595 -skiftregistrene både kan skaffe og synke strøm, men de dårlige nyhetene er at de har en grense for hvor mye strøm de kan skaffe eller synke. Individuelle pinner på 74HC595 har en maksimal strømforbruk på 70 mA, men det er best å beholde mindre enn 20 mA. De enkelte fargene i våre RGB -lysdioder har hver omtrent 20 mA trekk. Dette betyr at 74HC595 ikke direkte kan drive en hel rad med lysdioder hvis jeg ønsker å slå dem alle på.

Så i stedet for å drive raden direkte, vil 74HC595 i stedet drive en transistor for hver rad, og transistoren vil slå på eller av strømmen som driver raden. Siden designet bruker en vanlig anode -LED, vil koblingstransistoren være PNP. Hvis vi brukte en vanlig katod -LED, ville koblingstransistoren være NPN. Vær oppmerksom på at ved bruk av en PNP -transistor for å kjøre en rad, blir skiftregisterets innstilling for å slå den på nå lav ettersom en PNP -transistor trenger en negativ spenning mellom senderen og basen for å slås på, noe som gjør at positiv strøm kan strømme inn i rad.

En annen ting å vurdere er ønsket bitoppsett av skiftregistrene. Det er, blant skiftregistrene, hvilke biter som styrer hvilke rader eller kolonner i matrisen. Designet jeg sendte med er der den første biten, eller "mest betydningsfulle biten", som ble sendt til den daisy chain -skiftregistrene, kontrollerer kolonnen med LEDs røde element, den andre biten styrte den første kolonnens grønne element, den tredje biten styrer den første kolonnen blått element, den fjerde biten styrer den andre kolonnens røde element, … dette mønsteret gjentas på tvers av kolonnene venstre til høyre. Deretter kontrollerer den neste sendte biten den siste eller nederste raden, den neste den andre til siste raden, … dette gjentas til den siste biten som ble sendt, eller "minst signifikante bit", styrer den første eller øverste raden i matrisen.

Til slutt trengte jeg å bestemme hvilke motstander jeg ville bruke for hver av lysdiodene i RGB LED. Selv om du kunne bruke standardformelen som kombinerer spenning fremover og ønsket strøm for å beregne den nødvendige motstanden, fant jeg at å sette hver LEDs strøm til 20 milliampere resulterte i en off-white farge når alle de røde, grønne og blå lysdiodene var på. Så jeg begynte å se det. For mye rødt i det hvite betydde å øke den røde LED -motstanden ohm for å redusere strømmen. Jeg gjentatte ganger byttet ut motstander med forskjellige ohm til jeg fant en kombinasjon som ga en hvit farge som jeg følte var riktig. Den siste kombinasjonen var 180 Ω for den røde lysdioden, 220 Ω for den grønne lysdioden og 100 Ω for den blå lysdioden.

Trinn 2: Konstruksjon av maskinvare - brødbrett

Jernvare konstruksjon - brødbrett
Jernvare konstruksjon - brødbrett
Jernvare konstruksjon - brødbrett
Jernvare konstruksjon - brødbrett

Den første fasen av maskinvarekonstruksjonen var brødbrettet. Her laget jeg en 4x4 -matrise med RGB -lysdiodene. Denne matrisen krever 16 biter for å kontrollere, 12 for RGB -kolonnene og 4 for hver rad. To 74HC595 skiftregistre kan håndtere alt. Jeg undersøkte og designet først en krets jeg trodde ville fungere, og bygde den deretter på brødbrettet.

Sannsynligvis den største utfordringen med brødbrettbyggingen var å administrere alle ledningene. Jeg hentet et forhåndsformet trådsett for brødbrett, men da var det litt tungvint. Et triks som jeg syntes var nyttig, var å lage en "port" for tilkobling til Arduino -kortet. Det vil si at i stedet for å koble pinnene på Arduino direkte til de forskjellige IC -pinnene på brødbrettet, dedikere noen få rader på brødbrettet til å være tilkoblingspunktet for Arduino, og deretter koble de relevante ID -pinnene til disse radene. For dette prosjektet trenger du bare fem tilkoblinger til Arduino: +5V, bakken, data, klokke og lås.

Når brødbrettet var ferdig, måtte jeg teste det. Uten en slags driver for å sende de riktige signalene til skiftregistrene, klarte jeg imidlertid ikke å teste om maskinvarelayoutet fungerte.

Trinn 3: Design av driverprogramvare

Image
Image

Gitt min egen karriereerfaring med programvareutvikling, var dette den delen av prosjektet som jeg sannsynligvis var mest tydelig på om jeg skulle gå. Jeg undersøkte mange av de andre Arduino-baserte LED-matrisedriverne. Selv om det sikkert er gode drivere tilgjengelig, hadde ingen helt det designet jeg ønsket. Mine designmål for sjåføren var:

  • Tilby et API på høyt nivå for å kunne programmere bilder og animasjoner. De fleste driverne jeg så var mer fokusert på hardkodede bilder. Siden jeg også er en C ++ programmerer av fag, ønsket jeg å bruke god objektorientert design for å implementere og administrere aktiviteter for å tegne til LED -matrisen.
  • Bruk en dobbeltbuffert tilnærming til å administrere bildet på skjermen. Den ene bufferen er det som blir programmatisk trukket inn, mens den andre representerer tilstanden til matrisepikslene til enhver tid. Fordelen med denne tilnærmingen er at du ikke trenger å gjengi den neste bildeoppdateringen for skjermen helt mellom oppdateringssyklusene til multipleksingen.
  • Bruk PWM for å tillate mer enn de syv primitive fargene en RGB kan gjengi gjennom enkle kombinasjoner av de røde, grønne og blå elementene.
  • Skriv driveren slik at den "bare fungerer" med forskjellige størrelser RGB LED -matriser som fulgte min generelle tilnærming til matrisedesign. Vær oppmerksom på at mens maskinvaredesignet mitt bruker 74HC595 skiftregistre, forventer jeg at sjåføren min jobber med en hvilken som helst av/på -mekanisme for skiftregister som er lagt ut ved hjelp av et lignende bitoppsett som maskinvaredesignet mitt. For eksempel forventer jeg at sjåføren min jobber med en maskinvaredesign som brukte DM13A -brikker for å kontrollere kolonnene og en 74HC595 -brikke for å kontrollere radene.

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

Den første iterasjonen av sjåføren min var litt av en læringskurve om mulighetene til Arduino -plattformen. Den mest åpenbare begrensningen er RAM, som er 2K byte for Arduino Uno og Nano. Å bruke C ++ - objekter i et slikt scenario er ofte ikke anbefalt på grunn av minnekostnadene til objekter. Imidlertid følte jeg at hvis det er gjort riktig, oppveier fordelen med objekter i C ++ kostnadene (i RAM).

Den andre store utfordringen var å finne ut hvordan vi skulle implementere pulsbreddemodulasjonen via skiftregistrene, slik at jeg kunne generere mer enn de syv primitive fargene til RGB LED. Etter å ha programmert i mange år på Linux -plattformer, var jeg vant til å bruke konstruksjoner som tråder for å administrere prosesser som krever konsekvent timing. Tidspunktet for skiftregisteroppdateringsoperasjonen ender opp med å være ganske kritisk når du lager en driver for en LED -matrise som bruker multipleksing. Årsaken er at selv om multipleksingen skjer så raskt at øynene dine ikke kan se de enkelte lysdiodene blinke av og på, kan dine øyne fange opp forskjeller i den totale samlede tiden som noen av lysdiodene er på. Hvis en rad med lysdioder er konstant på i en lengre periode enn de andre, vil det se lysere ut under multipleksingen. Dette kan føre til ujevn lysstyrke i matrisen eller periodisk strobing av matrisen som helhet (dette skjer når en oppdateringssyklus tar lengre tid enn de andre).

Siden jeg trengte en konsekvent timemekanisme for å få skiftregisteroppdateringene til å være samtykke, men Arduino formelt ikke støtter tråd, måtte jeg lage min egen trådlignende mekanisme. Min første iterasjon av dette var ganske enkelt å lage en loop -timer som var avhengig av Arduino loop () -funksjonen og ville utløse en handling når en viss tid har gått siden forrige gang handlingen ble avfyrt. Dette er en form for "kooperativ multitasking". Høres bra ut, men i praksis viste dette seg å være inkonsekvent da avfyringshastigheten ble målt i mikrosekunder. Grunnen til dette er at hvis jeg hadde to av disse sløyfetimerne i gang, tok en av handlingene deres ofte lang nok tid til å få den andre handlingen til å skyte senere enn ønsket.

Jeg fant ut at løsningen på dette problemet er å bruke Arduinos opprinnelige klokkeavbruddsmekanisme. Denne mekanismen lar deg kjøre en liten bit kode med veldig konsekvente intervaller. Så jeg designet driverkoden rundt designelementet for å bruke en klokkeavbrudd for å utløse koden for å sende matrisens skiftregistre den neste oppdateringen i multiplex -syklusen. For å gjøre dette og la oppdateringer forekomme på skjermbildet for ikke å forstyrre en aktiv dump til skiftregistrene (noe vi vil kalle en "løpstilstand"), brukte jeg en tilnærming til å ha doble buffere for skiftregisterbitene, en for skriving og en for lesing. Når brukeren oppdaterer matrisebildet, skjer disse operasjonene i skrivebufferen. Når disse operasjonene er fullført, blir avbrudd midlertidig suspendert (dette betyr at klokkeforstyrrelsen ikke kan utløses) og skrivebufferen byttes ut med den forrige lesebufferen, og det er ikke den nye lesebufferen, så blir tolkene aktivert på nytt. Så når klokken avbryter, og indikerer at det er på tide å sende den neste bitkonfigurasjonen til skiftregistrene, leses denne informasjonen fra den nåværende lesebufferen. På denne måten oppstår det aldri noe skriving til en buffer som for øyeblikket kan leses fra under et klokkeavbrudd, noe som kan ødelegge informasjonen som sendes til skiftregistrene.

Å designe resten av driveren var et relativt enkelt tilfelle av objektorientert design. For eksempel opprettet jeg et objekt for å administrere skiftregisterbitbildet for en gitt skjermtilstand. Ved å kapsle inn koden for bit image management, var opprettelsen av den nevnte tvillingbuffer -tilnærmingen i seg selv en enkel øvelse. Men jeg skrev ikke denne Instructable for å prise dyder av objektorientert design. Andre designelementer inkluderer konseptet med en Glyph og et RGB -bilde. En Glyph er en grunnleggende bildekonstruksjon som ikke har medfødt fargeinformasjon. Du kan tenke på det som et svart -hvitt bilde. Når Glyph trekkes til LED -skjermen, gis fargeinformasjon for å indikere hvordan de "hvite" pikslene skal farges. Et RGB -bilde er et bilde der hver piksel har sin egen fargeinformasjon.

Jeg oppfordrer deg til å gå gjennom Arduino -skisseeksemplene og se på dokumentasjonsoversikten for driveren for å bli kjent med hvordan du bruker driveren til å lage bilder og animasjoner på en RGB LED -matrise.

Trinn 4: LED Ghosting

LED Ghosting
LED Ghosting
LED Ghosting
LED Ghosting

I en LED -matrise er "ghosting" fenomenet med en LED i matrisen som lyser når den ikke er ønsket, vanligvis et veldig redusert nivå. Min originale maskinvaredesign var utsatt for spøkelser, særlig i den siste raden. Årsaken til dette skyldes to ting: transistorer slås ikke av umiddelbart og parasittisk kapasitans i RGB -lysdiodene.

Når vi skanner gjennom radene, på grunn av det faktum at transistorer ikke slår seg av umiddelbart, blir den forrige raden i skanningssyklusen fortsatt delvis drevet når den neste raden slås på. Hvis en gitt kolonne som var slått av i forrige rad, slås på igjen når den nye raden får strøm, lyser LED -en i den kolonnen i forrige rad en liten stund mens den forrige radens koblingstransistor fortsatt er i ferd med å dreie av. Det som får transistoren til å ta merkbar tid å slå av, er metning i basen av transistoren. Dette får transistorens kollektor-emitterbane til å fortsette å lede når strøm fjernes fra basen, i det minste til metningen forsvinner. Gitt at vår oppdateringssyklus for multipleksing får rader til å være bevisst på i en periode målt i mikrosekunder, kan tiden som den forrige radens mettede transistor forblir ledende være en merkbar brøkdel av det. Som et resultat kan øyet ditt oppfatte den svært lille tiden som LED -lampen på forrige rad er slått på.

For å fikse transistormetningsproblemet kan en Schottky -diode legges til transistoren mellom basen og kollektoren for å forårsake litt tilbakestrøm til basen når transistoren er på, noe som forhindrer at transistoren blir mettet. Dette vil igjen føre til at transistoren slås av raskere når strømmen fjernes fra basen. Se denne artikkelen for en grundig forklaring av denne effekten. Som du kan se fra bildet i denne delen, er spøkelsen ganske tydelig uten dioden, men å legge dioden til kretsen for hver rad fjerner spøkelsen betydelig.

RGB -lysdioder er utsatt for et annet fenomen som kalles parasittisk kapasitans. Hovedårsaken til dette er det faktum at hver av de tre fargede lysdiodene i RGB LED -enheten hver har forskjellige spenninger fremover. Denne forskjellen i fremspenninger kan forårsake effekten av elektrisk kapasitans mellom hver av de enkelte LED -fargene. Siden en elektrisk ladning er bygd opp i LED -enheten når den drives, når strømmen er fjernet, må parasittkapasitansen utlades. Hvis den LED -kolonnen ellers er på for en annen rad strøm, vil parasittladningen tømmes gjennom den kolonnen LED og få den til å lyse kort. Denne effekten forklares pent i denne artikkelen. Løsningen er å legge til en utladningsbane for denne parasittiske ladningen annet enn gjennom selve LED -en, og deretter gi LED -en tid til å tømmes før kolonnen slås på igjen. I min maskinvaredesign oppnås dette ved å legge til en motstand på hver rad kraftledning som kobler styrke til bakken. Dette vil føre til at mer strøm trekkes når raden er drevet, men gir en utladningsbane for parasittkapasitansen når raden ikke er drevet.

Det er imidlertid verdt å merke seg at i praksis synes jeg effekten av parasittisk kapasitans er knapt merkbar (hvis du ser etter den, kan du finne den), og derfor anser jeg å legge til denne ekstra motstanden som valgfri. Effekten av sakte tiden for mettede transistorer er mye sterkere og merkbar. Likevel, hvis du inspiserer de tre bildene i denne delen, kan du se at motstandene fjerner alle spøkelser som fremdeles oppstår utover den for den langsomme transistoren.

Trinn 5: Sluttproduksjon og neste trinn

Image
Image

Den siste fasen av dette prosjektet var for meg å lage et kretskort (PCB). Jeg brukte open source -programmet Fritzing til å designe PCB. Selv om det var mange gjentagende oppgaver å utføre for å sette opp 100 lysdioder på et 10x10 bord, fant jeg faktisk denne fasen av prosjektet merkelig tilfredsstillende. Å finne ut hvordan hver elektriske vei ville bli lagt ut var som et puslespill, og å løse det puslespillet skapte en følelse av prestasjon. Siden jeg ikke er klar til å produsere kretskortene, brukte jeg en av de mange online -ressursene som gjør små oppgaver med tilpasset PCB. Lodding av delene var ganske rett frem siden designet mitt brukte alle gjennomgående hull.

Når jeg skriver denne instruksjonsboken, har jeg følgende planer for mine RGB LED Matrix -prosjekter:

  1. Fortsett å forbedre driveren på API-laget for å muliggjøre mer funksjonalitet på høyt nivå til programmereren, særlig tekstrulling.
  2. Lag større matrisedesigner, for eksempel 16x16 eller til og med 16x32.
  3. Utforsk bruk av MOSFET -er i stedet for BJT -er for radbytte
  4. Utforsk bruk av DM13As konstantstrømdrivere i stedet for 74HC595s for kolonnebytte
  5. Lag drivere for andre mikrokontrollplattformer, for eksempel Teensy, ODROID C2 eller Raspberry Pi.

Vær oppmerksom på at både maskinvaredesignet og driveren er utgitt under GPL v3 åpen kildekode -lisens på dette GitHub -depotet. Videre, siden selv om kretskortet produserer "små kjøringer" av PCB -designet mitt, får jeg fortsatt langt mer enn jeg personlig trenger. Så jeg selger fulle sett for mine forskjellige RGB LED -matrisedesign (PCB og alle deler inkludert) fra nettstedet mitt her.

Anbefalt: