Stuck in for loops!

hi,

i have a simple idea that is working, and i want it to work better!
trigger switch at the bottom of the stairs, and another at the top.
2 lights in the ceiling, 14 lights up the stairs and then 3 lights at the landing.

the premise is easy, trip the bottom switch and the ceiling lights turn on, then the steps in order going up, and then the landing lights go on, they stay on for 25 seconds and then fade out in order.

i have a dial at the bottom of the stairs, with 10 presets for colours

now my issue, is that when i have started the process, it goes through the process fine, but there is no possibility for interaction until the system has completed.

if i change the colour whilst the lights are on, it will be ignored until it has all faded out and waiting to restart.

i know that its getting stuck in the for loops for the fade ins and fade outs, but how to reorganise the code so if i change the dial mid step, the colours change.

thanks!

//  SAVED FOR POSTERITY
//        for(int i=0;i<NUM_LEDS;i++) {
//        leds[i].nscale8(200);
//        }

#include "FastLED.h"

#define NUM_LEDS 19          // 20
#define DATA_PIN 3           // 3
//#define CLOCK_PIN 13         // 13 (lpd8806)

CRGB leds[NUM_LEDS];

//  user variables
int stairsontime = 500;      // 25000
int interimtime = 500;       // 500
int accentdecay = 2;        // 20
int landingdecay = 1;       // 10
int stairlightuptime = 100;  // 100

int bright = 32;             // 255
 
// ACCENT COLOUR VARIABLES
int ahue;
int asat = 255;
int avol = 255;

// STAIR COLOUR VARIABLES
int bhue = 160;
int bsat = 255;
int bvol = 255;

// LANDING COLOUR VARIABLES
int chue = 160;
int csat = 255;
int cvol = 255;

int bottombutton = 5;
int topbutton = 6;
int patterndial = 21;

int whichbutton = 0;   // DEFAULT IS 0

volatile int bottombuttonstate = LOW;
volatile int topbuttonstate = LOW;
volatile int patternstate;

//int val = 2;
int val = analogRead(patterndial);
int huev = map(val, 0, 1023, 0, 255);
int pattern = 0;//map(val, 5, 811, 0, 10);   // 10 SETTINGS FOR POTENTIOMETER

void setup() {
  Serial.begin(38400);
  delay(2000);
  LEDS.setBrightness(bright);
  FastLED.addLeds<WS2811, DATA_PIN, RBG>(leds, NUM_LEDS);
  //FastLED.addLeds<LPD8806, DATA_PIN, CLOCK_PIN, BRG>(leds, NUM_LEDS);

  //set up the buttons
  pinMode(bottombutton, INPUT_PULLUP);
  pinMode(topbutton, INPUT_PULLUP);
  pinMode(patterndial, INPUT);

  //Attach the interrupt to the input pin and monitor for ANY Change
  attachInterrupt(bottombutton, bottomchange, CHANGE);
  attachInterrupt(topbutton, topchange, CHANGE);
  attachInterrupt(patterndial, patternchange, CHANGE);

  // clear the leds
  memset(leds, 0,  NUM_LEDS * sizeof(struct CRGB));
}

void loop() {
    Serial.println("program running");

  switch (whichbutton) {

  case 1:    // bottom step
    // ACCENT LIGHTING
    for (int i = 0; i < 255; i++) {
      leds[0] = CHSV(ahue, asat, i);
      leds[1] = CHSV(ahue, asat, i);
      LEDS.setBrightness(bright);
      FastLED.show();
    }
    // UP LIGHTING
    for (int i=2; i < 15; i++) {
      for (int fade = 0; fade < 255; fade++) { 
        leds[i] = CHSV( bhue, bsat, fade);
        FastLED.show();
      }
        delay(stairlightuptime);
    }    
    // LANDING LIGHTING
    for (int k = 0; k < 255; k++) {
      for (int j = 15; j < NUM_LEDS; j++) {
        leds[j] = CHSV(chue, csat, k);
        LEDS.setBrightness(bright);
        FastLED.show();  
      }
    }
    whichbutton = 3;
    delay(stairsontime);
    break;

  case 2:    // top step
      // LANDING LIGHTING
    for (int k = 0; k < 255; k++) {
      for (int j = 15; j < NUM_LEDS; j++) {
        leds[j] = CHSV(chue, csat, k);
        LEDS.setBrightness(bright);
        FastLED.show();  
      }
    }
    // ACCENT LIGHTING
    for (int i = 0; i < 255; i++) {
      leds[0] = CHSV(ahue, asat, i);
      leds[1] = CHSV(ahue, asat, i);
      LEDS.setBrightness(bright);
      FastLED.show();
    }
    // DOWN LIGHTING
    for (int i=14; i > 1; i--) {
      for (int fade = 0; fade < 255; fade++) { 
        leds[i] = CHSV( bhue, bsat, fade);
        FastLED.show();
      }
      delay(stairlightuptime);
    }
    whichbutton = 3;
    delay(stairsontime);
    break;

  case 3:   // all off   
    // END OF LIGHT
    // STEPS
    for (int fade = 255; 0 < fade; fade--) { 
      for (int i=2; i < 15; i++) {
        leds[i] = CHSV( bhue, bsat, fade);
        FastLED.show();
      }
    }
    delay(interimtime);  // delay between steps and landing
    for (int fade = 255; 0 < fade; fade--) { 
      for (int i=15; i < NUM_LEDS; i++) {
        leds[i] = CHSV( chue, csat, fade);
        FastLED.show();
        delay(landingdecay);  // speed of fade
      }
    }
    delay(interimtime);  // delay between landing and accent
    for (int fade = 255; 0 < fade; fade--) { 
      for (int i=0; i < 2; i++) {
        leds[i] = CHSV( ahue, asat, fade);
        FastLED.show();
        delay(accentdecay);  // speed of fade
      }
      whichbutton = 0;
    }    
    break;
  default: 
      for (int i=0; i < NUM_LEDS; i++) {
        leds[i] = CHSV( 0, 0, 0);
        FastLED.show();
      }
  }  // end of switch
  }  // end of void loop 

void bottomchange() {
  bottombuttonstate = !bottombuttonstate;
  patternchange();
  whichbutton = 1;
}

void topchange() {
  topbuttonstate = !topbuttonstate;
  patternchange();
  whichbutton = 2;
}

void patternchange() {
    Serial.println(pattern);
    val = analogRead(patterndial);
    pattern = map(val, 0, 1023, 0, 10);

  if (pattern == 1) {
    ahue = 0;
    bhue = 0;
    chue = 0;
  }  

  if (pattern == 2) {
    ahue = 16;
    bhue = 16;
    chue = 16;
  }  
  if (pattern == 3) {
    ahue = 32;
    bhue = 32;
    chue = 32;
  }  
  if (pattern == 4) {
    ahue = 48;
    bhue = 48;
    chue = 48;
  }  
  if (pattern == 5) {
    ahue = 64;
    bhue = 64;
    chue = 64;
  }  
  if (pattern == 6) {
    ahue = 80;
    bhue = 80;
    chue = 80;
  }  
  if (pattern == 7) {
    ahue = 96;
    bhue = 96;
    chue = 96;
  }  
  if (pattern == 8) {
    ahue = 112;
    bhue = 112;
    chue = 112;
  }  
  if (pattern == 9) {
    ahue = 128;
    bhue = 128;
    chue = 128;
  }  
  if (pattern == 10) {
    ahue = 160;
    bhue = 160;
    chue = 160;
  }  
}
void patternchange() {
    Serial.println(pattern);
    val = analogRead(patterndial);
    pattern = map(val, 0, 1023, 0, 10);

  if (pattern == 1) {
    ahue = 0;
    bhue = 0;
    chue = 0;
  }  

  if (pattern == 2) {
    ahue = 16;
    bhue = 16;
    chue = 16;
  }  
  if (pattern == 3) {
    ahue = 32;
    bhue = 32;
    chue = 32;
  }  
  if (pattern == 4) {
    ahue = 48;
    bhue = 48;
    chue = 48;
  }  
  if (pattern == 5) {
    ahue = 64;
    bhue = 64;
    chue = 64;
  }  
  if (pattern == 6) {
    ahue = 80;
    bhue = 80;
    chue = 80;
  }  
  if (pattern == 7) {
    ahue = 96;
    bhue = 96;
    chue = 96;
  }  
  if (pattern == 8) {
    ahue = 112;
    bhue = 112;
    chue = 112;
  }  
  if (pattern == 9) {
    ahue = 128;
    bhue = 128;
    chue = 128;
  }  
  if (pattern == 10) {
    ahue = 160;
    bhue = 160;
    chue = 160;
  }  
}

Why miss out 144?

Read, understand, and embrace the blink without delay philosophy. You might want to spend some time reading about state machines, too. Yes, you need to scrap that code, and start over, without even thinking about using delay().

the read without delay incurs the microsecond start, microsecond end, routine... this is fine, and is understood, but the for loops trap the code, or should the whole sequence be enveloped in the microsecond start / stop?

ill have the same issue, but in between each for loop it'll check something.

or do i need to check for millis "inside" the for loop?

AWOL:

void patternchange() {

if (pattern == 10) {
    ahue = 160;
    bhue = 160;
    chue = 160;
  } 
}



Why miss out 144?

160 on the hue scale is a bright blue, and is the best looking one. the programs in place were due to the nicest looking potentiometer i had to hand was a 10 point version. i would have preferred a single point potentiometer mapped to the entire 256 range, but this was a decent layaway solution.

hi

Consider me a simpleton in this stuff..

As you want to keep your style in coding
Have you considered putting a check inside your for loop statement?

There doesn't seem to be any actual problem with the for loops. The problem is the delay(), which makes one cycle of the loop() function take a very long time, no ?

I wrote an extended demo of the Blink Without Delay example in the first post of this Thread. It may form a basis for your project.

...R

  if (pattern == 1) {
    ahue = 0;
    bhue = 0;
    chue = 0;
  }  

  if (pattern == 2) {
    ahue = 16;
    bhue = 16;
    chue = 16;
  }  
  if (pattern == 3) {
    ahue = 32;
    bhue = 32;
    chue = 32;
  }  
  if (pattern == 4) {
    ahue = 48;
    bhue = 48;
    chue = 48;
  }  
  if (pattern == 5) {
    ahue = 64;
    bhue = 64;
    chue = 64;
  }  
  if (pattern == 6) {
    ahue = 80;
    bhue = 80;
    chue = 80;
  }  
  if (pattern == 7) {
    ahue = 96;
    bhue = 96;
    chue = 96;
  }  
  if (pattern == 8) {
    ahue = 112;
    bhue = 112;
    chue = 112;
  }  
  if (pattern == 9) {
    ahue = 128;
    bhue = 128;
    chue = 128;
  }  
  if (pattern == 10) {
    ahue = 160;
    bhue = 160;
    chue = 160;
  }  
}

This would be a lot neater if you used arrays for the hue values and the value of pattern as the index. If the hue values will always be equal you would only need one array and one hue value variable rather than one for each colour.

Don't even need an array. This would be even simpler if the last element was evenly spaced liked the rest.

switch( pattern ){
  case 10: pattern = 11;
  default: ahue = bhue = chue  = ( pattern - 1 ) * 16;
}

Hi all,

I am new in the field of programming, i have 16 stairs at my home, this code is working perfect for me but every time on side (bottom or top ) is triggered the system i waiting for an other triggering to shut down the LED's. Now i want tho change (add) something in the code that after one triggering (LED's ON) from any side to shut them off automatically after certain time. (not to wait for triggering again)

The code is in attachment.

THX in advance

Scara_16.ino (10.7 KB)

Edmond:
I am new in the field of programming, i have 16 stairs at my home,

Because you are using delay() between each light working and because you are not using an array yo store all the LED pin numbers it may mean a major rewrite of your code.

The alternative to using delay() for the timing is the technique in the Blink Without Delay example sketch. This is n extended demo of the technique several things at a time.

In principle, you need to record the value of millis() when the start button is pressed and then periodicaly check if the newest value of miilis() exceeds that saved value by whatever interval you choose.

startMillis = millis();

// and later

if (millis() - startMillis > interval) {
   // switch off LEDS
}

The problem is where to put the IF clause so that it gets checked regularly - you can see how it is done in several things

If you use an array to store the LED pins you can reduce your whole code to a few lines.

...R

This code is what i managed to modify from an other code what i found on the web (link to original code: Monkfish's LED Stair Lights (proof of concept) - Pastebin.com) i just added the other 7 led pins to the code. i am using 12V LED strips controlled by transistors. I have god knowledge of electronics but like i said before, just a few stuff in programming. Sow the thing with array for the pins no clue about.

The code is working fine. in stead of buttons i use ir crossbeam detector placed on the first and last step. when i walk up the stairs the lights are going on one by one with 250millis between the steps and when i reach the last step the lights ar going off with 700millis between the steps (And the same thing going down), That is OK, what i want is that after the first triggering form any direction, even if i don't cross any of the detector's, after a certain time the led's should go off. (fro example after 20 seconds)

Anyhow thx allot for your reply.

You will find that your code gets simpler and easier to read and maintain if you persevere with learning about how to use arrays.

You'll almost certainly need to get rid of all the calls to delay().

Attached are some pictures of the finished functional board.

For the moment i am learning c++, in the future for shore this stuff will be something easy for me but right now it is unknown Territory, I really need help with this project.

Edmond:
what i want is that after the first triggering form any direction, even if i don't cross any of the detector's, after a certain time the led's should go off. (fro example after 20 seconds)

I already outlined how to do that using millis().

...R