-
WS2811 and WS2812 One-Wire Communication Assembly Help
Hi all,
I'm working on a project with the WS2812B LED lights. The PIC needs to send 24 bits for every LED that is connected in series. The 1st byte being for the green, the 2nd byte being for the red, and the 3rd byte being for the blue component. The 24 bits for the first LED look like this,
Code:
'###### WS2812 HIGH BIT (1 CODE) ######
PORTD.0 = 1 'WS2812 DRIVE LINE
'####### T1H #######
ASM
nop ; ~97 nSecs
nop
nop
nop
nop
nop
nop
nop
ENDASM
PORTD.0 = 0 'WS2812 DRIVE LINE
'####### T1L #######
ASM
nop
nop
nop
ENDASM
PORTD.0 = 1 'WS2812 DRIVE LINE
'####### T1H #######
ASM
nop ; ~97 nSecs
nop
nop
nop
nop
nop
nop
nop
ENDASM
PORTD.0 = 0 'WS2812 DRIVE LINE
'####### T1L #######
ASM
nop
nop
nop
ENDASM
PORTD.0 = 1 'WS2812 DRIVE LINE
'####### T1H #######
ASM
nop ; ~97 nSecs
nop
nop
nop
nop
nop
nop
nop
ENDASM
PORTD.0 = 0 'WS2812 DRIVE LINE
'####### T1L #######
ASM
nop
nop
nop
ENDASM
PORTD.0 = 1 'WS2812 DRIVE LINE
'####### T1H #######
ASM
nop ; ~97 nSecs
nop
nop
nop
nop
nop
nop
nop
ENDASM
PORTD.0 = 0 'WS2812 DRIVE LINE
'####### T1L #######
ASM
nop
nop
nop
ENDASM
PORTD.0 = 1 'WS2812 DRIVE LINE
'####### T1H #######
ASM
nop ; ~97 nSecs
nop
nop
nop
nop
nop
nop
nop
ENDASM
PORTD.0 = 0 'WS2812 DRIVE LINE
'####### T1L #######
ASM
nop
nop
nop
ENDASM
PORTD.0 = 1 'WS2812 DRIVE LINE
'####### T1H #######
ASM
nop ; ~97 nSecs
nop
nop
nop
nop
nop
nop
nop
ENDASM
PORTD.0 = 0 'WS2812 DRIVE LINE
'####### T1L #######
ASM
nop
nop
nop
ENDASM
PORTD.0 = 1 'WS2812 DRIVE LINE
'####### T1H #######
ASM
nop ; ~97 nSecs
nop
nop
nop
nop
nop
nop
nop
ENDASM
PORTD.0 = 0 'WS2812 DRIVE LINE
'####### T1L #######
ASM
nop
nop
nop
ENDASM
PORTD.0 = 1 'WS2812 DRIVE LINE
'####### T1H #######
ASM
nop ; ~97 nSecs
nop
nop
nop
nop
nop
nop
nop
ENDASM
PORTD.0 = 0 'WS2812 DRIVE LINE
'####### T1L #######
ASM
nop
nop
nop
ENDASM
'#####################################
'###### WS2812 LOW BIT (0 CODE) ######
PORTD.0 = 1 'WS2812 DRIVE LINE
'####### T0H #######
ASM
nop ; 97 nSecs
nop
nop
ENDASM
PORTD.0 = 0 'WS2812 DRIVE LINE
'####### T0L #######
ASM
nop
nop
nop
nop
nop
nop
nop
nop
ENDASM
PORTD.0 = 1 'WS2812 DRIVE LINE
'####### T0H #######
ASM
nop ; 97 nSecs
nop
nop
ENDASM
PORTD.0 = 0 'WS2812 DRIVE LINE
'####### T0L #######
ASM
nop
nop
nop
nop
nop
nop
nop
nop
ENDASM
PORTD.0 = 1 'WS2812 DRIVE LINE
'####### T0H #######
ASM
nop ; 97 nSecs
nop
nop
ENDASM
PORTD.0 = 0 'WS2812 DRIVE LINE
'####### T0L #######
ASM
nop
nop
nop
nop
nop
nop
nop
nop
ENDASM
PORTD.0 = 1 'WS2812 DRIVE LINE
'####### T0H #######
ASM
nop ; 97 nSecs
nop
nop
ENDASM
PORTD.0 = 0 'WS2812 DRIVE LINE
'####### T0L #######
ASM
nop
nop
nop
nop
nop
nop
nop
nop
ENDASM
PORTD.0 = 1 'WS2812 DRIVE LINE
'####### T0H #######
ASM
nop ; 97 nSecs
nop
nop
ENDASM
PORTD.0 = 0 'WS2812 DRIVE LINE
'####### T0L #######
ASM
nop
nop
nop
nop
nop
nop
nop
nop
ENDASM
PORTD.0 = 1 'WS2812 DRIVE LINE
'####### T0H #######
ASM
nop ; 97 nSecs
nop
nop
ENDASM
PORTD.0 = 0 'WS2812 DRIVE LINE
'####### T0L #######
ASM
nop
nop
nop
nop
nop
nop
nop
nop
ENDASM
PORTD.0 = 1 'WS2812 DRIVE LINE
'####### T0H #######
ASM
nop ; 97 nSecs
nop
nop
ENDASM
PORTD.0 = 0 'WS2812 DRIVE LINE
'####### T0L #######
ASM
nop
nop
nop
nop
nop
nop
nop
nop
ENDASM
PORTD.0 = 1 'WS2812 DRIVE LINE
'####### T0H #######
ASM
nop ; 97 nSecs
nop
nop
ENDASM
PORTD.0 = 0 'WS2812 DRIVE LINE
'####### T0L #######
ASM
nop
nop
nop
nop
nop
nop
nop
nop
ENDASM
'#####################################
'###### WS2812 LOW BIT (0 CODE) ######
PORTD.0 = 1 'WS2812 DRIVE LINE
'####### T0H #######
ASM
nop ; 97 nSecs
nop
nop
ENDASM
PORTD.0 = 0 'WS2812 DRIVE LINE
'####### T0L #######
ASM
nop
nop
nop
nop
nop
nop
nop
nop
ENDASM
PORTD.0 = 1 'WS2812 DRIVE LINE
'####### T0H #######
ASM
nop ; 97 nSecs
nop
nop
ENDASM
PORTD.0 = 0 'WS2812 DRIVE LINE
'####### T0L #######
ASM
nop
nop
nop
nop
nop
nop
nop
nop
ENDASM
PORTD.0 = 1 'WS2812 DRIVE LINE
'####### T0H #######
ASM
nop ; 97 nSecs
nop
nop
ENDASM
PORTD.0 = 0 'WS2812 DRIVE LINE
'####### T0L #######
ASM
nop
nop
nop
nop
nop
nop
nop
nop
ENDASM
PORTD.0 = 1 'WS2812 DRIVE LINE
'####### T0H #######
ASM
nop ; 97 nSecs
nop
nop
ENDASM
PORTD.0 = 0 'WS2812 DRIVE LINE
'####### T0L #######
ASM
nop
nop
nop
nop
nop
nop
nop
nop
ENDASM
PORTD.0 = 1 'WS2812 DRIVE LINE
'####### T0H #######
ASM
nop ; 97 nSecs
nop
nop
ENDASM
PORTD.0 = 0 'WS2812 DRIVE LINE
'####### T0L #######
ASM
nop
nop
nop
nop
nop
nop
nop
nop
ENDASM
PORTD.0 = 1 'WS2812 DRIVE LINE
'####### T0H #######
ASM
nop ; 97 nSecs
nop
nop
ENDASM
PORTD.0 = 0 'WS2812 DRIVE LINE
'####### T0L #######
ASM
nop
nop
nop
nop
nop
nop
nop
nop
ENDASM
PORTD.0 = 1 'WS2812 DRIVE LINE
'####### T0H #######
ASM
nop ; 97 nSecs
nop
nop
ENDASM
PORTD.0 = 0 'WS2812 DRIVE LINE
'####### T0L #######
ASM
nop
nop
nop
nop
nop
nop
nop
nop
ENDASM
PORTD.0 = 1 'WS2812 DRIVE LINE
'####### T0H #######
ASM
nop ; 97 nSecs
nop
nop
ENDASM
PORTD.0 = 0 'WS2812 DRIVE LINE
'####### T0L #######
ASM
nop
nop
nop
nop
nop
nop
nop
nop
ENDASM
'#####################################
Here, I'm sending [255,0,0] for a pure green output. As you can see this code is not the most effective one. Specially, when you need to send data to 100+ WS2812B LEDs. If you add any FOR..NEXT, or IF...ENDIF loops, the precise timing of the HIGH and LOW bits is messed up. Actually, I think that any PICBasic command wouldn't help with the timing. Any help to implement this code in assembly would be appreciated. I'm using a PIC18F4550 at 48MHz.
Thank you,
Robert
-
1 Attachment(s)
Re: One-Wire Communication Assembly Help
basic looping structures are the very essence of good programing ,try this
its based on one of those 8x8 ws2812 panels and sends data TO 64 leds
it can handle upto 256/3 leds , and can take the data from sram and/or the flash rom
-
Re: One-Wire Communication Assembly Help
Thanks. Assembly is not something that I'm very familiar with. I'll go over this code. It seem to do what I need.
Robert
-
WS2811 One-Wire Communication Assembly Help
I am after such a project too. Unfortunately Assembly is not too friendly.
I found this AN from Microchip, AN1606 that uses the CLC module on some new chips, like the 16F1509.
After a cryptic analysis of the timing using TMR, PWM and CLC modules, the AN claims that can produce the strict timing required for the WS2811 chip.
Well, only the setting is shown and not the use of this settings on the PIC.
Anyone has any idea how to use the PIC for sending the RGB data?
Following is the settings for the 1509 registers to obtain the correct timing on the RC4/CLC4 port pin #6, based on the slow mode of WS2811.
Code:
' Initialize PIC16(L)F1509 CLC2, CLC4, Timer2, and MSSP
' for WS2811 signal transmission protocol
' Loading SSP1BUF register sends that data byte out the RC4/CLC4 pin
' PWM1 routed straight through CLC2
CLC2GLS0 = $20
CLC2GLS1 = $00
CLC2GLS2 = $00
CLC2GLS3 = $00
CLC2SEL0 = $00
CLC2SEL1 = $06
CLC2POL = $0E
CLC2CON = $82;
' (SPI SDO & SPI CLK) || (nSPI SDO & SPI CLK & PWM1)
' PWM1 comes through CLC2
CLC4GLS0 = $44
CLC4GLS1 = $10
CLC4GLS2 = $80
CLC4GLS3 = $20
CLC4SEL0 = $50
CLC4SEL1 = $05
CLC4POL = $01
CLC4CON = $C0
' Adjust Timer2 period for desired baud rate
' One bit period is two Timer2 periods
T2CON = $04
PR2 = 5
' Adjust PWM1 duty cycle for desired "0" data-bit duty cycle
' ‘1’ data-bit duty cycle is automatically 50%
PWM1CON = $E0
PWM1DCH = 2
PWM1DCL = 0
' MSSP configured for SPI master with Timer2_Period/2 clock
SSP1CON1 = $23
' Output on RC4/CLC4
TRISC = $EF
Any help appreciated.
Ioannis
-
3 Attachment(s)
Re: WS2811 and WS2812 One-Wire Communication Assembly Help
interesting find ioannis.
the an seems to lack many details not just how to use it ,I tried it out on a pic16f1619 and discovered that the an description of the clc cells setup is quite misleading
the reality is they are set like in these images
I'm not sure I have this exactly correct but it looks to work
i have included my working example it spits out data for 64 leds [192 bytes] in 2mS.
I cant see much advantage to it over my earlier routine you only have a few uS between bytes barely enough time for a pbp style dt interrupt
-
Re: WS2811 and WS2812 One-Wire Communication Assembly Help
a small refinement
CLC1 can be released from use its not needed with a 16f1619
by
CLC2SEL1 = $0E; in lieu of 04
-
Re: WS2811 and WS2812 One-Wire Communication Assembly Help
Richard, thanks for looking into this.
For 64 led's I think the timing for each frame is 3,84ms. Does it work with 2ms?
Anyway, you did a great job on this. Really fast!
Well, the AN implied, or at least I wanted to be that way, this solution would be fast enough for the MCU to do other tasks.
But as you tested, yes, seems there is not enough time.
I want to use this strips for a 60 led's (1m bar) for medical purposes and the timing is very strict.
Thanks,
Ioannis
-
Re: WS2811 and WS2812 One-Wire Communication Assembly Help
I may have measured that wrong, its more like 5mS now for 192 bytes
the spi takes 25uS per byte and there is a 5us gap between bytes as is
I think the gap between bytes needs to be less than 50uS
so an isr has 60us to get in do something and get out again
conversely an asm isr could feed the spi buffer every 60uS or so
-
Re: WS2811 and WS2812 One-Wire Communication Assembly Help
just for a joke I upped the osc to 32mHz ,
it still works , its less than 3mS now for 192 bytes
these things aren't that fussy
-
Re: WS2811 and WS2812 One-Wire Communication Assembly Help
just remembered de morgan equivalents , have not done Boolean algebra since ttl was in vogue
-
Re: WS2811 and WS2812 One-Wire Communication Assembly Help
It seems that the chips WS2811 are quite tolerant on the timing specs.
Ioannis
-
Re: WS2811 and WS2812 One-Wire Communication Assembly Help
-
1 Attachment(s)
Re: WS2811 and WS2812 One-Wire Communication Assembly Help
Quote:
Did you guys see this example/thread?
indeed . the point of my posts are to demonstrate tight loop routines that achieve the same task without all that spaghetti code
here is an interrupt driven version of the clc method using linear sram memory access to facilitate a 240 byte buffer on a pic16
-
Re: WS2811 and WS2812 One-Wire Communication Assembly Help
Yes, I understand what your goal is and want to try your code out. I have a 8x8 neopixel to run it on.
I referenced the other thread for the op who said he wasn't great at assembly code.
Thanks
-
Re: WS2811 and WS2812 One-Wire Communication Assembly Help
Quote:
Originally Posted by
mark_s
Yes, I understand what your goal is and want to try your code out. I have a 8x8 neopixel to run it on.
I would love to hear how you get on
-
Re: WS2811 and WS2812 One-Wire Communication Assembly Help
Richard I gave the code in post #2 a try. I don't have a 12mhz crystal so I am having problems configuring 4550 for 48mhz internal osc. My test board has a 10mhz resonator. The usb pre-scale stuff is throwing me off. If you could help me with the configurations for internal osc 48mhz or 40mhz using the pll and the 10mhz resonator. I may have it set ok I'm getting the signal on portc.0
Also as posted the code makes one pass and stops. Is this the way it is intended to function? The neopixel did nothing so I added "goto aloop"
above "stop" and get continuous pulse train on c.0. A few of the leds light. Unable to try your other code because I don't have that pic. Tomorrow I will give it another go.
Thanks
Code:
aloop:
p_pc=nows ;set number of leds to load
@ Flash2Ram _pixels,_rw1' Get a String from flash memory
p_pc=nows ;set number of leds to show
call showpix
goto aloop '????????????????
stop
end
-
Re: WS2811 and WS2812 One-Wire Communication Assembly Help
Quote:
I don't have a 12mhz crystal so I am having problems configuring 4550 for 48mhz internal osc. My test board has a 10mhz resonator. The usb pre-scale stuff is throwing me off. If you could help me with the configurations for internal osc 48mhz or 40mhz using the pll and the 10mhz resonator.
the pll input needs to be 4MHz if you are going to use it . a 10MHz resonator
cant be divided down to 4MHz using plldiv to keep pll input within specs .
the xtal/res needs to be a multiple of 4 for correct use, my board has a 20MHz xtal
out of spec operation may be possible but may lack stability required for this use
Quote:
Also as posted the code makes one pass and stops
yep that's all that code did , you should see a white "R" , a loop serves no
purpose here, the other examples are more elaborate
if you want text scroll
Code:
aloop:
for p_offset=0 to 1536 step 24
p_pc=nows ;set number of leds to load
@ Flash2Ram _pixels,_rw1' Get a String from flash memory
p_pc=nows ;set number of leds to show
call showpix
pause 200
next
goto aloop
stop
end
rw1:
@ DW 0,0,0, 0,0,0, 0,0,0, 0,0,0, 0,0,0, 0,0,0, 0,0,0, 0,0,0
@ DW 0,0,0, 0,0,0, 0,0,0, 0,0,0, 0,0,0, 0,0,0, 0,0,0, 0,0,0
@ DW 0,0,0, 0,0,0, 0,0,0, 0,0,0, 0,0,0, 0,0,0, 0,0,0, 0,0,0
@ DW 0,0,0, 0,0,0, 0,0,0, 0,0,0, 0,0,0, 0,0,0, 0,0,0, 0,0,0
@ DW 0,0,0, 0,0,0, 0,0,0, 0,0,0, 0,0,0, 0,0,0, 0,0,0, 0,0,0
@ DW 0,0,0, 0,0,0, 0,0,0, 0,0,0, 0,0,0, 0,0,0, 0,0,0, 0,0,0
@ DW 0,0,0, 0,0,0, 0,0,0, 0,0,0, 0,0,0, 0,0,0, 0,0,0, 0,0,0
@ DW 0,0,0, 0,0,0, 0,0,0, 0,0,0, 0,0,0, 0,0,0, 0,0,0, 0,0,0
;192
@ DW 0,0,0, 50,50,50, 50,50,50, 50,50,50, 0,0,0, 0,0,0, 0,0,0, 0,0,0 ;23
@ DW 0,0,0, 50,50,50, 0,0,0, 0,0,0, 50,50,50, 0,0,0, 0,0,0, 0,0,0 ;47
@ DW 0,0,0, 50,50,50, 0,0,0, 0,0,0, 50,50,50, 0,0,0, 0,0,0, 0,0,0 ;71
@ DW 0,0,0, 50,50,50, 50,50, 50,50,50, 50,0,0,0, 0,0,0, 0,0,0, 0,0,0 ;95
@ DW 0,0,0, 50,50,50, 0,0,0, 0,0,0, 50,50,50, 0,0,0, 0,0,0, 0,0,0 ;119
@ DW 0,0,0, 50,50,50, 0,0,0, 0,0,0, 50,50,50, 0,0,0, 0,0,0, 0,0,0 ;143
@ DW 0,0,0, 50,50,50, 0,0,0, 0,0,0, 50,50,50, 0,0,0, 0,0,0, 0,0,0 ;167
@ DW 0,0,0, 0,0,0, 0,0,0, 0,0,0, 0,0,0, 0,0,0, 0,0,0, 0,0,0 ;191
;384
@ DW 0,0,0, 0,0,0, 50,50,50, 50,50,50, 50,50,50, 0,0,0, 0,0,0, 0,0,0
@ DW 0,0,0, 0,0,0, 0,0,0, 50,50,50, 0,0,0, 0,0,0, 0,0,0, 0,0,0
@ DW 0,0,0, 0,0,0, 0,0,0, 50,50,50, 0,0,0, 0,0,0, 0,0,0, 0,0,0
@ DW 0,0,0, 0,0,0, 0,0,0, 50,50,50, 0,0,0, 0,0,0, 0,0,0, 0,0,0
@ DW 0,0,0, 0,0,0, 0,0,0, 50,50,50, 0,0,0, 0,0,0, 0,0,0, 0,0,0
@ DW 0,0,0, 0,0,0, 0,0,0, 50,50,50, 0,0,0, 0,0,0, 0,0,0, 0,0,0
@ DW 0,0,0, 0,0,0, 50,50,50, 50,50,50, 50,50,50, 0,0,0, 0,0,0, 0,0,0
@ DW 0,0,0, 0,0,0, 0,0,0, 0,0,0, 0,0,0, 0,0,0, 0,0,0, 0,0,0
;576
@ DW 0,0,0, 0,0,0, 50,50,50, 50,50,50, 50,50,50, 0,0,0, 0,0,0, 0,0,0
@ DW 0,0,0, 50,50,50, 0,0,0, 0,0,0, 0,0,0, 0,0,0, 0,0,0, 0,0,0
@ DW 0,0,0, 50,50,50, 0,0,0, 0,0,0, 0,0,0, 0,0,0, 0,0,0, 0,0,0
@ DW 0,0,0, 50,50,50, 0,0,0, 0,0,0, 0,0,0, 0,0,0, 0,0,0, 0,0,0
@ DW 0,0,0, 50,50,50, 0,0,0, 0,0,0, 0,0,0, 0,0,0, 0,0,0, 0,0,0
@ DW 0,0,0, 50,50,50, 0,0,0, 0,0,0, 0,0,0, 0,0,0, 0,0,0, 0,0,0
@ DW 0,0,0, 0,0,0, 50,50,50, 50,50,50, 50,50,50, 0,0,0, 0,0,0, 0,0,0
@ DW 0,0,0, 0,0,0, 0,0,0, 0,0,0, 0,0,0, 0,0,0, 0,0,0, 0,0,0
;768
@ DW 0,0,0 ,50,50,50, 0,0,0, 0,0,0, 50,50,50, 0,0,0, 0,0,0, 0,0,0
@ DW 0,0,0, 50,50,50, 0,0,0, 0,0,0, 50,50,50, 0,0,0, 0,0,0, 0,0,0
@ DW 0,0,0, 50,50,50, 0,0,0, 0,0,0, 50,50,50, 0,0,0, 0,0,0, 0,0,0
@ DW 0,0,0, 50,50,50, 50,50,50, 50,50,50, 50,50,50, 0,0,0, 0,0,0, 0,0,0
@ DW 0,0,0, 50,50,50, 0,0,0, 0,0,0, 50,50,50, 0,0,0, 0,0,0, 0,0,0
@ DW 0,0,0, 50,50,50, 0,0,0, 0,0,0, 50,50,50, 0,0,0, 0,0,0, 0,0,0
@ DW 0,0,0, 50,50,50, 0,0,0, 0,0,0, 50,50,50, 0,0,0, 0,0,0, 0,0,0
@ DW 0,0,0, 0,0,0, 0,0,0, 0,0,0, 0,0,0, 0,0,0, 0,0,0, 0,0,0
;960
@ DW 0,0,0, 0,0,0, 50,50,50, 50,50,50, 0,0,0, 0,0,0, 0,0,0, 0,0,0
@ DW 0,0,0, 50,50,50, 0,0,0, 0,0,0, 50,50,50, 0,0,0, 0,0,0, 0,0,0
@ DW 0,0,0, 50,50,50, 0,0,0, 0,0,0, 50,50,50, 0,0,0, 0,0,0, 0,0,0
@ DW 0,0,0, 50,50,50, 50,50,50, 50,50,50, 50,50,50, 0,0,0, 0,0,0, 0,0,0
@ DW 0,0,0, 50,50,50, 0,0,0, 0,0,0, 50,50,50, 0,0,0, 0,0,0, 0,0,0
@ DW 0,0,0, 50,50,50, 0,0,0, 0,0,0, 50,50,50, 0,0,0, 0,0,0, 0,0,0
@ DW 0,0,0, 50,50,50, 0,0,0, 0,0,0, 50,50,50, 0,0,0, 0,0,0, 0,0,0
@ DW 0,0,0, 0,0,0, 0,0,0, 0,0,0, 0,0,0, 0,0,0, 0,0,0, 0,0,0
;1152
@ DW 0,0,0, 50,50,50, 50,50,50, 50,50,50, 0,0,0, 0,0,0, 0,0,0, 0,0,0
@ DW 0,0,0, 50,50,50, 0,0,0, 0,0,0, 50,50,50, 0,0,0, 0,0,0, 0,0,0
@ DW 0,0,0, 50,50,50, 0,0,0, 0,0,0, 50,50,50, 0,0,0, 0,0,0, 0,0,0
@ DW 0,0,0, 50,50,50, 50,50,50, 50,50,50, 0,0,0, 0,0,0, 0,0,0, 0,0,0
@ DW 0,0,0, 50,50,50, 0,0,0, 0,0,0, 50,50,50, 0,0,0, 0,0,0, 0,0,0
@ DW 0,0,0, 50,50,50, 0,0,0, 0,0,0, 50,50,50, 0,0,0, 0,0,0, 0,0,0
@ DW 0,0,0, 50,50,50, 0,0,0, 0,0,0, 50,50,50, 0,0,0, 0,0,0, 0,0,0
@ DW 0,0,0, 0,0,0, 0,0,0, 0,0,0, 0,0,0, 0,0,0, 0,0,0, 0,0,0
;1344
@ DW 0,0,0 ,50,50,50, 50,50,50, 50,50,50, 0,0,0, 0,0,0, 0,0,0, 0,0,0
@ DW 0,0,0, 50,50,50, 0,0,0, 0,0,0, 50,50,50, 0,0,0, 0,0,0, 0,0,0
@ DW 0,0,0, 50,50,50, 0,0,0, 0,0,0, 50,50,50, 0,0,0, 0,0,0, 0,0,0
@ DW 0,0,0, 50,50,50, 0,0,0, 0,0,0, 50,50,50, 0,0,0, 0,0,0, 0,0,0
@ DW 0,0,0, 50,50,50, 0,0,0, 0,0,0, 50,50,50, 0,0,0, 0,0,0, 0,0,0
@ DW 0,0,0, 50,50,50, 0,0,0, 0,0,0, 50,50,50, 0,0,0, 0,0,0, 0,0,0
@ DW 0,0,0 ,50,50,50, 50,50,50, 50,50,50, 0,0,0, 0,0,0, 0,0,0, 0,0,0
@ DW 0,0,0, 0,0,0, 0,0,0, 0,0,0, 0,0,0, 0,0,0, 0,0,0, 0,0,0
;1536
@ DW 0,0,0, 0,0,0, 0,0,0, 0,0,0, 0,0,0, 0,0,0, 0,0,0, 0,0,0
@ DW 0,0,0, 0,0,0, 0,0,0, 0,0,0, 0,0,0, 0,0,0, 0,0,0, 0,0,0
@ DW 0,0,0, 0,0,0, 0,0,0, 0,0,0, 0,0,0, 0,0,0, 0,0,0, 0,0,0
@ DW 0,0,0, 0,0,0, 0,0,0, 0,0,0, 0,0,0, 0,0,0, 0,0,0, 0,0,0
@ DW 0,0,0, 0,0,0, 0,0,0, 0,0,0, 0,0,0, 0,0,0, 0,0,0, 0,0,0
@ DW 0,0,0, 0,0,0, 0,0,0, 0,0,0, 0,0,0, 0,0,0, 0,0,0, 0,0,0
@ DW 0,0,0, 0,0,0, 0,0,0, 0,0,0, 0,0,0, 0,0,0, 0,0,0, 0,0,0
@ DW 0,0,0, 0,0,0, 0,0,0, 0,0,0, 0,0,0, 0,0,0, 0,0,0, 0,0,0
@ DW 0,0,0, 0,0,0, 0,0,0, 0,0,0, 0,0,0, 0,0,0, 0,0,0, 0,0,0
-
Re: WS2811 and WS2812 One-Wire Communication Assembly Help
Richard
I changed the crystal to 20mhz and added the scroll code above. It's now working, so thanks for your efforts.
I'll study the other code and see what I can do.
Mark
-
1 Attachment(s)
Re: WS2811 and WS2812 One-Wire Communication Assembly Help
Similar to WS2811/2812 is the APA102C led chip, produced as a strip too.
The Datasheet is unclear of the timing specs.
I tried many hours to make it work but in vein. No led so far is under my control. Any ideas, welcome.
An example code is this:
Code:
arraywrite leds,[0,0,0,0,$f0,128,128,128,255,255,255,255]
shiftout led_data,led_clock,1,[leds[0],leds[1],leds[2],leds[3],leds[4],leds[5],leds[6],leds[7],leds[8],leds[9],leds[10],leds[11]]
Lcdout $fe,$1,"Stoped"
stop
Any help?
Ioannis
-
Re: WS2811 and WS2812 One-Wire Communication Assembly Help
-
Re: WS2811 and WS2812 One-Wire Communication Assembly Help
Hi Richard.
Thanks for the link. The real help was ... the color of the cables. On my strip the ground is Blue and +5V is Black. Really! They made +5V Black!
Of course I used Black as ground and that was the problem.
Be careful if color is not red then,
Black is +5, NOT ground.
Blue is Ground.
Chinese people might have a different color preferences...
I had it working now. Almost got crazy, since logic analyzer was showing all was OK!
This type of LED's is more easy to control since they do not need strict timings. Just spit out at whatever pace you like or can and LED's follow. Very easy for any MCU.
People have reported driving SPI up to 60MHz on these strips.
Ioannis
-
Re: WS2811 and WS2812 One-Wire Communication Assembly Help
The following is a simple test program to demonstrate how to use of APA-102 leds.
It lights the Blue led and shifts it ten places in 100ms interval.
To successfully manage this, tens of hours were spent... Datasheet sucks.
But in general is much easier to control as the timings are those of an SPI interface and can be really fast driven if you have the resources.
Code:
arraywrite red_a,[0,0,0,0,0,0,0,0,0,0,0]
arraywrite green_a,[0,0,0,0,0,0,0,0,0,0,0]
arraywrite blue_a,[255,0,0,0,0,0,0,0,0,0,0]
gosub display_led
stop
display_led:
for k=0 to led_num
for i=0 to led_num
shiftout led_data,led_clock,1,[lum,blue_a[i],green_a[i],red_a[i]]
next i
gosub shift_sub
next k
pause 1000 'delay from one color to another
return
shift_sub:
shiftout led_data,led_clock,1,[%11100011,0,0,0,0,0] 'END of Frame
pause 100'led move step delay
temp=red_a[k]:RED_A[k]=RED_A[k+1]:RED_A[k+1]=temp
temp=green_a[k]:green_a[k]=green_a[k+1]:green_a[k+1]=temp
temp=blue_a[k]:blue_a[k]=blue_a[k+1]:blue_a[k+1]=temp
return
Ioannis
-
1 Attachment(s)
Re: WS2811 and WS2812 One-Wire Communication Assembly Help
Quote:
But in general is much easier to control as the timings are those of an SPI interface and can be really fast driven if you have the resources.
I had 3 in the parts bin , so I had a go using mssp module . @64mhz with the fastest spi clk its no problem at all .
a complete 3 led frame is less than 80uS . heaps easier than ws2812:smile:
-
Re: WS2811 and WS2812 One-Wire Communication Assembly Help
Great job on the asm Richard.
Though this kind of LED's are easier most people look after the WS28xx series.
Ioannis
-
Re: WS2811 and WS2812 One-Wire Communication Assembly Help
Hello all,
here is, if someone interested my simple one (or more) neopixel driver. In demo it fades through basic RGB colours. Code is simply modifiable to lit up any kind of colour. Only changing the NeoRed, NeoGreen, NeoBlue variables.
Code:
'****************************************************************
'* Name : One_Neopixel_driver *
'* Author : Louis *
'* Notice : Copyright (c) 2019 *
'* : All Rights Reserved *
'* Date : 1. 12. 2019 *
'* Version : 1.0 *
'* Notes : *
'* : 12F1840 *
'****************************************************************
#CONFIG
__config _CONFIG1, _FOSC_INTOSC & _WDTE_OFF & _PWRTE_ON & _MCLRE_OFF & _CP_OFF & _CPD_OFF & _BOREN_ON & _CLKOUTEN_OFF & _IESO_ON & _FCMEN_ON
__config _CONFIG2, _WRT_OFF & _PLLEN_ON & _STVREN_ON & _BORV_19 & _LVP_OFF
#ENDCONFIG
DEFINE OSC 32 ; Use internal clock 32MHz
OSCCON = %11110000 ; 8 MHz internal x 4
OSCTUNE = %00000000 ; Internal osc tunning
WHILE !OSCSTAT.3 ; Wait for stable OSC
WEND
TRISA = 0
ANSELA = 0
OPTION_REG.7=1 ; disable internal pull-ups
ADCON0 = 0
ADCON1 = 0
;------------ Variables ---------------------
NeoGreen VAR BYTe
NeoBlue VAR BYTE
NeoRed VAR BYTE
NeoPixel VAR BYTE
BitCount VAR BYTE
DataBit VAR byte
Cnt var byte
n var byte
Flag var bit
;------------ ALIAS -------------------------
NeoPin VAR porta.2
;----------- Initialization ----------------
Clear ; Clear All
;------------ Main program ------------------
Main:
pause 10
if flag = 0 then
n=n+1
else
n=n-1
if n=0 then
flag = 0
cnt = cnt + 1
endif
endif
if n = 254 then flag = 1
if cnt > 2 then cnt = 0
if cnt = 0 then
NeoGreen = n ; value 0-254 for green color
else
NeoGreen = 0
endif
if cnt = 1 then
Neoblue = n ; value 0-254 for blue color
else
Neoblue = 0
endif
if cnt = 2 then
Neored = n ; value 0-254 for red color
else
Neored = 0
endif
gosub NeoDraw
GOTO Main
END
;------------ Extract bites ---------------
NeoDraw:
FOR BitCount = 7 TO 0 step -1
DataBit = NeoGreen.0[bitcount]
GOSUB NeoBit
NEXT
FOR BitCount = 7 TO 0 step -1
DataBit = NeoRed.0[bitcount]
GOSUB NeoBit
NEXT
FOR BitCount = 7 TO 0 step -1
DataBit = NeoBlue.0[bitcount]
GOSUB NeoBit
NEXT
RETURN
;------------ Pulse generator ---------------
NeoBit:
IF DataBit = 1 THEN
;generate 800ns pulse
NeoPin = 1
ASM
nop
nop
nop
nop
nop
ENDASM
NeoPin = 0
ELSE
;generate 400ns pulse
NeoPin = 1
ASM
nop
nop
ENDASM
NeoPin = 0
ENDIF
RETURN