Forum Rule: Always post complete source code & details to reproduce any issue!
Results 1 to 25 of 25

Thread: FastLed vs Neopixel vs Audio library - CPU overload?

  1. #1
    Junior Member
    Join Date
    Oct 2017
    Posts
    9

    FastLed vs Neopixel vs Audio library - CPU overload?

    Hey there!
    I try to point out my problem short - I have a ws2812b neopixel led strip with 144 led / m. I want to let them flicker and do some animations. Working great on pin 7 of the teensy 3.2.

    I also have the prop shield generating some sine waves mixed together based on gyro data. (and yes, it'll be a lightsaber finally managed to synthetically generate the lightsaber sound using 14 sine waves having the values of the fft of the original from the movies)

    Both working fine, but individually. I put together both codes to have the led control and the audio output, first try with the fastled library. Problem: only half the led strip is on, seems the audio processing takes too much CPU usage to be fast enough to cycle all the LEDs.

    Then I tried it with the neopixel library. There, LEDs are working fine but the audio output cracks every time leds.show() is called (in every loop iteration for the animation).

    The prop shield buffer is just meant for apa102, as I read. The buffer could fix the problem when using fastled again, but I just have ws2812b and they stay off when connected to the prop shield.

    Any ideas if this really is a CPU overload problem or other ways to solve this issue, maybe with "pseudo" threads?

    Thanks and cheers,
    Daniel
    Last edited by Phyxtra; 10-26-2017 at 08:38 PM.

  2. #2
    Moderator MichaelMeissner's Avatar
    Join Date
    Nov 2012
    Location
    Ayer Massachussetts
    Posts
    2,506

    Cool

    I suspect you have several things going on.

    Note, that ws2812b LEDs are timing sensitive. There is only one data pin, and you HAVE to deliver the data in the timing window specified. The Adafruit library does this by turning off interrupts while the whole 144 LED string is updated. I believe the FastLED library tries to be clever and allow interrupts, but as you mention things get messed up.

    You mentioned using pin 7 for the neopixels. If you are using the prop shield, the prop shield uses pin 7 as a control of whether to do level shifting for pins 11 and 13. So you can't use pin 7 with the prop shield. If you wanted to use the prop shield level shifter, you would have code like:
    Code:
    void setup (void)
    {
      pinMode (7, OUTPUT);
      // anything else
    }
    
    void loop (void)
    {
      // other code
      digitalWrite (7, HIGH);   // enable LED level shifting
      pixels.show ();     // do the neopixel thing
      digitalWrite (7, LOW);  // allow pins 11 and 13 to be used for other things
      // other code
    }
    The prop shield uses:
    • Pin 2 for i2c interrupts;
    • Pin 5 for audio enable;
    • Pin 6 for SPI CS for the flash memory controller;
    • Pin 7 for enabling/disabling the level shifter for the LEDs;
    • Pin 11 for SPI MISO and for level shifting;
    • Pin 12 for SPI MOSI;
    • Pin 13 for SPI SCK and for level shifting;
    • Pin 18/A4 for i2c SDA;
    • Pin 19/A5 for i2c SCL; (and)
    • Pin A14 for DAC output.


    Now, there is the issue I had when I tried to mix using the Adafruit neopixel library with things that do SPI (flash memory on the prop shield, TFT displays, etc.). If you look in my query, KurtE replied on how to switch from SPI mode to normal digital write mode, and back:


    One kludge way to solve the problem is add a Teensy LC that just does neopixels. Do everything else on the 3.2. Have some simple communication from the two teensys, of what sequence to use (i.e. use i2c, serial uart, or just have a few pins that when set high mean start an action). You would need to connect at least the grounds (you presumably can connect VIN too if you are careful to only have one power source at a time). The advantage is the LC has a builtin level shifter that converts pin 17/A3 to 5v output for the neopixels.

    Another way is to think about switching to APA102 (dotstars) which are less timing senstive, but need both a data and clock pin to do the LEDs. It is probably cheaper to get an LC, though whether you have enough space for both teensys, I dunno.
    Last edited by MichaelMeissner; 10-26-2017 at 10:14 PM.

  3. #3
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    15,720
    For more than about 50 WS2812 LEDs together with the audio library, OctoWS2811 is really the only viable path. The others all conflict with the interrupts needed for audio. Only OctoWS2811 leaves the CPU free and interrupts enabled during the LED updates.

  4. #4
    Junior Member
    Join Date
    Oct 2017
    Posts
    9
    Thank you both very much Paul, I now use the OctoWS2811 library, but as soon as show() is called, the audio stops at all. Did I do something wrong?

    EDIT: Ok it's the pin layout as I read from other threads. Might need to make some adjustments
    Last edited by Phyxtra; 10-27-2017 at 08:26 PM.

  5. #5
    Junior Member
    Join Date
    Oct 2017
    Posts
    9
    Is it possible to modify the Octo lib so it just outputs at pin 7? I commented out the other pins, but that didnt change anything. For the rest of the librarys code, I'm not familiar enough with registers, DMA and the bitshifting stuff.

  6. #6
    Senior Member duff's Avatar
    Join Date
    Jan 2013
    Location
    Las Vegas
    Posts
    876
    Quote Originally Posted by Phyxtra View Post
    Is it possible to modify the Octo lib so it just outputs at pin 7? I commented out the other pins, but that didnt change anything. For the rest of the librarys code, I'm not familiar enough with registers, DMA and the bitshifting stuff.
    Yes you can I have a hacked copy of the octo lib that I used with the prop shield. If you want to try it out i can post it on github?

  7. #7
    Senior Member
    Join Date
    Apr 2013
    Posts
    1,506
    Alternative that unfortunatly means ordering different LEDs are the SPI based ones that work much better with interrupts active (hence prop shield having the level converter on the SPI port).

    When you get it settled would be interested in seeing how you modulate against the sensors. I used what I suspect is a similar bank of sine generators, but didn't find a way I was happy with to parse motion sensing into modulation of the sound effects that didn't end up over driving into noise at least some of the time.

  8. #8
    Junior Member
    Join Date
    Oct 2017
    Posts
    9
    Quote Originally Posted by duff View Post
    Yes you can I have a hacked copy of the octo lib that I used with the prop shield. If you want to try it out i can post it on github?
    Oh wow, that would be awesome! Thanks

    Quote Originally Posted by GremlinWrangler View Post
    When you get it settled would be interested in seeing how you modulate against the sensors. I used what I suspect is a similar bank of sine generators, but didn't find a way I was happy with to parse motion sensing into modulation of the sound effects that didn't end up over driving into noise at least some of the time.
    The essential of all sine waves are their amplitude and their frequency, I'd say even the amplitude is more important on the lightsaber. I used Audacity to make a fft (or in later versions I guess it's called spectrum) and took the 14 first peaks starting with around 25Hz. The corresponding amplitude is given in db, to make it easer, I just made a function to convert from db to linear.
    Now having these, the should interact with the gyro data. I used the example, where roll, pitch and heading are computed. Roll isnt necessary for a lightsaber (I guess at least, when you just roll it, sound should remain the same).
    How to do that? Easy, just use the derivative of heading and pitch using tmp variables for both, first derivative value will be available not at time 0, but time 1. Ok, then I had the derivative for both and used sqrt(deriv_pitch^2 + deriv_heading^2) to modulate the frequency and the amplitude of ALL sine waves, such that freq = freq * (1 + sqrt(deriv_pitch^2 + deriv_heading^2) * scale_factor) and the same for the amplitude with maybe a different scale factor.

    The derivates I computed shows some peaks, I filtered them out "by hand" (if > threshold) use old value

  9. #9
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    15,720
    Ok, I've been intending to make a single pin non-blocking WS2812 library for years.

    Well, here it is!

    https://github.com/PaulStoffregen/WS2812Serial

    So far the only documentation is the BasicTest example. Hopefully it's easy to understand?

    Most testing as been on a Teensy 3.2 using pins 1, 5, 8 and 10. The other pins are untested. Teensy 3.5 & 3.6 are untested, but are likely to work. Teensy LC definitely does not work.

    This new library uses DMA without blocking interrupts at all. It should be possible to update 1 (perhaps long) strip of LEDs without disturbing audio or other interrupt sensitive libs. Pretty much the same as OctoWS2811, but using only 1 pin.

  10. #10
    Junior Member
    Join Date
    Oct 2017
    Posts
    9
    Quote Originally Posted by PaulStoffregen View Post
    Ok, I've been intending to make a single pin non-blocking WS2812 library for years.

    Well, here it is!

    https://github.com/PaulStoffregen/WS2812Serial

    So far the only documentation is the BasicTest example. Hopefully it's easy to understand?

    Most testing as been on a Teensy 3.2 using pins 1, 5, 8 and 10. The other pins are untested. Teensy 3.5 & 3.6 are untested, but are likely to work. Teensy LC definitely does not work.

    This new library uses DMA without blocking interrupts at all. It should be possible to update 1 (perhaps long) strip of LEDs without disturbing audio or other interrupt sensitive libs. Pretty much the same as OctoWS2811, but using only 1 pin.
    Wow, thanks Paul Was very excited testing it, unfortunatelly the BasicTest shows Rainbow colors fading from beginning to end, after 3 to 4 rainbows, the desired code runs through, lighting up the leds in the specified color. When orange is reached, it begins with some crazy rainbows again. The only stable color I could figure out was (0, 30, 0) and (0, 10, 0), a green. (0, 20, 0) and anything else causes again some crazy rainbows. Several power supplies tested. I used pin 1, prop shield connected (because soldered directly on). Is it a timing issue in the library?

  11. #11
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    15,720
    Try uncommenting the less intense colors. Does that make any difference? (other than less bright)

  12. #12
    Junior Member
    Join Date
    Oct 2017
    Posts
    9
    Quote Originally Posted by PaulStoffregen View Post
    Try uncommenting the less intense colors. Does that make any difference? (other than less bright)
    Sadly not, well, yes, another timing structure. I made two videos:
    Standard: https://youtu.be/XjL_rI_8seU
    Less: https://youtu.be/570xAK3hepg

    Code, other than less intense, is untouched. However, I need to admit, it's truly beautiful

  13. #13
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    15,720
    Have you measured the voltage at the far end of the LEDs while it's running? Does it really stay at or near 5 volts?

  14. #14
    Senior Member duff's Avatar
    Join Date
    Jan 2013
    Location
    Las Vegas
    Posts
    876
    I'm finishing up some stuff and I'll post my single wire OCTO hack that worked for me. Took at look at pauls serial version thats pretty cool also.

  15. #15
    Junior Member
    Join Date
    Oct 2017
    Posts
    9
    Quote Originally Posted by PaulStoffregen View Post
    Have you measured the voltage at the far end of the LEDs while it's running? Does it really stay at or near 5 volts?
    Normal minimal voltage drop, even connected the end to power source, no difference. Even with just 5 LEDs the rainbow effect appears. I edited the code to FastLed and everything is fine, I thought myself it could be a power issue, but now I think it's not. I'm not familiar with DMA unfortunatelly, otherwise I'd been invastigating on finding a solution and help you a bit after all that work

    Quote Originally Posted by duff View Post
    I'm finishing up some stuff and I'll post my single wire OCTO hack that worked for me. Took at look at pauls serial version thats pretty cool also.
    Cool, I'm gonna try that too!

  16. #16
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    15,720
    Hmmm... I'll try changing the timing. But it's going to mean the frame buffer grows to 12 bytes per LED instead of only 8.

  17. #17
    Junior Member
    Join Date
    Oct 2017
    Posts
    9
    Would be nice! shouldn't be too much of a problem, I will be (and I think many others too) very happy if the library runs stable with all sorts of ws2812b strips. I friend told me there are two versions with an identical datasheet but a different protocol and one can't instantly see which version they have, but I don't know if he's right there

  18. #18
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    15,720
    Ok, here's a change to alter the timing.

    https://github.com/PaulStoffregen/WS...707a2c9835e8a4

    When you update the code, please be sure to reopen the example. The new version uses 12 bytes per LED in the frame buffer, so obviously you don't want to use the old example with only 8 bytes allocated.

  19. #19
    Junior Member
    Join Date
    Oct 2017
    Posts
    9
    Quote Originally Posted by PaulStoffregen View Post
    Ok, here's a change to alter the timing.

    https://github.com/PaulStoffregen/WS...707a2c9835e8a4

    When you update the code, please be sure to reopen the example. The new version uses 12 bytes per LED in the frame buffer, so obviously you don't want to use the old example with only 8 bytes allocated.
    Oh man, you can't believe how happy I am right now. It's working, working like a charm - even with the prop shield running and all the animations and the sound synthesis. Thank you sooo much, honestly, I can't even believe that it's all working right now You are such a cool guy and a genius, THANKS!

  20. #20
    Senior Member
    Join Date
    Feb 2016
    Location
    Australia
    Posts
    155
    Quote Originally Posted by PaulStoffregen View Post
    Ok, ... Pretty much the same as OctoWS2811, but using only 1 pin.
    Except octows2811 is blocking?
    Does octows2811 block during setup of dma stuff or during sending of ws2811 data for duration of data?

    Is there no hope for octows2811 to be non blocking?

    Is the Serial part of ws2812 the key to all this?

    thanks.

  21. #21
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    15,720
    OctoWS2811 is also non-blocking. Technically, it does block interrupts for a very brief time while configuring the timer, but that is at most a couple microseconds. During the lengthy transmission of data to the LEDs, interrupts are *not* blocked. The show() function returns as soon as the DMA transfers are set up.

    WS2812Serial doesn't block interrupts at all.

  22. #22
    Member Etienne's Avatar
    Join Date
    Mar 2016
    Location
    Ardeche, France
    Posts
    28
    Hi,
    Great work.
    So if I understood well, the pin 17 of Teensy LC (that can directly drive WS2812 LEDs) can not be used with this library ?

  23. #23
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    15,720
    That's correct. But you can pretty easily wire another pin to it. Scroll to the end of the readme for details.

  24. #24
    Member Etienne's Avatar
    Join Date
    Mar 2016
    Location
    Ardeche, France
    Posts
    28
    Oh sorry I didn't see the end of the readme. I thought of this solution (connecting pin 24 to 17), but I was wondering if there is any risk of damaging the MCU if the code configures these 2 pins as outputs ? (shouldn't happen with the proper code though, as I guess all pins are initialized in Hi-z or input when cpu is started).

  25. #25
    Member PaulS's Avatar
    Join Date
    Apr 2015
    Location
    Netherlands
    Posts
    72
    I can confirm that wiring pin 24 to 17 works fine. Can also confirm that the timing change by Paul does work.
    See my other thread.

    A stable, external powersupply is required: when trying to display full white on a 24-LED NeoPixel Ring, the +1000mA is too much for my desktop USB port and the Teensy LC goes haywire...

    Regards,
    Paul

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •