![]() |
Forum Index : Microcontroller and PC projects : MM2: Neopixel, WS2812, RGB LED code
Author | Message | ||||
matherp Guru ![]() Joined: 11/12/2012 Location: United KingdomPosts: 10205 |
I received one of these in the post today: So I was able to properly test the code for sending out the pulse sequences and convert it into G8JCF-approved library format (I hope ![]() I was going to upload a video to YouTube but my camera found it completely impossible to video the display so a static picture must suffice. The attached code contains a simple example that fades in and out the colours and rotates them around the ring - I wish I had some artistic flair but that will have to do as an example! The code should be able to handle any number of WS2812 LEDs in the string - power supply and cost will be the limiting factors. The Cfunction code is included as comments. Remember to get rid of BB created spaces before running - I think they are only in the P40$ and P28$ strings. The WS2812.init routine sets the CPU speed to 48, the Cfunction will only operate correctly at this speed. Enjoy OPTION DEFAULT NONE OPTION EXPLICIT ' ' Function and subroutine calls ' ' WS2812.pulses: number of LEDs, PIC port numer (0=A..2=C), Pin number within the port, array of colour codes, buffer array used by the CFunction ' sub WS2812.pulses(numleds as integer, portnum as integer, pinnum as integer, colours() as integer, buffer() as integer) ' ' WS2812.getcolour: Get the green, red, and blue components for a specific LED from the colour array ' sub WS2812.getcolour(led as integer, greenness as integer, redness as integer, blueness as integer) ' ' WS2812.setcolour: Load the colour array for a specific LED from the green, red, and blue components ' sub WS2812.setcolour(led as integer, greenness as integer, redness as integer, blueness as integer) ' ' WS2812.INIT: set the pin to use for output to the LEDs and the number of LEDs in the string and sets up the required global variables and CPU speed ' SUB WS2812.INIT(LED_PIN as integer,NUMLEDS as INTEGER) ' ' WS2812.getpin: uses the pin number to get the port number and the pin number on the port by reference to the Device ID; returns true if a valid pin, false otherwise ' function WS2812.getpin(MMpin as integer,portnum as integer,pinnum as integer) as integer WS2812.INIT(16,7) 'set the pin for output and the number of LEDs ' EXAMPLE 'execute the example program ' end '___________________________________________________________ ____________________________________________________________ _______________ ' 'number of LEDs, PIC port numer (0=A..2=C), Pin number within the port, array of colour codes, buffer array used by the CFunction ' CFunction WS2812.Pulses 00000000 8fa30010 24020001 8ccc0000 01826004 8ca60000 14c20003 8ca50004 10a00009 3c0ebf88 24020002 14c20003 3c0ebf88 50a00007 25cd6234 25cd6034 10000005 25ce6038 25cd6134 10000002 25ce6138 25ce6238 34058000 3c02bf80 ac450600 8c820004 1c400005 8c880000 14400025 00000000 11000023 00000000 0060c021 00007821 1000001c 240bffff 30490020 8ce80004 00085040 00022827 00aa5004 8ce50000 00452806 01452825 00484007 0109280b 30a50001 a0c50000 2442ffff 144bfff2 24c60001 25ef0001 8c880000 8c820004 27180018 000f2fc3 00a2302a 14c00005 24e70008 14450006 01e8482b 11200004 00000000 03003021 1000ffe3 24020017 5c400006 3c02bf80 1440000b 3c05bf80 2d08001d 15000008 3c02bf80 8c460c00 3c05ffff 24a57fff 00c52824 ac450c00 10000006 8c820000 8ca20c10 2c420065 1040fffd 00000000 8c820000 000228c0 00021140 00453823 10e00025 00001021 3c05bf80 00623021 90c60000 10c0000f 00000000 adcc0000 aca00610 8ca60610 2cc60019 14c0fffd 00000000 adac0000 aca00610 8ca60610 2cc6000d 14c0fffd 00000000 1000000e 24420001 adcc0000 aca00610 8ca60610 2cc60005 14c0fffd 00000000 adac0000 aca00610 8ca60610 2cc60014 14c0fffd 00000000 24420001 1447ffe1 00623021 10000003 8c830004 00e01021 8c830004 5c600008 3c03bf80 14600009 00000000 8c830000 2c63001d 14600005 00000000 3c03bf80 8c640c00 34848000 ac640c00 adac0000 03e00008 00001821 End CFunction ' 'long long WS2812.Pulses(long long *numleds, long long *portname,long long *mypin,long long parray[], unsigned char sarray[]){ ' #define tmr4 *(volatile unsigned int *)0xbf800C10 //timer 1 configuration register ' #define tmr4con *(volatile unsigned int *)0xbf800C00 //timer 1 configuration register ' #define tmr1con *(volatile unsigned int *)0xbf800600 //timer 1 configuration register ' #define tmr1 *(volatile unsigned int *)0xbf800610 //timer 1 counter ' unsigned int index,pin=1<<*mypin; ' int k,bpos; ' unsigned int volatile * mysetport; ' unsigned int volatile * myclearport; ' if(*portname==0) { ' mysetport=(volatile unsigned int *)0xbf886038; ' myclearport=(volatile unsigned int *)0xbf886034; ' } ' if(*portname==1) { ' mysetport=(volatile unsigned int *)0xbf886138; ' myclearport=(volatile unsigned int *)0xbf886134; ' } ' if(*portname==2) { ' mysetport=(volatile unsigned int *)0xbf886238; ' myclearport=(volatile unsigned int *)0xbf886234; ' } ' tmr1con=0x8000; //turn on timer at full speed ' index=0; ' for(k=0;k<*numleds;k++){ //move the data into a single dimensional array that we can step though in even time ' for(bpos=23;bpos>=0;bpos--){ ' sarray[index]=(parray[k]>>bpos) & 1; ' index++; ' } ' } ' if(*numleds > 28) { //Decide how to avoid RTC interrupts ' tmr4con &= 0xFFFF7FFF; //turn off the real time clock if it is going to interfere ' } else { ' while(tmr4>100); //synchronise with the RTC to avoid interrupts ' } ' k=*numleds * 24;; //get the number of bytes to output ' for (index=0;index<k;index++){ //step through the input data ' // Note the timer settings are not obvious as the execution of the loop elongates the low pulses ' if (sarray[index]){ ' *mysetport=pin; ' tmr1=0; ' while(tmr1<25); //Tuned for the 700ns pulse ' *myclearport=pin; ' tmr1=0; ' while(tmr1<13); //Tuned for the 600ns pulse ' } else { ' *mysetport=pin; ' tmr1=0; ' while(tmr1<5); //Tuned for the 350ns pulse ' *myclearport=pin; ' tmr1=0; ' while(tmr1<20); //Tuned for the 800ns pulse ' } ' } ' if(*numleds > 28) tmr4con |= 0x0008000; //turn the clock back on ' *myclearport=pin; //Set the output low to create the reset pulse which loads the data ' return index; '} ' ' Load the colour array for a specific LED from the green, red, and blue components ' sub WS2812.setcolour(led as integer, greenness as integer, redness as integer, blueness as integer) colours(led)= ((greenness and &HFF)<<16) + ((redness and &HFF)<<8) + (blueness and &HFF) end sub ' ' Get the green, red, and blue components for a specific LED from the colour array ' sub WS2812.getcolour(led as integer, greenness as integer, redness as integer, blueness as integer) greenness=colours(led)>>16 redness=(colours(led)>>8) and &HFF blueness= colours(led) and &HFF end sub ' ' uses the pin number to get the port number and the pin number on the port by reference to the Device ID ' function WS2812.getpin(MMpin as integer,portnum as integer,pinnum as integer) as integer const P28$="N/AA00A01B00B01B02B03N/AA02A03B04A04N/AB05B06B07B08B09 N/AN/AB10B11B12B13B14B15N/AN/A" const P40$="B09C06C07C08C09N/AN/AB10B11B12B13A10A07B14B15N/AN/AN/A A00A01B00B01B02B03C00C01C02N/AN/AA02A03A08B04A04A09C03C04C05 N/AN/AB05B06B07B08" local integer i local a$ length 3 i=(MMpin-1)*3 +1 if (peek(word &HBF80F220) and &HFFFFFFF) = &H6610053 then if MMpin>=1 and MMpin<=28 then a$=mid$(p28$,i,3) else a$="N/A" endif else if MMpin>=1 and MMpin<=40 then a$=mid$(p40$,i,3) else a$="N/A" endif endif if a$="N/A" then WS2812.getpin=0 else portnum=asc(left$(a$,1))-65 pinnum=val(right$(a$,2)) WS2812.getpin=1 endif end function ' ' Initialise required global variables depending on the number of LEDs and set up the output pin and CPU speed ' SUB WS2812.INIT(LED_PIN as integer,nLEDs as INTEGER) CPU 48 'This speed is fixed for the Cfunction to work ' Global variables DIM INTEGER NUMLEDS=nLEDS DIM integer buffer(NUMLEDS*3-1) dim INTEGER colours(NUMLEDS) dim integer portnum,pinnum setpin LED_PIN,dout LOCAL INTEGER i=WS2812.getpin(LED_PIN,portnum,pinnum) end sub ' sub EXAMPLE local integer i,j,green,red,blue,maxbright=40 WS2812.setcolour(0,maxbright,maxbright,maxbright) 'white WS2812.setcolour(1, maxbright,0,0) 'green WS2812.setcolour(2,maxbright,maxbright,0) 'yellow WS2812.setcolour(3,0,maxbright,0) 'red WS2812.setcolour(4,0,maxbright,maxbright) 'magenta WS2812.setcolour(5,0,0,maxbright) 'blue WS2812.setcolour(6,maxbright,0,maxbright) 'cyan Do for j=1 to maxbright-1 i=WS2812.pulses(NUMLEDS,portnum,pinnum,colours(),buffer()) for i=0 to 6 WS2812.getcolour(i,green,red,blue) if green<>0 then green=green-1 if red<>0 then red=red-1 if blue<>0 then blue=blue-1 WS2812.setcolour(i,green,red,blue) next i pause 10 next j rotate for j=1 to maxbright-1 i=WS2812.pulses(NUMLEDS,portnum,pinnum,colours(),buffer()) for i=0 to 6 WS2812.getcolour(i,green,red,blue) if green<>0 then green=green+1 if red<>0 then red=red+1 if blue<>0 then blue=blue+1 WS2812.setcolour(i,green,red,blue) next i pause 10 next j loop end sub ' sub rotate 'rotates the colours round the edge of the display leaving white in the middle local integer i,j i=colours(6) for j=5 to 1 step -1 colours(j+1)=colours(j) next j colours(1)=i end sub |
||||
WhiteWizzard Guru ![]() Joined: 05/04/2013 Location: United KingdomPosts: 2932 |
You NEVER cease to amaze . . . . . . (and you're costing me a fortune in opto gadgets) ![]() |
||||
Zonker![]() Guru ![]() Joined: 18/08/2012 Location: United StatesPosts: 767 |
Sweet Pete..!! Just got off work.... Will give a 1 LED setup a tryout... Looks nice Thank you Dr. Awesome.. ![]() EDIT: Yikes... I can't seem to find the part... ![]() |
||||
aargee Senior Member ![]() Joined: 21/08/2008 Location: AustraliaPosts: 255 |
Matherp... thanks for the code and the work you've done with Neopixels and the WS2812. For all those wanting to run the demo program above, be aware that Matherp has written it for his string of seven LEDS. I changed it to successfully run my five LEDs although if I change it to run a 30 LED string, the 'colours' array bombs out. Just ran out of time, I'm off to work for now... Remember to take the spaces out of P28$ and P40$ strings that the Forum sticks in. Option DEFAULT NONE
Option EXPLICIT ' ' Function and subroutine calls ' ' WS2812.pulses: number of LEDs, PIC port numer (0=A..2=C), Pin number within the port, array of colour codes, buffer array used by the CFunction ' sub WS2812.pulses(numleds as integer, portnum as integer, pinnum as integer, colours() as integer, buffer() as integer) ' ' WS2812.getcolour: Get the green, red, and blue components for a specific LED from the colour array ' sub WS2812.getcolour(led as integer, greenness as integer, redness as integer, blueness as integer) ' ' WS2812.setcolour: Load the colour array for a specific LED from the green, red, and blue components ' sub WS2812.setcolour(led as integer, greenness as integer, redness as integer, blueness as integer) ' ' WS2812.INIT: set the pin to use for output to the LEDs and the number of LEDs in the string and sets up the required global variables and CPU speed ' SUB WS2812.INIT(LED_PIN as integer,NUMLEDS as INTEGER) ' ' WS2812.getpin: uses the pin number to get the port number and the pin number on the port by reference to the Device ID; returns true if a valid pin, false otherwise ' function WS2812.getpin(MMpin as integer,portnum as integer,pinnum as integer) s integer Dim As Integer Rob=4 'number of LEDS in Robs setup 0...n, so Rob=4 means 5 LEDs WS2812.INIT(17,5) 'set the pin for output and the number of LEDs ' EXAMPLE 'execute the example program ' End '___________________________________________________________ ____________________________________________________________ _______________ ' 'number of LEDs, PIC port numer (0=A..2=C), Pin number within the port, array of colour codes, buffer array used by the CFunction ' CFunction WS2812.Pulses 00000000 8fa30010 24020001 8ccc0000 01826004 8ca60000 14c20003 8ca50004 10a00009 3c0ebf88 24020002 14c20003 3c0ebf88 50a00007 25cd6234 25cd6034 10000005 25ce6038 25cd6134 10000002 25ce6138 25ce6238 34058000 3c02bf80 ac450600 8c820004 1c400005 8c880000 14400025 00000000 11000023 00000000 0060c021 00007821 1000001c 240bffff 30490020 8ce80004 00085040 00022827 00aa5004 8ce50000 00452806 01452825 00484007 0109280b 30a50001 a0c50000 2442ffff 144bfff2 24c60001 25ef0001 8c880000 8c820004 27180018 000f2fc3 00a2302a 14c00005 24e70008 14450006 01e8482b 11200004 00000000 03003021 1000ffe3 24020017 5c400006 3c02bf80 1440000b 3c05bf80 2d08001d 15000008 3c02bf80 8c460c00 3c05ffff 24a57fff 00c52824 ac450c00 10000006 8c820000 8ca20c10 2c420065 1040fffd 00000000 8c820000 000228c0 00021140 00453823 10e00025 00001021 3c05bf80 00623021 90c60000 10c0000f 00000000 adcc0000 aca00610 8ca60610 2cc60019 14c0fffd 00000000 adac0000 aca00610 8ca60610 2cc6000d 14c0fffd 00000000 1000000e 24420001 adcc0000 aca00610 8ca60610 2cc60005 14c0fffd 00000000 adac0000 aca00610 8ca60610 2cc60014 14c0fffd 00000000 24420001 1447ffe1 00623021 10000003 8c830004 00e01021 8c830004 5c600008 3c03bf80 14600009 00000000 8c830000 2c63001d 14600005 00000000 3c03bf80 8c640c00 34848000 ac640c00 adac0000 03e00008 00001821 End CFunction ' 'long long WS2812.Pulses(long long *numleds, long long *portname,long long *mypin,long long parray[], unsigned char sarray[]){ ' #define tmr4 *(volatile unsigned int *)0xbf800C10 //timer 1 configuration register ' #define tmr4con *(volatile unsigned int *)0xbf800C00 //timer 1 configuration register ' #define tmr1con *(volatile unsigned int *)0xbf800600 //timer 1 configuration register ' #define tmr1 *(volatile unsigned int *)0xbf800610 //timer 1 counter ' unsigned int index,pin=1<<*mypin; ' int k,bpos; ' unsigned int volatile * mysetport; ' unsigned int volatile * myclearport; ' if(*portname==0) { ' mysetport=(volatile unsigned int *)0xbf886038; ' myclearport=(volatile unsigned int *)0xbf886034; ' } ' if(*portname==1) { ' mysetport=(volatile unsigned int *)0xbf886138; ' myclearport=(volatile unsigned int *)0xbf886134; ' } ' if(*portname==2) { ' mysetport=(volatile unsigned int *)0xbf886238; ' myclearport=(volatile unsigned int *)0xbf886234; ' } ' tmr1con=0x8000; //turn on timer at full speed ' index=0; ' for(k=0;k<*numleds;k++){ //move the data into a single dimensional array that we can step though in even time ' for(bpos=23;bpos>=0;bpos--){ ' sarray[index]=(parray[k]>>bpos) & 1; ' index++; ' } ' } ' if(*numleds > 28) { //Decide how to avoid RTC interrupts ' tmr4con &= 0xFFFF7FFF; //turn off the real time clock if it is going to interfere ' } else { ' while(tmr4>100); //synchronise with the RTC to avoid interrupts ' } ' k=*numleds * 24;; //get the number of bytes to output ' for (index=0;index<k;index++){ //step through the input data ' // Note the timer settings are not obvious as the execution of the loop elongates the low pulses ' if (sarray[index]){ ' *mysetport=pin; ' tmr1=0; ' while(tmr1<25); //Tuned for the 700ns pulse ' *myclearport=pin; ' tmr1=0; ' while(tmr1<13); //Tuned for the 600ns pulse ' } else { ' *mysetport=pin; ' tmr1=0; ' while(tmr1<5); //Tuned for the 350ns pulse ' *myclearport=pin; ' tmr1=0; ' while(tmr1<20); //Tuned for the 800ns pulse ' } ' } ' if(*numleds > 28) tmr4con |= 0x0008000; //turn the clock back on ' *myclearport=pin; //Set the output low to create the reset pulse which loads the data ' return index; '} ' ' Load the colour array for a specific LED from the green, red, and blue components ' Sub WS2812.setcolour(led As integer, greenness As integer, redness As integer, blueness As integer) colours(led)= ((greenness And &HFF)<<16) + ((redness And &HFF)<<8) + (blueness And &HFF) End Sub ' ' Get the green, red, and blue components for a specific LED from the colour array ' Sub WS2812.getcolour(led As integer, greenness As integer, redness As integer, blueness As integer) greenness=colours(led)>>16 redness=(colours(led)>>8) And &HFF blueness= colours(led) And &HFF End Sub ' ' uses the pin number to get the port number and the pin number on the port by reference to the Device ID ' Function WS2812.getpin(MMpin As integer,portnum As integer,pinnum As integer) As integer Const P28$="N/AA00A01B00B01B02B03N/AA02A03B04A04N/AB05B06B07B08B09 N/AN/AB10B11B12B13B14B15N/AN/A" Const P40$="B09C06C07C08C09N/AN/AB10B11B12B13A10A07B14B15N/AN/AN/A A00A01B00B01B02B03C00C01C02N/AN/AA02A03A08B04A04A09C03C04C05 N/AN/AB05B06B07B08" Local integer i Local a$ length 3 i=(MMpin-1)*3 +1 If (Peek(word &HBF80F220) And &HFFFFFFF) = &H6610053 Then If MMpin>=1 And MMpin<=28 Then a$=Mid$(p28$,i,3) Else a$="N/A" EndIf Else If MMpin>=1 And MMpin<=40 Then a$=Mid$(p40$,i,3) Else a$="N/A" EndIf EndIf If a$="N/A" Then WS2812.getpin=0 Else portnum=Asc(Left$(a$,1))-65 pinnum=Val(Right$(a$,2)) WS2812.getpin=1 EndIf End Function ' ' Initialise required global variables depending on the number of LEDs and set up the output pin and CPU speed ' Sub WS2812.INIT(LED_PIN As integer,nLEDs As INTEGER) CPU 48 'This speed is fixed for the Cfunction to work ' Global variables Dim INTEGER NUMLEDS=nLEDS Dim integer buffer(NUMLEDS*3-1) Dim INTEGER colours(NUMLEDS) Dim integer portnum,pinnum SetPin LED_PIN,dout Local INTEGER i=WS2812.getpin(LED_PIN,portnum,pinnum) End Sub ' Sub EXAMPLE Local integer i,j,green,red,blue,maxbright=40 WS2812.setcolour(0,maxbright,maxbright,maxbright) 'white WS2812.setcolour(1, maxbright,0,0) 'green WS2812.setcolour(2,maxbright,maxbright,0) 'yellow WS2812.setcolour(3,0,maxbright,0) 'red WS2812.setcolour(4,0,maxbright,maxbright) 'magenta 'WS2812.setcolour(5,0,0,maxbright) 'blue 'WS2812.setcolour(6,maxbright,0,maxbright) 'cyan Do For j=1 To maxbright-1 i=WS2812.pulses(NUMLEDS,portnum,pinnum,colours(),buffer()) For i=0 To Rob WS2812.getcolour(i,green,red,blue) If green<>0 Then green=green-1 If red<>0 Then red=red-1 If blue<>0 Then blue=blue-1 WS2812.setcolour(i,green,red,blue) Next i Pause 10 Next j rotate For j=1 To maxbright-1 i=WS2812.pulses(NUMLEDS,portnum,pinnum,colours(),buffer()) For i=0 To Rob WS2812.getcolour(i,green,red,blue) If green<>0 Then green=green+1 If red<>0 Then red=red+1 If blue<>0 Then blue=blue+1 WS2812.setcolour(i,green,red,blue) Next i Pause 10 Next j Loop End Sub ' Sub rotate 'rotates the colours round the edge of the display leaving white in the middle Local integer i,j i=colours(Rob) For j=Rob-1 To 1 Step -1 colours(j+1)=colours(j) Next j colours(1)=i End Sub For crying out loud, all I wanted to do was flash this blasted LED. |
||||
matherp Guru ![]() Joined: 11/12/2012 Location: United KingdomPosts: 10205 |
aargee Did you get the code working for the 30 LED string? I've checked it on the oscilloscope and it certainly seems to send the correct signals. These is one very strange thing about these devices. With a normal shift register such as the 74HC595, the last bit sent ends up in the first device in the chain so if I have three chained together and I send 3 bytes of information the first byte sent loads into the third device. The WS2812 is completely the opposite. The first device in the chain "captures" the first three bytes (24-bit colour word). No matter how many more bytes I send this first WS2812 will load the first colour word sent when the load pulse occurs. This continues down the chain. This does mean that you can send any number of colour words to a chain and depending on the length of the chain, say N leds, it will always be colour words 1 to N that are used, the remainder just clock out of the last WS2812 in the chain. |
||||
plasma Guru ![]() Joined: 08/04/2012 Location: GermanyPosts: 437 |
@matherp My code is testet with 245 leds and need no second array. Maybe if you mixed the codes .... Gtx |
||||
Zonker![]() Guru ![]() Joined: 18/08/2012 Location: United StatesPosts: 767 |
@Matherp... So, (talking about the LED's), From what you are saying... The first LED takes in 3 bytes, (24bits) and knows it's his data to store. That means nothing comes out of his output pin until he gets his 24... Then, he just passes the rest of the bits to his neighbor down the way... Humm... Then we should be able to see nothing coming out of the output pin until 24 bits have elapsed on each IC... There can't be any "no-op" code to pass because all possible codes are used for RGB data. In the LED controller code, the firmware would take the first 24 bits, then hook-up the input pin to the output pin to pass the rest of the "other" data... If "Mr. Scope" shows data being shifted out early, then I am totally confused on how it's being done... Each LED doesn't know where it sits in the string... (if any)... P.S. - I still haven't found the only one I got from Spark-fun... ![]() However, it's payday..! (will be getting more) |
||||
aargee Senior Member ![]() Joined: 21/08/2008 Location: AustraliaPosts: 255 |
I haven't actually tried it with the 30 string, but its behaviour seems to indicate that it should work. The C Function bit is OK, it was just the "Example " part of the program that you had tuned to your 7 LED board that needed modification. I'll see if I can check it before the weekend is over. For crying out loud, all I wanted to do was flash this blasted LED. |
||||
Bill.b![]() Senior Member ![]() Joined: 25/06/2011 Location: AustraliaPosts: 235 |
Hi All I have used the code for 24 LEDS and it worked OK. I changed the rotate sub to include all LEDs in the sequence. Bill In the interests of the environment, this post has been constructed entirely from recycled electrons. |
||||
viscomjim Guru ![]() Joined: 08/01/2014 Location: United StatesPosts: 925 |
How 'bout these bad boys (apa102)... they seem a bit easier to implement, i thinks.. HERE and HERE EDIT... This is from Adafruit's website... They're also a great upgrade for people who have loved and used NeoPixels for a few years but want something even better. DotStar LEDs use genertic 2-wire SPI, so you can push data much faster than with the NeoPixel 800 KHz protocol and there's no specific timing required. They also have much higher PWM refresh rates, so you can do Persistence-of-Vision (POV) and have less flickering, particularly at low brightness levels. HERE. These look pretty cool. I am going to try and get my hands on a few and try the umite spi function. Might be interesting... |
||||
viscomjim Guru ![]() Joined: 08/01/2014 Location: United StatesPosts: 925 |
I know this is an older thread, but does anyone know if this ws2812 cfunction is working with the latest version of mmbasic 5.1 or 5.2? I am not in a position to try it right now as I am away from my "lab", but if anyone is using it, could you provide some feedback Thanks, Sent from my iPhone 6 Jim |
||||
Bill.b![]() Senior Member ![]() Joined: 25/06/2011 Location: AustraliaPosts: 235 |
Hi Jim check this one http://www.thebackshed.com/forum/forum_posts.asp?TID=8311 Bill In the interests of the environment, this post has been constructed entirely from recycled electrons. |
||||
matherp Guru ![]() Joined: 11/12/2012 Location: United KingdomPosts: 10205 |
Works fine on 5.2. If anyone is using this code seriously I could improve it using the new facilities in recent releases - let me know |
||||
viscomjim Guru ![]() Joined: 08/01/2014 Location: United StatesPosts: 925 |
Hi Bill.b, do you prefer the apa102 over the ws2812 from your experience? The ws2812 seems to be very popular these days. What do you think? Matherp, I actually plan on using these in future products as a multi function indicator led and some other cool led lighting projects. I think you're efforts in improving this function would be a great addition to the uMite! Being able to have control over a bunch of leds using only one pin has limitless possibilities. What are your thoughts as to ws2812 vs apa102. It seems I see more info and usage with the ws2812 on the web at this point. I for one would certainly greatly appreciate your efforts here!!!! and I am hoping (pretty sure) I'm not the only one! EDIT: HERE is what I have played with using the esp8266 basic. It has some very basic functions for the neopixels and seems to work pretty good with limited commands. |
||||
WhiteWizzard Guru ![]() Joined: 05/04/2013 Location: United KingdomPosts: 2932 |
I personally find the APA102 easier to drive as in they are less time critical with the data in signal. Also you can drive them much faster so if driving lots of LEDs then you can have a flicker free display (but obviously you need a 'meaty' PSU!!) Note there is an APA102 variant which runs cooler than the cheaper APA102C (as it has a different package which is better at dissipating heat). Note: I have only had five single WS2812s running before; whereas I have a 1m strip of 60 APA102s so cannot personally say how easy it is to drive a large number of WS2812s. |
||||
Nathan Regular Member ![]() Joined: 10/01/2016 Location: GermanyPosts: 49 |
![]() I have a APA102 indicator LED on the CPU board and use some PL9823 8mm and 5mm LEDs, they are WS2812s compatible. The timing is a little bit different. The control of the APA102 is easy and very stable. For the WS2812 the timing ix a little bit tricky. I have both LED types on the same SPI channel. They are controlled by two 2 to 1 multiplexer, which build up the chip select and also makes the 3.3V to 5V transistion. I personally like the APA102 very much, but in some cases there is no way around the WS2812. It really depends on your application and of course the price. Nathan |
||||
Bill.b![]() Senior Member ![]() Joined: 25/06/2011 Location: AustraliaPosts: 235 |
I use both APA102 and WS2812 for my Christmas displays, I find the apa102 much easier to program different sequences. I have addressed up to 48 ws2812s with great success with a MX170 Bill In the interests of the environment, this post has been constructed entirely from recycled electrons. |
||||
![]() |
![]() |
The Back Shed's forum code is written, and hosted, in Australia. | © JAQ Software 2025 |