Skip to content

Commit 5f8e7bb

Browse files
authored
Merge pull request #5 from pimoroni/master
Added Pi 3 B+ support, compatibility with legacy examples, fixed rst readme
2 parents 4db1d93 + 3dd7a84 commit 5f8e7bb

17 files changed

+841
-111
lines changed

README.md

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,13 @@
11
# RPi WS281x Python
22

3-
This is an unofficial Python distribution of the ws281x library: http://github.com/richardghirst/rpi_ws281x
3+
This is the official Python distribution of the ws281x library: http://github.com/richardghirst/rpi_ws281x
44

5-
It's intended to support the Unicorn HAT library, but can be used for driving other WS281x-based LED projects.
5+
# Installing
66

7-
### Based Upon rpi_ws281x
7+
## From pip
88

9-
`unicornhat` is based upon a modified, Pi 2/3 compatible version of the RPi ws281x Library by Jeremy Garff.
9+
Most users should simply run:
1010

11-
The library was modified by Richard Hirst.
12-
13-
* Modified version: https://github.com/richardghirst/rpi_ws281x
14-
* Original: https://github.com/jgarff/rpi_ws281x
11+
```
12+
sudo pip install rpi_ws281x
13+
```

examples/SK6812_lowlevel.py

Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
# Example of low-level Python wrapper for rpi_ws281x library.
2+
# Author: Tony DiCola ([email protected]), Jeremy Garff ([email protected])
3+
#
4+
# This is an example of how to use the SWIG-generated _rpi_ws281x module.
5+
# You probably don't want to use this unless you are building your own library,
6+
# because the SWIG generated module is clunky and verbose. Instead look at the
7+
# high level Python port of Adafruit's NeoPixel Arduino library in strandtest.py.
8+
#
9+
# This code will animate a number of WS281x LEDs displaying rainbow colors.
10+
import time
11+
12+
import _rpi_ws281x as ws
13+
14+
# LED configuration.
15+
LED_CHANNEL = 0
16+
LED_COUNT = 16 # How many LEDs to light.
17+
LED_FREQ_HZ = 800000 # Frequency of the LED signal. Should be 800khz or 400khz.
18+
LED_DMA_NUM = 10 # DMA channel to use, can be 0-14.
19+
LED_GPIO = 18 # GPIO connected to the LED signal line. Must support PWM!
20+
LED_BRIGHTNESS = 255 # Set to 0 for darkest and 255 for brightest
21+
LED_INVERT = 0 # Set to 1 to invert the LED signal, good if using NPN
22+
# transistor as a 3.3V->5V level converter. Keep at 0
23+
# for a normal/non-inverted signal.
24+
#LED_STRIP = ws.WS2811_STRIP_RGB
25+
#LED_STRIP = ws.WS2811_STRIP_GBR
26+
#LED_STRIP = ws.SK6812_STRIP_RGBW
27+
LED_STRIP = ws.SK6812W_STRIP
28+
29+
30+
# Define colors which will be used by the example. Each color is an unsigned
31+
# 32-bit value where the lower 24 bits define the red, green, blue data (each
32+
# being 8 bits long).
33+
DOT_COLORS = [ 0x200000, # red
34+
0x201000, # orange
35+
0x202000, # yellow
36+
0x002000, # green
37+
0x002020, # lightblue
38+
0x000020, # blue
39+
0x100010, # purple
40+
0x200010 ] # pink
41+
42+
43+
# Create a ws2811_t structure from the LED configuration.
44+
# Note that this structure will be created on the heap so you need to be careful
45+
# that you delete its memory by calling delete_ws2811_t when it's not needed.
46+
leds = ws.new_ws2811_t()
47+
48+
# Initialize all channels to off
49+
for channum in range(2):
50+
channel = ws.ws2811_channel_get(leds, channum)
51+
ws.ws2811_channel_t_count_set(channel, 0)
52+
ws.ws2811_channel_t_gpionum_set(channel, 0)
53+
ws.ws2811_channel_t_invert_set(channel, 0)
54+
ws.ws2811_channel_t_brightness_set(channel, 0)
55+
56+
channel = ws.ws2811_channel_get(leds, LED_CHANNEL)
57+
58+
ws.ws2811_channel_t_count_set(channel, LED_COUNT)
59+
ws.ws2811_channel_t_gpionum_set(channel, LED_GPIO)
60+
ws.ws2811_channel_t_invert_set(channel, LED_INVERT)
61+
ws.ws2811_channel_t_brightness_set(channel, LED_BRIGHTNESS)
62+
ws.ws2811_channel_t_strip_type_set(channel, LED_STRIP)
63+
64+
ws.ws2811_t_freq_set(leds, LED_FREQ_HZ)
65+
ws.ws2811_t_dmanum_set(leds, LED_DMA_NUM)
66+
67+
# Initialize library with LED configuration.
68+
resp = ws.ws2811_init(leds)
69+
if resp != ws.WS2811_SUCCESS:
70+
message = ws.ws2811_get_return_t_str(resp)
71+
raise RuntimeError('ws2811_init failed with code {0} ({1})'.format(resp, message))
72+
73+
# Wrap following code in a try/finally to ensure cleanup functions are called
74+
# after library is initialized.
75+
try:
76+
offset = 0
77+
while True:
78+
# Update each LED color in the buffer.
79+
for i in range(LED_COUNT):
80+
# Pick a color based on LED position and an offset for animation.
81+
color = DOT_COLORS[(i + offset) % len(DOT_COLORS)]
82+
83+
# Set the LED color buffer value.
84+
ws.ws2811_led_set(channel, i, color)
85+
86+
# Send the LED color data to the hardware.
87+
resp = ws.ws2811_render(leds)
88+
if resp != ws.WS2811_SUCCESS:
89+
message = ws.ws2811_get_return_t_str(resp)
90+
raise RuntimeError('ws2811_render failed with code {0} ({1})'.format(resp, message))
91+
92+
# Delay for a small period of time.
93+
time.sleep(0.25)
94+
95+
# Increase offset to animate colors moving. Will eventually overflow, which
96+
# is fine.
97+
offset += 1
98+
99+
finally:
100+
# Ensure ws2811_fini is called before the program quits.
101+
ws.ws2811_fini(leds)
102+
# Example of calling delete function to clean up structure memory. Isn't
103+
# strictly necessary at the end of the program execution here, but is good practice.
104+
ws.delete_ws2811_t(leds)

examples/SK6812_strandtest.py

Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
# NeoPixel library strandtest example
2+
# Author: Tony DiCola ([email protected])
3+
#
4+
# Direct port of the Arduino NeoPixel library strandtest example. Showcases
5+
# various animations on a strip of NeoPixels.
6+
import time
7+
8+
from neopixel import *
9+
10+
11+
# LED strip configuration:
12+
LED_COUNT = 40 # Number of LED pixels.
13+
LED_PIN = 18 # GPIO pin connected to the pixels (must support PWM!).
14+
LED_FREQ_HZ = 800000 # LED signal frequency in hertz (usually 800khz)
15+
LED_DMA = 10 # DMA channel to use for generating signal (try 10)
16+
LED_BRIGHTNESS = 255 # Set to 0 for darkest and 255 for brightest
17+
LED_INVERT = False # True to invert the signal (when using NPN transistor level shift)
18+
LED_CHANNEL = 0
19+
LED_STRIP = ws.SK6812_STRIP_RGBW
20+
#LED_STRIP = ws.SK6812W_STRIP
21+
22+
23+
# Define functions which animate LEDs in various ways.
24+
def colorWipe(strip, color, wait_ms=50):
25+
"""Wipe color across display a pixel at a time."""
26+
for i in range(strip.numPixels()):
27+
strip.setPixelColor(i, color)
28+
strip.show()
29+
time.sleep(wait_ms/1000.0)
30+
31+
def theaterChase(strip, color, wait_ms=50, iterations=10):
32+
"""Movie theater light style chaser animation."""
33+
for j in range(iterations):
34+
for q in range(3):
35+
for i in range(0, strip.numPixels(), 3):
36+
strip.setPixelColor(i+q, color)
37+
strip.show()
38+
time.sleep(wait_ms/1000.0)
39+
for i in range(0, strip.numPixels(), 3):
40+
strip.setPixelColor(i+q, 0)
41+
42+
def wheel(pos):
43+
"""Generate rainbow colors across 0-255 positions."""
44+
if pos < 85:
45+
return Color(pos * 3, 255 - pos * 3, 0)
46+
elif pos < 170:
47+
pos -= 85
48+
return Color(255 - pos * 3, 0, pos * 3)
49+
else:
50+
pos -= 170
51+
return Color(0, pos * 3, 255 - pos * 3)
52+
53+
def rainbow(strip, wait_ms=20, iterations=1):
54+
"""Draw rainbow that fades across all pixels at once."""
55+
for j in range(256*iterations):
56+
for i in range(strip.numPixels()):
57+
strip.setPixelColor(i, wheel((i+j) & 255))
58+
strip.show()
59+
time.sleep(wait_ms/1000.0)
60+
61+
def rainbowCycle(strip, wait_ms=20, iterations=5):
62+
"""Draw rainbow that uniformly distributes itself across all pixels."""
63+
for j in range(256*iterations):
64+
for i in range(strip.numPixels()):
65+
strip.setPixelColor(i, wheel(((i * 256 // strip.numPixels()) + j) & 255))
66+
strip.show()
67+
time.sleep(wait_ms/1000.0)
68+
69+
def theaterChaseRainbow(strip, wait_ms=50):
70+
"""Rainbow movie theater light style chaser animation."""
71+
for j in range(256):
72+
for q in range(3):
73+
for i in range(0, strip.numPixels(), 3):
74+
strip.setPixelColor(i+q, wheel((i+j) % 255))
75+
strip.show()
76+
time.sleep(wait_ms/1000.0)
77+
for i in range(0, strip.numPixels(), 3):
78+
strip.setPixelColor(i+q, 0)
79+
80+
81+
# Main program logic follows:
82+
if __name__ == '__main__':
83+
# Create NeoPixel object with appropriate configuration.
84+
strip = Adafruit_NeoPixel(LED_COUNT, LED_PIN, LED_FREQ_HZ, LED_DMA, LED_INVERT, LED_BRIGHTNESS, LED_CHANNEL, LED_STRIP)
85+
# Intialize the library (must be called once before other functions).
86+
strip.begin()
87+
88+
print ('Press Ctrl-C to quit.')
89+
while True:
90+
# Color wipe animations.
91+
colorWipe(strip, Color(255, 0, 0)) # Red wipe
92+
colorWipe(strip, Color(0, 255, 0)) # Blue wipe
93+
colorWipe(strip, Color(0, 0, 255)) # Green wipe
94+
colorWipe(strip, Color(0, 0, 0, 255)) # White wipe
95+
colorWipe(strip, Color(255, 255, 255)) # Composite White wipe
96+
colorWipe(strip, Color(255, 255, 255, 255)) # Composite White + White LED wipe
97+
# Theater chase animations.
98+
theaterChase(strip, Color(127, 0, 0)) # Red theater chase
99+
theaterChase(strip, Color(0, 127, 0)) # Green theater chase
100+
theaterChase(strip, Color(0, 0, 127)) # Blue theater chase
101+
theaterChase(strip, Color(0, 0, 0, 127)) # White theater chase
102+
theaterChase(strip, Color(127, 127, 127, 0)) # Composite White theater chase
103+
theaterChase(strip, Color(127, 127, 127, 127)) # Composite White + White theater chase
104+
# Rainbow animations.
105+
rainbow(strip)
106+
rainbowCycle(strip)
107+
theaterChaseRainbow(strip)

examples/SK6812_white_test.py

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
# NeoPixel library strandtest example
2+
# Author: Tony DiCola ([email protected])
3+
#
4+
# Direct port of the Arduino NeoPixel library strandtest example. Showcases
5+
# various animations on a strip of NeoPixels.
6+
import time
7+
8+
from neopixel import *
9+
10+
# LED strip configuration:
11+
LED_COUNT = 30 # Number of LED pixels.
12+
LED_PIN = 18 # GPIO pin connected to the pixels (must support PWM!).
13+
LED_FREQ_HZ = 800000 # LED signal frequency in hertz (usually 800khz)
14+
LED_DMA = 10 # DMA channel to use for generating signal (try 10)
15+
LED_BRIGHTNESS = 255 # Set to 0 for darkest and 255 for brightest
16+
LED_INVERT = False # True to invert the signal (when using NPN transistor level shift)
17+
LED_CHANNEL = 0
18+
#LED_STRIP = ws.SK6812_STRIP_RGBW
19+
LED_STRIP = ws.SK6812W_STRIP
20+
21+
22+
# Define functions which animate LEDs in various ways.
23+
def colorWipe(strip, color, wait_ms=50):
24+
"""Wipe color across display a pixel at a time."""
25+
for i in range(strip.numPixels()):
26+
strip.setPixelColor(i, color)
27+
strip.show()
28+
time.sleep(wait_ms/1000.0)
29+
30+
31+
# Main program logic follows:
32+
if __name__ == '__main__':
33+
# Create NeoPixel object with appropriate configuration.
34+
strip = Adafruit_NeoPixel(LED_COUNT, LED_PIN, LED_FREQ_HZ, LED_DMA, LED_INVERT, LED_BRIGHTNESS, LED_CHANNEL, LED_STRIP)
35+
# Intialize the library (must be called once before other functions).
36+
strip.begin()
37+
38+
print ('Press Ctrl-C to quit.')
39+
while True:
40+
# Color wipe animations.
41+
colorWipe(strip, Color(255, 0, 0), 0) # Red wipe
42+
time.sleep(2)
43+
colorWipe(strip, Color(0, 255, 0), 0) # Blue wipe
44+
time.sleep(2)
45+
colorWipe(strip, Color(0, 0, 255), 0) # Green wipe
46+
time.sleep(2)
47+
colorWipe(strip, Color(0, 0, 0, 255), 0) # White wipe
48+
time.sleep(2)
49+
colorWipe(strip, Color(255, 255, 255), 0) # Composite White wipe
50+
time.sleep(2)
51+
colorWipe(strip, Color(255, 255, 255, 255), 0) # Composite White + White LED wipe
52+
time.sleep(2)

examples/lowlevel.py

Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
# Example of low-level Python wrapper for rpi_ws281x library.
2+
# Author: Tony DiCola ([email protected]), Jeremy Garff ([email protected])
3+
#
4+
# This is an example of how to use the SWIG-generated _rpi_ws281x module.
5+
# You probably don't want to use this unless you are building your own library,
6+
# because the SWIG generated module is clunky and verbose. Instead look at the
7+
# high level Python port of Adafruit's NeoPixel Arduino library in strandtest.py.
8+
#
9+
# This code will animate a number of WS281x LEDs displaying rainbow colors.
10+
import time
11+
12+
import _rpi_ws281x as ws
13+
14+
# LED configuration.
15+
LED_CHANNEL = 0
16+
LED_COUNT = 16 # How many LEDs to light.
17+
LED_FREQ_HZ = 800000 # Frequency of the LED signal. Should be 800khz or 400khz.
18+
LED_DMA_NUM = 10 # DMA channel to use, can be 0-14.
19+
LED_GPIO = 18 # GPIO connected to the LED signal line. Must support PWM!
20+
LED_BRIGHTNESS = 255 # Set to 0 for darkest and 255 for brightest
21+
LED_INVERT = 0 # Set to 1 to invert the LED signal, good if using NPN
22+
# transistor as a 3.3V->5V level converter. Keep at 0
23+
# for a normal/non-inverted signal.
24+
25+
# Define colors which will be used by the example. Each color is an unsigned
26+
# 32-bit value where the lower 24 bits define the red, green, blue data (each
27+
# being 8 bits long).
28+
DOT_COLORS = [ 0x200000, # red
29+
0x201000, # orange
30+
0x202000, # yellow
31+
0x002000, # green
32+
0x002020, # lightblue
33+
0x000020, # blue
34+
0x100010, # purple
35+
0x200010 ] # pink
36+
37+
38+
# Create a ws2811_t structure from the LED configuration.
39+
# Note that this structure will be created on the heap so you need to be careful
40+
# that you delete its memory by calling delete_ws2811_t when it's not needed.
41+
leds = ws.new_ws2811_t()
42+
43+
# Initialize all channels to off
44+
for channum in range(2):
45+
channel = ws.ws2811_channel_get(leds, channum)
46+
ws.ws2811_channel_t_count_set(channel, 0)
47+
ws.ws2811_channel_t_gpionum_set(channel, 0)
48+
ws.ws2811_channel_t_invert_set(channel, 0)
49+
ws.ws2811_channel_t_brightness_set(channel, 0)
50+
51+
channel = ws.ws2811_channel_get(leds, LED_CHANNEL)
52+
53+
ws.ws2811_channel_t_count_set(channel, LED_COUNT)
54+
ws.ws2811_channel_t_gpionum_set(channel, LED_GPIO)
55+
ws.ws2811_channel_t_invert_set(channel, LED_INVERT)
56+
ws.ws2811_channel_t_brightness_set(channel, LED_BRIGHTNESS)
57+
58+
ws.ws2811_t_freq_set(leds, LED_FREQ_HZ)
59+
ws.ws2811_t_dmanum_set(leds, LED_DMA_NUM)
60+
61+
# Initialize library with LED configuration.
62+
resp = ws.ws2811_init(leds)
63+
if resp != ws.WS2811_SUCCESS:
64+
message = ws.ws2811_get_return_t_str(resp)
65+
raise RuntimeError('ws2811_init failed with code {0} ({1})'.format(resp, message))
66+
67+
# Wrap following code in a try/finally to ensure cleanup functions are called
68+
# after library is initialized.
69+
try:
70+
offset = 0
71+
while True:
72+
# Update each LED color in the buffer.
73+
for i in range(LED_COUNT):
74+
# Pick a color based on LED position and an offset for animation.
75+
color = DOT_COLORS[(i + offset) % len(DOT_COLORS)]
76+
77+
# Set the LED color buffer value.
78+
ws.ws2811_led_set(channel, i, color)
79+
80+
# Send the LED color data to the hardware.
81+
resp = ws.ws2811_render(leds)
82+
if resp != ws.WS2811_SUCCESS:
83+
message = ws.ws2811_get_return_t_str(resp)
84+
raise RuntimeError('ws2811_render failed with code {0} ({1})'.format(resp, message))
85+
86+
# Delay for a small period of time.
87+
time.sleep(0.25)
88+
89+
# Increase offset to animate colors moving. Will eventually overflow, which
90+
# is fine.
91+
offset += 1
92+
93+
finally:
94+
# Ensure ws2811_fini is called before the program quits.
95+
ws.ws2811_fini(leds)
96+
# Example of calling delete function to clean up structure memory. Isn't
97+
# strictly necessary at the end of the program execution here, but is good practice.
98+
ws.delete_ws2811_t(leds)

0 commit comments

Comments
 (0)