Skip to content

Add Ability to specify start hue and hue amount to affect all other e… #4

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 2 commits into
base: experimental
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion RGBShades.ino
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,9 @@ functionList effectList[] = {threeSine,
colorFill,
sideRain,
shadesOutline,
hearts};
hearts,
pickHueStartColor,
pickHueAmount};

// Timing parameters
#define cycleTime 15000
Expand Down
106 changes: 89 additions & 17 deletions effects.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,13 @@ void threeSine() {
// startup tasks
if (effectInit == false) {
effectInit = true;
effectDelay = 20;
if(doHueSubsection)//Pause the effect to show the last saved hue amount
{
effectDelay = 600;
return;
}
}
effectDelay = 20;

// Draw one frame of the animation into the LED array
for (byte x = 0; x < kMatrixWidth; x++) {
Expand All @@ -25,8 +30,20 @@ void threeSine() {
byte sinDistanceR = qmul8(abs(y*(255/kMatrixHeight) - sin8(sineOffset*9+x*16)),2);
byte sinDistanceG = qmul8(abs(y*(255/kMatrixHeight) - sin8(sineOffset*10+x*16)),2);
byte sinDistanceB = qmul8(abs(y*(255/kMatrixHeight) - sin8(sineOffset*11+x*16)),2);

leds[XY(x,y)] = CRGB(255-sinDistanceR, 255-sinDistanceG, 255-sinDistanceB);

if(doHueSubsection)
{
CRGB firstColor = SectionCHSV(0, 255, 255);
CRGB secondColor = SectionCHSV(85, 255, 255);
CRGB thirdColor = SectionCHSV(170, 255, 255);
leds[XY(x,y)] =
firstColor.nscale8(255-sinDistanceR) +
secondColor.nscale8(255-sinDistanceG) +
thirdColor.nscale8(255-sinDistanceB);
}else
{
leds[XY(x,y)] = CRGB(255-sinDistanceR, 255-sinDistanceG, 255-sinDistanceB);
}
}
}

Expand Down Expand Up @@ -57,7 +74,7 @@ void plasma() {
for (int x = 0; x < kMatrixWidth; x++) {
for (int y = 0; y < kMatrixHeight; y++) {
byte color = sin8(sqrt(sq(((float)x-7.5)*10+xOffset-127)+sq(((float)y-2)*10+yOffset-127))+offset);
leds[XY(x,y)] = CHSV(color, 255, 255);
leds[XY(x,y)] = SectionCHSV(color, 255, 255);
}
}

Expand All @@ -83,7 +100,7 @@ void rider() {
int brightness = abs(x*(256/kMatrixWidth) - triwave8(riderPos)*2 + 127)*3;
if (brightness > 255) brightness = 255;
brightness = 255 - brightness;
CRGB riderColor = CHSV(cycleHue, 255, brightness);
CRGB riderColor = SectionCHSV(cycleHue, 255, brightness);
for (byte y = 0; y < kMatrixHeight; y++) {
leds[XY(x,y)] = riderColor;
}
Expand All @@ -107,7 +124,7 @@ void glitter() {
// Draw one frame of the animation into the LED array
for (int x = 0; x < kMatrixWidth; x++) {
for (int y = 0; y <kMatrixHeight; y++) {
leds[XY(x,y)] = CHSV(cycleHue,255,random8(5)*63);
leds[XY(x,y)] = SectionCHSV(cycleHue,255,random8(5)*63);
}
}

Expand All @@ -118,6 +135,7 @@ void glitter() {
byte currentColor = 0;
byte currentRow = 0;
byte currentDirection = 0;
CRGB selectedColor = 0;
void colorFill() {

// startup tasks
Expand All @@ -129,14 +147,18 @@ void colorFill() {
currentDirection = 0;
currentPalette = RainbowColors_p;
}
if (!doHueSubsection)
selectedColor = currentPalette[currentColor];
else
selectedColor = SectionCHSV(currentColor * 16, 255, 255);

// test a bitmask to fill up or down when currentDirection is 0 or 2 (0b00 or 0b10)
if (!(currentDirection & 1)) {
effectDelay = 45; // slower since vertical has fewer pixels
for (byte x = 0; x < kMatrixWidth; x++) {
byte y = currentRow;
if (currentDirection == 2) y = kMatrixHeight - 1 - currentRow;
leds[XY(x,y)] = currentPalette[currentColor];
leds[XY(x,y)] = selectedColor;
}
}

Expand All @@ -146,7 +168,7 @@ void colorFill() {
for (byte y = 0; y < kMatrixHeight; y++) {
byte x = currentRow;
if (currentDirection == 3) x = kMatrixWidth - 1 - currentRow;
leds[XY(x,y)] = currentPalette[currentColor];
leds[XY(x,y)] = selectedColor;
}
}

Expand Down Expand Up @@ -177,9 +199,9 @@ void threeDee() {
for (byte x = 0; x < kMatrixWidth; x++) {
for (byte y = 0; y < kMatrixHeight; y++) {
if (x < 7) {
leds[XY(x,y)] = CRGB::Blue;
leds[XY(x,y)] = SectionCHSV(170, 255, 255);
} else if (x > 8) {
leds[XY(x,y)] = CRGB::Red;
leds[XY(x,y)] = SectionCHSV(0, 255, 255);
} else {
leds[XY(x,y)] = CRGB::Black;
}
Expand All @@ -204,7 +226,7 @@ void sideRain() {
scrollArray(rainDir);
byte randPixel = random8(kMatrixHeight);
for (byte y = 0; y < kMatrixHeight; y++) leds[XY((kMatrixWidth-1) * rainDir,y)] = CRGB::Black;
leds[XY((kMatrixWidth-1)*rainDir, randPixel)] = CHSV(cycleHue, 255, 255);
leds[XY((kMatrixWidth-1)*rainDir, randPixel)] = SectionCHSV(cycleHue, 255, 255);

}

Expand All @@ -221,7 +243,10 @@ void confetti() {

// scatter random colored pixels at several random coordinates
for (byte i = 0; i < 4; i++) {
leds[XY(random16(kMatrixWidth),random16(kMatrixHeight))] = ColorFromPalette(currentPalette, random16(255), 255);//CHSV(random16(255), 255, 255);
if (!doHueSubsection)
leds[XY(random16(kMatrixWidth),random16(kMatrixHeight))] = ColorFromPalette(currentPalette, random16(255), 255);
else
leds[XY(random16(kMatrixWidth), random16(kMatrixHeight))] = SectionCHSV(random16(255), 255, 255);
random16_add_entropy(1);
}

Expand All @@ -240,7 +265,7 @@ void slantBars() {

for (byte x = 0; x < kMatrixWidth; x++) {
for (byte y = 0; y < kMatrixHeight; y++) {
leds[XY(x,y)] = CHSV(cycleHue, 255, quadwave8(x*32+y*32+slantPos));
leds[XY(x,y)] = SectionCHSV(cycleHue, 255, quadwave8(x*32+y*32+slantPos));
}
}

Expand All @@ -263,7 +288,10 @@ void shadesOutline(){
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 43,
44, 67, 66, 65, 64, 63, 50, 37, 21, 22, 36, 51, 62, 61, 60, 59,
58, 57, 30, 29};
if (!doHueSubsection)
leds[OutlineTable[x]] = currentPalette[currentColor];
else
leds[OutlineTable[x]] = SectionCHSV(currentColor * 16, 255, 255);
if (erase)
leds[OutlineTable[x]] = CRGB::Black;
x++;
Expand Down Expand Up @@ -298,18 +326,62 @@ void hearts() {
y = 0;
if (y == 0)
for (x = 0; x < 6; x++)
leds[SmHeart[x]] = CRGB::Salmon; //Tried to transition from pink-ish to red. Kinda worked.
leds[SmHeart[x]] = SectionCHSV(0, 255, 255);
if (y == 1)
for (x = 0; x < 18; x++)
leds[MedHeart[x]] = CRGB::Tomato;
leds[MedHeart[x]] = SectionCHSV(42, 255, 255);
if (y == 2)
for (x = 0; x < 26; x++)
leds[LrgHeart[x]] = CRGB::Crimson;
leds[LrgHeart[x]] = SectionCHSV(84, 255, 255);
if (y == 3){
for (x = 0; x < 40; x++)
leds[HugeHeart[x]] = CRGB::Red;
leds[HugeHeart[x]] = SectionCHSV(126, 255, 255);
effectDelay = 450;} //set the delay slightly longer for HUGE heart.
if (y == 4)
FastLED.clear();
y++;
}

//Blasts a hue over all LEDs, the color when the effect ends becomes the start hue for all other effects
void pickHueStartColor() {
// startup tasks
if (effectInit == false) {
effectInit = true;
effectDelay = 15;
doHueSubsection = true;
}
fillAll(SectionCHSV(0, 255, 255));
incrimentHueOffset(1);
}

//Left to right rainbow, when the effect is over, the length of the hue shift is used to limit hue in all other effects
void pickHueAmount()
{
// startup tasks
if (effectInit == false) {
effectInit = true;
//Add a delay here for a moment to verify settings
effectDelay = 300;
return;
}
effectDelay = 40;//Speed back to normal

incrimentHueAmmount(1);
byte maxLeds = kMatrixHeight * kMatrixWidth;
//Loop left to right over each led
for (byte y = 0; y < kMatrixHeight; y++) {
for (byte x = 0; x < (kMatrixWidth - 0); x++) {
byte number = (x*kMatrixHeight) + y;
//Draw a led of the hue of the max value if the division of hue had stopped there
if ((hueAmmount) >(number * (255 / maxLeds)))
{
leds[XY(x, y)] = CHSV(((255. * number) / maxLeds) + hueOffset, 255, 255);
}
else
{
leds[XY(x, y)] = SectionCHSV(0, 0, 0);
}
}
}
}

30 changes: 30 additions & 0 deletions utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,36 @@ void hueCycle(byte incr) {
cycleHue+=incr;
}

/* Instead of a perpetually incrimenting hue, override hue calculations to instead do a
* sinusodial loop back and forth over a smaller section of the scale.
* This can allow various effects, ice, hue, or even single colors.
* If the hue ammount is close to max, switch back to an incrimental mode and allow pallets
* to be used again. Continually incrimenting the offset and ammount allows the autoCycle
* mode to keep making new sections.
*/
//Keep making new effects.
byte hueOffset = 0;//The start hue for our cycle
byte hueAmmountIncrimentor = 0;//incrimentor for generating the hueAmmount
byte hueAmmount = 1;//The distance across the hue scale to allow sliding
bool doHueSubsection = false;//Switch to go back to a continuous hue slide (no more back & forth)
CHSV SectionCHSV(uint8_t h, uint8_t s, uint8_t v)
{
//return a hue from a sinusodial wave across our current section of the hue scale
if (doHueSubsection)return CHSV((quadwave8(h) / (255. / hueAmmount)) + hueOffset, s, v);
return CHSV(h, s, v);
}
void incrimentHueOffset(uint8_t offset)
{
hueOffset += offset;
}
void incrimentHueAmmount(uint8_t offset)
{
hueAmmountIncrimentor += offset;
//Don't actually increase it till it loops to 0, instead make it go up, then back down.
hueAmmount = triwave8(hueAmmountIncrimentor);
doHueSubsection = hueAmmount < 230;//If the hue amount is almost a full rainbow, make it a full rainbow to allow pallet effects and others
}

// Set every LED in the array to a specified color
void fillAll(CRGB fillColor) {
for (byte i = 0; i < NUM_LEDS; i++) {
Expand Down