WS2812 example: Improve bandwidth tolerance #486
Merged
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
The WS2812 PIO example uses poor choices of T1, T2, and T3, leading to poor support for transmission frequencies other than 0.8 MHz. Specifically, the example PIO program, when run at a bit frequency of 0.8 MHz, is at the bounds of the tolerances specified in the WS2812B datasheet.
This PR improves the maximum bit frequency to 1.028 MHz while remaining within tolerance (a 28% improvement).
Context:
The WS2812B datasheet lists the following tolerances:
0.4 us +- 0.15 us
=0.25 us .. 0.55 us
0.8 us +- 0.15 us
=0.65 us .. 0.95 us
0.85 us +- 0.15 us
=0.7 us .. 1 us
0.45 us +- 0.15 us
=0.3 us .. 0.6 us
Note: This gives a minimum possible time-per-bit of 0.95 us, and a maximum possible time-per-bit of 1.55 us
These relate to the example's constants
T1, T2, T3
as follows:T1 / (T1 + T2 + T3) / bit_frequency
(T1 + T2) / (T1 + T2 + T3) / bit_frequency
T2 / (T1 + T2 + T3) / bit_frequency
(T2 + T3) / (T1 + T2 + T3) / bit_frequency
Analysis of various choices of
T1,T2,T3
:Here, I use
T_bit
to indicate the time required to transmit 1 bit,F_bit = 1 / T_bit
as the maximum bit transmission frequency, and(T1,T2,T3)
as a tuple of constants. In each case, I report the bounds onT_bit
andF_bit
required to stay within the tolerance intervals specified in the datasheet.1.25 us <= T_bit <= 1.25 us
800,000 Hz <= F_bit <= 800,000 Hz
(T1,T2,T3) = (2,5,3)
(total 10 PIO cycles / bit)0.95 us <= T_bit <= 1.357 us
736,843 <= F_bit <= 1,052,631 Hz
(T1,T2,T3) = (5,8,6)
(total 19 PIO cycles / bit)0.97223 us <= T_bit <= 1.3888 us
720,000 Hz <= F_bit <= 1,028,571 Hz
(T1,T2,T3) = (7,10,8)
(total 25 PIO cycles / bit)1 us <= T_bit <= 1.357 us
736,843 Hz <= F_bit <= 1,000,000 Hz
(T1,T2,T3) = (3,4,3)
(total 10 PIO cycles / bit)1.085 us <= T_bit <= 1.55 us
645,162 Hz <= F_bit <= 921,658 Hz
(T1,T2,T3) = (11,8,12)
(total 31 PIO cycles / bit)Conclusion:
This PR implements timing 3., giving bandwidth options in the range
720000 Hz .. 1028571 Hz
, and has been tested on a 12-LED WS2812B strip at 1 MHz. By making this adjustment, those using the WS2812 example as a starting point will have significantly greater freedom to experiment with alternate bandwidths, without replicating the work above.Disclaimer:
Though I am currently employed by IBM, this PR is completely unrelated to my employment, and was undertaken without using either company time or resources.