Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support for WS2812 via PWM #2132

Open
qiuyoo opened this issue Sep 19, 2023 · 17 comments
Open

Support for WS2812 via PWM #2132

qiuyoo opened this issue Sep 19, 2023 · 17 comments
Labels
api-suggestion Early API idea and discussion, it is NOT ready for implementation Priority:3 Work that is nice to have

Comments

@qiuyoo
Copy link

qiuyoo commented Sep 19, 2023

Problem:
Currently, there is a method to support WS2812 LEDs through SPI, which is great. However, I would like to suggest the addition of support for WS2812 LEDs via PWM as well.

Description:
The current implementation provides support for WS2812 LEDs using the SPI interface, which works well in many cases. However, there are scenarios where PWM-based control for WS2812 LEDs can be more advantageous.

Use Case:

PWM (Pulse Width Modulation) is widely used for controlling LEDs and offers precise control over the LED's brightness.
Some hardware configurations may not have access to SPI, making PWM a more accessible option.
Supporting PWM for WS2812 LEDs would make the library more versatile and compatible with a wider range of hardware setups.
Proposed Solution:
I propose adding support for WS2812 LEDs via PWM to complement the existing SPI support. This would provide users with more flexibility in choosing the appropriate control method based on their hardware and application requirements.

Additional Information:

It's important to maintain backward compatibility and ensure that users can easily switch between SPI and PWM control methods.
Detailed documentation and examples for using WS2812 LEDs via PWM would be valuable for users.
Thank you for considering this feature request. Please let me know if you need any further information or if there are any questions regarding this proposal.

@qiuyoo qiuyoo added the api-suggestion Early API idea and discussion, it is NOT ready for implementation label Sep 19, 2023
@ghost ghost added the untriaged label Sep 19, 2023
@raffaeler
Copy link
Contributor

I'm not sure to understand the request correctly.
The LEDs controlled via WS2812 use a 1-wire protocol on the data line to set the value of the RGB(W) internal leds, including the brightness.
By using PWM on the power line, you compromise exchanging data on the data wire.

Am I missing something?

@qiuyoo
Copy link
Author

qiuyoo commented Sep 20, 2023

In certain scenarios, this requirement arises. Currently, I am controlling 700 LEDs using a single PWM pin, with independent power supplies. However, the existing code is in Python, and I would like to transition to a .NET Core version for this project.

@qiuyoo
Copy link
Author

qiuyoo commented Sep 20, 2023

I have an idea: I'm using PCA9685 to extend 16 PWM channels, all of which are meant to drive WS2812 LEDs. However, since there is no PWM support, I'm unable to implement it.

@pgrawehr
Copy link
Contributor

Can you point us at a data sheet or the python implementation that you're using? Like Raffaele I'm quite confused as to how that should work.

@qiuyoo
Copy link
Author

qiuyoo commented Sep 20, 2023

Can you point us at a data sheet or the python implementation that you're using? Like Raffaele I'm quite confused as to how that should work.

https://github.com/rpi-ws281x/rpi-ws281x-python

@raffaeler
Copy link
Contributor

I'm still confused.
According to the link you posted:

Both PWM and PCM use DMA transfer to output the control signal for the LEDs.

This means that PWM is used to send the bits as you would do with the SPI.
This also means that PWM is not used to dim the brightness of the led power as you would do with any traditional led.

All the WS2812 leds have an internal IC taking care to indipendently drive the R, G, B and (if present) W from any brightness from 0 to 255. For example you if send over the data line the RGB data to 128,0,0 you will have a mid-brightness red, while the full brightness led could be obtained, of course, with 255,0,0.

That said, using PWM as data line is doable but I am not sure it would be a popular request as it would not add any additional feature to use the SPI.

If I misunderstood what you mean, please clarify.

@qiuyoo
Copy link
Author

qiuyoo commented Sep 20, 2023

Yes, using PWM is feasible, and functionally equivalent to SPI. The main consideration here is the scalability of PWM, which offers a lot of possibilities in terms of quantity. If you look at open-source projects in other languages, you'll likely understand that this feature is necessary.

@raffaeler
Copy link
Contributor

Please bring some examples here.

Once you drive with PWM, the number of leds on the data line (they are connected in serial) does not change anything.
SPI is the fastest possible communication line, therefore if you want the highest possible data rate to program a huge number of leds, SPI is the way to go (faster than PWM for this purpose).

@qiuyoo
Copy link
Author

qiuyoo commented Sep 20, 2023

Currently, my projects concern is the ability to expand the number of PWM channels, but I haven't found a way to expand the quantity for SPI yet. I have tried using the SoftwarePwmChannel in System.Device.Pwm, and it can also illuminate WS2812 LEDs. However, I didn't fully understand the calculation method used inside it. In the development of my project, I've searched for a lot of information, and it seems that .NET support is quite limited. I would like to provide as much support as possible, at least to offer an additional option.

@raffaeler
Copy link
Contributor

raffaeler commented Sep 20, 2023

You can have a decent speed when you use dedicated hardware and not by emulating in software.
This is true for any peripheral, including SPI and PWM.

If you need multiple channels, you can use the FT4232H series of boards which have multiple HW SPI on board.
You can find these modules (or similars) using these ICs via popular distributors or on AliExpress:
https://ftdichip.com/product-category/products/modules/

Similarly, there are boards offering multiple HW PWMs (usually used to drive motors, but they are general purpose). I use this kind of board: https://www.aliexpress.com/item/1005004626900806.html

I didn't fully understand the calculation method used inside it.

I never wrote the code to drive the WS2812 but the best way is to use the oscilloscope to verify that what you write is what you expect. Once you write byes over the pwm in the expected serial order, you are done.

I would like to provide as much support as possible, at least to offer an additional option.

We gladly accept PRs of course :-)
If you want to contribute adding support for this WS2812 using PWM, you are more than welcome. Anyway, I don't think that this could solve your problem.

@qiuyoo
Copy link
Author

qiuyoo commented Sep 20, 2023

Okay, thank you. I will try some other solutions.

@raffaeler
Copy link
Contributor

You are welcome. Let us know how it goes.
Should PWM become important to solve the problem, I would be curious to understand the use-case.

@qiuyoo
Copy link
Author

qiuyoo commented Sep 20, 2023

We are currently using a Raspberry Pi 3B along with a PCB expansion board developed by the supplier. The PCB expansion board is already in use and cannot be adjusted. The PCB is connected to 700 WS2812 LED lights, with PWM0 (Pin 18) and PWM1 (Pin 13) respectively. The original program is written in Python and is based on this project: https://github.com/rpi-ws281x/rpi-ws281x-python. However, we now want to modify it so that every 100 LEDs form a PWM channel, ensuring that a malfunctioning LED in the middle does not affect the ones behind it. The current solution we are considering is to connect a PCA9685 device externally to the Raspberry Pi. The PCA9685 can expand to provide 16 PWM data interfaces. That's the idea.

@raffaeler
Copy link
Contributor

You should make some test before proceeding. Let me explain the reason.
Those PWM ICs are meant to be programmed once and then they produce the constant PWM duty cycle (on/off timings).
Instead, you want to 'hack' the PWM by creating train of bits that makes up the bytes to transmit on the data lines.
Basically, you want to emulate the SPI behavior on a PWM.

I am not sure that you could do with the PCA9685 (which I also linked before) because this IC just get the parameters for the duty cycle while you should continuosly reprogram the 16 channels for each bit.
For this reason I am not sure the timings are compatible with the RPi.
Make a test to validate your solution first.

If instead you use multiple SPI ports, it's easier because the SPI is meant to get bytes and serialize them to the SPI channel, which is exactly how the WS2812 data line expects the bit train.

@qiuyoo
Copy link
Author

qiuyoo commented Sep 20, 2023

I need to conduct some tests, theoretically, it should be feasible.

@raffaeler
Copy link
Contributor

I need to conduct some tests, theoretically, it should be feasible.

In theory yes, but you will need to use a lot of CPU from the RPi because you have to change the PWM duty cycle for each bit on all the 16 channels.

For your info, the mega-screens that use huge amount of WS2812 leds, do not use boards like the Raspberry PI. They use a dedicated FPGA which can provide syncrhonous and instantaneous flow of data. Using a FPGA you don't even need SPI or PWM, but just 'bitbang' the I/O in hardware. I have played with a Verilog code sample to manage the WS2812 leds.

@krwq krwq added Needs: Author Feedback We are waiting for author to react to feedback (action required) untriaged and removed untriaged labels Sep 21, 2023
@ghost
Copy link

ghost commented Sep 25, 2023

This issue has been automatically marked as stale because it has been marked as requiring author feedback but has not had any activity for 4 days. It will be closed if no further activity occurs within 3 days of this comment.

@krwq krwq added the Priority:3 Work that is nice to have label Sep 28, 2023
@krwq krwq added untriaged Status: No Recent Activity and removed Needs: Author Feedback We are waiting for author to react to feedback (action required) labels Sep 28, 2023
@krwq krwq removed the untriaged label Sep 28, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
api-suggestion Early API idea and discussion, it is NOT ready for implementation Priority:3 Work that is nice to have
Projects
None yet
Development

No branches or pull requests

4 participants