Bitars banka steg för steg: Arduino kontroll av WS2811, WS2812 och WS2812B RGB lysdioder (5 / 5 steg)

Steg 5: Bitbanging en puls våg på en ATMega328p mikrokontroller




En av fördelarna med att använda en mikrokontroller i motsats till, säg en dator CPU, är att vi har en väldigt tight kontroll om tidpunkten för instruktionerna vi program in i den. I själva verket för att visa hur exakt denna kontroll kan vara, kommer vi att använda monteringsanvisningar istället för den typiska hög nivå funktionen såsom digitalWrite. Användning av församlingen tillåter oss att veta exakt hur många klockcykler tas upp under utförandet av varje instruktion.

Eftersom Arduino Uno R3 utveckling Styrelsen upprätthåller en 16MHz externa klocksignalen på den inbyggda ATMega328p, utför mikrokontroller en 1 klockcykel instruktion i exakt 62.5ns (1/16 MHz = 62.5ns). Eftersom vi kan ta reda på hur många klockcykler varje anvisning äger, kan vi kontrollera exakt hur många instruktioner måste vi skapa vår signal.

Som vi såg tidigare, för att överföra en 1 till WS281X chip måste vi sända en signal om att stannar på en (hög) maxvärdet för 0.8μs, och sedan stannar vid ett minimivärde (låg) för 0.45μs. Därför vill vi skriva en lista med instruktioner som:

-Ställ in digital stift till hög
-Vänta 0.8μs
-Anger digital pin till låg
-Väntar 0.45μs

I assembler, kan detta uppnås genom följande kod:

ASM flyktiga)
Instruktion klockan Beskrivning PhaseLite överförs
"sbi %0, %1\n\t" / / 2 PIN-hög (T = 2)
"rjmp. + 0\n\t" / / 2 nop nop (T = 4)
"rjmp. + 0\n\t" / / 2 nop nop (T = 6)
"rjmp. + 0\n\t" / / 2 nop nop (T = 8)
"rjmp. + 0\n\t" / / 2 nop nop (T = 10)
"rjmp. + 0\n\t" / / 2 nop nop (T = 12)
"nop\n\t" / / 1 nop (T = 13)
"cbi %0, %1\n\t" / / 2 PIN låg (T = 15)
"rjmp. + 0\n\t" / / 2 nop nop (T = 17)
"rjmp. + 0\n\t" / / 2 nop nop (T = 19)
"nop\n\t" / / 1 nop (T = 20) 1
::
Ingående operander
"I" (_SFR_IO_ADDR(PORT)), //%0
"I" (PORT_PIN) //%1
);

Instruktion
Den första kolumnen innehåller instruktionen församlingen följt av en radmatning och fliken tecken, som gör den slutliga assembler notering genererade av kompilatorn mer läsbar.

Klockan
Den andra kolumnen visar antalet klockcykler varje anvisning äger. För denna uppsättning enkla instruktioner finns endast ett möjligt värde, vi får se senare hur några instruktioner (t.ex. villkorlig) kan ha 1, 2 eller 3 möjliga värden. Kom ihåg att varje klockcykel på 16 MHz Arduino Uno tar 62.5ns.

Beskrivning
Den tredje kolumnen visar en mycket kort beskrivning av vad varje operation gör.

Fas
Använda termen lite löst, använder vi den som anger den kumulativa summan av klockcykler instruktionerna som utförts hittills har vidtagit.

För att skicka ett enda 255 värde — 11111111 i binär — till den WS281X vi måste upprepa denna uppsättning instruktioner 8 gånger. Dessutom, om vi sätter in en 50μs (eller större) paus mellan överföringar av 8-bitars sekvensen, WS281X spärrarna överförda data till dess utgång register. När data är låst, aktiverar den första lysdioden (grön) av WS281X till en maximal ljusstyrkenivå. Arduino skiss inuti bitbang_255.zip visar denna operation.

För att skicka en 0 måste vi ändra den kod som producerar en 1 genom att minska den tid under vilken signalen har en hög (maximum) värde och öka den tid under vilken signalen är låg (minimum). Dessutom bör vi notera att värdena till varje LED alltid bör anges med 8 bitar. Till exempel, om vi ville skicka ett värde av 105 — 1101001 i binär-skulle vi behöva skicka de 8 bitarna 01101001 inklusive den ledande 0. Den kod som producerar en 0 ser ut:

ASM flyktiga)
Instruktion klockan Beskrivning PhaseLite överförs
"sbi %0, %1\n\t" / / 2 PIN-hög (T = 2)
"rjmp. + 0\n\t" / / 2 nop nop (T = 4)
"rjmp. + 0\n\t" / / 2 nop nop (T = 6)
"cbi %0, %1\n\t" / / 2 PIN låg (T = 8)
"rjmp. + 0\n\t" / / 2 nop nop (T = 10)
"rjmp. + 0\n\t" / / 2 nop nop (T = 12)
"rjmp. + 0\n\t" / / 2 nop nop (T = 14)
"rjmp. + 0\n\t" / / 2 nop nop (T = 16)
"rjmp. + 0\n\t" / / 2 nop nop (T = 18)
"rjmp. + 0\n\t" / / 2 nop nop (T = 20) 0
::
Ingående operander
"I" (_SFR_IO_ADDR(PORT)), //%0
"I" (PORT_PIN) //%1
);

Vi kan använda Arduino skiss inuti bitbang_105.zip för att generera signalen vars bild kan ses på skärmdumpen oscilloskop som är kopplade till detta steg.

Nu, för WS281X ska ha vitaktig färg vi vill ha, måste vi skicka inte en utan tre 255 värden – i vilket fall vår signal består av 24 — innan väntar på 50μs uppgifter till spärren. Vi kunde göra detta genom att kopiera-klistra elva monteringsanvisningarna ovan 23 gånger (du kan ge det ett försök ändra bitbang_255.ino skissen). Men koden skulle vara opraktiskt för att skicka värden till mer än en WS281X marker. En bättre lösning vore att skriva en loop som skulle gå igenom 8-bitars värden tills alla tre av dem har skickats.

Skissen inuti bitbang_whitish.zip innehåller en tydlig beskrivning av de åtgärder som vidtas för att uppnå det önskade resultatet. Huvudavsnittet, skrivna i församlingen logik ovan, ser ut som följer:

ASM flyktiga)
Instruktion klockan Beskrivning fas
"nextbit:\n\t" / / - etikett (T = 0)
"sbi %0, %1\n\t" / / 2 signal hög (T = 2)
"sbrc %4, 7\n\t" / / 1-2 om MSB (T =?)
"mov %6, %3\n\t" / / 0-1 tmp ska ställa signal hög (T = 4)
"dec %5\n\t" / / 1 minskning bitcount (T = 5)
"nop\n\t" / / 1 nop (tomgång 1 klockcykel) (T = 6)
"st % a2, %6\n\t" / / 2 set PORT till tmp (T = 8)
"mov %6, %7\n\t" / / 1 reset tmp för att låg (standard) (T = 9)
"breq nextbyte\n\t" / / 1-2 if bitcount == 0 -> nextbyte (T =?)
"rol %4\n\t" / / 1 skifta MSB Vänsterriktad (T = 11)
"rjmp. + 0\n\t" / / 2 nop nop (T = 13)
"cbi %0, %1\n\t" / / 2 signal låg (T = 15)
"rjmp. + 0\n\t" / / 2 nop nop (T = 17)
"nop\n\t" / / 1 nop (T = 18)
"rjmp nextbit\n\t" / / 2 bitcount! = 0 -> nextbit (T = 20)
"nextbyte:\n\t" / / - etikett -
"ldi %5, 8\n\t" / / 1 reset bitcount (T = 11)
"ld %4, %a8+\n\t" / / 2 val = * p ++ (T = 13)
"cbi %0, %1\n\t" / / 2 signal låg (T = 15)
"rjmp. + 0\n\t" / / 2 nop nop (T = 17)
"nop\n\t" / / 1 nop (T = 18)
"dec %9\n\t" / / 1 minskning bytecount (T = 19)
"brne nextbit\n\t" / / 2 om bytecount! = 0 -> nextbit (T = 20)
::
);

Det bästa sättet att förstå av detta avsnitt är att överväga olika fall scenarier och följ församlingen koden rad för rad. Vi vet till exempel att skicka ett värde 255, måste vi skicka 8 bitar med en timing som motsvarar en 1. Med andra ord, den Digital Pin ansluten till WS281X bör förbli hög för 13 cykler (0.8125μs) och låg för 7 (0.4375μs). Koden ovan att uppnå detta? Låt oss se vad som händer när vi börjar överföra:

ASM flyktiga)
"nextbit:\n\t" / / Detta är bara en etikett för att styra hoppen nedan.
"sbi %0, %1\n\t" / / signalen är inställd på hög, instruktion använder 2 cykler.
"sbrc %4, 7\n\t" / / sant. Skicka 255 innebär nuvarande MSB är 'set' (= 1).
"mov %6, %3\n\t" / / Detta är utförat. "tmp" är satt till hög.
"dec %5\n\t" / / Bit överförs, minska bitars räknare.
"nop\n\t" / / behöver på tomgång för att komma till de 13 klockcykler.
"st % a2, %6\n\t" / / skriva "tmp" värdet till hamnen (pin fortfarande hög).
"mov %6, %7\n\t" / / Set "tmp" Low för nästa passera genom öglan.
"breq nextbyte\n\t" / / falskt. Bitars räknare är inte 0, använda 1 cykel och fortsätta.
"rol %4\n\t" / / skifta bytevärdet MSB Vänsterriktad.
"rjmp. + 0\n\t" / / Idle för 2 klockcykler. Etappen nådde T = 13.
"cbi %0, %1\n\t" / / Ställ in signal till låg.
"rjmp. + 0\n\t" / / Idle för 2 klockcykler.
"nop\n\t" / / Idle för 1 klockcykel.
"rjmp nextbit\n\t" / / bitars räknare var inte 0 så hoppa till nästa bit. T = 20.
);

Så instruktionerna som faktiskt få utförat generera en signal på data stift som är 13 cykler hög (0.8125μs) och 7 LOW (0.4375μs), således skicka lite med värdet 1 till WS281X. Om vi fortsätter att studera vad koden gör när resten av bitarna skickas, och vad den gör när värden än 255 används, vi ska få en djupare förståelse av denna särskilt genomförandet av bitbanging.

Personligen hoppas jag att du hittar denna tutorial användbart för att komma igång med bitbanging egna meddelande protokoll närhelst det är nödvändigt!

Se Steg
Relaterade Ämnen

Super enkel 10-steg arduino sequencer

Denna sequencer är så enkelt jag behöver bara ett steg visar hur! Just nu är det är en 10 steg sequencer men kan lätt bli mer rättvis genom att ändra variabeln "steg" i koden.https://Instagram.com/p/2_uf05wwEc/Allt du behöver för detta projekt ä...

Smart WIFI Video bil (Arduino kontroll)

Alla av oss har en utforskning önskan på okänd ort. När jag och min partner tittar på filmen "The Martian" och se att det finns en robotbil i Mars - - en planet som är femtio - sex miljoner kilometer från vår jord. "Han" arbetar på Mar...

Seriella Servo Controller w/Arduino - kontroll upp till 12 servon samtidigt med Arduino och en USB-anslutning

jag kommer att visa dig hur du använder din Arduino för att styra upp till 12 servon på en gång med minimal jitter. Med ett enkelt seriellt gränssnitt kan du kontrollera positionen för upp till 12 servo kanaler. Upp till 10 ögonblicksbild positioner...

Hemgjord Lizylotte robotarm DIY Robotic ram projekt chassi Draw Arduino kontroll

Hemgjord Lizylotte robotarm DIY Robotic ram projekt chassi Draw Arduino kontrollMaterial:1 st aluminiumlegering 245 mm x 42 mm x 12 mm1 st aluminiumlegering 200 mm x 22 x 12 mm1 st aluminiumlegering 100 mm x 160 x 12 mm för säng1 st steg motor 42 x 4...

Hacking en Keychain digitalkamera för Arduino kontroll

fotografering alternativ för Arduino är få och långt mellan. Webbkameror är praktiska för applikationer som kite fotografering eller offentliga fotografering, om du känner för att köpa en 200 fot USB-kabel. Och aktuella tekniker för fristående Arduin...

Arduino - kontroll lysdioder med en fjärrkontroll

Hi guys,Jag delar med dig ett projekt jag gjort nyligen. I'ts om hur du kan kontrollera vissa lysdioder med en fjärrkontroll och din Arduino. Men du kan tillämpa detta på alla elektroniska enheter såsom motorer, ljus t.ex.Du kan besöka min hemsida fö...

Nybörjare 123D krets Arduino kontroll servon

Detta är en kort instruktion om använder 123D kretsar för att ställa in en Arduino med några potentiometrar och som styr placeringen av servon.Steg 1: inställningarSkapa ett konto på 123d.circuits.io/Liksom de flesta hemsida nu är det enkelt att länk...

Hemgjord Lizylotte Robot Arm Robotic Draw med Arduino kontroll

Hemgjord Lizylotte robotarm Robotic Rita Arduino kontroll DIY Laser gravyr Frame 3D-skrivare PlotterMaterial:1 st 57 mm Stepper motor 1,8 grader ta från gamla kopieringsapparat1 st 42 mm Stepper motor 1,8 grader ta från gamla kopieringsapparat2 st FL...

Arduino Mega 8 x 8 x 8 RGB LED Cube

"Så du vill bygga en 8 x 8 x 8 RGB LED Cube"Jag har spelat runt med elektronik och Arduinos ett tag nu, inklusive bygga en hög amp switch controller för min bil och en sex körfält Pinewood Derby domare för våra scouter grupp.Jag var så fascinera...

Kontroll RGB lysdioder med en handrörelse.

IntroduktionVi var välkomna att hjälpa till vid våra lokala grundskolan STEM natt och behövde en cool demonstration, med lite tid att förbereda.Så, vi tittade igenom tech vi hade liggandes, och kom upp med idén att använda den LeapMotion handen track...

CPU-fläkten hacka - RGB lysdioder - Arduino & TLC5940

I detta Instructable, jag kommer att vägleda dig genom processen att hacka och konvertera en tydlig, 120 mm PWM fläkt används gemensamt hushåll datorer från en enda färg LED till individuellt adresserbara RGB lysdioder. Tillämpningar av detta hack är...

Chalieplexing 4 RGB-lysdioder med 4 trådar på Arduino

Har du alla behov många lysdioder, men bara några sladdar? Då är Charlieplexing en stor sak att prova. Med bara 4 trådar kan du köra 12 ledde med endast 4 motstånd som ett extra skydd och utan någon "informationsövertag" komponent som en 74595 e...

Färg kalibrera RGB lysdioder med en Arduino

De flesta människor tror lysdioder och Arduinos relationerna avslutas med ett ögonblick skiss. Därefter måste du gå mot motorer, smarta hem och andra "allvarliga" saker. Tja, kanske jag är långsam eller kanske är det bara att jag är en grafisk k...

Låg höjd miljöövervakning med en Arduino baserade väder Instrument och Aeropod Remote Sensing plattform

ProjektöversiktStudenter på New Lothrop High School i Michigan har arbetat tillsammans för att bygga en plattform för remote sensing låg höjd som kallas en "Aeropod" och rummen har det med ett "Arduino" baserade väder instrument att sa...

Arduino Mega GPS med LCD och SD loggning

Använd din Audino Mega som en GPS logger med tydlig LCD display och 5 funktionsknappar. En bi-färg LED används för att ange statusinformation.SDcard kan vara kvar i och läsa med en kort läsaren skiss, med utgång till den seriella Monitor.Detta instru...

Arduino solar storma controller + effektreglering och data loggning online med Xbee WiFi

För ett tag sedan jag började arbeta på en sol laddningsregulatorn, det var baserat på en PIC mikrokontroller, en 20 x 4 tecken display och koden är skriven i assembler. Det fungerade bra och arbetade fortfarande när jag bestämde mig att lägga mer ti...

Polisens blixtljus med scanner rgb lysdioder och Arduino

Det är inte en riktig blixt mönster som används av polisen.Bara några öglor programmeras av mig att demonstrera några möjligheter.DISCLAIMER:JAG ÄR INTE ANSVARIGA FÖR ÅTGÄRDER ELLER KONSEKVENSER NÄR DET GÄLLER DENNA TUTORIAL.Använd det endast inomhus...

Skicka SMS från Arduino över Internet med ENC28J60 och Thingspeak

Detta Instructable förklarar hur du skickar ett SMS från en Arduino använder Internet. Det finns många sätt att närma sig detta och jag kommer att förklara ett av de olika metoder som används för att utföra denna uppgift.Några viktiga punkter som beh...

Ambilight för icke påverkbar RGB lysdioder [använder Arduino]

Först av allt.. Om du inte vet vad Ambilgiht är Check Ambilgiht PhillipsKolla in min andra tutorial om du inte har en arduino TUTeftersom det är samma rgb ledde och samma 3 transistorer som jag använt tidigare varför lägger arduino att fungera?Svaret...