Zukane
Zukane

Reputation: 51

Replace delay() with millis inside a for loop Arduino

In my code I want to replace the effect of delay() with millis or any other method that allows the use of button inputs while the code still runs. I am making an obstacle-type game where the player has to dodge incoming LEDs.

int LEDrows[4][4] = {{9, 8, 7, 6}, {5, 4, 3, 2}};
int Button = 1;
int ButtonCheck = 0;
int playerPosition = 0;

void setup()
{
  pinMode(Button, INPUT);
  for(int p=0; p>=1; p++){
    for(int b=0; b>=3; b++){
      pinMode(LEDrows[p][b], OUTPUT);
    }
  }
}

void loop()
{
  ButtonCheck = digitalRead(Button);
  if(ButtonCheck != 0){
    playerPosition += 1;
    
    if (playerPosition == 1){
      digitalWrite(LEDrows[0][3], HIGH);
      digitalWrite(LEDrows[1][3], LOW);
    }
    if (playerPosition > 1){
      playerPosition = 0;
      digitalWrite(LEDrows[1][3], HIGH);
      digitalWrite(LEDrows[0][3], LOW);
    }
  }
  
  int i = random(0, 2);
  for (int j = 0; j <= 3; j++) {
    digitalWrite(LEDrows[i][j], HIGH);
    delay(250);
    digitalWrite(LEDrows[i][j], LOW);
    delay(250);
  }
  delay(500);
}

I have two rows of 4 LEDS, stored in a nested list which i am iterating through. The LEDs will light up in a random row. I want to make the LED light up, wait 250ms, then make it disappear again, and wait 250ms. If this delay()-like effect can be achieved without using the delay function, then i would be pleased to learn how to do so.

Upvotes: 0

Views: 1474

Answers (2)

Clifford
Clifford

Reputation: 93524

Use static variables to retain state and timestamps of the events you want to be periodic. For example, the following will set an LED in a random column on row zero, and every 250ms will move it to the next row until after reaching row 3, it will restart at a new random column.

  static int j = 0 ;
  static int i = 0 ;
  
  // When j == 0, set initial LED
  if( j == 0 )
  {
      i = random(0, 2);
      digitalWrite(LEDrows[i][j], HIGH ) ;
  }
  
     
  // Get current millisecond tick
  unsigned long now = millis() ;

  // Every 250ms move the LED     
  static unsigned long led_timestamp = millis() ;
  if( now - led_timestamp > 250 )
  {
      led_timestamp = now ;

      digitalWrite(LEDrows[i][j], LOW ) ;
      j++ ;
      if( j > 3 )
      {
          j = 0 ;
      }
      else
      {
          digitalWrite(LEDrows[i][j], HIGH ) ;
      }
  }

The general pattern is:

static unsigned long timestamp = millis() ;
unsigned long now = millis() ;

if( now - timestamp > PERIOD_MS )
{
    timestamp = now ;

    // do something every PERIOD_MS here
    ...
}

With multiple timestamp variables you can perform tasks at various independent intervals.

Upvotes: 1

pdnr7
pdnr7

Reputation: 26

void toggle(uint8_t row,uint8_t col){
 static long time[4][4];

 long curr_time = millis(); //current system time
 long last_time = time[row][col];

 if(curr_time >= (last_time + toogle_delay)){
    digitalWrite((LEDrows[row][col]),!digitalread((LEDrows[row][col])));
    time[row][col] = curr_time;
 }
 else{}
}

Upvotes: 0

Related Questions