jgarff / rpi_ws281x

Userspace Raspberry Pi PWM library for WS281X LEDs
BSD 2-Clause "Simplified" License
1.78k stars 622 forks source link

use rpi_ws281x together with several PWM channels created by pigpio or wiringpi #419

Open dallen98 opened 3 years ago

dallen98 commented 3 years ago

I'm using rpi_ws281x (via python) in PWM mode on GPIO 18 and 19 and this works fine standalone. However I wish to know Using either wiringpi or pigpio if all or most of the GPIO pins can output the led signal (I'm using rpi_ws281x 4.2.2 on a Raspberry Pi 3B+ running Raspbian.)

Is this a known issue, or is there another way to use the rpi_ws281x library together with a PWM signal on the other channels?

alexwhittemore commented 3 years ago

I've been doing some extensive digging on a system trying to drive an LED with PWM on GPIO12, while simultaneously driving neopixels on GPIO13. I COULD NOT get this to work with wiringpi driving the PWM on 12. WiringPi driving PWM on 12 would poison the PWM system or something such that timing would be incorrect for neopixels on 13 until the Pi was rebooted.

I have finally realized that using RPi.GPIO to drive PWM on GPIO12 does not interfere with neopixel operation on GPIO13 via rpi_ws281x.

Perhaps this helps you or others who google their way here!

sporubcan commented 2 years ago

Hello, I have FAN PWM control connected to GPIO13 and NeoPixel to GPIO12. Both are working standalone well. But when I start FAN PWM on GPIO13 (channel 1), it interferes NeoPixel on GPIO12 (channel 0). Did you find the solution please? Thank you in advance!

combs commented 2 years ago

I'm digging into this myself. The best I've been able to figure is that PWM0 and PWM1 share a clock, so you have to set the PWM frequency to the clock that rpi_ws281x needs, or initialize rpi_ws281x second. (speculative... testing.) Otherwise the strict timing requirements of the LEDs are not met.

I think the clock that rpi_ws281x uses is 19.2MHz raw pixel clock, OSC_FREQ in ws2811.c. 54MHz for Pi 4. I'm trying to work out how this translates to the hertz value expected by hardware pwm libraries. I wonder if it might just be 19200000/256 but that's just a guess.

RPi.GPIO sorta works because it uses software PWM instead of hardware (it doesn't seem to support hardware PWM), which flickers or jitters when the CPU is busy, as in my application.

combs commented 1 year ago

I haven't been able to get rpi_ws281x to cooperate with PWM GPIO usage on the other pin in any construction order. Womp womp.

Got some more useful clues, though, by poking around in /sys/class/pwm/ after enabling the pwm-2chan dtoverlay in /boot/config.txt. (See /boot/overlay/README for details)

It looks like the period is 13333 on my Pi Zero after rpi_ws281x is initialized. In theory, I could use this for PWM dimming an LED by scaling everything to fractions of that overall period and reenabling the second output: writing the desired value to duty_cycle and writing 1 to enable. (Note that you must write 0 to duty_cycle before changing period.)

It didn't seem like anything was being output for me, though. I couldn't see why--it seems like both RPI_PWM_CTL_EN1 and EN2 bits are being set in ws2811.c. Will dig a little more into my setup when time permits. I might just have too much capacitance for PWM at this high a frequency; it's an oddball setup with a 12v automotive LED bulb being driven from a boost converter through a L293D. So that's plenty of places where this could be falling down.