millis! making my head spin

:0 Ive been going through tutorial after tutorial but I cant seem to replicate what ive done with the delay command. Problem is im combining this programming with other loops so I cant use the delay.

Heres the code that im trying to get all of the delays switched from milis:

int ledPin1 = 13;
int ledPin2 = 12;
void setup()
{
pinMode(ledPin1, OUTPUT);
pinMode(ledPin2, OUTPUT); // sets the digital pin as output
}

void loop()
{
digitalWrite(ledPin1, HIGH); //START FLSH
digitalWrite(ledPin2, LOW);
delay(50);
digitalWrite(ledPin1, LOW);
digitalWrite(ledPin2, LOW);
delay(50);
digitalWrite(ledPin1, HIGH);
digitalWrite(ledPin2, LOW);
delay(50);
digitalWrite(ledPin1, LOW);
digitalWrite(ledPin2, LOW);
delay(50);
digitalWrite(ledPin1, HIGH);
digitalWrite(ledPin2, LOW);
delay(50);
digitalWrite(ledPin1, LOW);
digitalWrite(ledPin2, LOW);
delay(50);
digitalWrite(ledPin1, HIGH);
digitalWrite(ledPin2, LOW);
delay(50);
digitalWrite(ledPin1, LOW);
digitalWrite(ledPin2, LOW);
delay(50);
digitalWrite(ledPin1, LOW);
digitalWrite(ledPin2, HIGH);
delay(50);
digitalWrite(ledPin1, LOW);
digitalWrite(ledPin2, LOW);
delay(50);
digitalWrite(ledPin1, LOW);
digitalWrite(ledPin2, HIGH);
delay(50);
digitalWrite(ledPin1, LOW);
digitalWrite(ledPin2, LOW);
delay(50);
digitalWrite(ledPin1, LOW);
digitalWrite(ledPin2, HIGH);
delay(50);
digitalWrite(ledPin1, LOW);
digitalWrite(ledPin2, LOW);
delay(50);
digitalWrite(ledPin1, LOW);
digitalWrite(ledPin2, HIGH);
delay(50);
digitalWrite(ledPin1, LOW); //END FLSH
digitalWrite(ledPin2, LOW);
delay(50);
digitalWrite(ledPin1, HIGH); //START FLSH
digitalWrite(ledPin2, LOW);
delay(50);
digitalWrite(ledPin1, LOW);
digitalWrite(ledPin2, LOW);
delay(50);
digitalWrite(ledPin1, HIGH);
digitalWrite(ledPin2, LOW);
delay(50);
digitalWrite(ledPin1, LOW);
digitalWrite(ledPin2, LOW);
delay(50);
digitalWrite(ledPin1, HIGH);
digitalWrite(ledPin2, LOW);
delay(50);
digitalWrite(ledPin1, LOW);
digitalWrite(ledPin2, LOW);
delay(50);
digitalWrite(ledPin1, HIGH);
digitalWrite(ledPin2, LOW);
delay(50);
digitalWrite(ledPin1, LOW);
digitalWrite(ledPin2, LOW);
delay(50);
digitalWrite(ledPin1, LOW);
digitalWrite(ledPin2, HIGH);
delay(50);
digitalWrite(ledPin1, LOW);
digitalWrite(ledPin2, LOW);
delay(50);
digitalWrite(ledPin1, LOW);
digitalWrite(ledPin2, HIGH);
delay(50);
digitalWrite(ledPin1, LOW);
digitalWrite(ledPin2, LOW);
delay(50);
digitalWrite(ledPin1, LOW);
digitalWrite(ledPin2, HIGH);
delay(50);
digitalWrite(ledPin1, LOW);
digitalWrite(ledPin2, LOW);
delay(50);
digitalWrite(ledPin1, LOW);
digitalWrite(ledPin2, HIGH);
delay(50);
digitalWrite(ledPin1, LOW); //END FLSH
digitalWrite(ledPin2, LOW);
delay(50);
digitalWrite(ledPin1, HIGH); //START FLSH
digitalWrite(ledPin2, LOW);
delay(50);
digitalWrite(ledPin1, LOW);
digitalWrite(ledPin2, LOW);
delay(50);
digitalWrite(ledPin1, HIGH);
digitalWrite(ledPin2, LOW);
delay(50);
digitalWrite(ledPin1, LOW);
digitalWrite(ledPin2, LOW);
delay(50);
digitalWrite(ledPin1, HIGH);
digitalWrite(ledPin2, LOW);
delay(50);
digitalWrite(ledPin1, LOW);
digitalWrite(ledPin2, LOW);
delay(50);
digitalWrite(ledPin1, HIGH);
digitalWrite(ledPin2, LOW);
delay(50);
digitalWrite(ledPin1, LOW);
digitalWrite(ledPin2, LOW);
delay(50);
digitalWrite(ledPin1, LOW);
digitalWrite(ledPin2, HIGH);
delay(50);
digitalWrite(ledPin1, LOW);
digitalWrite(ledPin2, LOW);
delay(50);
digitalWrite(ledPin1, LOW);
digitalWrite(ledPin2, HIGH);
delay(50);
digitalWrite(ledPin1, LOW);
digitalWrite(ledPin2, LOW);
delay(50);
digitalWrite(ledPin1, LOW);
digitalWrite(ledPin2, HIGH);
delay(50);
digitalWrite(ledPin1, LOW);
digitalWrite(ledPin2, LOW);
delay(50);
digitalWrite(ledPin1, LOW);
digitalWrite(ledPin2, HIGH);
delay(50);
digitalWrite(ledPin1, LOW); //END FLSH
digitalWrite(ledPin2, LOW);
delay(50);
digitalWrite(ledPin1, LOW); //START ALT
digitalWrite(ledPin2, HIGH);
delay(50);
digitalWrite(ledPin1, LOW);
digitalWrite(ledPin2, LOW);
delay(150);
digitalWrite(ledPin1, HIGH);
digitalWrite(ledPin2, LOW);
delay(50);
digitalWrite(ledPin1, LOW);
digitalWrite(ledPin2, LOW);//END ALT
delay(150);
digitalWrite(ledPin1, LOW); //START ALT
digitalWrite(ledPin2, HIGH);
delay(50);
digitalWrite(ledPin1, LOW);
digitalWrite(ledPin2, LOW);
delay(150);
digitalWrite(ledPin1, HIGH);
digitalWrite(ledPin2, LOW);
delay(50);
digitalWrite(ledPin1, LOW);
digitalWrite(ledPin2, LOW);//END ALT
delay(150);
digitalWrite(ledPin1, LOW); //START ALT
digitalWrite(ledPin2, HIGH);
delay(50);
digitalWrite(ledPin1, LOW);
digitalWrite(ledPin2, LOW);
delay(150);
digitalWrite(ledPin1, HIGH);
digitalWrite(ledPin2, LOW);
delay(50);
digitalWrite(ledPin1, LOW);
digitalWrite(ledPin2, LOW);//END ALT
delay(150);
digitalWrite(ledPin1, LOW); //START ALT
digitalWrite(ledPin2, HIGH);
delay(50);
digitalWrite(ledPin1, LOW);
digitalWrite(ledPin2, LOW);
delay(150);
digitalWrite(ledPin1, HIGH);
digitalWrite(ledPin2, LOW);
delay(50);
digitalWrite(ledPin1, LOW);
digitalWrite(ledPin2, LOW);//END ALT
delay(150);
}

It produces two different patterns in one loop. It has almost a strobe effect.

I was looking at this thread and trying to do an approach using the switch command like they did but I wasn't able to get it to work. (http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1275166350)

My goal for this program is to put the arduino onto a rotary switch and have a different flash pattern assigned to each setting on the rotary switch. I should be able to do that on my own I just need help understanding how to use millis to create flash patterns that arnt as simple as just on/off at a preset rate.

Thanks in advanced.

Start by looking at and fulling understanding the Blink Without Delay example. That is really the baseline for understanding how to accomplish this. I don't mean take a glance at it, I mean read it, run it, tweak it until you know exactly what it is doing.

When you fully understand it, realize that you can change the interval at will. In fact, what about an array of the delay times and a counter that increments through each "step"" to determine what the next interval should be? If you can understand that, then integrating what the LEDs should be doing at each "step" parallels what you did with the delay times.

Arrch:
Start by looking at and fulling understanding the Blink Without Delay command. That is really the baseline for understanding how to accomplish this. I don't mean take a glance at it, I mean read it, run it, tweak it until you know exactly what it is doing.

When you fully understand it, realize that you can change the interval at will. In fact, what about an array of the delay times and a counter that increments through each "step"" to determine what the next interval should be? If you can understand that, then integrating what the LEDs should be doing at each "step" shouldn't be difficult.

Exactly what im thinking. I am going to do like an array of delays produced by the millis instead of delays. Thats what im trying to figure out. Still waiting for my ah-hah moment with this millis stuff. Ill go through the blinkwithoutdelay again see if I can get it this time.

My problem is that I dont want a large chunk of code everytime I want the loop to pause for a second. I have yet to find a good way to do this other than delay. I really want like a one line command like delay works but with every millis tutorial I end with with a large chunk of code just to pause 500 miliseconds which i will be doing alot. Is there like a way to define a milli's pause for 500 miliseconds?

Mobius_One_Fox3:
My problem is that I dont want a large chunk of code everytime I want the loop to pause for a second. I have yet to find a good way to do this other than delay. I really want like a one line command like delay works but with every millis tutorial I end with with a large chunk of code just to pause 500 miliseconds which i will be doing alot. Is there like a way to define a milli's pause for 500 miliseconds?

I guess your definition of "a large chunk" of code is a bit different from mine, because using millis() to do something at a certain interval requires only a handful of lines of code.

The problem is if you're not using delay, then you have to deal with the loop() iterations, and how your "pause" works with in conjunction with it. That "pause" code would likely be run thousands of times during that 500 ms, so you have to be very methodical about how that is implemented.

A simple example of this is the Blink Without Delay versus something like "if it's been 20 seconds, do this and keep doing this until we reset the timer". If delay() doesn't affect your code in other aspects, you can use it to implement both these scenarios. However, with millis(), these scenarios are implemented differently.

Arrch:
I guess your definition of "a large chunk" of code is a bit different from mine, because using millis() to do something at a certain interval requires only a handful of lines of code.

The problem is if you're not using delay, then you have to deal with the loop() iterations, and how your "pause" works with in conjunction with it. That "pause" code would likely be run thousands of times during that 500 ms, so you have to be very methodical about how that is implemented.

A simple example of this is the Blink Without Delay versus something like "if it's been 20 seconds, do this and keep doing this until we reset the timer". If delay() doesn't affect your code in other aspects, you can use it to implement both these scenarios. However, with millis(), these scenarios are implemented differently.

Alright I gotcha. I found this code in an old tutorial but I think there is a problem with it.

unsigned long currentTime = 0; //this variable will be overwritten by millis() each iteration of loop
unsigned long pastTime = 0; //no time has passed yet
int currentState = 0; //the default state
int wait = 0; //no need to wait, nothing has happened yet

void setup()
{
pinMode(13, OUTPUT); //the LED we're going to blink.. I just put 13 in as a magic number so it doesn't spoil the view of the worthwhile millis code
}

void loop()
{
pastTime = currentTime; //currentTime at this point is the current time from the previous iteration, this should now be pastTime
currentTime = millis(); //currentTime is now the current time (again).

unsigned long timePassed = currentTime - pastTime; //this is roll-over proof, if currentTime is small, and pastTime large, the result rolls over to a small positive value, the time that has passed

if(timePassed >= wait) //part1 of the state engine
{
switch(currentState) //part2 of the state engine, its this simple, an if and a switch
{
case 0: //the default state.. turn the led on!
digitalWrite(13, HIGH); //light the LED up!
wait = 500; //wait 500 milliseconds before doing something from this state engine again
currentState = 1; //the next state that should be executed is 1
break; //break out of the switch, else it'll execute the case below this one too

case 1:
digitalWrite(13, LOW); //turn the LED off again
wait = 500; //wait 500 milliseconds again before turning the LED on again
currentState = 0; //turning the LED on again is done in state 0
break;
}
}
}

For some reason it doesnt switch between states it only stays on case 0. Do you guys see any issues with it? I am trying to use this as my base to learn about millis.

You want to set pastTime only inside the if statement. Or something that takes the place of pastTime, since then name wouldn't reflect its meaning.

void setup()
{
  pinMode(13, OUTPUT); //the LED we're going to blink.. I just put 13 in as a magic number so it doesn't spoil the view of the worthwhile millis code
}

void loop()
{
  pastTime    = currentTime; //currentTime at this point is the current time from the previous iteration, this should now be pastTime
  currentTime = millis();    //currentTime is now the current time (again).
  
  unsigned long timePassed = currentTime - pastTime; //this is roll-over proof, if currentTime is small, and pastTime large, the result rolls over to a small positive value, the time that has passed

  ...
}

Walk through these three lines of code, assuming after each iteration, millis() is incremented by 1. You'll quickly see that timePassed will never be greater than 1.

Threads about millis, making my head spin....

tested, works, but you'll have to figure out how

// Led On Then Off -- Rippling leds demo
unsigned long  blinkOnTime =  50UL;

// this needs 4 leds and resistors, one each on pins 4, 5, 6, 7, all to ground
#define         LEDS  4
byte            ledPin[ LEDS ] = { 
  4, 5, 6, 7 };
unsigned long   ledTime[ LEDS ][ 2 ]; // start and duration 

// blink() must be run first thing in loop(), it checks the time as well as sets blinks
byte  blinkCheck( byte led )
{
  static unsigned long  lastTime = 0UL;
  byte    turnOff = 0;

  if ( millis() != lastTime ) // only check once per milli because......
  {
    lastTime = millis();

    if ( lastTime - ledTime[ led ][ 0 ] > ledTime[ led ][ 1 ])  // duration ran out 
    {
      digitalWrite( ledPin[ led ], LOW );  
      turnOff = 1;  
//      Serial.print( led, DEC );
//      Serial.println( " off" );    
    }
  }

  return  turnOff;
}

void  blink( byte led, unsigned long time )
{
  if ( led < LEDS )
  {
    ledTime[ led ][ 0 ] = millis();
    ledTime[ led ][ 1 ] = time;
    digitalWrite( ledPin[ led ], HIGH );
//    Serial.print( led, DEC );
//    Serial.println( " on" );    
  }
}

void setup( void )
{
//  Serial.begin( 9600 );
  for ( byte i = 0; i < LEDS; i++ )
  {
    pinMode( ledPin[ i ], OUTPUT );
    digitalWrite( ledPin[ i ], LOW );
  }
  blink( 0, blinkOnTime );
}

void loop( void )
{
  static byte  led = 0;

  if ( blinkCheck( led )) // return > 0 means led turned off
  {
    led = (( led + 1 ) & 3 );
    blink( led, blinkOnTime );
  }  
}