WS2811 and WS2812 One-Wire Communication Assembly Help


Closed Thread
Results 1 to 25 of 25

Hybrid View

  1. #1
    Join Date
    Jan 2009
    Location
    Miami, Florida USA
    Posts
    637

    Default 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
    "No one is completely worthless. They can always serve as a bad example."

    Anonymous

  2. #2
    Join Date
    May 2013
    Location
    australia
    Posts
    2,380


    Did you find this post helpful? Yes | No

    Default 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
    Attached Files Attached Files
    Warning I'm not a teacher

  3. #3
    Join Date
    Jan 2009
    Location
    Miami, Florida USA
    Posts
    637


    Did you find this post helpful? Yes | No

    Default 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
    "No one is completely worthless. They can always serve as a bad example."

    Anonymous

  4. #4
    Join Date
    Nov 2003
    Location
    Greece
    Posts
    3,795


    Did you find this post helpful? Yes | No

    Default 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
    Last edited by Ioannis; - 14th October 2017 at 21:52.

  5. #5
    Join Date
    May 2013
    Location
    australia
    Posts
    2,380


    Did you find this post helpful? Yes | No

    Default 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
    Attached Images Attached Images   
    Attached Files Attached Files
    Warning I'm not a teacher

  6. #6
    Join Date
    May 2013
    Location
    australia
    Posts
    2,380


    Did you find this post helpful? Yes | No

    Default 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
    Warning I'm not a teacher

  7. #7


    Did you find this post helpful? Yes | No

    Default 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

Similar Threads

  1. PIC to WS2812B / WS2811 IC
    By comwarrior in forum mel PIC BASIC Pro
    Replies: 6
    Last Post: - 19th January 2018, 20:37
  2. ws2812 - pic12f1822
    By richard in forum Code Examples
    Replies: 0
    Last Post: - 12th January 2016, 10:52
  3. Assembly
    By Normnet in forum mel PIC BASIC Pro
    Replies: 0
    Last Post: - 19th March 2007, 04:44
  4. How do you do this in Assembly
    By ice in forum mel PIC BASIC Pro
    Replies: 3
    Last Post: - 10th May 2005, 07:47
  5. Assembly?
    By Dwayne in forum General
    Replies: 11
    Last Post: - 4th January 2004, 19:18

Members who have read this thread : 2

You do not have permission to view the list of names.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts