can't get millis delay to work

First, you've helped me and dozens of others to understand "blink w/o delay". I have employed it a number of times but struggle with it each time. Delay is easy to use, you want an action to continue for a set period of time you write delay(time in ms). So very easy. "blink w/o delay" is not as easy to implement (at least for me).

In the first instance I write to the servo using the millis timing method as I have used it in the past. It does not work. I have obviously missed something.

What I want to do is indicated by the three other servo processes. The code follows:

#include <Servo.h> 
#include <Ping.h>

Ping ping = Ping(8,74,19);
Servo myservo;  // create servo object to control a servo 

long blinkTimer2;
int pos = (0);    // variable to store the servo position 
int outputPin = 12;
int outputPin2 = 13;
int outputPin3 = 11;


void setup() 

{
Serial.begin(9600);  
myservo.attach(9);  // attaches the servo on pin 9 to the servo object 
pinMode(outputPin, OUTPUT);
pinMode(outputPin2, OUTPUT);
pinMode(outputPin3, OUTPUT);
} 

void loop() 

{ 
  ping.fire();
  Serial.print("Microseconds: ");
  Serial.print(ping.microseconds());
  Serial.print(" | Inches ");
  Serial.print(ping.inches());
  //Serial.print(" | Centemeters: ");
  //Serial.print(ping.centemeters());
  Serial.println();
  
  
   {                                  
    myservo.write(0);  
    Serial.print(0);
    Serial.println(" ");
    digitalWrite(outputPin2, HIGH); 
    blinkTimer2 = millis() + 1500;
    digitalWrite(outputPin2, LOW); 
    blinkTimer2 = millis() + 35;                       
   } 
  
    {                                
     myservo.write(90);              
     Serial.print(90);
     Serial.println(" ");
     digitalWrite(outputPin3, HIGH); 
     delay(1000);
     digitalWrite(outputPin3, LOW); 
     delay(35);                        
    }
 
     {                                
      myservo.write(180);               
      Serial.print(180);
      Serial.println(" ");
      digitalWrite(outputPin, HIGH); 
      delay(1000);
      digitalWrite(outputPin, LOW); 
      delay(35);
      } 
  
  
       {                                
        myservo.write(90);              
        Serial.print(90);
        Serial.println(" ");
        digitalWrite(outputPin3, HIGH); 
        delay(1000);
        digitalWrite(outputPin3, LOW); 
        delay(35);                        
       }
  
  
  
}
   {                                  
    myservo.write(0);  
    Serial.print(0);
    Serial.println(" ");
    digitalWrite(outputPin2, HIGH);
    blinkTimer2 = millis() + 1500;
    digitalWrite(outputPin2, LOW);
    blinkTimer2 = millis() + 35;                      
   }

First question. What are the curly braces ({}) for?

Second question. You set blinkTimer2 to a value, turn off the output pin you just turned on, and the set blinkTimer2 to a new value. Yet, you never use blinkTimer2 anywhere else. What are you trying to do?

Third question. Do you really understand how millis is used in the blink without delay example? I don't mean this in any mean-spirited way, but it seems that you do not.

To have something happen later, you have two choices. You can set a timer, and wait (doing absolutely nothing else) until the timer goes off. When it goes off, it will be time to do whatever it was you were waiting for.

On the other hand, you could check your watch periodically, to see if it is time to do whatever.

The delay function (and the Blink example) use the first approach. The millis function, and some additional code (as illustrated in the Blink Without Delay example) use the second approach.

As an example, the phone rings. It's your girlfriend. She wants you to pick her up at 7:00 tonight, to go to a movie. It's 3:30 now. You need to leave at 6:30 to pick her up.

You could determine that requires a call to delay of 3 hours, and sit in a chair doing nothing until it's time to go pick her up.

On the other hand, you could do your homework. At the end of each page, check your watch. Is it time to go? If not, keep studying. If so, close the books and go.

You get done with your homework. Is is time to go? No. Mow the grass. Every time you turn around, check your watch.

One way, you get nothing else done. The other way, you get plenty of other stuff done.

What you have done in the code you posted was determine when it was time to leave on your date. Then, you left on your date. Then, you determined when it was time to go home. Then, you went home, without ever actually getting to see the girlfriend or the movie.

(If you're married, substitute wife (or mistress) for girlfriend, everywhere. Unless you like trouble.)

PaulS, thank you for responding so quickly.

First question. What are the curly braces ({}) for?

I don't know. Residue from a cutting pasting misunderstanding no doubt. I will remove them.

Second question. You set blinkTimer2 to a value, turn off the output pin you just turned on, and the set blinkTimer2 to a new value. Yet, you never use blinkTimer2 anywhere else. What are you trying to do?

I write to the servo four times. Once (in the first instance) I attempted to replace the "delay" seen the following three instances:

It was my intention to move the servo to 0,90,and180 degrees and then back again. To send the position of the servo back via serial port. The servo hosts a ping ultrasound sensor. I want to collect the ping info at each of three servo positions and compare them to adjust course. The ping info is also collected and sent via serial port.

If I write each instance like this:

myservo.write(90);
Serial.print(90);
Serial.println(" ");
digitalWrite(outputPin3, HIGH);
delay(1000);
digitalWrite(outputPin3, LOW);
delay(35);

all is well. However, I need to replace the delay as it pauses the entire program in each instance it's used. I had tried this:

myservo.write(0);
Serial.print(0);
Serial.println(" ");
digitalWrite(outputPin2, HIGH);
blinkTimer2 = millis() + 1500;
digitalWrite(outputPin2, LOW);
blinkTimer2 = millis() + 35;

I thought I had copied it from previous code that had worked for me. It's frustrating because I thought I had this millis delay thing down. I appreciate your "for dummies" explanation. Thank you for taking the time to help. I'll let you know if this gets me going.

In fact I just finished "C programming for dummies" in attempt to understand the code I've been "copying" and make it work in various ways. Not one thing is mentioned about millis timing in all 500 plus pages. On to the next text book which I have been told is more useful. It looks a little bit over my head but I have time to study.

The C language itself doesn't include the millis function, so you won't find it covered in any C (or C++) book. It is a core function of the Arduino.

My explanation on how the 'blink without delay' works...

You use millis() to get the current time of the microcontroller (since it started).

unsigned long currentTime = 0; //haven't started yet, the current time is thus 0
unsigned long previousTime = 0; //havent started yet, the previous time is thus 0

void loop()
{
  currentTime = millis(); //get the current time
  unsigned long millisPassed = currentTime-previousTime; //get the difference between the current time and the previous time
  previousTime = currentTime; //this time measurement will be the previous time for the next time this code runs
}

Use the millisPassed value to determine whether the wait is over using an if statement.
I really don't get how this can be considered complex :-X
It is regular delta based mathematics...

Ok, admittedly, I'm an IT guy, so this sort of thinking is natural for me :-/

PaulS, indeed. And so without the help of other more knowledgeable folks like yourself, I'd get no where. Thanks again! :slight_smile:

Imahilus, Yes! I think I get that. I will get back to this string and let you know if I've finally learned this or not. I do believe I've gotten it. :smiley:

And to the rest of you who have suffered through this with me... thank you for your patience. :-[

Heres a 'blink without delay' I wrote from scratch this afternoon (apart from the comments :wink: ). It blinks 2.5 times a second and outputs the running time to the serial. I find the example version confusing too, see what you make of this :

/*
 
 Stephen's Blink and long term clock accuracy
 
 */

int ledPin =  13; // LED connected to digital pin 13
unsigned long time;
unsigned long secloop = 1000;
boolean liteon = false;


// The setup() method runs once, when the sketch starts

void setup()   {                
  // initialize the digital pin as an output:
  pinMode(ledPin, OUTPUT);     
  Serial.begin(115200);
}

// the loop() method runs over and over again,
// as long as the Arduino has power

void loop()                     
{
  time = millis();
  if (time >= secloop){
    secloop = secloop + 200;
    Serial.println(secloop/100,DEC);
    if (liteon){
      digitalWrite(ledPin, HIGH); 
      liteon = false;
    }
    else
    {
      digitalWrite(ledPin, LOW); 
      liteon = true;
    };
  };
}

'Secloop' started life as a second but evolved into 0.2 seconds.

No offense, pluggy, but I find the regular blink without delay example a lot more obvious...
It just has massive amounts of comments that don't say a thing.
The normal example is nearly identical to the thing I've posted here.

My issue with your example is mostly the use of magic numbers, while it is obvious to you why they are those numbers, others can only geuss.
The initial 1000 value of secloop for instance, I don't know.
I'm geussing an initial start-up delay, since you increment the value later on.
The 200 which you keep increasing it by is the delay between each state change of the LED (state change being; turning it on or off).
Figured that part out by your 2.5 blinks a second remark in your post (2.5 blinks, a blink being a LED turning on, and off, thus 5 state changes.. wait a minute, thats 200 milliseconds per state change!..)
I reckon crucial bits to put into comments :wink:

Other than that, a good alternative to the normal method.

The initial setting of sec loop to 1000 is left over from my initial sketch where it was intended to loop every second, it didn't effect the long term running so it got left. The light blinks on and off in 400 millisconds (200 on, 200 off) hence 2.5 times a second. It wasn't written as a blink, thats just to let me know its running, the bit I want is the running time output to the serial. At the other end I sample values at minute intervals and log them over time to establish how accurate the clock is on the arduino.

I'm not good with comments, it was written for my own use before I saw this thread, and it fit so I posted it. The "magic numbers" avoids accumulative errors which can happen in these kinds of programs, not a problem in many cases but definitely important when you're establishing how accurate the arduinos clock is.

As a sideline, I've definitely established that crystals are more accurate than ceramic resonators. (Nahh, you don't say :wink: ). I have long term programs running that have established that my 3 real Duemilanoves are good to better than a second a day (the best one is almost good to a second a week). My cheap Ebay knockoff duemilanove is good to within 3 seconds a day and a homebrew with a ceramic resonator gains about 14 seconds a day.