with advance thanks to Mark Kriegsman and Marc Miller for the help they've already

@marmil - so I tried changing delay to speed with this:

// Overall twinkle speed.
// 0 (VERY slow) to 8 (VERY fast).
uint8_t TWINKLE_SPEED = 0;
//(which I was very proud of myself for figuring out on my own)

and then this:

drawTwinkles( leds);
FastLED.setBrightness(analogRead(A2)/4);
TWINKLE_SPEED = map(analogRead(1), 0, 1023, 0, 255);
gDensity = map(analogRead(0), 0, 1023, 0, 8);
FastLED.show();

which resulted in a very interesting thing…my twinkle is actually more like activity lights on a server, BUT the speed…whoa! I’m only getting adjustments from REALLY fast up to LUDICROUS SPEED…which might be a bit much…the twinkle is kinda cool though…

so for grins, I put back in the delay line, and that seems to give me a tune AND a FINE tune handle on the speed…which is really interesting, and I think would make a fine addition to the box…so to help me better understand, what exactly is the difference between these 2 commands? and what exactly are they controlling?

so NOW, I just need help with getting the switch to work to choose pallets …and maybe tweaking the density control line…it feels like all the adjustments are within a 1/2 turn of the pot, off to full between 12 & 6 on the dial…maybe too many steps between 0 & 255?

@Stuart_Taylor You mentioned the delay line with the debounce with the switch bit…and changing it to FastLED.delay…but since I have that already being read from a pot, won’t that muck things up?

and another update…I poked around looking for basic pushbutton code, and came across a previous discussion where you recommended +Andrew Tuline’s demo100 with switch-https://gist.github.com/atuline/9ea9b277c1e9be341a41 but I’ll be durned if I can figure out how to incorporate it into FOX without mucking up all the other tweaks that Mark & Marc have put into it!

Nice job. For the twinkle speed, instead of mapping to 0-255:
TWINKLE_SPEED = map(analogRead(1), 0, 1023, 0, 255);
I think you want to map to a range of 0-8 (based on Mark’s original suggestion in his code), so like this:
TWINKLE_SPEED = map(analogRead(1), 0, 1023, 0, 8);

Or if you want to go to a slightly higher speed (maybe all the way to 11!) then something like this:
TWINKLE_SPEED = map(analogRead(1), 0, 1023, 0, 11);
You can set what you feel would be the appropriate max twinkle speed this way.

Also note, when rotating your potentiometer knob if it seems backwards, ie. things increase when you’d expect them to decrease when rotating the knob a certain direction, you can reverse that with the mapping. Going from this:
TWINKLE_SPEED = map(analogRead(1), 0, 1023, 0, 8);
to this reverses the direction on the knob.
TWINKLE_SPEED = map(analogRead(1), 0, 1023, 8, 0);
This is useful if you realize you’ve soldered the pos/neg wires on your potentiometer backwards.

After you map twinkle speed to 0-8 then I’m guessing you can remove the delay (or hard code it to something very small/almost zero).

@marmil yeesh, I thought i had made the speed limit 8, but I actually tweaked DENSITY…duh…which also explains the wacky behavior of that pot…

now that I cleared that brainfart, I’m here:

drawTwinkles( leds);
FastLED.setBrightness(analogRead(A2)/4);
TWINKLE_SPEED = map(analogRead(1), 0, 1023, 0, 11);
FastLED.delay(analogRead(A3)/8);
gDensity = map(analogRead(0), 0, 1023, 0, 255);

FastLED.show();

leaving both speed AND delay seems to give me another neat handle on the twinkle, so I think I’d like to leave that in…

reversing the numbers, while handy, wont be necessary, as I would NEVER, EVER reverse solder my contacts…at least not today…yet…

now for the pushbutton…

@Michael_Sime Here’s an example with added button functionality to switch palettes.
[Do not just copy and replace your current code with this though! It’s older code and I removed the potentiometer stuff in this code. Just check out the updates and copy those parts to your current code. You can also update the strip type, number of leds, and button pin number and run this example too.]

@marmil I KNEW there had to be a simpler way to do that! ran your example and it worked fine, and then I copied & pasted the idiot-proof commented code into my last version and it works like a charm…even with the serial monitor…

one thing- the cross-fade between pallets isn’t really wanted or necessary…after reading thru the code umpteen times, I figured out that the line
EVERY_N_MILLISECONDS( 10 ) {
nblendPaletteTowardPalette( gCurrentPalette, gTargetPalette, 12);
controls that…so I changed the 10 to a 0 & it’s better, but there’s still a fade…knowing how my set dresser bretheren will be tweaking this, instant feedback might be better…is there a way to eliminate it completely? maybe on button press, blank the strip and then start the new palette?

and how difficult would it be (code wise) to add a display to this for further user feedback? your addition of the serial read made me think that maybe a wee LCD window might be gooder…of course then I’d have to change the code to show palette name instead of a number

and finally, send me a email with your address…!

I slightly tweaked my code with button example for the nblendPaletteTowardPalette part. Have another look, line 129. Every n milliseconds reduced from 10 to 5, but more importantly, change the number on the end of nblendPaletteTowardPalette from 12 to 254 /and/ repeat the line a few times. Hopefully this makes the switch fast enough.

It should not be hard to add an LCD display as long as you have the free pins on your controller. It could be updated whenever the button is pressed.

I pinged you on Linkedin.

@marmil you done did it again…near-instant (or close enough) palette switching…now to maybe tinker with a LCD display of the serial data, and change the display to give a descriptive palette name instead of a number?

and of course to play with the palettes themselves…do you know if that color picking scheme is necessary? or could something similar be done?

What do you mean by “that color picking scheme”? And what might you prefer?

LCD’s are fun and it can be pretty useful to be able to display some meaningful text. Here’s a good place to start.

Adafruit’s LCD tutorial is good and has some more in depth info too.
https://learn.adafruit.com/adafruit-arduino-lesson-11-lcd-displays-1/overview

If you don’t have an LCD yet you can get them fairly cheap on Amazon such as this one that conveniently comes with header pins and a variable resistor (for adjusting screen contrast).
https://www.amazon.com/dp/B0059H616G/

One thing to note is that these LCDs need 6 pins to control them, so make sure your micro controller has enough available pins if you want to add one to your setup.

@marmil by "the color picking scheme’ I was referring to the blocks of colors like this:
const TProgmemRGBPalette16 RedGreenWhite_p FL_PROGMEM =
{ CRGB::Red, CRGB::Red, CRGB::Red, CRGB::Red,
CRGB::Red, CRGB::Red, CRGB::Red, CRGB::Red,
CRGB::Red, CRGB::Red, CRGB::Gray, CRGB::Gray,
CRGB::Green, CRGB::Green, CRGB::Green, CRGB::Green };

I assume the ‘palette16’ and the 16 calls for color are related, but not sure why we need 16…I guess for to make more random or something? I was thinking that something a bit simPler could be done, but I guess it doesn’t really matter if we kinda need to stick to the 16x colors in a palette

The other thing was the naming & how the serial.read shows it- instead of showing the palette number, I’d want to show a descriptive name

I cleaned up my prototype from 3 small breadboards to one big one last night and added a 2x16 LCD, ran Hello World so I know I wired it correctly, huzzah!

after doing that, I found the Adafruit code to display serial data:

// include the library code:
#include <LiquidCrystal.h>

// initialize the library with the numbers of the interface pins
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);

void setup() {
// set up the LCD’s number of columns and rows:
lcd.begin(16, 2);
// initialize the serial communications:
Serial.begin(9600);
}

void loop() {
// when characters arrive over the serial port…
if (Serial.available()) {
// wait a bit for the entire message to arrive
delay(100);
// clear the screen
lcd.clear();
// read all the available characters
while (Serial.available() > 0) {
// display each character to the LCD
lcd.write(Serial.read());
}
}
}

which I attempted to insert into our blinkyserver code, but again, I seem to be floundering about in the dark… I put the #inlcude & initialize in at the top of the sketch, added the setup() in amongst the other setup stuff, but then I dunno where to put the LCD loop function…I find that depending on where I place it in amongst the main loop, the code may or may not compile…I don’t think you can have more than on loop can you? I even tried putting toward the end of the sketch by the serial print lines, to no avail…methinks I’m missing another semicolon or something…or it’s just placement…or I’m an idiot…one of those is definitely the issue

here’s my last try if anyone is so inclined to take a look so they can see what a silly bugger I am…and thanks in advance

I don’t think you want any of those Serial available or Serial read lines. That’s used if you were sending data to the micro controller and it needed to check if there was data, and if so read it. You’re not doing that so you can delete those lines. You’re in the right section for adding the lcd.setCursor and lcd.print lines though. More related to this below.

Yes, your palettes are going to be setup something like the examples, with 16 color entries. But there are a few things you can do that might make it more logical to you, or make them easier to update/tweak. For example define the colors with simple names and use those in the palette. Remember you can define a color using the built in FastLED names, or with RGB, HSV, or HEX. Whatever you prefer. I would also suggest renaming all the palettes to something that is meaningful to you in regards to a server rack display. Make a list of names that would make sense to someone looking at the LCD screen (16 characters or less!) Then start renaming/ordering/building new palettes.

Example defining colors different ways and with simple names

// Defined colors
#define bk CRGB::Black
#define r1 CRGB::Red;
#define g1 CRGB::Green;
#define g2 CRGB( 0, 255, 0)
#define g3 CHSV( 96, 255, 255)
#define g4 0x00FF00
#define b1 CRGB::Blue

// palette with only greens version 1
const TProgmemPalette16 greens_v1 PROGMEM =
{
g1, g2, g1, g2,
g2, bk, g2, bk,
g1, g1, g1, g1,
g1, bk, g2, g2
};

// palette with only greens version 2
const TProgmemPalette16 greens_v2 PROGMEM =
{
g1, g2, g1, g2, g3, g4, g3, g4,
bk, g3, bk, g3, g4, g4, g4, g3
};

etc.

Then you will update your ActivePaletteList[] with all your custom palettes:
const TProgmemRGBPalette16* ActivePaletteList[] = {
&greens_v1,
&greens_v2,
&red_v1,
&multicolor_v1 //etc
};

Then to be able to print out those palette names to the LCD make a list with those names in the exact same order. You can however change the text to read however you’d like, such as capitalizing things or using spaces instead of underscores for example. Keeping the same order is the important part. So something like this using the names from ActivePaletteList above, but slightly re-formatting how the end user will see the name:

// palette names to display on LCD
// [Must be the same number of palettes and in the same order as in ActivePaletteList above. Re-formatting the actual text displayed is fine though. Note spaces have been added in the quotes to make it a total of 16 chars so it will complete overwrite any previous text on the LCD screen.]
const char * paletteNames[] = {
" Greens only v1 ",
" Greens only v2 ",
" Reds v1 ",
" Multicolor v1 "
};

Then under this line:
Serial.print(" Current palette choice: “); Serial.println(whichPalette);
You can add this to get a name to go with the number:
Serial.print(” Palette name: "); Serial.println(paletteNames[whichPalette]);
(And confirm the number is matching with the name :slight_smile:

Similarly, you can use this for printing the name to the LCD. So something like:
lcd.setCursor(0, 0); // col 0, line 0
lcd.print(“Current palette:”);
lcd.setCursor(0, 1); // col 0, line 1
lcd.print(paletteNames[whichPalette]);

SUCCESS!
missing/deleted image from Google+

Huzzah!

(Also impressed with and appreciate your super clean prototyping setup. :slight_smile:

@marmil well, remember I DID say I had to clean it up…:wink: V1 was on 3 different breadboards & loose jumpers and dangly bits…

tonite’s homework- renaming palettes and making new ones…probably just a mix of primary colors along with white…

thanks again for all of your help!