tinue / apa102-pi

Pure Python library to drive APA102 LED stripes; Use with Raspberry Pi.
GNU General Public License v2.0
201 stars 71 forks source link

Rainbow corruption? #37

Closed ThOr101 closed 4 years ago

ThOr101 commented 4 years ago

Hello, I'm not a python expert, so me trying to follow the code isn't going exceptionally well after 3 days.

Is there a chance that the rainbow function sends corrupted data to LEDs beyond 255? I have 4 reels of 150 LEDs. All the other functions work well, but that slow trip through the rainbow... the end gets all flickery. I've put in the 3.3V to 5V signal converter, and I have 5V at the junction between every reel.

I've put debug statements in the rainbow colorscheme to print out the values being set, but I just can't seem to understand them other than led_index_rounded_wrapped never gets above 255.

Thanks much!

tinue commented 4 years ago

Hi, In my version of the color sample, there are NUM_LED = 430. For testing, I use a 144 LED per meter strip, and it's 3 meters long. So it's way beyond 255 LEDs, and I can't see any issue on my strip. You can see my strip here: https://www.youtube.com/watch?v=SfUwiBJVz6g

I only feed power on one end, which is visible if I show only white, for example: The LEDs get noticeably dimmer towards the end.

Also, if you say "flickery" then I am not sure if this is software. I have seen flicker on my strip, which is why it's not a 432 LED strip anymore. I had to cut out two LEDs and re-solder the strip, because there was a shaky connection towards the end of one of the three 1 Meter strips. Unfortunately it was not the last strip, so I got flicker from the end of the second strip all across the third strip.

Could you maybe try to connect the strips in a different order?

krux702 commented 4 years ago

Had the same issue on a strip of 640+ LEDs.. I fixed it by updating the Rainbow routine to set the LED brightness on the strip.set_pixel_rgb function call.

in apa102.py I have BRIGHTNESS = 0b00011111

and then in colorschemese.py strip.set_pixel_rgb(i, pixel_color, strip.BRIGHTNESS)

From what I could tell it seemed something was getting corrupted on longer strands. When doing some testing I gradually increased the brightness level and at a certain point I would see corruption, like the brightness value was getting set over the max value allowed. I still see it on occasion on maybe the last 15 or so LEDs, but no where near as bad as it was.

tinue commented 4 years ago

I will test this as well. It makes a lot of sense: The voltage drops a bit with each LED. The brighter the LEDs is, the more the voltage drops. It's very possible that the micro controller in the LEDs starts to malfunction if the voltage goes below a certain level. Having less brightness, or more / stronger power supplies will fix this.

ThOr101 commented 4 years ago

Hello Martin, Thank you for the fast reply, apologies for my delayed response. I have a 60A 5V power supply. All white looks pretty good, maybe the very last LED is slightly red. I also have power at the beginning of reel 1, and in between reel 3 and 4, so I think I have good power distribution.

I attempted the suggestion posted by krux702, but that didn't seem to fix it.

A note that when I say flickering, I should have been more specific in that the colors go wild. I get good brightness, it's just that the color doesn't match. What is odd is that when the sequence goes to repeat it looks as though it "clears out" the odd colors, this is why I thought it was a buffer corruption issue.

I took some videos to hopefully better explain the situation.

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

Using the default run color cycle (430 LEDS, but looks like 450 are actually running) https://www.youtube.com/watch?v=3-36Lv9FHbg

Took the default run color cycle and increased NUM_LED to 600 https://www.youtube.com/watch?v=PRT350KQ10s

Some things I notice when running the last one. When it is running 1 color through each LED, the first 10 or so LED's will have the color from the previous run.

Also, the LED's only flicker at the beginning of the cycle sequence, and after the sequence restarts, but somewhere in the middle (aqua - blue) it seems to "settle down".

Thanks much!

ThOr101 commented 4 years ago

Oh, sorry, you also asked if I could connect them in a different order. I have 6 strips in total and I've swapped them around, etc. Always happens on the last strips in the sequence. So I don't think it is a hardware fault issue (as in a bad LED corrupting the data as it gets passed along).

ThOr101 commented 4 years ago

Hmm, I don't think it is problem with your code, though now I'm really not sure what is happening. I put an if statement into the Rainbow function that only set the pixel if the number was greater than 500, then backed it "up" all the way to 50. As you can see in this video, if I keep the first 50 LEDs dark, then about 530 of them function really well.

If keep the first 100 dark, they all (except the dark ones) work great.

If I darken only the first 10, I get "disco" and with all of them on, also "disco".

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

krux702 commented 4 years ago

I noticed it happened more often when the brightness level was higher. It could be because of voltage sag mid way in the strip. I'm powering from both ends of each segment (about 150 lights per segment) but if I have things at max brightness and a static color, like white, you can see where the voltage is lower at the segment mid point. I plan to run additional power at the strip mid points to see if the problem clears up, but haven't yet

On November 16, 2019 9:52:31 AM PST, ThOr101 notifications@github.com wrote:

Hmm, I don't think it is problem with your code, though now I'm really not sure what is happening. I put an if statement into the Rainbow function that only set the pixel if the number was greater than 500, then backed it "up" all the way to

  1. As you can see in this video, if I keep the first 50 LEDs dark, then about 530 of them function really well.

If keep the first 100 dark, they all (except the dark ones) work great.

If I darken only the first 10, I get "disco" and with all of them on, also "disco".

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

-- You are receiving this because you commented. Reply to this email directly or view it on GitHub: https://github.com/tinue/apa102-pi/issues/37#issuecomment-554659236

krux702 commented 4 years ago

I also rewrote the driver in C, and still see the issue, so I don't think it's a code thing.

On November 16, 2019 9:20:28 AM PST, ThOr101 notifications@github.com wrote:

Oh, sorry, you also asked if I could connect them in a different order. I have 6 strips in total and I've swapped them around, etc. Always happens on the last strips in the sequence. So I don't think it is a hardware fault issue (as in a bad LED corrupting the data as it gets passed along).

-- You are receiving this because you commented. Reply to this email directly or view it on GitHub: https://github.com/tinue/apa102-pi/issues/37#issuecomment-554656556

ThOr101 commented 4 years ago

Thanks for your followup krux702. I just added power at all 5 points in my 4 reel setup. I did a white test with 50% brightness and I can see the red sag dips in the middle.

It didn't change any of my results with the disco lights though.

tinue commented 4 years ago

There is a comment in the driver "Essentially the driver sends additional zeroes to LED 1 as long as it takes for the last color frame to make it down the line to the last LED."

On my strip every LED delays the signal by 1/2 cycle. This is why the function clock_end_frame sends half as many zeroes as there are LEDs. Maybe your LEDs are different, and more / less zeroes are required. Actually too many zeroes should not hurt, so you could try to use // 8 instead of // 16.

But somehow I don't think that this will help. Such a difference would affect all color programs, and not only the color cycle.

Meanwhile I tried my strip with full brightness, and now the last LED is completely dark red when it should be white. There is no problem at all otherwise.

tinue commented 4 years ago

I found a very interesting blog post: https://cpldcpu.wordpress.com/2016/12/13/sk9822-a-clone-of-the-apa102/ Could it be that your LEDs are SK9822?

I added the proposed fix to the development branch. Would it be possible to try this out?

I also ordered some SK9822 strands from China, and should be able to test this myself in a few weeks.

tinue commented 4 years ago

I cobbled together all of the LED strips that I could find, and can now also see the problem. What helped was lowering the SPI bus frequency. In apa102.py I used a lower value, namely max_speed_hz=6000000. This fixed the problem for me. I could also make the problem worse by increasing the speed. With max_speed_hz=16000000 nothing works anymore, with max_speed_hz=12000000 two reels are fine, and the entire third reel is flickering.

Could you give this a try please?

ThOr101 commented 4 years ago

Hello Martin, Thanks for all the help. Wow. Amazing. In order of your notes. I tried //8 instead of //16 and that didn't do anything.

I don't think I have SK9822. I tried to make sure of that when I was purchasing them. I tried the driver you have in development, but that actually made it worse. I realized why though, as the development driver increases the max brightness.

Combining that information with your third suggestion, I started decreasing the max_speed_hz. With the original driver (Max Brightness 31) I can eliminate the flicker at 3000000 hz. With the new driver (Max Brightness 120) I can eliminate the flicker at 1500000 hz. Luckily, for what I'm doing, I don't need to go very fast, so this actually helps point me at a reasonable solution.

I could actually see the disco flicker going away the slower and slower I set the max_speed.

Just to go full circle. I also tried the original driver, set the MAX_BRIGHTNESS to 120, and had the same results as the new driver with the SK9822 info it it, I had to get down to 1500000hz before the flicker disappeared.

It seems to me, for my rig I can have any 2 of the 3: Length, brightness, speed. Luckily, I don't need a lot of speed for my application.

Happy to keep trying other variations. Thanks for the help!

tinue commented 4 years ago

You're welcome; Also thanks to @krux702 for helping with tests! I'll keep the issue open until I get around documenting this in the readme.

While the observations are clear, I can't explain them. The length of a strip or the brightness will affect the voltage on the power rails, but this can be countered by adding power supplies, which is what you did.

The "cleanliness" of the signal should not be affected by the length of the strip. If the data gets correctly read by an LED's control chip, then it's pushed out on the other side "fresh": There is no error accumulation.

But also because of this property: As soon as one chip has issues, everything after this chip will be broken, which is what can be observed.

So what I would expect is this: If there is a "weak" chip in the chain, then it should trigger the issue regardless of its placement. If you switch reels, then the problem should switch as well. But this doesn't happen: The problem is always at the end of the chain.

ThOr101 commented 4 years ago

Hi Martin, You have correctly and succinctly collected and summarized all issues, evidence and work arounds.
Thank you for writing this in the first place!

tinue commented 4 years ago

Thanks again, I released a new version with additional documentation.

krux702 commented 4 years ago

So on my LED strip, knocking the SPI speed down from 6000000 to 3000000 eliminates the flicker and allows me to turn the brightness up to 31 (all 5 brightness bits on), at 6000000 I had to turn the brightness down to 7 and would still occasionally see flicker if it was doing the rainbow pattern. Curiously I wouldn't see the flicker if it was just all white. So looks like that was the fix.

On 2019-11-17 18:21, ThOr101 wrote:

Hello Martin, Thanks for all the help. Wow. Amazing. In order of your notes. I tried //8 instead of //16 and that didn't do anything.

I don't think I have SK9822. I tried to make sure of that when I was purchasing them. I tried the driver you have in development, but that actually made it worse. I realized why though, as the development driver increases the max brightness.

Combining that information with your third suggestion, I started decreasing the max_speed_hz. With the original driver (Max Brightness 31) I can eliminate the flicker at 3000000 hz. With the new driver (Max Brightness 120) I can eliminate the flicker at 1500000 hz. Luckily, for what I'm doing, I don't need to go very fast, so this actually helps point me at a reasonable solution.

I could actually see the disco flicker going away the slower and slower I set the max_speed.

Just to go full circle. I also tried the original driver, set the MAX_BRIGHTNESS to 120, and had the same results as the new driver with the SK9822 info it it, I had to get down to 1500000hz before the flicker disappeared.

It seems to me, for my rig I can have any 2 of the 3: Length, brightness, speed. Luckily, I don't need a lot of speed for my application.

Happy to keep trying other variations. Thanks for the help!

-- You are receiving this because you commented. Reply to this email directly, view it on GitHub [1], or unsubscribe [2].

Links:

[1] https://github.com/tinue/apa102-pi/issues/37?email_source=notifications&email_token=AAM6OR5RW6DDNQZZAQIRQJDQUH3Z3A5CNFSM4IYRRLY2YY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOEEI6XGQ#issuecomment-554822554 [2] https://github.com/notifications/unsubscribe-auth/AAM6OR6J3I6OPXQAVRAKN5DQUH3Z3ANCNFSM4IYRRLYQ

tinue commented 4 years ago

I found a post from Paul Stoffregen who analyzed this issue: https://www.pjrc.com/why-apa102-leds-have-trouble-at-24-mhz/ It looks like the data and clock signals run apart, and that the clock becomes deformed. There is no mention of the brightness; He probably did not realize that this has an influence as well.

The "all white" is only a single strip update, while the rainbow programs update the strip very quickly. Maybe only e.g. 10% of the updates fail. You could try to modify the "white" part and instead of painting white once, paint white as often as possible. I bet it would flicker in this case as well.

tinue commented 4 years ago

Some experiments with a brand new SK9822 strip, 5 meters (720 LEDs):

So it appears that the SK9822 LEDs are much better for long / bright strips, but they are not perfect either.