Page 1 of 1
Forum

Welcome to the Tweaking4All community forums!
When participating, please keep the Forum Rules in mind!

Topics for particular software or systems: Start your topic link with the name of the application or system.
For example “MacOS X – Your question“, or “MS Word – Your Tip or Trick“.

Please note that switching to another language when reading a post will not bring you to the same post, in Dutch, as there is no translation for that post!



multiple ws2812b st...
 
Share:
Notifications
Clear all

[Solved] multiple ws2812b strands and effects

25 Posts
2 Users
0 Likes
10.4 K Views
 Hans
(@hans)
Famed Member Admin
Joined: 11 years ago
Posts: 2678
 

That's great to hear, and you should be proud of yourself! Not many people hang-on to figure things out! 

Making RunningLights faster can be tricky, since the sin calculation is probably the only thing that chews up most of the consumed time.

void RunningLights(byte red, byte green, byte blue, int WaveDelay) {
  int Position=0;
  
  for(int i=0; i<NUM_LEDS*2; i++)
  {
      Position++; // = 0; //Position + Rate;
      for(int i=0; i<NUM_LEDS; i++) {
        setPixel(i,((sin(i+Position) * 127 + 128)/255)*red,
                   ((sin(i+Position) * 127 + 128)/255)*green,
                   ((sin(i+Position) * 127 + 128)/255)*blue);
      }
      
      showStrip();
      delay(WaveDelay); // <-- this line
  }
}

The fastest, with this code, would be by removing the indicated line.
But you will probably not gain much with that, if anything at all (since you already used WaveDelay=0).

To make the sin calculations faster, you could create an array with pre-calculated values.
So create an array of integers 0 - NUM_LEDS, and fill it with the values "sin" would have produced.

Maybe this can be as simple as the following code.

Note: 

  • I've stored most of the calculation (the common part) in the array (in setup(), since we only want to do this once, and keep reusing the values)
  • I have no idea how much faster this will be, and if it's even faster (I assume it will be faster though)
...

int SinValues[NUM_LEDS];
...
void setup() {
  ...
  for (int 1=0; i<NUM_LEDS; i++) { // populate array with numbers
        SinValues = ((sin(i+Position) * 127 + 128)/255);
  } ...
} ...
void RunningLights(byte red, byte green, byte blue, int WaveDelay) {
  int Position=0;
  
  for(int i=0; i<NUM_LEDS*2; i++)
  {
      Position++; // = 0; //Position + Rate;
      for(int i=0; i<NUM_LEDS; i++) {
        setPixel(i,SinValues*red,
                   SinValues*green,
                   SinValues*blue);
      }
      
      showStrip();
      delay(WaveDelay); 
  }
}

Hope this helps ... 


   
ReplyQuote
 Hans
(@hans)
Famed Member Admin
Joined: 11 years ago
Posts: 2678
 

p.s. I'm curious about your findings speed-wise! 


   
ReplyQuote
(@supramp)
Active Member
Joined: 5 years ago
Posts: 16
Topic starter  

If I get some time tonight I will copy the current sketch, and  make the modifications.  If I think about it, I will splice together a short video showing the differences between the wavedelay changes, and the new code. Its proving difficult to shorten the effect time without speeding up the speed in which the light wave travels.  I will keep you posted.


   
ReplyQuote
(@supramp)
Active Member
Joined: 5 years ago
Posts: 16
Topic starter  

I havent had a chance to work on this since, but I will update when I do. But another question arises.

I received my vibration sensor today and it seem very sensitive. Causing my interrupt to stay active until it calms down.  This was foreseeable,  but unplanned. Is there a way to put a timer, or delay on the interrupt so that it triggers,  but can't reinitiate until it clears or cant reinitiate for a set time, say 1000 or 2000 ms?


   
ReplyQuote
 Hans
(@hans)
Famed Member Admin
Joined: 11 years ago
Posts: 2678
 

Well, you could try to use the detachinterrupt() function as soon as it triggers the interrupt, wait for 2 seconds and use attachinterrupt() to re-attach the interrupt again. I've never tried that, but it's worth a shot ... I noticed in one of your code examples that you have the interrupts call Strobe and RunningLights directly though. To avoid issues, I'd make those separate functions, to avoid that buttons no longer respond.

Not sure if this is the cleanest way of doing it, though and you may have some timing issues, although I do recall timer interrupts.
Some articles on the timer interrupts topic: AdaFruit, Instructables and RobotShop Arduino 101.


   
ReplyQuote
(@supramp)
Active Member
Joined: 5 years ago
Posts: 16
Topic starter  

Im going to research the detachinterrupt() that you mentioned, as for the way the interrupts call the void functions, this was the way I was able to get ut to work without causing problems in my void loop.  How would you change it using the last sketch I posted?


   
ReplyQuote
(@supramp)
Active Member
Joined: 5 years ago
Posts: 16
Topic starter  

Do you think this will work? Leaving the setup alone, and adding this in the void loop. I assume when the pin is pressed, the interrupt triggers outside of the void loop. which would in return detach the pin in the void strobe and only reattach it in when it goes low .  Thats the idea anyway. added lines are in bold

void loop() {
    if (BUTTON_Vibrate == High{
	attachInterrupt(digitalPinToInterrupt(BUTTON_Vibrate);
	}
    else {
 	meteorRain(0xff,0xff,0xff,10, 64, true, 15);  // blue meteor rain
 	FadeInOut(0xff, 0xff, 0xff);                  // blue fade in-out
        }
}
void Strobe(byte red, byte green, byte blue, int StrobeCount, int FlashDelay, int EndPause){
 detachInterrupt(digitalPinToInterrupt(BUTTON_Vibrate));
  for(int j = 0; j < 10; j++) {
    setAll_0(0xff,0xff,0xff);
    setAll_1(0xff,0xff,0xff);
    showStrip_0();
    showStrip_1();
    delay(50);
    setAll_0(0,0,0);
    setAll_1(0,0,0);
    showStrip_0();
    showStrip_1();
    delay(50);
  }
 delay(25);
}

   
ReplyQuote
 Hans
(@hans)
Famed Member Admin
Joined: 11 years ago
Posts: 2678
 

I'm not sure if that will work.

You could try:

void loop() {
  if (BUTTON_Vibrate == High{
  attachInterrupt(digitalPinToInterrupt(BUTTON_Vibrate);
  }
  else {
  detachInterrupt(digitalPinToInterrupt(BUTTON_Vibrate));
  meteorRain(0xff,0xff,0xff,10, 64, true, 15); // blue meteor rain
  FadeInOut(0xff, 0xff, 0xff); // blue fade in-out
  }
}

It would take some experimenting to get the desired timing.


   
ReplyQuote
(@supramp)
Active Member
Joined: 5 years ago
Posts: 16
Topic starter  

I havent given up on this, Just had a busy week.  Had to put down our furried family member.  I will be sure to update this when I get a chance in case it may help someone else in the future.


   
ReplyQuote
 Hans
(@hans)
Famed Member Admin
Joined: 11 years ago
Posts: 2678
 

Hi Supramp,

having lost my share of furry friends, I know how devastating this can be.
My sympathies on your loss 


   
ReplyQuote
Page 2 / 2
Share: