adafruit / Adafruit_CircuitPython_NeoPixel

CircuitPython drivers for neopixels.
MIT License
302 stars 98 forks source link

not support more than 30 LEDs bug #151

Closed xgqfrms closed 1 year ago

xgqfrms commented 1 year ago

not support more than 30 LEDs bug

Why are many LEDs not lit?

image

environment

Raspberry Pi 3B, BCM GPIO 18 PIN

5V/2.5A unofficial power supply (⚠️ There may be a low voltage error)

Python 3.9.2

one WS2812B RGB LED strip of 1M long with 60 LEDs

packages

$ sudo pip3 install rpi_ws281x

$ sudo pip3 install adafruit-circuitpython-neopixel

$ sudo pip3 install --force-reinstall adafruit-blinka
# equal to
$ sudo python3 -m pip install --force-reinstall adafruit-blinka

codes

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

import board
import neopixel
from time import sleep

# 60 LEDs
pixels = neopixel.NeoPixel(board.D18, 60)
while True:
  for x in range(0, 60):
    pixels[x] = (255, 0, 0)
    sleep(0.1)

"""
$ chmod +x ./led-strip.py
# ❌ Can't open /dev/mem: Permission denied
# $ ./led-strip.py

# ✅
$ sudo ./led-strip.py
"""
FoamyGuy commented 1 year ago

I don't have an answer for certain, but a few questions and observations that may be related:

xgqfrms commented 1 year ago

@FoamyGuy Thanks for your time!

AC to DC, 5V/2.5A Power Supply (Micro USB)

  1. just use the Raspberry Pi 3B 5V GPIO PIN
  2. I didn't configure the brightness level for it. (the brightness level should be the default value)

I will try your suggestions later.

how to clear the WS2812B's buffer data?

buffer cache error?

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

import board
import neopixel
from time import sleep

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

def clear_buffer():
  for x in range(0, 60):
    pixels[x] = (0, 0, 0)
xgqfrms commented 1 year ago

update 2023.06.01

60 LEDs with 255 brightness level need to add an external Power Supply.

5V/4A power.

image

image

But the test result is not expected

image

The test code is as follows, why doesn't every LED light up red?

#!/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)
    print("pixels[x] =", x, pixels[x])

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

try:
  red_led_strip()
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 ./led-strip.py
# ❌ Can't open /dev/mem: Permission denied
# $ ./led-strip.py

# ✅
$ sudo ./led-strip.py
"""

image

xgqfrms commented 1 year ago

wiring diagram

image

FoamyGuy commented 1 year ago

@xgqfrms A few words of caution before anything else:

As for the different colors on your strip: What happens if you try setting the bpp value to 4 when you initialize the strip: https://github.com/adafruit/Adafruit_CircuitPython_NeoPixel/blob/main/neopixel.py#L110 like this:

pixels = neopixel.NeoPixel(board.D18, 60, bpp=4)
xgqfrms commented 1 year ago

@FoamyGuy Thanks for your reminder.

That's a 220V to 5V power converter, so this should be safe.

input AC: 220V (+15%/-15%) output DC: 5V/4A

image

https://item.taobao.com/item.htm?id=560000671481

After adding the bpp=4 in the code, the result is still the same.

:param int bpp: Bytes per pixel. 3 for RGB and 4 for RGBW pixels.

https://github.com/adafruit/Adafruit_CircuitPython_NeoPixel/blob/main/neopixel.py#LL52C5-L52C70

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

import board
import neopixel
from time import sleep

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

def red_led_strip():
  for x in range(0, 60):
    pixels[x] = (255, 0, 0)
    sleep(0.1)
    # print("pixels[x] =", x, pixels[x])
    print("pixels[{}] =".format(x), x, pixels[x])

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

try:
  red_led_strip()
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 ./led-strip.py
# ❌ Can't open /dev/mem: Permission denied
# $ ./led-strip.py

# ✅
$ sudo ./led-strip.py
"""
FoamyGuy commented 1 year ago

I meant that the way the wires are connected leaves them exposed so a person could accidentally touch them. Ideally that should be secured more so it's not possible to accidentally touch the live wires.

What happens if you try like this:

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

# then down inside of your loop:

    pixels[x] = (255, 0, 0, 0)  # <- add the fourth item in the tuple for the White in RGBW.
xgqfrms commented 1 year ago

These are the details of my RGB LED strip, it's not an RGBW LED strip.

Brand: BTF-LIGHTING WS2812B RGB LED Strip 5050 SMD RGB LED IC: built-in Color: RGB Power: 0.3V/LED 60 LEDs/1M

image

https://detail.tmall.com/item.htm?id=672774081874

The official distribution wiring diagram of BTF-LIGHTING WS2812B LED Pixel Strip

image

https://www.btf-lighting.com/collections/ws2812b-5v/products/ws2812b-led-pixel-strip-30-60-74-96-100-144-pixels-leds-m

the WS2812B manual

https://cdn-shop.adafruit.com/datasheets/WS2812B.pdf

FoamyGuy commented 1 year ago

Sorry, I don't really have any other ideas about what could be causing it to put different colors than the ones the code is setting.

if you use pixels.fill((255, 0, 0)) instead of looping and setting each pixel one at a time. Or if you use hex instead of tuples does it make any difference? like pixels.fill(0xff0000) I wouldn't expect either to change the behavior, but I'm out of any other ideas for troubleshooting.

xgqfrms commented 1 year ago

@FoamyGuy Anyway, Thanks a lot.

init NeoPixel with all params, result still the same.

The LED channel is GRB,

  1. GRB

pixels = neopixel.NeoPixel(board.D18, 60, bpp=3, brightness=1.0, auto_write=True, pixel_order=neopixel.GRB)

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

import board
import neopixel
from time import sleep

print("pixel_order =", neopixel.GRB)
# 60 LEDs
pixels = neopixel.NeoPixel(board.D18, 60, bpp=3, brightness=1.0, auto_write=True, pixel_order=neopixel.GRB)

print("pixels =", pixels)

def red_led_strip():
  for x in range(0, 60):
    pixels[x] = (255, 0, 0)
    sleep(0.1)
    # print("pixels[x] =", x, pixels[x])
    print("pixels[{}] =".format(x), x, pixels[x])

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

try:
  red_led_strip()
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 ./led-strip.py
# ❌ Can't open /dev/mem: Permission denied
# $ ./led-strip.py

# ✅
$ sudo ./led-strip.py
"""
  1. GRBW

pixels = neopixel.NeoPixel(board.D18, 60, bpp=4, brightness=1.0, auto_write=True, pixel_order=neopixel.GRBW)

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

import board
import neopixel
from time import sleep

print("pixel_order =", neopixel.GRBW)
# 60 LEDs
pixels = neopixel.NeoPixel(board.D18, 60, bpp=4, brightness=1.0, auto_write=True, pixel_order=neopixel.GRBW)
print("pixels =", pixels)

def red_led_strip():
  for x in range(0, 60):
    pixels[x] = (255, 0, 0, 0)
    sleep(0.1)
    # print("pixels[x] =", x, pixels[x])
    print("pixels[{}] =".format(x), x, pixels[x])

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

try:
  red_led_strip()
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 ./led-strip.py
# ❌ Can't open /dev/mem: Permission denied
# $ ./led-strip.py

# ✅
$ sudo ./led-strip.py
"""
xgqfrms commented 1 year ago

Buy a new LED strip❓

After trying many times, I still can't fix it.

Maybe it's a LED strip bug, who knows?

Its channel is RBG ???

def grb_test():
  pixels[0] = (255, 0, 0)
  print("pixels[0] =", pixels[0])
  pixels[1] = (0, 255, 0)
  print("pixels[1] =", pixels[1])
  pixels[2] = (0, 0, 255)
  print("pixels[2] =", pixels[2])
  sleep(3.0)

image

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

import board
import neopixel
from time import sleep

print("pixel_order =", neopixel.GRB)
# 60 LEDs
pixels = neopixel.NeoPixel(board.D18, 60, bpp=3, brightness=1.0, auto_write=True, pixel_order=neopixel.GRB)
# print("pixels =", pixels)

# LED Strip bug ❌ `RBG` !== `neopixel.GRB` ❓

def grb_test():
  # Red ❌ (Green ✅)
  pixels[0] = (255, 0, 0)
  print("pixels[0] =", pixels[0])
  # Blue ❌ (Red ✅)
  pixels[1] = (0, 255, 0)
  print("pixels[1] =", pixels[1])
  # Green ❌ (Blue ✅)
  pixels[2] = (0, 0, 255)
  print("pixels[2] =", pixels[2])
  sleep(3.0)

def clear_buffer():
  print("clear buffer")
  for x in range(0, 60):
    pixels[x] = (0, 0, 0)
  sleep(1)

clear_buffer()

try:
  grb_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)
  # cleanup
  clear_buffer()
  print('clear 🚀')
dhalbert commented 1 year ago

@xgqfrms Did you fix it, or did you give up?

xgqfrms commented 1 year ago

2023.06.12 update

It's not a bug of the neopixel.

#!/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)
    # print("pixels[x] =", x, pixels[x])
    print("pixels[{}] =".format(x), x, pixels[x])

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

try:
  red_led_strip()
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 ./led-strip.py
# ❌ Can't open /dev/mem: Permission denied
# $ ./led-strip.py

# ✅
$ sudo ./led-strip.py
"""

image

The BTF-LIGHTING brand is a great product ✅

This is an excellent product 🚀, I recommend buying it!

image

https://item.taobao.com/item.htm?id=522197656009

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
xgqfrms commented 1 year ago

RGB version

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

#!/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 ./led-strip.py
# ❌ Can't open /dev/mem: Permission denied
# $ ./led-strip.py

# ✅
$ sudo ./led-strip.py
"""
MasudRana72 commented 1 year ago

So, RPI 3B is the problem? Do you fix the issue for 3B?

xgqfrms commented 1 year ago

@MasudRana72 You can try it with the following hardware.

Raspberry Pi 3B + 12.5W official power supply ❓(I don't have this one power supply for now.)

$ vcgencmd get_throttled

Raspberry Pi 12.5W Micro USB Power Supply

https://www.raspberrypi.com/products/micro-usb-power-supply/

https://datasheets.raspberrypi.com/power-supply/micro-usb-power-supply-product-brief.pdf

MasudRana72 commented 1 year ago

ok, at last the problem solved here for my RPI 3 b. I commented the line #dtparam=audio=on in /boot/config.txt file.

it gives throttled=0x50000. and works in undervoltage also. Posting it might help someone. check this link(Pi 3B user): https://tutorials-raspberrypi.com/connect-control-raspberry-pi-ws2812-rgb-led-strips/

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