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 most likely no translated for the post!





LED pattern stuck e...
 
Share:
Notifications
Clear all

[Solved] LED pattern stuck every time I release latching switch  

  RSS

(@lakerice)
Eminent Member
Joined: 3 months ago
Posts: 25
July 16, 2020 8:25 PM  

Hi, I've recently put together a setup with a tactile/momentary switch, latching switch, and Arduino Nano using an altered version of the All Effects sketch from this site.  However, although the tactile switch works perfectly in toggling from one sketch to another, the latching switch has a peculiar tendency to pause the effect when I power it off (it powers on fine).  Of note, the power LED on the Arduino itself shows on and off when I push and release the latching switch, but when in the off position it pauses the sketch.  I was told by a friend this shouldn't be happening since the VIN input on the Arduino shouldn't be affected by code.  Hopefully someone here can help me, as it would not be very product friendly to have to manually unplug the adapter from the DC jack every time you want to power off :)  Thanks in advance!

Here is a "schematic" of my setup to the best of my knowledge:

latching switch schematic

Here's the code (I've posted this before, but for convenience sake, here it is in full):

#include "FastLED.h"
#include <EEPROM.h>
#define NUM_LEDS 60

CRGB leds[NUM_LEDS];
#define PIN 5
#define BRIGHTNESS 100

#define BUTTON 2
byte selectedEffect=0;

void setup()
{
FastLED.addLeds<WS2811, PIN, GRB>(leds, NUM_LEDS).setCorrection( TypicalLEDStrip );
pinMode(2,INPUT_PULLUP); // internal pull-up resistor
attachInterrupt (digitalPinToInterrupt (BUTTON), changeEffect, CHANGE); // pressed
digitalWrite(2, HIGH); // turn on pullup resistors
delay(100); // little 100ms delay before attaching the interrupt for the button

}

// *** REPLACE FROM HERE ***
void loop() {
EEPROM.get(0,selectedEffect);

if(selectedEffect>9) {
selectedEffect=0;
EEPROM.put(0,0);
}

switch(selectedEffect) {






case 1 : {
// NewKITT - Color (red, green, blue), eye size, speed delay, end pause
NewKITT(0x00, 0xff, 0x11, 8, 10, 50);
break;
}

case 2 : {
// Twinkle - Color (red, green, blue), count, speed delay, only one twinkle (true/false)
RunningLights(0xff,0xd7,0x00, 50);
break;
}



case 3 : {
// Sparkle - Color (red, green, blue), speed delay
Sparkle(0x4d, 0x4d, 0xff, 0);
break;
}

case 4 : {
// SnowSparkle - Color (red, green, blue), sparkle delay, speed delay
SnowSparkle(0x38, 0x00, 0x33, 20, random(100,1000));
break;
}



case 5 : {
// rainbowCycle - speed delay
rainbowCycle(20);
break;
}



case 6 : {
// theaterChaseRainbow - Speed delay
theaterChaseRainbow(50);
break;
}

case 7 : {
// Fire - Cooling rate, Sparking rate, speed delay
Fire(55,120,15);
break;
}


// simple bouncingBalls not included, since BouncingColoredBalls can perform this as well as shown below
// BouncingColoredBalls - Number of balls, color (red, green, blue) array, continuous
// CAUTION: If set to continuous then this effect will never stop!!!





case 8 : {
// meteorRain - Color (red, green, blue), meteor size, trail decay, random trail decay (true/false), speed delay
meteorRain(0x38,0x00,0xff,10, 64, true, 30);
break;
}
}
}

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


// *************************
// ** LEDEffect Functions **
// *************************




void NewKITT(byte red, byte green, byte blue, int EyeSize, int SpeedDelay, int ReturnDelay){
RightToLeft(red, green, blue, EyeSize, SpeedDelay, ReturnDelay);
LeftToRight(red, green, blue, EyeSize, SpeedDelay, ReturnDelay);
OutsideToCenter(red, green, blue, EyeSize, SpeedDelay, ReturnDelay);
CenterToOutside(red, green, blue, EyeSize, SpeedDelay, ReturnDelay);
LeftToRight(red, green, blue, EyeSize, SpeedDelay, ReturnDelay);
RightToLeft(red, green, blue, EyeSize, SpeedDelay, ReturnDelay);
OutsideToCenter(red, green, blue, EyeSize, SpeedDelay, ReturnDelay);
CenterToOutside(red, green, blue, EyeSize, SpeedDelay, ReturnDelay);
}

// used by NewKITT
void CenterToOutside(byte red, byte green, byte blue, int EyeSize, int SpeedDelay, int ReturnDelay) {
for(int i =((NUM_LEDS-EyeSize)/2); i>=0; i--) {
setAll(0,0,0);

setPixel(i, red/10, green/10, blue/10);
for(int j = 1; j <= EyeSize; j++) {
setPixel(i+j, red, green, blue);
}
setPixel(i+EyeSize+1, red/10, green/10, blue/10);

setPixel(NUM_LEDS-i, red/10, green/10, blue/10);
for(int j = 1; j <= EyeSize; j++) {
setPixel(NUM_LEDS-i-j, red, green, blue);
}
setPixel(NUM_LEDS-i-EyeSize-1, red/10, green/10, blue/10);

showStrip();
delay(SpeedDelay);
}
delay(ReturnDelay);
}

// used by NewKITT
void OutsideToCenter(byte red, byte green, byte blue, int EyeSize, int SpeedDelay, int ReturnDelay) {
for(int i = 0; i<=((NUM_LEDS-EyeSize)/2); i++) {
setAll(0,0,0);

setPixel(i, red/10, green/10, blue/10);
for(int j = 1; j <= EyeSize; j++) {
setPixel(i+j, red, green, blue);
}
setPixel(i+EyeSize+1, red/10, green/10, blue/10);

setPixel(NUM_LEDS-i, red/10, green/10, blue/10);
for(int j = 1; j <= EyeSize; j++) {
setPixel(NUM_LEDS-i-j, red, green, blue);
}
setPixel(NUM_LEDS-i-EyeSize-1, red/10, green/10, blue/10);

showStrip();
delay(SpeedDelay);
}
delay(ReturnDelay);
}

// used by NewKITT
void LeftToRight(byte red, byte green, byte blue, int EyeSize, int SpeedDelay, int ReturnDelay) {
for(int i = 0; i < NUM_LEDS-EyeSize-2; i++) {
setAll(0,0,0);
setPixel(i, red/10, green/10, blue/10);
for(int j = 1; j <= EyeSize; j++) {
setPixel(i+j, red, green, blue);
}
setPixel(i+EyeSize+1, red/10, green/10, blue/10);
showStrip();
delay(SpeedDelay);
}
delay(ReturnDelay);
}

// used by NewKITT
void RightToLeft(byte red, byte green, byte blue, int EyeSize, int SpeedDelay, int ReturnDelay) {
for(int i = NUM_LEDS-EyeSize-2; i > 0; i--) {
setAll(0,0,0);
setPixel(i, red/10, green/10, blue/10);
for(int j = 1; j <= EyeSize; j++) {
setPixel(i+j, red, green, blue);
}
setPixel(i+EyeSize+1, red/10, green/10, blue/10);
showStrip();
delay(SpeedDelay);
}
delay(ReturnDelay);
}

void Twinkle(byte red, byte green, byte blue, int Count, int SpeedDelay, boolean OnlyOne) {
setAll(0,0,0);

for (int i=0; i<Count; i++) {
setPixel(random(NUM_LEDS),red,green,blue);
showStrip();
delay(SpeedDelay);
if(OnlyOne) {
setAll(0,0,0);
}
}

delay(SpeedDelay);
}


void Sparkle(byte red, byte green, byte blue, int SpeedDelay) {
int Pixel = random(NUM_LEDS);
setPixel(Pixel,red,green,blue);
showStrip();
delay(SpeedDelay);
setPixel(Pixel,0,0,0);
}

void SnowSparkle(byte red, byte green, byte blue, int SparkleDelay, int SpeedDelay) {
setAll(red,green,blue);

int Pixel = random(NUM_LEDS);
setPixel(Pixel,0xff,0xff,0xff);
showStrip();
delay(SparkleDelay);
setPixel(Pixel,red,green,blue);
showStrip();
delay(SpeedDelay);
}

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++) {
// sine wave, 3 offset waves make a rainbow!
//float level = sin(i+Position) * 127 + 128;
//setPixel(i,level,0,0);
//float level = sin(i+Position) * 127 + 128;
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);
}
}



void rainbowCycle(int SpeedDelay) {
byte *c;
uint16_t i, j;

for(j=0; j<256*5; j++) { // 5 cycles of all colors on wheel
for(i=0; i< NUM_LEDS; i++) {
c=Wheel(((i * 256 / NUM_LEDS) + j) & 255);
setPixel(i, *c, *(c+1), *(c+2));
}
showStrip();
delay(SpeedDelay);
}
}

// used by rainbowCycle and theaterChaseRainbow
byte * Wheel(byte WheelPos) {
static byte c[3];

if(WheelPos < 85) {
c[0]=WheelPos * 3;
c[1]=255 - WheelPos * 3;
c[2]=0;
} else if(WheelPos < 170) {
WheelPos -= 85;
c[0]=255 - WheelPos * 3;
c[1]=0;
c[2]=WheelPos * 3;
} else {
WheelPos -= 170;
c[0]=0;
c[1]=WheelPos * 3;
c[2]=255 - WheelPos * 3;
}

return c;
}



void theaterChaseRainbow(int SpeedDelay) {
byte *c;

for (int j=0; j < 256; j++) { // cycle all 256 colors in the wheel
for (int q=0; q < 3; q++) {
for (int i=0; i < NUM_LEDS; i=i+3) {
c = Wheel( (i+j) % 255);
setPixel(i+q, *c, *(c+1), *(c+2)); //turn every third pixel on
}
showStrip();

delay(SpeedDelay);

for (int i=0; i < NUM_LEDS; i=i+3) {
setPixel(i+q, 0,0,0); //turn every third pixel off
}
}
}
}

void Fire(int Cooling, int Sparking, int SpeedDelay) {
static byte heat[NUM_LEDS];
int cooldown;

// Step 1. Cool down every cell a little
for( int i = 0; i < NUM_LEDS; i++) {
cooldown = random(0, ((Cooling * 10) / NUM_LEDS) + 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= NUM_LEDS - 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 < NUM_LEDS; j++) {
setPixelHeatColor(j, heat[j] );
}

showStrip();
delay(SpeedDelay);
}

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(Pixel, 255, 255, heatramp);
} else if( t192 > 0x40 ) { // middle
setPixel(Pixel, 255, heatramp, 0);
} else { // coolest
setPixel(Pixel, heatramp, 0, 0);
}
}



void meteorRain(byte red, byte green, byte blue, byte meteorSize, byte meteorTrailDecay, boolean meteorRandomDecay, int SpeedDelay) {
setAll(0,0,0);

for(int i = 0; i < NUM_LEDS+NUM_LEDS; i++) {


// fade brightness all LEDs one step
for(int j=0; j<NUM_LEDS; j++) {
if( (!meteorRandomDecay) || (random(10)>5) ) {
fadeToBlack(j, meteorTrailDecay );
}
}

// draw meteor
for(int j = 0; j < meteorSize; j++) {
if( ( i-j <NUM_LEDS) && (i-j>=0) ) {
setPixel(i-j, red, green, blue);
}
}

showStrip();
delay(SpeedDelay);
}
}

// used by meteorrain
void fadeToBlack(int ledNo, byte fadeValue) {
#ifdef ADAFRUIT_NEOPIXEL_H
// NeoPixel
uint32_t oldColor;
uint8_t r, g, b;
int value;

oldColor = strip.getPixelColor(ledNo);
r = (oldColor & 0x00ff0000UL) >> 16;
g = (oldColor & 0x0000ff00UL) >> 8;
b = (oldColor & 0x000000ffUL);

r=(r<=10)? 0 : (int) r-(r*fadeValue/256);
g=(g<=10)? 0 : (int) g-(g*fadeValue/256);
b=(b<=10)? 0 : (int) b-(b*fadeValue/256);

strip.setPixelColor(ledNo, r,g,b);
#endif
#ifndef ADAFRUIT_NEOPIXEL_H
// FastLED
leds[ledNo].fadeToBlackBy( fadeValue );
#endif
}

// *** REPLACE TO HERE ***



// ***************************************
// ** FastLed/NeoPixel Common Functions **
// ***************************************

// Apply LED color changes
void showStrip() {
#ifdef ADAFRUIT_NEOPIXEL_H
// NeoPixel
strip.show();
#endif
#ifndef ADAFRUIT_NEOPIXEL_H
// FastLED
FastLED.show();
#endif
}

// Set a LED color (not yet visible)
void setPixel(int Pixel, byte red, byte green, byte blue) {
#ifdef ADAFRUIT_NEOPIXEL_H
// NeoPixel
strip.setPixelColor(Pixel, strip.Color(red, green, blue));
#endif
#ifndef ADAFRUIT_NEOPIXEL_H
// FastLED
leds[Pixel].r = red;
leds[Pixel].g = green;
leds[Pixel].b = blue;
#endif
}

// Set all LEDs to a given color and apply it (visible)
void setAll(byte red, byte green, byte blue) {
for(int i = 0; i < NUM_LEDS; i++ ) {
setPixel(i, red, green, blue);
}
showStrip();
}

ReplyQuote
(@lakerice)
Eminent Member
Joined: 3 months ago
Posts: 25
July 16, 2020 11:18 PM  

Well it looks like I spoke too soon...all I had to do was move the latching switch to the 5v on the LED strip itself (between the positive on the DC jack and the 5v on the LED strip).  A no-brainer for most I'm sure :p Hopefully this helps people anyway!


ReplyQuote
 Hans
(@hans)
Noble Member Admin
Joined: 7 years ago
Posts: 1521
July 17, 2020 5:11 AM  

Hi Lakerice!

Things like this happen to all of us haha - but thanks for posting anyway!
You're right: someone will run into this as well and find your post helpful 👍 🙂 


ReplyQuote
(@davidl)
New Member
Joined: 2 months ago
Posts: 2
August 4, 2020 1:08 PM  

@lakerice Do you understand the reason why you had to make the change that you did?

Originally, you had split the power from the + of the DC power, and placed the latching switch only on the leg that went to the Arduino, which means that when you opened the switch, you powered off the Arduino, but left the LED strip powered on. The LED driver chips on the strips simply latch the last received command, so with the Arduino powered-off, and no additional commands, the strip simply displays whatever the last state was. When you clos the latching switch again, the Arduino reboots, and restarts at the last saved pattern.

When you move the latching switch from the leg that goes to the Arduino, to the leg that goes to the LED strip, opening that switch will now turn off the power to the LEDs, and so the strip will no longer illuminate. Interestingly, the Arduino will still be running, and will still be responding to presses of your momentary switch - you just won't be able to see any results of that. If you close the latching switch again, the LED strip will light up, and the pattern will be whatever the Arduino is currently displaying - it won't revert back to the starting pattern.

If your intention is to power off both the Arduino *and* the LED strip with the latching switch, you need to move it to a slightly different place. Placing the latching switch immediately after the + terminal from your DC power, and then adding the two legs for power to the Arduino and LED strip *after* the latching switch, will accomplish this.


Hans liked
ReplyQuote
Share: