]> Repositories - hackapet/Adafruit_Blinka.git/blobdiff - src/adafruit_blinka/microcontroller/raspi_23/neopixel.py
add RGBW support
[hackapet/Adafruit_Blinka.git] / src / adafruit_blinka / microcontroller / raspi_23 / neopixel.py
index 6dab8dc9d1676ba2c5b8b31cb02db04d9d3f22f0..3d670c703ce2404ed9a099a980e244872997d7f2 100644 (file)
@@ -9,7 +9,7 @@ LED_FREQ_HZ    = 800000     # Frequency of the LED signal.  We only support 800K
 LED_DMA_NUM    = 10         # DMA channel to use, can be 0-14.
 LED_BRIGHTNESS = 255        # We manage the brightness in the neopixel library
 LED_INVERT     = 0          # We don't support inverted logic
-LED_STRIP      = ws.WS2811_STRIP_RGB # We manage the color order within the neopixel library
+LED_STRIP      = None # We manage the color order within the neopixel library
 
 # a 'static' object that we will use to manage our PWM DMA channel
 # we only support one LED strip per raspi
@@ -36,7 +36,18 @@ def neopixel_write(gpio, buf):
         channel = ws.ws2811_channel_get(_led_strip, LED_CHANNEL)
 
         # Initialize the channel in use
-        ws.ws2811_channel_t_count_set(channel, math.ceil(len(buf)/3)) # we manage 4 vs 3 bytes in the library
+        count = 0
+        if len(buf) % 3 == 0:            
+            # most common, divisible by 3 is likely RGB
+            LED_STRIP = ws.WS2811_STRIP_RGB
+            count = len(buf)//3
+        elif len(buf) % 4 == 0:
+            LED_STRIP = ws.SK6812_STRIP_RGBW
+            count = len(buf)//4
+        else:
+            raise RuntimeError("We only support 3 or 4 bytes-per-pixel")
+
+        ws.ws2811_channel_t_count_set(channel, count) # we manage 4 vs 3 bytes in the library
         ws.ws2811_channel_t_gpionum_set(channel, gpio._pin.id)
         ws.ws2811_channel_t_invert_set(channel, LED_INVERT)
         ws.ws2811_channel_t_brightness_set(channel, LED_BRIGHTNESS)
@@ -48,6 +59,8 @@ def neopixel_write(gpio, buf):
     
         resp = ws.ws2811_init(_led_strip)
         if resp != ws.WS2811_SUCCESS:
+            if resp == -5:
+                raise RuntimeError("NeoPixel support requires running with sudo, please try again!")
             message = ws.ws2811_get_return_t_str(resp)
             raise RuntimeError('ws2811_init failed with code {0} ({1})'.format(resp, message))
         atexit.register(neopixel_cleanup)
@@ -56,12 +69,20 @@ def neopixel_write(gpio, buf):
     if gpio._pin.id != ws.ws2811_channel_t_gpionum_get(channel):
         raise RuntimeError("Raspberry Pi neopixel support is for one strip only!")
 
+    if ws.ws2811_channel_t_strip_type_get(channel) == ws.WS2811_STRIP_RGB:
+        bpp = 3
+    else:
+        bpp = 4
     # assign all colors!
-    for i in range(len(buf) // 3):
-        r = buf[3*i]
-        g = buf[3*i+1]
-        b = buf[3*i+2]
-        pixel = (r << 16) | (g << 8) | b
+    for i in range(len(buf) // bpp):
+        r = buf[bpp*i]
+        g = buf[bpp*i+1]
+        b = buf[bpp*i+2]
+        if bpp == 3:
+            pixel = (r << 16) | (g << 8) | b
+        else:
+            w = buf[bpp*i+3]
+            pixel = (w << 24) | (r << 16) | (g << 8) | b
         ws.ws2811_led_set(channel, i, pixel)
     
     resp = ws.ws2811_render(_led_strip)