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!




Guitar backlight le...
 
Share:
Notifications
Clear all

Guitar backlight led effects

12 Posts
2 Users
3 Likes
2,011 Views
(@Anonymous)
Joined: 1 second ago
Posts: 0
Topic starter  

Hi all, complete rookie here.

 

Loving the Arduino so far, but still just can't get my head around how all this works. Reverse engineering for me just isn't making sense.

 

What I'm going to do is put a 60 LED RBG strip on the back of my guitar for live shows (see here - yes, that's me). This was using a standard RGB strip that isn't addressable, so no fancy effects other than rainbow fades (ie total led strip is always same colour).

While I don't actually have the strip in hand yet, I'd like to have the effects from the All-In-One set run in random places on the strip, not at the 'start' of the strip and to change to the next effect by push-button (which I believe is already written into the all-effects code). Effects that I would like adjusted:

- Fire: effect should happen in two places (maybe centering somewhere near LED #15-20 and #40-45).

- Meteor Rain: Just about right, but could be better suited if it was faster, and randomly coloured.

 

I have ABSOLUTELY no idea where or how to start other than uploading the All-In-One to the Arduino and connecting the wires 😥 

 

Please help!


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

That looks awesome - love it! And you started in the right place (the forum)! 👍 

Do I understand this right: you only want 2 effects (custom Fire and Meteor rain), based on the All-in-One LED project?

Some more questions;

Fire Effect;

So you want the fire effect to run double (2 at the same time).
I'm just not sure what you mean with centered somewhere near 15-20 and 40-45 (I presume this is based on the shape of your guitar)?

Meteor Rain;

There are 2 ways to get Meteor Rain faster;
1. The last parameter when the function is called, set this one to zero.
2. Use the FastLED library instead of the NeoPixel library. FastLED is more mature and faster in general.

If these 2 tricks still are not fast enough, then you could try tinkering with the "NUM_LEDS+NUM_LEDS" value in the for-loop in the meteor rain function.
Start with "NUM_LEDS" instead of "NUM_LEDS+NUM_LEDS", and slowly increase this (eg. NUM_LEDS+1, NUM_LEDS+2, etc) until you see it fitting for your parameters.
I'm guessing you'll end up somewhere around "NUM_LEDS+meteorSize".

Let me know where you get stuck and where I can help. I'd like to help where I can 😊 


   
shwifty reacted
ReplyQuote
(@Anonymous)
Joined: 1 second ago
Posts: 0
Topic starter  

Thank you for the reply!

I’m happy with all the other effects in the complete set, so the only two I would like customised are the fire and meteor. 

For fire, yes, based on the shape of the guitar, roughly led chip number 20 (from the start of the strip) and 40 are the center where I would like the two fire effects to happen. Yes, double effect (going both ways if that makes sense? If you want more clarification I can try explain it better).

I will have a tinker with what you recommended for meteor (but I only have a 24 led ring to try it on at the moment - the new strip will arrive next week). Any chance that could also be mirrored? As in happening twice?

And how do I go about making sure it’s using the FastLED library instead of Neopixel?

This post was modified 3 years ago by Anonymous

   
ReplyQuote
 Hans
(@hans)
Famed Member Admin
Joined: 11 years ago
Posts: 2654
 
Posted by: @shwifty

For fire, yes, based on the shape of the guitar, roughly led chip number 20

It would be good to determine the beginning point, so I'd define those, so you can play with them and see what works best.
For now I assume both are the same length.

// way in the beginning of the sketch, near #define NUM_LEDS
#define FireStart1 10  // LED where the first fire starts
#define FireStart2 30  // LED where the second fire starts
#define FireLength 20  // Number of LEDs for each fire effect

 

Next we need to adjust the Fire function to use these values, which means we have to adjust the setPixelHeatColor function as well.
The code below replaces the existing functions.
Something like this (I am unable to test this code, since I do not have the hardware handy at the moment);

// New Fire functions
void Fire(int Cooling, int Sparking, int SpeedDelay) {
  static byte heat[FireLength];
  int cooldown;
 
  // Step 1.  Cool down every cell a little
  for( int i = 0; i < FireLength; i++) {
    cooldown = random(0, ((Cooling * 10) / FireLength) + 2);
   
    if(cooldown>heat[i]) {
      heat[i]=0;
    } else {
      heat[i]=heat[i]-cooldown;
    }
  }
 
  // Step 2.  Heat from each cell drifts 'up' and diffuses a little
  for( int k= FireLength - 1; k >= 2; k--) {
    heat[k] = (heat[k - 1] + heat[k - 2] + heat[k - 2]) / 3;
  }
   
  // Step 3.  Randomly ignite new 'sparks' near the bottom
  if( random(255) < Sparking ) {
    int y = random(7);
    heat[y] = heat[y] + random(160,255);
    //heat[y] = random(160,255);
  }

  // Step 4.  Convert heat to LED colors
  for( int j = 0; j < FireLength; j++) {
    setPixelHeatColor(j, heat[j] );
  }

  showStrip();
  delay(SpeedDelay);
}

// New setPixelHeatColor function
void setPixelHeatColor (int Pixel, byte temperature) {
  // Scale 'heat' down from 0-255 to 0-191
  byte t192 = round((temperature/255.0)*191);
 
  // calculate ramp up from
  byte heatramp = t192 & 0x3F; // 0..63
  heatramp <<= 2; // scale up to 0..252
 
  // figure out which third of the spectrum we're in:
  if( t192 > 0x80) {                     // hottest
    setPixel(FireStart1+Pixel, 255, 255, heatramp);
    setPixel(FireStart2+Pixel, 255, 255, heatramp);
  } else if( t192 > 0x40 ) {             // middle
    setPixel(FireStart1+Pixel, 255, heatramp, 0);
    setPixel(FireStart2+Pixel, 255, heatramp, 0);
  } else {                               // coolest
    setPixel(FireStart1+Pixel, heatramp, 0, 0);
    setPixel(FireStart2+Pixel, heatramp, 0, 0);
  }
}

 

Doing the meteor rain twice is possible of course, but I'll have to look into that as it is a little more complicated due to the fading of the LEDs.

As for selecting FastLED vs NeoPixel;

If you see in the first lines of your sketch something like this:

#include <Adafruit_NeoPixel.h>

 

then replace it with this:

#include "FastLED.h"

 

The sketch was written to accommodate both.
Now, having said that: we could potentially remove all code that makes this work for both libraries, but I'm not sure if we get much speed gain with that.


   
shwifty reacted
ReplyQuote
 Hans
(@hans)
Famed Member Admin
Joined: 11 years ago
Posts: 2654
 

Forgot to answer your "mirror" question I guess haha.

As you can see in the part of the "setPixelHeatColor" function, we basically  do it twice (FiresTart1+Pixel and FireStart2+Pixel).

  if( t192 > 0x80) {                     // hottest
    setPixel(FireStart1+Pixel, 255, 255, heatramp);
    setPixel(FireStart2+Pixel, 255, 255, heatramp);
  } else if( t192 > 0x40 ) {             // middle
    setPixel(FireStart1+Pixel, 255, heatramp, 0);
    setPixel(FireStart2+Pixel, 255, heatramp, 0);
  } else {                               // coolest
    setPixel(FireStart1+Pixel, heatramp, 0, 0);
    setPixel(FireStart2+Pixel, heatramp, 0, 0);

 

This could be the place to mirror the meteor effect.

Lets' assume the FireStart2 position is the middle position over which we mirror.
In that case you could rewrite the code something like this:

  if( t192 > 0x80) {                     // hottest
    setPixel(FireStart2+Pixel, 255, 255, heatramp);
    setPixel( (FireStart2-1) -Pixel, 255, 255, heatramp);
  } else if( t192 > 0x40 ) {             // middle
    setPixel(FireStart2+Pixel, 255, heatramp, 0);
    setPixel((FireStart2-1) - Pixel, 255, heatramp, 0);
  } else {                               // coolest
    setPixel(FireStart2+Pixel, heatramp, 0, 0);
    setPixel((FireStart2-1)  -Pixel, heatramp, 0, 0);

 

I'm setting the LED number "FireStart2 + Pixel", and the LED before FireStart2 (FireStart2-1) minus the Pixel.

This should cause a mirror effect. 😊 

 


   
shwifty reacted
ReplyQuote


(@Anonymous)
Joined: 1 second ago
Posts: 0
Topic starter  

Amazing work. I still can't make heads or tails of what is going on or how it works, but playing with numbers is at least changing the effects to my liking 🙃 


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

Cool - well, it usually takes a little playing with numbers for me as well 😊 
Let me know if you have any question later on 😉 


   
ReplyQuote
(@Anonymous)
Joined: 1 second ago
Posts: 0
Topic starter  

Awesome. I think I have tweaked all the effects to my liking, just waiting on one more component before I get into assembly.

 

I have 2 LAST REQUESTS:

1. Is it possible to make an equaliser effect? Similar to these lamps in this video?? (But the gradient going from green to yellow to red?) The random bouncing may be a challenge...

2. Can the push-button select a random effect rather than scroll through a set order? And do each effect once before it repeats? I'm guessing this may just need to add a counter to each effect ('0' for not used yet, '1' for used, then once each effect is assigned '1', it will reset them all to '0')

 

I feel greedy asking, but you've done such an amazing job and you really know what you're doing. It would be years before I learn how to do this stuff.


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

Cool, and thank you for the compliment - just remember that I'm just a hobbyist as well 😉 

I'll start with your second question, since that's the easier one to answer.

To change the button to a select a random effect, we just have to make a minor change (assuming you're using the base code from the All-in-One project).
We only have to look at the changeEffect() function:

void changeEffect() {
  if (digitalRead (BUTTON) == HIGH) {
    selectedEffect++;
    EEPROM.put(0, selectedEffect);
    asm volatile ("  jmp 0");
  }
}

 

Instead of increasing the selectedEffect value, we just make that a random number.
Something like this:

void changeEffect() {
  if (digitalRead (BUTTON) == HIGH) {
    selectedEffect = random(0,18); // 18 = number of effects you have
    EEPROM.put(0, selectedEffect);
    asm volatile ("  jmp 0");
  }
}

 

You'll see the "selectedEffect = random(0,18)" which replaces the original "selectedEffect++" line.
Here "18" is the number of effects you have, so in case you have less or more than 18, you'll need to adjust that number.

It is the same number as used at the beginning of the "void loop()" function where it checks if the selectedEffect is within range (where it says if(selectedEffect>18) )

We will need to add this line somewhere in the "void setup()" function to make a better randomizer (still not the best randomizer though):

randomSeed(analogRead(0));

 

I'll try to answer the other question in the next reply to keep things organized 😉 


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

Making a green-yellow-red gradient is most certainly possible, but I'd call that a new effect.

I had to look for an "easy" way to make a gradient and it seems the latest FastLED library has a DEFINE_GRADIENT_PALETTE function for that.
(untested by me, since I do not have my LED strips readily available)

So in the beginning of your code (before "void setup()")  we need to define the palette we're going to use.

The numbers are set in this order:

// not real code! Just to illustrate what the numbers mean
DEFINE_GRADIENT_PALETTE(heatmap_gp) {
 StartPosition1, RedPos1, GreenPos1, BluePos1,
 StartPosition2, RedPos2, GreenPos2, BluePos2,
 StartPosition3, RedPos3, GreenPos3, BluePos3  }; 

 

(you can define more colors if you'd like by simply adding a line - just make sure the starting point of each color is greater than the previous color in the gradient)

DEFINE_GRADIENT_PALETTE(heatmap_gp) {
  0,     0,  0,  255,   //green starts at led 0
128,   255,  255,  0,   //yellow at led 128
224,   255, 0,  0,      //red at led yellow  }; 

CRGBPalette16 myPalette = heatmap_gp; 

// after this the void setup function

 

 With this we have created a gradient scale of 255 steps, called "myPalette".

Next we have to use this in a function, something like this:

void ShowPalette( int LEDCount ) {
  // set all LEDs to black
  FastLED.clear();  

  // Copy Gradient
  for(int i; i<LEDCount; i++ ) {
    leds[i] = ColorFromPalette( myPalette, (255/NUM_LEDS) * i );
  }

  // Show the gradient
  FastLED.show();
}

 

You see the calculation ( (255/NUM_LEDS)*i ) which is needed to convert a 255 color count to match a NUM_LEDS number of LEDs (since you most likely do not have 255 LEDs on your guitar 🤣 ).

This means that the number of displayed LEDs will display the entire color range only when all LEDs (NUM_LEDS) are being lit.

Alternatively, you could scale the gradient so that the gradient always shows the 3 colors (so the gradient grows and shrinks with the LEDCount we pass to the function).
This could be done something like this:

void ShowPalette( int LEDCount ) {
  // set all LEDs to black
  FastLED.clear();  

  // Copy Gradient
  for(int i; i<LEDCount; i++ ) {
    leds[i] = ColorFromPalette( myPalette, (255/LEDCount) * i );
  }

  // Show the gradient
  FastLED.show();
}

 

We can call this effect like so:

ShowPalette(random(0,NUM_LEDS)); // pick a random length between zero and NUM_LEDS-1

 

You'll have to play a little with the numbers to get it just right for your purposes. of course.

For example; when calling ShowPalette, I'd want to make sure that there is a minimum number of LEDs visible, for example

ShowPalette(random(15,NUM_LEDS)); // pick a random length between 15 and NUM_LEDS-1

 

Again: I have not tested this code, since my gear is not anywhere near me.

 


   
ReplyQuote


(@Anonymous)
Joined: 1 second ago
Posts: 0
Topic starter  

OK, it's looking pretty good. Just trying to finalize all my parts and get it working all together.

Last question. I know I requested a button press for a random effect (which actually needs debouncing. It seems to trigger multiple presses and flick through effects), but I'd love to also have the option of time switch. How would I change the random effect to change every X seconds??


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

Awesome! I'm so curious to see what the end result will look like 😁 

Debouncing can be done in several ways. One is by registering the time a button was pressed in a global variable. When the button gets pressed again, we check if at least an X amount on milliseconds have passed.

Randomizing effects; This may be a little bit more challenging.
I'd make that one of the selectable effects, and inside the call for that effect, I'd randomly call the other effect functions, each after a random number of milliseconds. You may need an extra global variable for selecting and timing these.

I hope that makes sense ... 😜 

 


   
ReplyQuote

Like what you see and you'd like to help out? 

The best way to help is of course by assisting others with their questions here in the forum, but you can also help us out in other ways:

- Do your shopping at Amazon, it will not cost you anything extra but may generate a small commission for us,
- send a cup of coffee through PayPal ($5, $10, $20, or custom amount),
- become a Patreon,
- donate BitCoin (BTC), or BitCoinCash (BCH).

Share: