rpi-ws281x / rpi-ws281x-python

Python library wrapping for the rpi-ws281x library
BSD 2-Clause "Simplified" License
323 stars 103 forks source link

Where can I find the API for the rpi-ws281x-python library? #95

Closed xgqfrms closed 1 year ago

xgqfrms commented 1 year ago

Where can I find the API for the rpi-ws281x-python library?

need to read the source code?

https://github.com/rpi-ws281x/rpi-ws281x-python/blob/master/library/rpi_ws281x/rpi_ws281x.py#L102

xgqfrms commented 1 year ago

The below code makes the 60 LEDs light white color. ✅

#!/usr/bin/env python3
# coding: utf8

from time import sleep
from rpi_ws281x import PixelStrip, Color

# LED strip configuration:
LED_COUNT = 60        # Number of LED pixels.
LED_PIN = 18          # GPIO pin connected to the pixels (18 uses PWM!).
# LED_PIN = 10        # GPIO pin connected to the pixels (10 uses SPI /dev/spidev0.0).
LED_FREQ_HZ = 800000  # LED signal frequency in hertz (usually 800khz)
LED_DMA = 10          # DMA channel to use for generating signal (try 10)
LED_BRIGHTNESS = 20   # Set to 0 for darkest and 255 for brightest
LED_INVERT = True     # True to invert the signal (when using NPN transistor level shift)
LED_CHANNEL = 0       # set to '1' for GPIOs 13, 19, 41, 45 or 53

# Create NeoPixel object with appropriate configuration.
strip = PixelStrip(LED_COUNT, LED_PIN, LED_FREQ_HZ, LED_DMA, LED_INVERT, LED_BRIGHTNESS, LED_CHANNEL)

# Intialize the library (must be called once before other functions).
strip.begin()
print("Test ✅")

# clear
for i in range(strip.numPixels()):
    strip.setPixelColor(i, Color(0, 0, 0))
strip.show()
sleep(1)

# Switch all pixels on
for i in range(strip.numPixels()):
    # here work as expect ✅
    strip.setPixelColor(i, Color(255, 255, 255))
strip.show()

print("Test finished 🎉")
exit()

image

But after running once the above code, the below code did not change the LED's lighting result anymore. ❌

All 60 LED colors remain white color.

So, what's wrong with this?

#!/usr/bin/env python3
# coding: utf8

from time import sleep
from rpi_ws281x import PixelStrip, Color

# LED strip configuration:
LED_COUNT = 60        # Number of LED pixels.
LED_PIN = 18          # GPIO pin connected to the pixels (18 uses PWM!).
# LED_PIN = 10        # GPIO pin connected to the pixels (10 uses SPI /dev/spidev0.0).
LED_FREQ_HZ = 800000  # LED signal frequency in hertz (usually 800khz)
LED_DMA = 10          # DMA channel to use for generating signal (try 10)
LED_BRIGHTNESS = 20   # Set to 0 for darkest and 255 for brightest
LED_INVERT = True     # True to invert the signal (when using NPN transistor level shift)
LED_CHANNEL = 0       # set to '1' for GPIOs 13, 19, 41, 45 or 53

# Create NeoPixel object with appropriate configuration.
strip = PixelStrip(LED_COUNT, LED_PIN, LED_FREQ_HZ, LED_DMA, LED_INVERT, LED_BRIGHTNESS, LED_CHANNEL)

# Intialize the library (must be called once before other functions).
strip.begin()
print("Test ✅")

# clear
for i in range(strip.numPixels()):
    strip.setPixelColor(i, Color(0, 0, 0))
strip.show()
sleep(1)

# Switch all pixels on
for i in range(strip.numPixels()):
    # here not work as expect ❌
    strip.setPixelColor(i, Color(255, 0, 0))
strip.show()

print("Test finished 🎉")
exit()
Gadgetoid commented 1 year ago

You pretty much need to read the source. I don't have much time to maintain or support this library, and driving ws281x pixels from the Pi has always been a crapshoot.

Solid white is a really bad colour to use for testing, it's likely that your initial code doesn't work properly and the result just happens to correlate with what you're trying to accomplish. Use a logical test pattern like repeating Red/Green/Blue.

Also LED_INVERT should probably be False in your case, I don't see any inline transistor in your setup.

xgqfrms commented 1 year ago

After changing to LED_INVERT = False, the result is still not as expected.

image

#!/usr/bin/env python3
# coding: utf8

from time import sleep
from rpi_ws281x import PixelStrip, Color

# LED strip configuration:
LED_COUNT = 60        # Number of LED pixels.
LED_PIN = 18          # GPIO pin connected to the pixels (18 uses PWM!).
# LED_PIN = 10        # GPIO pin connected to the pixels (10 uses SPI /dev/spidev0.0).
LED_FREQ_HZ = 800000  # LED signal frequency in hertz (usually 800khz)
LED_DMA = 10          # DMA channel to use for generating a signal (try 10)
# color channel GRB ❓
LED_BRIGHTNESS = 50   # Set to 0 for darkest and 255 for brightest
LED_INVERT = False     # True to invert the signal (when using NPN transistor level shift)
LED_CHANNEL = 0       # set to '1' for GPIOs 13, 19, 41, 45 or 53

# Create a NeoPixel object with the appropriate configuration.
strip = PixelStrip(LED_COUNT, LED_PIN, LED_FREQ_HZ, LED_DMA, LED_INVERT, LED_BRIGHTNESS, LED_CHANNEL)

# Initialize the library (must be called once before other functions).
strip.begin()
print("Test beginning ✅")

def clear_buffer():
  for i in range(LED_COUNT):
    strip.setPixelColor(i, Color(0, 0, 0))
  strip.show()
  sleep(1)

def test():
  print("strip.numPixels() =", strip.numPixels())
  for i in range(strip.numPixels()):
    # white ✅
    # strip.setPixelColor(i, Color(255, 255, 255))
    # red ❌
    strip.setPixelColor(i, Color(255, 0, 0))
  strip.show()
  sleep(1)

try:
  test()
except KeyboardInterrupt:
  print('Ctrl + C exit ✅')
except RuntimeError as error:
  print("error =", error, error.args[0])
  pass
except Exception as error:
  print("exception =", error)
  raise error
finally:
  print("after three seconds, auto clear buffer! 👻")
  sleep(3.0)
  clear_buffer()
  print("Test finished 🎉")

exit()
xgqfrms commented 1 year ago

GitHub generate API

image

https://github.com/rpi-ws281x/rpi-ws281x-python/blob/master/library/rpi_ws281x/rpi_ws281x.py

xgqfrms commented 1 year ago

solution ✅

Raspberry Pi 4B 8GB + official Power Supply (5V/3A)

Raspberry Pi 15W USB-C Power Supply

https://www.raspberrypi.com/products/type-c-power-supply/

#!/usr/bin/env python3
# coding: utf8

from time import sleep
from rpi_ws281x import PixelStrip, Color

# LED strip configuration:
LED_COUNT = 60        # Number of LED pixels.
LED_PIN = 18          # GPIO pin connected to the pixels (18 uses PWM!).
# LED_PIN = 10        # GPIO pin connected to the pixels (10 uses SPI /dev/spidev0.0).
LED_FREQ_HZ = 800000  # LED signal frequency in hertz (usually 800khz)
LED_DMA = 10          # DMA channel to use for generating a signal (try 10)
# LED_BRIGHTNESS = 50   # Set to 0 for darkest and 255 for brightest
LED_BRIGHTNESS = 255   # Set to 0 for darkest and 255 for brightest
LED_INVERT = False     # True to invert the signal (when using NPN transistor level shift)
LED_CHANNEL = 0       # set to '1' for GPIOs 13, 19, 41, 45 or 53

# Create a NeoPixel object with the appropriate configuration.
strip = PixelStrip(LED_COUNT, LED_PIN, LED_FREQ_HZ, LED_DMA, LED_INVERT, LED_BRIGHTNESS, LED_CHANNEL)

# Initialize the library (must be called once before other functions).
strip.begin()
print("Test beginning ✅")

def clear_buffer():
  for i in range(LED_COUNT):
    strip.setPixelColor(i, Color(0, 0, 0))
  strip.show()
  sleep(1.0)

def rgb_test():
  # print("strip.numPixels() =", strip.numPixels())
  while True:
    for i in range(strip.numPixels()):
      # red led ✅
      strip.setPixelColor(i, Color(255, 0, 0))
      strip.show()
      sleep(0.1)
    sleep(1.0)
    for i in range(strip.numPixels()):
      # green led ✅
      strip.setPixelColor(i, Color(0, 255, 0))
      strip.show()
      sleep(0.1)
    sleep(1.0)
    for i in range(strip.numPixels()):
      # blue led ✅
      strip.setPixelColor(i, Color(0, 0, 255))
      strip.show()
      sleep(0.1)
    sleep(1.0)

try:
  rgb_test()
except KeyboardInterrupt:
  print('Ctrl + C exit ✅')
  clear_buffer()
except RuntimeError as error:
  print("error =", error, error.args[0])
  clear_buffer()
  pass
except Exception as error:
  print("exception =", error)
  clear_buffer()
  raise error

demo

https://www.youtube.com/watch?v=By0FcsZxn6g

xgqfrms commented 1 year ago

Hardware change

Raspberry Pi 3B 1GB => Raspberry Pi 4B 8GB

Raspberry Pi 4B + 15W official power supply ✅

$ vcgencmd get_throttled
throttled=0x0

Raspberry Pi 3B + 5V/2.5A unofficial power supply ❌

$ vcgencmd get_throttled
throttled=0x50000
MasudRana72 commented 1 year ago

https://github.com/adafruit/Adafruit_CircuitPython_NeoPixel/issues/151#:~:text=So%2C%20RPI%203B%20is%20the%20problem%3F%0ADo%20you%20fix%20the%20issue%20for%203B%3F

xgqfrms commented 1 year ago

https://github.com/adafruit/Adafruit_CircuitPython_NeoPixel/issues/151#issuecomment-1597369750

xgqfrms commented 1 year ago

final solution ✅

https://www.youtube.com/watch?v=4fF5joeQ2dY

$ vcgencmd get_throttled
throttled=0x0

disable audio snd_bcm2835

$ sudo vim /boot/config.txt

$ sudo cat /boot/config.txt

# Enable audio (loads snd_bcm2835)
# ✅ fix: https://github.com/adafruit/Adafruit_CircuitPython_NeoPixel/issues/151
# dtparam=audio=on
$ sudo reboot

$ sudo ./neopixel-strip-rgb.py
# OR
$ sudo ./pixel-strip-rgb.py
$ cat ./neopixel-strip-rgb.py
#!/usr/bin/env python3
# coding: utf8

import board
import neopixel
from time import sleep

# 60 LEDs
pixels = neopixel.NeoPixel(board.D18, 60)

def red_led_strip():
  for x in range(0, 60):
    pixels[x] = (255, 0, 0)
    sleep(0.1)
def green_led_strip():
  for x in range(0, 60):
    pixels[x] = (0, 255, 0)
    sleep(0.1)
def blue_led_strip():
  for x in range(0, 60):
    pixels[x] = (0, 0, 255)
    sleep(0.1)

def clear_buffer():
  for x in range(0, 60):
    pixels[x] = (0, 0, 0)

try:
  red_led_strip()
  sleep(1.0)
  green_led_strip()
  sleep(1.0)
  blue_led_strip()
  sleep(1.0)
except KeyboardInterrupt:
  print('Ctrl + C exit ✅')
except RuntimeError as error:
  print("error =", error, error.args[0])
  pass
except Exception as error:
  print("exception =", error)
  raise error
finally:
  print("after three seconds, auto clear buffer! 👻")
  sleep(3.0)
  # cleanup
  clear_buffer()
  print('clear 🚀')

"""
$ chmod +x ./neopixel-strip-rgb.
# ✅
$ sudo ./neopixel-strip-rgb.
"""
$ cat pixel-strip-rgb.py
#!/usr/bin/env python3
# coding: utf8

from time import sleep
from rpi_ws281x import PixelStrip, Color

# LED strip configuration:
LED_COUNT = 60        # Number of LED pixels.
LED_PIN = 18          # GPIO pin connected to the pixels (18 uses PWM!).
# LED_PIN = 10        # GPIO pin connected to the pixels (10 uses SPI /dev/spidev0.0).
LED_FREQ_HZ = 800000  # LED signal frequency in hertz (usually 800khz)
LED_DMA = 10          # DMA channel to use for generating a signal (try 10)
# LED_BRIGHTNESS = 255   # Set to 0 for darkest and 255 for brightest
LED_BRIGHTNESS = 51   # Set to 0 for darkest and 255 for brightest
LED_INVERT = False     # True to invert the signal (when using NPN transistor level shift)
LED_CHANNEL = 0       # set to '1' for GPIOs 13, 19, 41, 45 or 53

# Create a NeoPixel object with the appropriate configuration.
strip = PixelStrip(LED_COUNT, LED_PIN, LED_FREQ_HZ, LED_DMA, LED_INVERT, LED_BRIGHTNESS, LED_CHANNEL)

# Initialize the library (must be called once before other functions).
strip.begin()
print("Test beginning ✅")

def clear_buffer():
  for i in range(LED_COUNT):
    strip.setPixelColor(i, Color(0, 0, 0))
  strip.show()
  sleep(1.0)

def rgb_test():
  # print("strip.numPixels() =", strip.numPixels())
  while True:
    for i in range(strip.numPixels()):
      # red led ✅
      strip.setPixelColor(i, Color(255, 0, 0))
      strip.show()
      sleep(0.1)
    sleep(1.0)
    for i in range(strip.numPixels()):
      # green led ✅
      strip.setPixelColor(i, Color(0, 255, 0))
      strip.show()
      sleep(0.1)
    sleep(1.0)
    for i in range(strip.numPixels()):
      # blue led ✅
      strip.setPixelColor(i, Color(0, 0, 255))
      strip.show()
      sleep(0.1)
    sleep(1.0)

try:
  rgb_test()
except KeyboardInterrupt:
  print('Ctrl + C exit ✅')
  clear_buffer()
  sleep(2.0)
except RuntimeError as error:
  print("error =", error, error.args[0])
  clear_buffer()
  pass
except Exception as error:
  print("exception =", error)
  clear_buffer()
  raise error
finally:
  print("clear buffer ✅")
  clear_buffer()
  sleep(3.0)
"""
$ sudo ./pixel-strip-rgb.py
"""

image