hi! I am trying to select different functions in a programm with a switch.

hi!

I am trying to select different functions in a programm with a switch. Each function is a different programm for a led strip

I am using a code published by adafruit and I did some adaptations for my project, but the button was not really working. I posted the code at arduino forum and I was explained that the mistake is that the code is not looking at the button very often because the other functions take time and it only gets to look at the button at the end of each light display.

Somebody could guide me on the way to figure this out?

Thanks!


#include <Adafruit_NeoPixel.h>

#define PIN 6
#define TPIXEL 128 //The total amount of pixel’s/led’s in your connected strip/stick (Default is 60)

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
int switchPin = 10; // switch is connected to pin 10
int val; // variable for reading the pin status
int val2;
int buttonState; // variable to hold the button state
int lightMode = 0; // how many times the button has been pressed
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

Adafruit_NeoPixel strip = Adafruit_NeoPixel(TPIXEL, PIN, NEO_GRB + NEO_KHZ800);
// our RGB → eye-recognized gamma color
byte gammatable[256];

void setup() {
Serial.begin(9600); // Set up serial communication at 9600bps

strip.setBrightness(100); //adjust brightness here

pinMode(switchPin, INPUT_PULLUP); // Set the switch pin as input
pinMode(PIN, OUTPUT);
buttonState = digitalRead(switchPin); // read the initial state

strip.begin();
strip.show(); // Initialize all pixels to ‘off’

// thanks PhilB for this gamma table!
// it helps convert RGB colors to what humans see
for (int i=0; i<256; i++) {
float x = i;
x /= 255;
x = pow(x, 2.5);
x *= 255;
gammatable[i] = x;
//Serial.println(gammatable[i]);
}}

void loop(){
val = digitalRead(switchPin); // read input value and store it in val
delay (20);
val2 = digitalRead(switchPin);
if (val == val2) {
if (val != buttonState && val==LOW) { // the button state has changed!
if (lightMode == 0) {
lightMode = 1;
}
else if (lightMode == 1) {
lightMode = 2;
}
else if (lightMode == 2){
lightMode = 0;
}
}
}

buttonState = val; // save the new state in our variable

if (lightMode == 0) {
rain();
delay(20);
}
if (lightMode == 1) {
rain_rc();
delay(20);
}
if (lightMode == 2) {
rainbowCycle(10);
delay(20);
}
}

//////////////////////////////////////////////////////////////////////////////////////////////// Rain Blue Program
void rain() {
// Create an array of 20 raindrops
const int count = 20;
int pos[count];
// Set each rain drop at the starting gate.
// Signify by a position of -1
for( int i=0; i < count; i++) {
pos[i]=-1;
}
// Main loop. Keep looping until we’ve done
// enough “frames.”
boolean done=false;
int counter = 0;
while(!done) {
// Start by turning all LEDs off:
for(int i=0; i<strip.numPixels(); i++)
strip.setPixelColor(i, 0);

// Loop for each rain drop
for( int i=0; i < count; i++) {
// If the drop is out of the starting gate,
// turn on the LED for it.
if( pos[i] >= 0 ) {
//////////////////////////////////////////////////////////COLOR
strip.setPixelColor(pos[i], strip.Color(0,0,127));
// Move the drop down one row
pos[i] -= 7;
// If we’ve fallen off the strip, but us back at the starting gate.
if( pos[i] < 0 )
pos[i]=-1;
}
// If this drop is at the starting gate, randomly
// see if we should start it falling.
if ( pos[i] == -1 && random(40) == 0 && counter < 380 ) {
// Pick one of the 6 starting spots to begin falling
pos[i] = 143-random(6);
}
strip.show();
delay(2);
}}}
//////////////////////////////////////////////////////////////////////////////////////////////// Rain Random Color Program
void rain_rc() {
// Create an array of 20 raindrops
const int count = 20;
int pos[count];
// Set each rain drop at the starting gate.
// Signify by a position of -1
for( int i=0; i < count; i++) {
pos[i]=-1;
}
// Main loop. Keep looping until we’ve done
// enough “frames.”
boolean done=false;
int counter = 0;
while(!done) {
// Start by turning all LEDs off:
for(int i=0; i<strip.numPixels(); i++)
strip.setPixelColor(i, 0);

// Loop for each rain drop
for( int i=0; i < count; i++) {
// If the drop is out of the starting gate,
// turn on the LED for it.
if( pos[i] >= 0 ) {
///////////////////////////////////////////////////////////////////////COLOR
strip.setPixelColor(pos[i], strip.Color(random(256),random(256),random(256)));
// Move the drop down one row
pos[i] -= 7;
// If we’ve fallen off the strip, but us back at the starting gate.
if( pos[i] < 0 )
pos[i]=-1;
}
// If this drop is at the starting gate, randomly
// see if we should start it falling.
if ( pos[i] == -1 && random(40) == 0 && counter < 380 ) {
// Pick one of the 6 starting spots to begin falling
pos[i] = 143-random(6);
}
strip.show();
delay(2);
}}}
//////////////////////////////////////////////////////////////////////////////////////////////// Rainbow Cycle Program - Equally distributed
void rainbowCycle(uint8_t wait) {
uint16_t i, j;

for(j=0; j<256*5; j++) { // 5 cycles of all colors on wheel
for(i=0; i< strip.numPixels(); i++) {
strip.setPixelColor(i, Wheel(((i * 256 / strip.numPixels()) + j) & 255));
}
strip.show();
delay(wait);
}
}
// Input a value 0 to 255 to get a color value.
// The colours are a transition r - g - b - back to r.
uint32_t Wheel(byte WheelPos) {
if(WheelPos < 85) {
return strip.Color(WheelPos * 3, 255 - WheelPos * 3, 0);
} else if(WheelPos < 170) {
WheelPos -= 85;
return strip.Color(255 - WheelPos * 3, 0, WheelPos * 3);
} else {
WheelPos -= 170;
return strip.Color(0, WheelPos * 3, 255 - WheelPos * 3);
}}
////////////////////////////////////////////////////////////////////////////////////////////////

If you REALLY want this program to work properly with a button, in my (not so expert) opinion, you’ll have to learn it, tear it apart and re-write it from scratch.

  1. It uses blocking delays, which slow down the program and make it harder for the button to work.
  2. It uses nested for loops, which do the same.
  3. Lines 174 through 185 are the equivalent of a built-in function with FastLED.
  4. Not sure why the gamma table at the beginning is required.

In summary, if you don’t understand the code and if it doesn’t work for you, then you’ve taken a step too far.

Where to start? Depending on your level of experience, I would start at square 1.

  1. That would be to write a short button program.
  2. Learn how to use non-blocking delays.
  3. Write display routines without nested for loops or non-blocking delays.
  4. Combined a couple of your individual routines with your button routine.

As an aside, most of my demos at:

try to follow the above philosophy. That is, to have a very high frame rate so that things like buttons can be used to select different routines.

thank you very much for your message Andrew. As you might have correctly guessed, I am far away from expertise, and I do not understand this code totally. I was just trying to do an easy adaptation of it for my benefit, but I also realized that this is beyond my level, so I decided to post my conflict to see if anybody has already done something like this.

I will in the meantime follow your advice, in a slow pace.

:slight_smile:

Here’s a FastLED library function you can use in your loop to see how fast your routines are:

Serial.println(LEDS.getFPS());

The lower the value, the more difficult it is to check your button. I try to keep mine well over 100fps. Great for debugging slow routines.

That would be one of the first steps: drop that Adafruit library and switch over to FastLED. :wink:

@Andrew_Tuline
Andrew Tuline, your demos are very very interesting … they are also effective and educational. Thanks for sharing.
A community grows so!