Driver for WS2812

Questions and discussion about The WiPy 1.0 board and CC3200 boards.
Target audience: Users with a WiPy 1.0 or CC3200 board.
Oliv'
Posts: 13
Joined: Fri Oct 30, 2015 9:18 am

Driver for WS2812

Post by Oliv' » Tue Nov 03, 2015 12:44 pm

After few try, I have finally a working driver for WS2812, many thanks to Architekt for the example and Dani for the support.
There is some speed improvements to do, but it will come later :lol:

Here is the driver, I included a test code to do a chase:

Code: Select all

from ws2812 import WS2812

chain = WS2812( ledNumber=16, brightness=100 )
data = [(255, 102, 0), (127, 21, 0), (63, 10, 0), (31, 5, 0),
        (15, 2, 0), (7, 1, 0), (0, 0, 0), (0,0,0),
        (0, 0, 0), (0, 0, 0), (0, 0, 0), (0,0,0),
        (0, 0, 0), (0, 0, 0), (0, 0, 0), (0,0,0)
       ]
chain.show( data )


while True:
    data = data[1:] + data[0:1]
    chain.show( data )
    time.sleep_ms( 150 )
IMG_20151103_131419_1.jpg
IMG_20151103_131419_1.jpg (54.88 KiB) Viewed 9989 times

nui_de
Posts: 40
Joined: Fri Oct 23, 2015 3:27 pm

Re: Driver for WS2812

Post by nui_de » Thu Nov 05, 2015 8:41 pm

Hi,

sure you know it already but there is a typo in Line 105 in ws2812.py

buf[index+14] = buf_bytes[red & mask]
mask has to be also 0x03 i guess....

User avatar
danicampora
Posts: 342
Joined: Tue Sep 30, 2014 7:20 am
Contact:

Re: Driver for WS2812

Post by danicampora » Thu Nov 05, 2015 8:45 pm

Based on Oliv' driver I have written another one a bit more compact. It the meantime is here:

https://github.com/danicampora/wipy/blo ... /ws2812.py

Oliv'
Posts: 13
Joined: Fri Oct 30, 2015 9:18 am

Re: Driver for WS2812

Post by Oliv' » Fri Nov 06, 2015 9:39 pm

danicampora wrote:Based on Oliv' driver I have written another one a bit more compact.
A lot better for understanding but, as discussed on Github, it takes 2.5 time more to fill the buffer for 128 led. So it might be difficult to drive a lot of led or do huge effects.
If one of my projects requires it, I might try to wrote the driver in C, it is not the aim of Python but memcpy() is really missing here :) .
nui_de wrote: buf[index+14] = buf_bytes[red & mask]
mask has to be also 0x03 i guess....
Yep corrected, sorry for the mistake. I don't know how it has happened, my local repo has not this typo...

zzz
Posts: 1
Joined: Mon Nov 09, 2015 1:18 pm

Re: Driver for WS2812

Post by zzz » Mon Nov 09, 2015 1:52 pm

After reading about using hardware SPI for "bit-banging" I've spent some time attempting to generate the required signals for WS2812. I see some nice tricks in your code!

Initially I attempted to do SPI with the defaults of CPOL=0, CPHA=0 but ran into the issue of the SPI MOSI line being high in its idle state, meaning that the WS2812 would be unable to see the first bit sent on the SPI bus because of the lack of a rising edge until after the first zero bit had been sent. I attempted to fix this by switching to CPOL=0, CPHA=1 which takes the MOSI line low before sending data.

I see that Oliv' fixes this problem by reconfiguring the MOSI pin. Very neat!

Code: Select all

# Enable pull down
Pin('GP16', mode=Pin.ALT, pull=Pin.PULL_DOWN)
Another thing I noticed while looking at the signals from SPI.write() was that there were often 1.3-1.6uS long pauses, sometimes even millisecond long pauses, between each byte sent with SPI.write(array_of_bytes) in 8-bit mode (the default).

Is that what danicampora calls 'dead cycles' in this comment?

Code: Select all

# bus 0, 8MHz => 125 ns by bit, each transfer is the cycles long due to the CC3200
# spi dead cycles, therefore => 125*10=1.25 us as required by the WS2812
# no automatic pin assigment since we only need MOSI
self.spi = SPI(0, SPI.MASTER, baudrate=8000000, pins=None)
Pin('GP16', mode=Pin.ALT, pull=Pin.PULL_DOWN, alt=7)
(also, I notice that CPHA=1 has been removed in danicampora's code - interesting!)

nui_de
Posts: 40
Joined: Fri Oct 23, 2015 3:27 pm

Re: Driver for WS2812

Post by nui_de » Mon Nov 09, 2015 8:31 pm

Hi...

i have a strange Problem driving my neopixel ring.
Everything worked just fine but now all the pixel of the ring are 100% On all the time.

I can't figure out what happened...
Tried the following:

- using library from daniel (same result)
- reset filesystem / reinstalled firmware
- put the wipy on my breadboard instead of the expansion board
- tried new Neopixel-ring
- tried new wipy board

Any Idea? It did work...

Using the ws2812 from oliv:

Code: Select all

import machine
import time
from ws2812 import WS2812
from machine import UART
import os

uart = UART(0, baudrate=115200)
os.dupterm(uart)

from network import WLAN
wlan = WLAN() # get current object, without changing the mode

if machine.reset_cause() != machine.SOFT_RESET:
    wlan.init(WLAN.STA)
    # configuration below MUST match your home router settings!!
    wlan.ifconfig(config=('192.168.178.107', '255.255.255.0', '192.168.178.1', '8.8.8.8'))

if not wlan.isconnected():
    # change the line below to match your network ssid, security and password
    wlan.connect('lalala', auth=(WLAN.WPA2, 'lalala'), timeout=5000)
    while not wlan.isconnected():
        machine.idle() # save power while waiting
		
chain = WS2812(ledNumber=16, brightness=100)
data = [(255, 102, 0),(200, 80, 0), (160, 42, 0), (140,30,0), (127, 21, 0), (63, 10, 0), (31, 5, 0),(15, 2, 0), (7, 1, 0), (0,0, 0), (80,80,200),(0, 0, 0), (0, 0, 0), (0, 0, 0), (0,0,0),(0, 0, 0)]
chain.show(data)

while True:
    data = data[1:] + data[0:1]
    
    
    chain.show(data)
    time.sleep_ms( 40 )

Oliv'
Posts: 13
Joined: Fri Oct 30, 2015 9:18 am

Re: Driver for WS2812

Post by Oliv' » Mon Nov 09, 2015 9:15 pm

zzz wrote:Another thing I noticed while looking at the signals from SPI.write() was that there were often 1.3-1.6uS long pauses, sometimes even millisecond long pauses, between each byte sent with SPI.write(array_of_bytes) in 8-bit mode (the default).
Did you disabled the interrupts ? It could explain the time variation between two words, the DMA is not enabled in the Wipy
nui_de wrote: - reset filesystem / reinstalled firmware
It might be the issue : which firmwire are you using ? Both release on Wipy's Github repo have a bug on SPI clock selection, you should recompile from HEAD on MicroPython's Github or use the firmware linked on this page
Dani, you should add a warning about that in the library ;)

nui_de
Posts: 40
Joined: Fri Oct 23, 2015 3:27 pm

Re: Driver for WS2812

Post by nui_de » Mon Nov 09, 2015 10:20 pm

Hi Oliv'

yep!! that was the problem - many thanks!

I must have installed a working FW first and then "updated" to 1.1.0
not aware of the bug :roll:

nui_de
Posts: 40
Joined: Fri Oct 23, 2015 3:27 pm

Re: Driver for WS2812

Post by nui_de » Tue Nov 10, 2015 6:58 am

Hi,

I have an issue with setting the brightness, I was trying to smoothly dim the leds down
from 100% to 0 but the led "jumps" in brightness - when it is already darker it becomes brighter again
with lower dim-level - looks like disco ;)

Do you have the same problem or is it only me?

Oliv'
Posts: 13
Joined: Fri Oct 30, 2015 9:18 am

Re: Driver for WS2812

Post by Oliv' » Tue Nov 10, 2015 10:47 pm

nui_de wrote:Do you have the same problem or is it only me?
You are not alone :)

I just tried a fade an have the same disco lights :P
I think it comes from the way brightness works in the library I copied, I really need to take some time to add hue/saturation

Post Reply