LED animation functions won't play with each other

EL Wire/Tape/Panels, LEDs, pixels and strips, LCDs and TFTs, etc products from Adafruit

Moderators: adafruit_support_bill, adafruit

Please be positive and constructive with your questions and comments.
Locked
User avatar
qbit
 
Posts: 27
Joined: Thu Aug 06, 2015 5:36 pm

LED animation functions won't play with each other

Post by qbit »

I started with the techno tiki tutorial: https://learn.adafruit.com/techno-tiki-rgb-led-torch

I want to isolate the two animations and turn them into functions, which I can later tack onto the NeoPixel strandtest code as additional animations.

Each function works fine by itself, but when both are on together, animation1 does not play - it jumps right to animation2 which loops forever. However, the LED refresh for animation2 slows down a tiny bit. Is the code is somehow repeatedly jumping through animation1 but w/o staying long enough to play it?

If I comment out animation2, then animation1 plays fine. And vice-versa. But animation1 will not play when both functions are active.

I tried to compare this to the NeoPixel strandtest functions, it looks very similar, but I can't figure out the problem... Help! What am I missing here?

Code: Select all

#include <Adafruit_NeoPixel.h>

#ifdef __AVR__
  #include <avr/power.h>
#endif

#define PIXEL_PIN      1    // Pin connected to the NeoPixel strip.

#define PIXEL_COUNT    7    // Number of NeoPixels.

#define PIXEL_TYPE     NEO_GRB + NEO_KHZ800

#define SPEED_MS       175  // Animation speed (in milliseconds).  This is how
                            // long to spend in a single animation frame.
                            //Higher values are slower.  
                            //over 200 it gets choppy

// Color animation values.  Each value is a 24-bit RGB color value that will be displayed
// at that current step in the animation.

const int colorSteps = 24;  // Number of steps in the animation.
const uint32_t colorAnimation[colorSteps] PROGMEM =

 { 0xFF0000, 0xDA2424, 0xB64848, 0x916D6D, 0x6D9191, 0x48B6B6, 0x24DADA, 0x00FFFF, // Red-cyan
   0xFFFF00, 0xDADA24, 0xB6B648, 0x91916D, 0x6D6D91, 0x4848B6, 0x2424DA, 0x0000FF, // Yellow-blue
   0x00FF00, 0x24DA24, 0x48B648, 0x6D916D, 0x916D91, 0xB648B6, 0xDA24DA, 0xFF00FF // Green-magenta
 };
Adafruit_NeoPixel strip = Adafruit_NeoPixel(PIXEL_COUNT, PIXEL_PIN, PIXEL_TYPE);

void setup() {
  
    // This is for Trinket 5V 16MHz, you can remove these three lines if you are not using a Trinket
  #if defined (__AVR_ATtiny85__)
    if (F_CPU == 16000000) clock_prescale_set(clock_div_1);
  #endif
  // End of trinket special code
  
  // Initialize and clear the NeoPixel strip.
  strip.begin();
  strip.clear();
  strip.show(); // Initialize all pixels to 'off'
}

void loop() {

animation1();

animation2();

}

void animation1(){
  for (int i = 0; i < PIXEL_COUNT; ++i) {
      // solid color pulse of all pixels.
      uint8_t currentStep = (millis()/SPEED_MS)%(colorSteps*2-2);
      if (currentStep >= colorSteps) {
        currentStep = colorSteps-(currentStep-(colorSteps-2));
      }
      // Note that colors are stored in flash memory so they need to be read
      // using the pgmspace.h functions.
      uint32_t color = pgm_read_dword_near(&colorAnimation[currentStep]);
      strip.setPixelColor(i, color);
      strip.show();
    }
 }

void animation2(){
  for (int i = 0; i < PIXEL_COUNT; ++i) {
      // Moving color pulse.  Use position to change brightness.
      uint8_t currentStep = (millis()/SPEED_MS-i)%(colorSteps*2-2);
      
      if (currentStep >= colorSteps) {
        currentStep = colorSteps-(currentStep-(colorSteps-2));
      }
      // Note that colors are stored in flash memory so they need to be read
      // using the pgmspace.h functions.
      uint32_t color = pgm_read_dword_near(&colorAnimation[currentStep]);
      strip.setPixelColor(i, color); 
      strip.show();
      
    }
}

User avatar
adafruit_support_bill
 
Posts: 88088
Joined: Sat Feb 07, 2009 10:11 am

Re: LED animation functions won't play with each other

Post by adafruit_support_bill »

To run multiple animations concurrently, you would need to do something like this:
https://learn.adafruit.com/multi-taskin ... 3/overview

User avatar
qbit
 
Posts: 27
Joined: Thu Aug 06, 2015 5:36 pm

Re: LED animation functions won't play with each other

Post by qbit »

No - I'm not trying to run them concurrently - I'm trying to run them as consecutive functions, just like on the NeoPixel strandtest.

In the NeoPixel strandtest, a function is called in void loop() - it plays through that animation, then moves on to the next function.

I want my code to do the same. But in my sample code it won't play through animation1 unless animation2 is commented out.

It doesn't matter which order I call them in. And if I leave them both active, then it (appears to) skip animation1 and just loops animation2.

I say "appears to" because I can see the LEDs flickering slightly as they play through animation2, but it plays smoothly when animation1 is commented out.

It feels like animation2 is hijacking the code for some reason that I don't understand...

User avatar
qbit
 
Posts: 27
Joined: Thu Aug 06, 2015 5:36 pm

Re: LED animation functions won't play with each other

Post by qbit »

Do I need some kind of delay to give animation1 time to run?

I noticed the functions in the strandtest code have "uint8_t wait" and they insert that variable in delay(wait); at the end of the function...

But I'm not sure how to use that code...

User avatar
qbit
 
Posts: 27
Joined: Thu Aug 06, 2015 5:36 pm

Re: LED animation functions won't play with each other

Post by qbit »

And if I just put delay(10); at the end of animation1 and run the code, it still skips animation1, but animation2 plays extremely fast.

How is the code in animation1 affecting the code in animation2 when they are different functions???

I'm so confused!

User avatar
qbit
 
Posts: 27
Joined: Thu Aug 06, 2015 5:36 pm

Re: LED animation functions won't play with each other

Post by qbit »

I tried this code using "unit8_t wait", and again, they run fine when one or the other is commented out. But when both functions are active I just get a rapid strobe effect of changing colors.

Code: Select all

void loop(void) {

animation1(5);
//animation2(10);

}

void animation1(uint8_t wait){
  for (int i = 0; i < PIXEL_COUNT; ++i) {
      // solid color pulse of all pixels.
      uint8_t currentStep = (millis()/SPEED_MS)%(colorSteps*2-2);
      if (currentStep >= colorSteps) {
        currentStep = colorSteps-(currentStep-(colorSteps-2));
      }
      // Note that colors are stored in flash memory so they need to be read
      // using the pgmspace.h functions.
      uint32_t color = pgm_read_dword_near(&colorAnimation[currentStep]);
      strip.setPixelColor(i, color);
      strip.show();
      delay(wait);
    }
 }

void animation2(uint8_t wait){
  for (int i = 0; i < PIXEL_COUNT; ++i) {
      // Moving color pulse.  Use position to change brightness.
      uint8_t currentStep = (millis()/SPEED_MS-i)%(colorSteps*2-2);
      
      if (currentStep >= colorSteps) {
        currentStep = colorSteps-(currentStep-(colorSteps-2));
      }
      // Note that colors are stored in flash memory so they need to be read
      // using the pgmspace.h functions.
      uint32_t color = pgm_read_dword_near(&colorAnimation[currentStep]);
      strip.setPixelColor(i, color); 
      strip.show();
      delay(wait);
    }
}

User avatar
Disciple
 
Posts: 852
Joined: Tue Jan 06, 2015 8:13 pm

Re: LED animation functions won't play with each other

Post by Disciple »

Hello from an amateur coder. Have another look at the strandtest code.
Each effect called in the loop() function is another small loop. Each effect loops through its changes to the pixel colors and doesn't exit until complete. The effects in your code just need loops added, so that each can spend a little time running before they quit. Here's an idea.

Code: Select all

void loop() {
  animation1(6000);   // 6 seconds of this
  animation2(4000);   // 4 seconds of that
}

void animation1(uint32_t wait){

  wait += millis();    // Set a stop time

  while(millis() < wait) {    // Keep looping until stop time reached
    for (int i = 0; i < PIXEL_COUNT; ++i) {
      // solid color pulse of all pixels.
      uint8_t currentStep = (millis()/SPEED_MS)%(colorSteps*2-2);
      if (currentStep >= colorSteps) {
        currentStep = colorSteps-(currentStep-(colorSteps-2));
      }
      // Note that colors are stored in flash memory so they need to be read
      // using the pgmspace.h functions.
      uint32_t color = pgm_read_dword_near(&colorAnimation[currentStep]);
      strip.setPixelColor(i, color);
      strip.show();
    }
  }
}

void animation2(uint32_t wait){

  wait += millis();    // Set a stop time

  while(millis() < wait) {    // Keep looping until stop time reached
    for (int i = 0; i < PIXEL_COUNT; ++i) {
      // Moving color pulse.  Use position to change brightness.
      uint8_t currentStep = (millis()/SPEED_MS-i)%(colorSteps*2-2);

      if (currentStep >= colorSteps) {
        currentStep = colorSteps-(currentStep-(colorSteps-2));
      }
      // Note that colors are stored in flash memory so they need to be read
      // using the pgmspace.h functions.
      uint32_t color = pgm_read_dword_near(&colorAnimation[currentStep]);
      strip.setPixelColor(i, color);
      strip.show();
    }
  }
}
See what you think. (Your original code would be useful for controlling two simultaneous groups of pixels, each doing their own independent display.) Best of success.

Hallelujah!
Disciple

User avatar
adafruit_support_bill
 
Posts: 88088
Joined: Sat Feb 07, 2009 10:11 am

Re: LED animation functions won't play with each other

Post by adafruit_support_bill »

As Disciple says, each of your animation functions is just one iteration of a loop. If you put one of them inside the loop() function, it will work as expected. If you put two of them there, the first will be immediately overwritten by the second. That is why it appears that only the second one is running - slowly.

User avatar
qbit
 
Posts: 27
Joined: Thu Aug 06, 2015 5:36 pm

Re: LED animation functions won't play with each other

Post by qbit »

Thank you, Disciple and Bill, I was pretty sure it was just running one cycle of the function like you said. But I still don't understand how the strandtest code stays in the function until completed. I ran your sample code but now it updates a single LED every six seconds... I've tried so many different variations of delays and delay times but nothing seems to work.

I made an LED sequin hat for a friend for Halloween, and wrote some basic blink functions for it. I had the same problem with functions overlapping and solved it with a crude counter - which I think is basically what your sample code is doing?

I implemented the counter in my animation code here and now both animations work fine.

I feel like it's an amateur solution, but I guess I just need to study the strandtest code a bit more to understand how "wait" works etc.

Thanks for the help!

Code: Select all

void animation1(){

  for(int reps = 0; reps <10000; reps++){  

    for (int i = 0; i < PIXEL_COUNT; ++i) {
      // solid color pulse of all pixels.
      uint8_t currentStep = (millis()/SPEED_MS)%(colorSteps*2-2);
      if (currentStep >= colorSteps) {
        currentStep = colorSteps-(currentStep-(colorSteps-2));
      }
      // Note that colors are stored in flash memory so they need to be read
      // using the pgmspace.h functions.
      uint32_t color = pgm_read_dword_near(&colorAnimation[currentStep]);
      strip.setPixelColor(i, color);
      strip.show();
    }
  }
}

User avatar
adafruit_support_bill
 
Posts: 88088
Joined: Sat Feb 07, 2009 10:11 am

Re: LED animation functions won't play with each other

Post by adafruit_support_bill »

Yes, that is the basic idea. Look at the strandtest functions, they all do something similar.

Code: Select all

void animation1(){

  for(int reps = 0; reps <10000; reps++){  

Locked
Please be positive and constructive with your questions and comments.

Return to “Glowy things (LCD, LED, TFT, EL) purchased at Adafruit”