Want a solution for delay() function

There is a some sort of problem with millis() function. can someone tell why this isn't work. only first if statement only works and after that doesn't work. If there is a better solution please show that too

unsigned long current_time; 
unsigned long previous_time=0;
unsigned long delay_time = 150;

void setup() { 
  previous_time=current_time;
}
void loop() {
current_time=millis();
}
void on_and_off_layers_up_down_not_timed() {
  unsigned long delay_time = 150;

  bool loading = false;
  bool loading_1 = false;
  bool loading_2 = false;
  bool loading_3 = false;
  bool loading_4 = false;

  loading = true;

  if (current_time - previous_time > delay_time && loading == true) {
    previous_time = current_time;
    for (int i = 2; i != 0; i--) {
      on_the_whole_cube();
      loading_1 = true;
      previous_time = current_time;

      if (current_time - previous_time > delay_time && loading_1 == true) {
        for (int i = 4; i != 0; i--) {
          digitalWrite(layer[i - 1], 0);
          loading_2 = true;
          previous_time = current_time;

        }
        loading_1 = false;
        
      }
      else if (current_time - previous_time > delay_time && loading_2 == true) {
        for (int i = 0; i < 4; i++) {
          digitalWrite(layer[i], 1);
          //delay(delay_time);
          loading_3 = true;
          previous_time = current_time;
          
        }
        loading_2 = false;
      }
      
      else if (current_time - previous_time > delay_time && loading_3 == true) {
        for (int i = 0; i < 4; i++) {
          digitalWrite(layer[i], 0);
          //delay(delay_time);
          loading_4 = true;
          previous_time = current_time;
          loading_3 = false;

        }
      }
      for (int i = 4; i != 0; i--) {
        digitalWrite(layer[i - 1], 1);
        delay(delay_time);

      }
    }
  }
}

Multi-tasking the Arduino - Part 1 (digikey.com)

1 Like

Please post your entire sketch, not just snippets of code.

Whenever something "doesn't work" you need to explain more. What happens or doesn't happen?

1 Like

When you get to the second if you have changed the value of:

previous_time

So it is the same as

current_time

So the second if can never be true.

1 Like

entire code has thousands of lines of statements. that's why I didn't posted whole code.

What can I do to avoid that?
If I removed that statement from there what I was expected will not happen. Isn't it?

What if the problem is somewhere in those 1000 lines? :slight_smile: Obviously I can't find something I can't see.

Do you not understand the logic that is going on in that part of the program? If not, you have to go look and analyze it.

What @anon57585045 said. I have told you what it does, only you know what you want it to do, so you have to figure out how to make it do that.

Then you need to write a small program that illustrates the problem and nothing else, post that program.

Ummm... no the code isn't contacting with other part if used delay() without using millis() function code is working finely.
And in this part dosen't have any problems?

You have some "weird stuff" like

  bool loading = false;
...
  loading = true;

Here you have created two variables with the same name:

   previous_time = current_time;
...
      unsigned long previous_time = current_time;

I have absolutely no idea what you are talking about.

And the code, as presented, does absolutely nothing! ONLY setup() and loop will be run, and neither will actually DO anything at all, as each contains only a single line of code that WILL be discarded by the optmizer. NO other functions will ever be called, so all the other "1000 lines of code" will never even be uploaded to the board.

here is the whole code


int column[16] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, A0, A1}; //initializing and declaring led rows
int layer[4] = {A2, A3, A4, A5}; //initializing and declaring led layers

unsigned long current_time; //to store the present time from millis
unsigned long previous_time = 0;

void setup() {  //this will run only once at startup

  for (int i = 0; i < 16; i++) { //setting columns to OUTPUT
    pinMode(column[i], OUTPUT);

  }
  for (int i = 0; i < 4; i++) { //setting layers to OUTPUT
    pinMode(layer[i], OUTPUT);

  }
  previous_time = current_time;

}
void loop() {  
  current_time = millis();


  off_the_cube();
  on_and_off_layers_up_down_not_timed();
}
void off_the_cube() {   //this function will turn off whole cube

  for (int i = 0; i < 16; i++) {
    digitalWrite(column[i], HIGH);

  }
  for (int i = 0; i < 4; i++) {
    digitalWrite(layer[i], LOW);

  }
}
void on_the_whole_cube() {

  for (int i = 0; i < 16; i++) {
    digitalWrite(column[i], LOW);

  }
  for (int i = 0; i < 4; i++) {
    digitalWrite(layer[i], HIGH);

  }
}
void on_and_off_layers_up_down_not_timed() {
  unsigned long delay_time = 150;

  bool loading = false;
  bool loading_1 = false;
  bool loading_2 = false;
  bool loading_3 = false;
  bool loading_4 = false;

  loading = true;

  if (current_time - previous_time > delay_time && loading == true) {
    for (int i = 2; i != 0; i--) {
      on_the_whole_cube();
      loading_1 = true;
      previous_time = current_time;

      if (current_time - previous_time > delay_time && loading_1 == true) {
        for (int i = 4; i != 0; i--) {
          digitalWrite(layer[i - 1], 0);
          loading_2 = true;


        }
        loading_1 = false;
      }
      previous_time = current_time;


      if (current_time - previous_time > delay_time && loading_2 == true) {
        for (int i = 0; i < 4; i++) {
          digitalWrite(layer[i], 1);
          //delay(delay_time);
          loading_3 = true;

        }

        loading_2 = false;
      }
      previous_time = current_time;

      if (current_time - previous_time > delay_time && loading_3 == true) {
        for (int i = 0; i < 4; i++) {
          digitalWrite(layer[i], 0);
          //delay(delay_time);
          loading_4 = true;
          loading_3 = false;

        }
      }
      previous_time = current_time;

      for (int i = 4; i != 0; i--) {
        digitalWrite(layer[i - 1], 1);
        delay(delay_time);

      }
    }
  }
}

I corrected it. but no luck

What happens if you add some brackets to all your relevant if clauses like this:

if ((current_time - previous_time > delay_time) && (loading == true)) {

and set previous_time to current_time only when the delay time is over:

This does never get over a reasonable delay_time!

  previous_time = current_time;
 if (current_time - previous_time > delay_time && loading_1 == true) {
        for (int i = 4; i != 0; i--) {
          digitalWrite(layer[i - 1], 0);
          loading_2 = true;


        }
        loading_1 = false;
      }
      previous_time = current_time;

It has to be like this:

 if (current_time - previous_time > delay_time && loading_1 == true) {
        for (int i = 4; i != 0; i--) {
          digitalWrite(layer[i - 1], 0);
          loading_2 = true;


        }
        loading_1 = false;
        previous_time = current_time;
      }
      

Oops and this will also not work:

void on_and_off_layers_up_down_not_timed() {
  unsigned long delay_time = 150;
  bool loading = false;                // All these booleans will be set false
  bool loading_1 = false;            // every time you enter this function
  bool loading_2 = false;            // if you like them to keep their last state
  bool loading_3 = false;            // after re-entry you had to declare them
  bool loading_4 = false;            // as static!

  loading = true;

  if ((current_time - previous_time > delay_time) && (loading == true)) {
    for (int i = 2; i != 0; i--) {
      on_the_whole_cube();
      loading_1 = true;

      previous_time = current_time;
      if (current_time - previous_time > delay_time && loading_1 == true) {
        for (int i = 4; i != 0; i--) {
          digitalWrite(layer[i - 1], 0);
          loading_2 = true;


        }
        loading_1 = false;
      }
      previous_time = current_time;


      if (current_time - previous_time > delay_time && loading_2 == true) {
        for (int i = 0; i < 4; i++) {
          digitalWrite(layer[i], 1);
          //delay(delay_time);
          loading_3 = true;

        }

        loading_2 = false;
      }
      previous_time = current_time;

      if (current_time - previous_time > delay_time && loading_3 == true) {
        for (int i = 0; i < 4; i++) {
          digitalWrite(layer[i], 0);
          //delay(delay_time);
          loading_4 = true;
          loading_3 = false;

        }
      }
      previous_time = current_time;

      for (int i = 4; i != 0; i--) {
        digitalWrite(layer[i - 1], 1);
        delay(delay_time);

      }
    }
  }
}
1 Like

Your code is monolithic and complex, has no comments or documentation. Good luck with it.

1 Like

:face_holding_back_tears: :face_holding_back_tears: :face_holding_back_tears:

till here code is working as I intended. I'm wondering after that what is happening.

There are a number of mistakes in your code:

  • You set previous_time to current_time at the wrong place (e.g. directly before the if clauses); this way the difference between current_time and previous_time is always zero ...
  • You use local variables to control the behaviour of a function after re-entry (in loop() the function is performed and re-entered in the next loop) . These variables lose their contents and start with "false" again when the function is called the next time ...

This sketch should do it; give it a try :wink:

int column[16] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, A0, A1}; //initializing and declaring led rows
int layer[4] = {A2, A3, A4, A5}; //initializing and declaring led layers

unsigned long current_time; //to store the present time from millis
unsigned long previous_time = 0;
byte loading = 0;


void setup() {  //this will run only once at startup
  Serial.begin(115200);
  for (int i = 0; i < 16; i++) { //setting columns to OUTPUT
    pinMode(column[i], OUTPUT);
  }
  for (int i = 0; i < 4; i++) { //setting layers to OUTPUT
    pinMode(layer[i], OUTPUT);
  } 
  off_the_cube();
  SetLoadingTo(0); 
}

void loop() {
  current_time = millis();
//  off_the_cube();
  on_and_off_layers_up_down_not_timed();
}

void off_the_cube() {   //this function will turn off whole cube
  for (int i = 0; i < 16; i++) {
    digitalWrite(column[i], HIGH);
  }
  for (int i = 0; i < 4; i++)  {
    digitalWrite(layer[i], LOW);
  }
}

void on_the_whole_cube() {
  for (int i = 0; i < 16; i++) {
    digitalWrite(column[i], LOW);
  }
  for (int i = 0; i < 4; i++) {
    digitalWrite(layer[i], HIGH);
  }
}

void on_and_off_layers_up_down_not_timed() {
  unsigned long delay_time = 150;
  if ((current_time - previous_time > delay_time) && (loading == 0)) {
    for (int i = 2; i != 0; i--) {
      on_the_whole_cube();
    }
    SetLoadingTo(1);
  }
  if ((current_time - previous_time > delay_time) && (loading == 1)) {
    for (int i = 4; i != 0; i--) {
      digitalWrite(layer[i - 1], 0);
    }
    SetLoadingTo(2);
  }
  if ((current_time - previous_time > delay_time) && (loading == 2)) {
  for (int i = 0; i < 4; i++) {
      digitalWrite(layer[i], 1);
      //delay(delay_time);
    }
    SetLoadingTo(3);
  }
  if ((current_time - previous_time > delay_time) && (loading == 3)) {
  for (int i = 0; i < 4; i++) {
      digitalWrite(layer[i], 0);
      //delay(delay_time);
    }
    SetLoadingTo(4);
  }
  if ((current_time - previous_time > delay_time) && (loading == 4)) {
  for (int i = 4; i != 0; i--) {
      digitalWrite(layer[i - 1], 1);
      delay(delay_time);
    }
    SetLoadingTo(0); // This starts all over again
  }

}

void SetLoadingTo(byte val) {
  loading = val;
  previous_time = millis();
  Serial.println(loading);
}

(But it is just a simple correction of your code ... It would be better to rewrite the sketch in a way that you do not use delays() in the for-loops ... )

P.S.: I commented out off_the_cube() in loop() and moved it to setup(). Otherwise you would switch off the cube every loop() instead of going through the stages 0 to 4

If you want the cube to be switched off you can add a stage 5 where you call off_the_cube().