Switching between LED sequences

Hello again all
I have been playing all day with different ways to switch between the diffenrent sequences, modes, that the LED's should be displaying.

/*Alittle something for my dad's H0 modeltrain
*this is the light for a swing from the '50s
*based on a 8 LED kit from some web retailer.
*the code is simple, as were the Tivoli light in the '50s
************************************************************************/
const int buttonInterval = 100; // number of millisecs between button readings
const int buttonPin = 2;    // the number of the pushbutton pin
//LED Pin Variables
const int ledPins[] = {3, 4, 5, 6, 7, 8, 9, 10, 11, 12}; 
                                   //An array to hold the pin each LED is connected to
                                   //i.e. LED #0 is connected to pin 2, LED #1, 3 and so on
                                   //to address an array use ledPins[0] this would equal 2
                                   //and ledPins[9] would equal 11
                                   //Just write in, the pins you use
int buttonState;             // the current reading from the input pin
int lastButtonState = LOW;   // the previous reading from the input pin

int funcCount = 7;           //Here you put how many functions you have                                   
int sequence = 1;            //Here we hold the current sequence in the program
int pinCount = 10;           //Here you type how many LED's you have in your array                         
int Time = 300;              //Here you put how fast the LED's shall shift
// the following variables are long's because the time, measured in miliseconds,
// will quickly become a bigger number than can be stored in an int.
long lastDebounceTime = 0;  // the last time the output pin was toggled
long debounceDelay = 50;    // the debounce time; increase if the output flickers                                   
boolean Next = false;

/***********************************************************************************
 * setup() - this function runs once when you turn your Arduino on
 * We the three control pins to outputs
 ******************************************************************************/
void setup() {
    //Set each pin connected to an LED to output mode (pulling high (on) or low (off)
int i;
 for( int i=0; i < pinCount; i++){
      pinMode(ledPins[i],OUTPUT); //we use this to set each LED pin to output
  }
{
  pinMode(buttonPin, INPUT);
}
}
/****************************************************************************************
 * loop() - this function will start after setup finishes and then repeat
 * we call a function called oneAfterAnother().
*****************************************************************************************/
 
void loop() {
 readButton();               // call the functions that do the work
  if (Next == true)
  if(sequence == funcCount)
 {
 sequence = 1;
}
else
{
  sequence++;
}

switch(sequence)
{
  case 1:
  slowonalloff();
  break;
  case 2:
  oneAfterAnotherLoop();
  break;
  case 3:
  LowToHigh();
  break;
  case 4:
  HighToLow();
  break;
  case 5:
  UpAndDown();
  break;
  case 6:
  SlowOnSlowOff();
  break;
  case 7:
  SlowOnSlowOffReverse();
  break;
}

}

/******************************************************************
Here we start typing in the different types of sequenses we want in
our program.
******************************************************************/
 void readButton() {
// read the state of the switch into a local variable:
  int reading = digitalRead(buttonPin);

  // check to see if you just pressed the button 
  // (i.e. the input went from LOW to HIGH),  and you've waited 
  // long enough since the last press to ignore any noise:  

  // If the switch changed, due to noise or pressing:
  if (reading != lastButtonState) {
    // reset the debouncing timer
    lastDebounceTime = millis();
  } 
  
  if ((millis() - lastDebounceTime) > debounceDelay) {
    // whatever the reading is at, it's been there for longer
    // than the debounce delay, so take it as the actual current state:

    // if the button state has changed:
    if (reading != buttonState) {
      buttonState = reading;
    }
    if (buttonState == HIGH) {
     Next = true;
    }
  }
}
/******************************************************************************/
 void oneAfterAnotherLoop(){
 //Turn Each LED on one after another
  for(int i = 0; i <= 9; i++){
    digitalWrite(ledPins[i], HIGH);  //Turns on LED #i each time this runs i
    delay(Time);                //gets one added to it so this will repeat 
  }                                  //8 times the first time i will = 0 the final
                                     //time i will equal 7;
//Turn Each LED off one after another
  for(int i = 9; i >= 0; i--){  //same as above but rather than starting at 0 and counting up
                                //we start at seven and count down
    digitalWrite(ledPins[i], LOW);  //Turns off LED #i each time this runs i
    delay(Time);                //gets one subtracted from it so this will repeat 
  }                                  //8 times the first time i will = 7 the final
                                     //time it will equal 0
 }
/*******************************************************************************************
*/
                                     
void slowonalloff(){
 // int delaytime = 350; //the time (in milliseconds) to pause between LEDs
                       //make smaller for quicker switching and larger for slower
//Turn each LED on one after another
 for(int i = 0; i <pinCount; i++){
    digitalWrite(ledPins[i], HIGH);  
    delay(Time);                 
  }                                  
                                     
//Turn all LED off at one
for(int i = 0; i <pinCount;i++ ){
digitalWrite(ledPins[i], LOW);        //Turns all LED off at once
  }
  {
  delay(Time);
}
}
/*************************************************************************************/

void LowToHigh(){ //This will run the light from the buttom to the top
  for(int i = 0; i < pinCount; i++) { 
    digitalWrite(ledPins[i], HIGH); //Will turn the LED on
    delay(Time);
  digitalWrite(ledPins[i], LOW); //Now we turn it off

  }
}

/**********************************************************************************/
void HighToLow(){ //This runs the light from the top to the buttom
  for(int i=pinCount - 1; i >=0; i--) { 
    digitalWrite(ledPins[i], HIGH); //Turn the LED on
    delay(Time); //Wait a little
  digitalWrite(ledPins[i], LOW);//And off again

  }
}
/************************************************************************************/
void UpAndDown(){
  for (int i = 0; i < pinCount; i++) {
    digitalWrite (ledPins[i], HIGH);
    delay(Time);
  digitalWrite(ledPins[i],LOW);
  }
{
    for(int i=pinCount - 1; i >=0; i--) { 
    digitalWrite(ledPins[i], HIGH); //Turn the LED on
    delay(Time); //Wait a little
  digitalWrite(ledPins[i], LOW);//And off again
    }
}
}
/********************************************************************************/
void SlowOnSlowOff(){
//Turn each LED on one after another
 for(int i = 0; i <pinCount; i++){
    digitalWrite(ledPins[i], HIGH);  
    delay(Time);                 
  }                                  
                                     
//Turn each LED off again
for(int i = 0; i <pinCount;i++ ){
digitalWrite(ledPins[i], LOW);        //Turns all LED off at once
  delay(Time);
}
}
/*********************************************************************************/
void SlowOnSlowOffReverse(){
//Turn each LED on one after another
 for(int i = pinCount; i <0; i--){
    digitalWrite(ledPins[i], HIGH);  
    delay(Time);                 
  }                                  
                                     
//Turn each LED off again
for(int i = pinCount; i <0;i-- ){
digitalWrite(ledPins[i], LOW);        //Turns all LED off at once
  delay(Time);
}
}

I have tried different ways, started out with the "Debounce" example. Did not work for me.
The "Button" example, saving the state until I used it and setting it to LOW after. Did not work for me.
Been looking all over the internet after solutions and can get my head around it.
The problem is that it will not ALWAYS change the sequence when I pressed the button. And sometimes it changes more than one sequence.
It differs ALOT on the speed that I update my LED's at. That means:

int Time = 300;              //Here you put how fast the LED's shall shift

and that's not good.
I have now gone with Robin2's example to run a lot of stuff at the same time, I can't get it to work and now I'm a little tired of it.
Is there a kind soul that can poke me in the right direction?

Time to lose all those calls to delay().

I have now gone with Robin2's example to run a lot of stuff at the same time

...but I forgot to post it.

Time to lose all those calls to delay().m

Then I need a totally different way to turn the LED on and off???
And I thought that I were a good boy and beginning to write and understand my own code...

...but I forgot to post it.

Accualy it's in there, the part that calls for button reading is from him. The rest of the code was for a servo, blinking two LED's differently and turning on and off the onboad LED when the button is pressed.
My idea was to:
Check if the button is pressed.
If it is, set the "Next" boolearn to true.
Switch case if "Next" is true
Setting "Next" to false when the case shifted once.

But I need to build my functions in an othe way to do that?

I have been looking to the "While" and "Do_While" examples, but did not really get any useful information out of it. Meaning I did not really understand how to use it.

Then I need a totally different way to turn the LED on and off?

No, digitalWrite will work just as well.

No, digitalWrite will work just as well.

But if I can't wait for a time to pass before turning on the next LED, then I need to "update" what to do at a certain time, right??
I did understand that for the program to work, I need to skip the delay () and instead "update" the program at the right time. I have been looking at how to do it, but everywere I look, it's just two LED's bliking at different rates.
I can't get that to work with ten LED's working together, differently depending on what case I want it to show.

but everywere I look, it's just two LED's bliking at different rates.

If you can blink two LEDs at different rates, you can blink ten LEDs at different rates.

but everywere I look, it's just two LED's bliking at different rates.
I can't get that to work with ten LED's working together, differently depending on what case I want it to show.

The principle is the same. It is time to move to the next state, or it isn't.

@Pady, I can't figure out what you are trying to do. Can you start over and explain what you want to achieve? Then we can think about how to do that.

Writing out the requirement may also help to clear things up in your own mind.

...R

If you can blink two LEDs at different rates, you can blink ten LEDs at different rates.

Yes ofcause, what you mean is that I should set the LED's to blink at the right time, instead of turning on or off after some time as gone since the last turn on/off?

The principle is the same. It is time to move to the next state, or it isn't.

Yes I can see that, but to put it in some code that does what I want, I can't see that. :fearful:

@Pady, I can't figure out what you are trying to do. Can you start over and explain what you want to achieve? Then we can think about how to do that.

Writing out the requirement may also help to clear things up in your own mind.

...R

The Idea as it is right now:
Startup running a sequence of the ten LED's going HIGH one after another, and when all are HIGH, go LOW all at once
That is the main thing that this board is going to do

void slowonalloff(){
 //Turn each LED on one after another
 for(int i = 0; i <pinCount; i++){
    digitalWrite(ledPins[i], HIGH);  
    delay(Time);                 
  }                                  
                                     
//Turn all LED off at one
for(int i = 0; i <pinCount;i++ ){
digitalWrite(ledPins[i], LOW);        //Turns all LED off at once
  }
  {
  delay(Time);
}
}

I think that it is fun to add more and different sequences:
as all LED's go HIGH, one after another, and the LOW one after another.

void oneAfterAnotherLoop(){
 //Turn Each LED on one after another
  for(int i = 0; i < pinCount; i++){
    digitalWrite(ledPins[i], HIGH);  //Turns on LED #i each time this runs i
    delay(Time);                //gets one added to it so this will repeat 
  }                                  //8 times the first time i will = 0 the final
                                     //time i will equal 7;
//Turn Each LED off one after another
  for(int i = pinCount; i > 0; i--){  //same as above but rather than starting at 0 and counting up
                                //we start at seven and count down
    digitalWrite(ledPins[i], LOW);  //Turns off LED #i each time this runs i
    delay(Time);                //gets one subtracted from it so this will repeat 
  }                                  //8 times the first time i will = 7 the final
                                     //time it will equal 0
 }

Only one LED goes HIGH and then LOW

void LowToHigh(){ //This will run the light from the buttom to the top
  for(int i = 0; i < pinCount; i++) { 
    digitalWrite(ledPins[i], HIGH); //Will turn the LED on
    delay(Time);
  digitalWrite(ledPins[i], LOW); //Now we turn it off

  }
}

as for now I have 7 sequences. I think by myself, "What can I use to switch between the sequences?" A button "yippie, I have 10, just laying around"
So I added a button, I should be detecting a HIGH state and saving that state (as a boolean, true) till it uses it to switch to next sequence (case), and then set the state (boolean) back to false.
The code shall have an easy way to set the speed of the sequence,

int Time = 300;              //Here you put how fast the LED's shall shift

because, as it looks now, I don't really know how fast it's going to be. (I realise that I can't use delay())
An easy way to add more sequences, or take them out again.
and I might need to do different speeds for each sequence.

I wrote in, the debounce example because I thought that it would make it easier to use, than cooking up something new...
The problem is that, with that code, it shifts longer than the next seqence, or not at all.
Then I were looking at your code Robin2, and I think it looks good, but can't figure out how to make the different sequences?

I really hope that you could understand that??
When it's in my head, everything is so easy to understand, but as i read what I have wrote... Not so easy...

Pady:
When it's in my head, everything is so easy to understand, but as i read what I have wrote... Not so easy...

I suspected as much. And (even if you don't post it here) it would probably be a good idea to write it up more clearly another couple of times until you have covered every step and there is no ambiguity about anything.

Sorry if I am going over old ground (put you did PM me so this is the price :)) ...

You want to have several sequences - which means you need a convenient way to define and store the sequences.

Then you need a mechanism to implement one sequence

And a mechanism to select the appropriate sequence

In pseudo code it would look like this

void loop() {
  readSwitchesAndSaveValues();
  selectSequence();
  implementSequence();
}

Thinking-on-the-go a way to define a sequence might be ...

an array with as many elements as leds and a 1 or 0 in a position would define whether the led is on or off
another array with the same number of elements but each element holds the interval from one led lighting to the next. So something like this

byte ledPins[] =     {    5,   6,   7,   8};
  // this pair of arrays defines a sequence
byte ledLighting[] = {    1,   1,   1,   1}; // as many as you need
int ledMillis[] =    {   0,  100, 100,   0}; // first 2 leds light after 100 msecs, last 2 light at same time

If these were in two arrays of arrays (sorry, I know its getting to sound complex) the buttons would select which sequence to use. You could have another array that defines the order that sequences are selected so it could go through several in sequence.

The code for lighting a sequence should then be reasonably simple (I haven't tested this - and it is version 2 after my editor crashed so it may be worse than usual)

void implementSequence() {
  
  static byte ledNum;            // static variables hold their value
  static unsigned long lastLedOn;
  static unsigned long ledInterval;
  
  currentMillis = millis();
  if (currentMillis - lastLedOn >= ledInterval) {  // the usual time check
    lastLedOn += ledInterval;    // save the current time
    
    digitalWrite([ledPins[ledNum], ledLighting[ledNum]); // light an led
    
    ledNum ++; // move on to the next in the sequence
    if (ledNum >= 4) {
      ledNum = 0;
      sequenceDone = true; // this will be a global variable to signal to other parts of code
    }
    ledInterval = ledMillis[ledNum];
  }
}

...R

Ok, so I have been playing around with this millis() stuff and the code I have now is:

const byte ledPins[] = {3,4,5,6,7,8,9,10,11,12};  //Here I put the LED's in an array
const byte pinCount = 10;  //and here we put the MAX LED's in for simplicity laster on

// Variables will change:
int ledState = LOW;             // ledState used to set the LED

// the follow variables is a long because the time, measured in miliseconds,
// will quickly become a bigger number than can be stored in an int.
long previousMillis = 0;        // will store last time LED was updated
long interval = 1000;           // interval at which to blink (milliseconds)
unsigned long currentMillis;
static unsigned long lastLedOn;
static unsigned long ledInterval;
/*****************************************************************************/
void setup(){
  int i;
  for( int i=0; i < pinCount; i++){
    pinMode(ledPins[i],OUTPUT); //we use this to set each LED pin to output
  }
}
/****************************************************************************/
void loop(){
  slowOnAllOff;

}
/***************************************************************************/
void slowOnAllOff(){
  currentMillis = millis();
  if (currentMillis - lastLedOn >= ledInterval) {  // the usual time check
    lastLedOn += ledInterval;   // save the current time
  }

  //Turn each LED on one after another
  if (currentMillis >=interval){  //if it is time?
    for(int i = 0; i <pinCount; i++)  //select the next LED in the array
      digitalWrite(ledPins[i], HIGH);  //and turn that on
  }
  {
    interval; 
  }                                  

  //Turn all LED off at once
  if (lastLedOn == pinCount)for(int i = 0; i <pinCount;i++ ){  //if the last LED that HIGH == the last LED in the arrya
    digitalWrite(ledPins[i], LOW);        //Turns all LED off at once

  }

}

As I suspect you proff programmers can see that it does not work yet, but I hope I am beginning to understand it,or?

@Robin2

I suspected as much. And (even if you don't post it here) it would probably be a good idea to write it up more clearly another couple of times until you have covered every step and there is no ambiguity about anything.

Sorry if I am going over old ground (put you did PM me so this is the price smiley) ...

If the price is to understand and learn, I'm willing to pay :slight_smile:
I played around with your complete code, but could not get it going, so I started out a little on my own, and a little with your code and a little with

long sequenceDelay = 500;
long flashDelay = 1000;
 
boolean LED13state = false;     // the LED will turn ON in the first iteration of loop()
boolean LED12state = false;     // need to seed the light to be OFF
long waitUntil13 = 0;
long waitUntil12 = sequenceDelay;         // the seed will determine time between LEDs
void setup() {
   pinMode(13, OUTPUT);
   pinMode(12, OUTPUT);
}
void loop() {
   digitalWrite(13, LED13state);     // each iteration of loop() will set the IO pins,
   digitalWrite(12, LED12state);
   // checking to see if enough time has elapsed
   if (millis() >= waitUntil13) {
      LED13state = !(LED13state);
      waitUntil13  += flashDelay;
      // this if-statement will not execute for another 1000 milliseconds
   }
  // keep in mind, waitUntil12 was already seeded with a value of 500
   if (millis() >= waitUntil12) {
      LED12state = !(LED12state);
      waitUntil12 += flashDelay;
   }
}

I think that it is a good idea to take a step back and get the slowOnAllOff(); working.
I discovered that when I got that cracking with the old code, it started to loosen up :wink:
What do you think of my progress?
Any thougts or pointers?

The key feature of the code snippet I posted is that all the timing for all the LEDs is done in the same piece of code. If you start extending the code to have different bits for different leds or different times you end up with a mess that God couldn't unravel.

Before you start a project like this you MUST (in my opinion) decide how you are gong to represent the data you want to process as well as how you intend to process the data. They must go together. I don't see any of that in your code. Its as if you get one piece working and then add on another bit. That will work for two or three bits but it quickly becomes unmanageable. The code that turns the LEDs on must also turn them off. They get turned off because you have provided data that says "turn me off", not because you have special code that says turn them off.

So (following from my earlier code) these arrays control the turning on

byte ledLighting[] = {    1,   1,   1,   1}; // as many as you need
int ledMillis[] =    {   0,  100, 100,   0}; // first 2 leds light after 100 msecs, last 2 light at same time

and another pair will control the turning off all at the same time

byte ledLighting[] = {   0,   0,   0,   0}; 
int ledMillis[] =    {   0,   0,   0,   0};

and these need to be combined into arrays of arrays like this

byte ledLighting[2][4] = {
       {    1,   1,   1,   1},
       {   0,   0,   0,   0}
};

and

int ledMillis[2][4] = {
      {   0,  100, 100,   0},
      {   0,   0,   0,   0}
};

Then the code to make both sequences happen would be

void implementSequence() {
  
  static byte sequenceNum;
  static byte ledNum;            // static variables hold their value
  static unsigned long lastLedOn;
  static unsigned long ledInterval;
  
  currentMillis = millis();
  if (currentMillis - lastLedOn >= ledInterval) {  // the usual time check
    lastLedOn += ledInterval;    // save the current time
    
    digitalWrite([ledPins[ledNum], ledLighting[ledSequenceNum][ledNum]); // light an led
    
    ledNum ++; // move on to the next in the sequence
    if (ledNum >= 4) {
      ledNum = 0;
      ledSequenceNum ++;
      if (ledSequenceNum >= 2) {
         ledSequenceNum = 0;
         sequenceDone = true; // this will be a global variable to signal to other parts of code
      }
    }
    ledInterval = ledMillis[ledSequenceNum][ledNum];
  }
}

You obviously need to top and tail this to get it to work.

...R

I don't understand it :frowning:
Here's your code again, but with the LED's set as OUTPUT.
I can se the different arrays

byte ledLighting[] = {    1,   1,   1,   1}; // as many as you need
int ledMillis[] =    {   0,  100, 100,   0}; // first 2 leds light after 100 msecs, last 2 light at same time
byte ledLighting[] = {   0,   0,   0,   0}; 
int ledMillis[] =    {   0,   0,   0,   0};
byte ledLighting[2][4] = {
       {    1,   1,   1,   1},
       {   0,   0,   0,   0}
};
int ledMillis[2][4] = {
      {   0,  100, 100,   0},
      {   0,   0,   0,   0}
};

But I have no clue on what to do with it or what it means :-S
Is the {1, 1, 1, 1} for {HIGH, HIGH, HIGH, HIGH} and if, how do the code know?
I'm begging to understand this, but when I never had any experience with programming in any form, this is hard to cope with.
If I get this going, I hope that a lot of noobs like me would use it, because I think that a lot ask this question on how to make a pattern without delay. Not just bliking...

const byte ledPins[] = {3, 4, 5, 6, 7, 8, 9, 10, 11, 12};
const byte pinCount = 4;
byte ledLighting[] = {   0,   0,   0,   0}; 
int ledMillis[] =    {   0,   0,   0,   0};
unsigned long currenMillis;
boolean sequenceDone;


void setup(){
  int i;
  for( int i=0; i < pinCount; i++){
    pinMode(ledPins[i],OUTPUT); //we use this to set each LED pin to output
  }
}

void loop(){
}


void implementSequence() {
  
  static byte sequenceNum;
  static byte ledNum;            // static variables hold their value
  static unsigned long lastLedOn;
  static unsigned long ledInterval;
  
  currentMillis = millis();
  if (currentMillis - lastLedOn >= ledInterval) {  // the usual time check
    lastLedOn += ledInterval;    // save the current time
    
    digitalWrite([ledPins[ledNum], ledLighting[ledSequenceNum][ledNum]); // light an led
    
    ledNum ++; // move on to the next in the sequence
    if (ledNum >= 4) {
      ledNum = 0;
      ledSequenceNum ++;
      if (ledSequenceNum >= 2) {
         ledSequenceNum = 0;
         sequenceDone = true; // this will be a global variable to signal to other parts of code
      }
    }
    ledInterval = ledMillis[ledSequenceNum][ledNum];
  }
}

HIGH (and true) are just a long-winded ways of writing 1 and LOW (and false) are the same as 0. Computers only work with 1s and 0s. The compiler knows what HIGH means and converts the words we can understand into the numbers.

The array could just as well be {HIGH, HIGH, HIGH, HIGH}

This code is two arrays each containing an array of 4 elements. The first row means that all the leds will light (at their appropriate times) and the second array means they will all be switched off. You can extend the arrays with more rows (sequences) or more columns (leds) to suit your design.

byte ledLighting[2][4] = {
       {    1,   1,   1,   1},
       {   0,   0,   0,   0}
};

This code has corresponding arrays that deal with the timing. Again, each row represents a sequence and each column represents an LED. The first row means that the first LED will light immediately, the second one after 100 millisecs, the third after a further 100 msecs and the fourth will light at the same time as the third (well actually a few microseconds later because it will happen in the next loop of the code).

int ledMillis[2][4] = {
      {   0,  100, 100,   0},
      {   0,   0,   0,   0}
};

If it helps I will try to build a working piece of code later today.

...R

Ahh now I understand what that piece of code means, that cleared a lot, and those two arrays goes together in a function?
Ex. void sequence1?

If you could and would write an example of how it could look like, I would be more than happy.
I hope you understand that I'm not lazy or more-than-usual stupid, I just need to understand how it works together :slight_smile:
If I can help you with something or in any other way do something, just say :slight_smile:

This piece of code works on my Mega - its easier to get 4 leds working on a Mega because the Uno only has three ground connections. It should work fine on an Uno as well.

byte ledPins[] = {    5,   6,   7,   8};

byte ledLighting[6][4] = {
                 {    1,   1,   1,   1},
                 {    0,   0,   0,   0},
                 {    1,   1,   1,   1},
                 {    0,   0,   0,   0},
                 {    1,   1,   1,   1},
                 {    0,   0,   0,   0}
};

int ledMillis[6][4] = {
                 {1000,  200, 200,   0},
                 {1000,    0,   0,   0},
                 {1000,  200, 200, 200},
                 {1000,  100, 100, 100},
                 {1000,  200, 500, 500},
                 {1000,    0,   0,   0}
};

byte numSequences = 6;
byte numLeds = 4;

int ledSequenceNum = 0; // this is used in two functions
boolean ledSequenceDone = false;


void setup() {

  Serial.begin(9600);
  Serial.println("Starting LedSequence.ino");

  for(byte n = 0; n < numLeds; n++){
    pinMode(ledPins[n], OUTPUT);
  }

}

void loop() {
//  readSwitchesAndSaveValues();
  selectSequence();
  implementSequence();
}

void selectSequence() {
  
  if (ledSequenceDone == true) {
     ledSequenceNum ++;
     if (ledSequenceNum >= numSequences) {
           ledSequenceNum = 0;
     }
     ledSequenceDone = false;
  }
}

void implementSequence() {

  static byte ledNum;            // static variables hold their value
  static unsigned long lastLedOn;
  static unsigned long ledInterval;
  
  unsigned long currentMillis = millis();
  
  if (currentMillis - lastLedOn >= ledInterval) {  // the usual time check
    lastLedOn += ledInterval;    // save the current time
    
    digitalWrite(ledPins[ledNum], ledLighting[ledSequenceNum][ledNum]); // light an led
    
    ledNum ++; // move on to the next in the sequence
    if (ledNum >= 4) {
      ledNum = 0;
      ledSequenceDone = true; 
    }
    ledInterval = ledMillis[ledSequenceNum][ledNum];
  }
}

There is at least one substantial shortcoming in the mechanism I have chosen to store the sequences - can you spot it? (It was the first mechanism that came to mind)

...R

It does work now :slight_smile:

There is at least one substantial shortcoming in the mechanism I have chosen to store the sequences - can you spot it? (It was the first mechanism that came to mind)

About the shortcomming: A int; to hold the time to do the action (turning 1 or 0) and then a thought: is'ent it custom to put all the variebles in the top? and the static an all that? or is it just me that got that wrong?

Variables that have global scope (ie available to all parts of the program) are declared at the start of the program. Variables whose scope is limited to a function are declared within that function.

ahh ok, thank you :slight_smile:

@Robin2
And the arrays to setting the light 1 or 0 is declared as a global and not in it's own function. If I put it in it's own function and make two different and then the "Debounce" example for the butten and when that is HIGH, chance to another sequence/pattern in a case; machine.
is that about right?

Modified 5 PM

The whole code:

byte ledPins[] = {5, 6, 7, 8};
int i = 500;
byte ledLighting[6][4] = {
                 {1, 1, 1, 1},
                 {0, 0, 0, 0},
                 {1, 1, 1, 1},
                 {0, 0, 0, 0},
                 {1, 1, 1, 1},
                 {0, 0, 0, 0}
};

int ledMillis[6][4] = {
                 {i, i, i, i},
                 {i, 0, 0, 0},
                 {i, i, i, i},
                 {i, 0, 0, 0},
                 {i, i, i, i},
                 {i, 0, 0, 0}
};

byte ledLighting2[6][4] = {
   {1, 1, 1, 1},
   {0, 0, 0, 0},
   {1, 1, 1, 1},
   {0, 0, 0, 0},
   {1, 1, 1, 1},
   {0, 0, 0, 0}
};

int ledMillis2[6][4] = {
  {i, i, i, i},
  {i, i, i, i},
  {i, i, i, i},
  {i, i, i, i},
  {i, i, i, i},
  {i, i, i, i},
};

byte numSequences = 6;
byte numLeds = 4;

int ledSequenceNum = 0; // this is used in two functions
boolean ledSequenceDone = false;


void setup() {

  Serial.begin(9600);
  Serial.println("Starting LedSequence.ino");

  for(byte n = 0; n < numLeds; n++){
    pinMode(ledPins[n], OUTPUT);
  }

}

void loop() {
//  readSwitchesAndSaveValues();
  selectSequence();
  implementSequence();
}

void selectSequence() {
  
  if (ledSequenceDone == true) {
     ledSequenceNum ++;
     if (ledSequenceNum >= numSequences) {
           ledSequenceNum = 0;
     }
     ledSequenceDone = false;
  }
}

void implementSequence() {

  static byte ledNum;            // static variables hold their value
  static unsigned long lastLedOn;
  static unsigned long ledInterval;
  
  unsigned long currentMillis = millis();
  
  if (currentMillis - lastLedOn >= ledInterval) {  // the usual time check
    lastLedOn += ledInterval;    // save the current time
    
    digitalWrite(ledPins[ledNum], ledLighting[ledSequenceNum][ledNum]); // light an led
    
    ledNum ++; // move on to the next in the sequence
    if (ledNum >= 4) {
      ledNum = 0;
      ledSequenceDone = true; 
    }
    ledInterval = ledMillis[ledSequenceNum][ledNum];
  }
}

Why can't I move

byte ledLighting[6][4] = {
                 {1, 1, 1, 1},
                 {0, 0, 0, 0},
                 {1, 1, 1, 1},
                 {0, 0, 0, 0},
                 {1, 1, 1, 1},
                 {0, 0, 0, 0}
};

int ledMillis[6][4] = {
                 {i, i, i, i},
                 {i, 0, 0, 0},
                 {i, i, i, i},
                 {i, 0, 0, 0},
                 {i, i, i, i},
                 {i, 0, 0, 0}
};

to it's own function "void slowOnAllOf"? and just call that case 1
and select it something like:

void loop() {
      if(sequence == funcCount)
    {
      sequence = 0;
    }
    else
    {
      sequence++;
    }

  switch(sequence)
  {
  case 1:
    slowonalloff();
    break;
  case 2:
    oneAfterAnotherLoop();
    break;
  case 3:
    LowToHigh();
    break;
  case 4:
    HighToLow();
    break;
  case 5:
    UpAndDown();
    break;
  case 6:
    SlowOnSlowOff();
    break;
  case 7:
    SlowOnSlowOffReverse();
    break;
  }

}

but I think I understand how to make the sequences, but with 10 LED's they would get pretty long, if I just want one LED to be lit at a time, like the larson scanner example.

A different sort of shortcoming altogether.

With my data structure it is easy to control the leds from left to right but not so easy to control them from right to left.

Glad its working, and I hope it makes sense.

...R