how to use millis instead of delay?

Hi there, my first post. i am very new to arduino and just start my first application. what i am trying to do is to control a valve with the use of a ardunion board and a servo. there are many valves and a servo for each. I want the some of the valve to stay open for, say half a second then close, and the other valves to repond to other digital inputs. now i tried to use the sample ‘sweep’ sketch, however the ‘delay’ function will put the whole thing to a stop, no other input can be processed. i found some posts suggesting the ‘millis’ will not put the program on hold, but i so far failed to find a sample to replace the ‘delay’ in the ‘sweep’ sketch.
the following is my sketch for 2 servos without digital inputs.

thank you for your help!

#include <Servo.h>

Servo myservo; // create servo object to control a servo
// a maximum of eight servo objects can be created
Servo myservo1;

int pos = 0; // variable to store the servo position

int potpin = 0; // analog pin used to connect the potentiometer

int val; // variable to read the value from the analog pin

void setup()
{
myservo.attach(9); // attaches the servo on pin 9 to the servo object
myservo1.attach(6);
}

void loop()
{
val = analogRead(potpin); // reads the value of the potentiometer (value between 0 and 1023)
val = map(val, 0, 1023, 500, 5000); // scale it to use it with the servo (value between 500ms and 5000ms)
{
for(pos = 25; pos < 125; pos +=125) // goes from 15 degrees to 68.2 degrees
{ // in steps of 45 degree
myservo.write(pos); // tell servo to go to position in variable ‘pos’
delay(500);
myservo1.write(pos);
delay(val);
}
for(pos = 125; pos>=125; pos-=65) // goes from 68.2 degrees to 15 degrees
{
myservo.write(pos); // tell servo to go to position in variable ‘pos’
delay(500);
myservo1.write(pos);
delay(val);
}
}
}

Hey there

delay() should work fine: Instead I would be looking closely at the for loops.

for(pos = 125; pos>=125; pos-=65)

(1) pos = 125, pos>=125 =true
(2) pos = 60, pos>=125 = false

…does not loop

for(pos = 25; pos < 125; pos +=125)
(1) pos = 25, pos < 125 = true
(2) pos = 150, pos < 125 = false

… does not loop

if you don’t understand why this doesn’t work, see http://www.arduino.cc/en/Reference/For

I would recommend changing the pos += 125 to something smaller.

If you want to make a millis() check instead, I would recommend that you look at a “do while” loop.

//setup: 
unsigned long Starttimer
unsigned long Endtimer
unsigned long Present

//in your loop:
present = millis()

//when you want to set the timer:
Starttimer=millis()
Endtimer=Starttimer + 500;

if (Endtimer < present){
 //do something after 500 milliseconds
}

or maybe use the do/while loop while Endtimer > present

//when you want to set the timer:
Starttimer=millis()
Endtimer=Starttimer + 500;

if (Endtimer < present){
//do something after 500 milliseconds
}

This won’t wait for Endtimer to be larger than present: Instead the “//do something after 500 milliseconds” will never work.

If you really want to do this, look at the do while loop on this post:
http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1280934067/#5

Thanks for replying! please forgive me for not understanding some of your points. the thing is that to my understanding the 'delay' will stop the program from responding to other inputs, while the 'millis' would not. So i would like to find a way to replace the 'delay' with 'millis' or the 'do while'. if Big Oil's code works it would be great! very encograged by your replies! if you can kindly point me to links with samples with 'millis' or 'do while' i think i be able to figure out how to make it work. thank you again! :D

The millis() is just a free running counter (in milliseconds). It starts when your program does and you can check it whenever you want.
http://www.arduino.cc/en/Reference/Millis

for the “do while”, the Arduino tutorial is:
http://www.arduino.cc/en/Reference/DoWhile
It is basically a “while” loop that does the code in the {} before checking if the condition is still true. Statements and flow control - C++ Tutorials is another good website to learn on. When you look at that second website, you will see a lot of “cout <<” and “cin >>” - Don’t worry about them, because they are just C++'s way of doing a “Serial.print” and “Serial.read”.

The next level up from that is to use timer interrupts, but they are an advanced subject which usually only get used in time critical situation. (I wouldn’t bother with them for your project)

Have a look at the BlinkWithoutDelay sample sketch that comes with the IDE (also here: http://www.arduino.cc/en/Tutorial/BlinkWithoutDelay )

It shows you how to do something at a regular time interval without using delay() (which as previously mentioned blocks execution of other statements).

Andrew

thanks again! put together the following codes: sweep with pot to control sweeping intervals and millis instead of delay. but myservo1 does not alway move after myservo! they do not sync! they are suppose to move one after the other in sync. because the first servo, that is myservo, will not wait for the second servo, myservo1, to complete its move! how can i keep them in sync? please help! thanks! :-/ :-/

codes:

//thanks to all who helped (InvalidApple,Big Oil,Andrew and the pot2val writer!
// based on sweep by BARRAGAN http://barraganstudio.com
// and blink without dely created 2005 by David A. Mellis modified 8 Feb 2010 by Paul Stoffregen

#include <Servo.h>

Servo myservo; // create servo object to control a servo
Servo myservo1; // a maximum of eight servo objects can be created

int pos = 0; // variable to store the servo position
int potpin = 0;
int val;
int myservopin = 9;
int myservo1pin = 6;
long previousMillis = 0;
long previousMillis1 = 0;
long interval = 500;
void setup()
{
myservo.attach(9); // attaches the servo on pin 9 to the servo object
myservo1.attach(6);
}

void loop()
{
val = analogRead(potpin); // reads the value of the potentiometer (value between 0 and 1023)
val = map(val, 0, 1023, 0, 3000); // scale it to use it with the servo (value between 0ms and 3000ms)
unsigned long currentMillis = millis();
unsigned long currentMillis1 = millis();
if(currentMillis - previousMillis > interval+val) {
// save the last time you blinked the LED
previousMillis = currentMillis;
if (myservo.read() > 30)
myservo.write(30);
else
myservo.write(115);
digitalWrite(myservopin, pos);
}

if(currentMillis1 - previousMillis1 > interval*2+val) { // myservo1 moves one interval after myservo
previousMillis1 = currentMillis1;
if (myservo1.read() > 30)
myservo1.write(30);
else
myservo1.write(115);
digitalWrite(myservo1pin, pos);
}
}
:-/

unsigned long currentMillis = millis();
 unsigned long currentMillis1 = millis();

Why do you have two "now" variables?

myservo.read() does not actually tell you where the servo is. It only tells you where you last told the servo to go. Can't you remember where you last told it to go?

int myservopin = 9;
int myservo1pin = 6;

 myservo.attach(9);  // attaches the servo on pin 9 to the servo object
 myservo1.attach(6);

What's the point of defining myservopin and myservo1pin if you are not going to use them?

   digitalWrite(myservopin, pos);

The digitalWrite function expects HIGH or LOW as the 2nd argument. I doubt that pos is either HIGH or LOW. You want to use analogWrite to use PWM output.

But, you DO NOT want to use PWM with servos.

In any case, what do you suppose this is doing to the servo?

One final comment, and this is more of a pet peeve of mine. If you have two of something, like servos, and you want to use numbers in the variable names, use numbers in both of them:

Servo myServo1;
Servo myServo2;

rather than in only one of them:

Servo myServo;
Servo myServo1;

It's much easier to see in the code where you refer to the wrong variable name if both names have numbers. If one name has a number, but the other one does not, the code looks unprofessional - like some code was pasted in without taking the time to make it blend in.

I'm getting off my soap box now.

thanks Paul, cleaned up the code! it works but the sync problem is not solved. have a good night!

// put together on 09Aug2010 by Leanne. sweep with pot to control sweep intervals and millis instead of delay.
//but myservo1 does not alway move after myservo! they do not sync! because the first servo, that is myservo, will not wait for
//the second servo, myservo1, to complete its move! how can i keep them in sync? please help!
//thanks to all who helped (InvalidApple,Big Oil,Andrew and the pot2val writer!
// based on sweep by BARRAGAN http://barraganstudio.com
// and blink without dely created 2005 by David A. Mellis modified 8 Feb 2010 by Paul Stoffregen

#include <Servo.h>

Servo servo1; // create servo object to control a servo
Servo servo2; // a maximum of eight servo objects can be created

int pos = 0; // variable to store the servo position
int potpin = 0;
int val;
int servo1pin = 9;
int servo2pin = 6;
long previousMillis = 0;
long previousMillis1 = 0;
long interval = 500;
void setup()
{
servo1.attach(servo1pin); // attaches the servo on pin 9 to the servo object
servo2.attach(servo2pin);
}

void loop()
{
val = analogRead(potpin); // reads the value of the potentiometer (value between 0 and 1023)
val = map(val, 0, 1023, 0, 3000); // scale it to use it with the servo (value between 0ms and 3000ms)
unsigned long currentMillis = millis();
if(currentMillis - previousMillis > interval+val) {
// save the last time you blinked the LED
previousMillis = currentMillis;
if (servo1.read() > 30)
servo1.write(30);
else
servo1.write(115);

}

if(currentMillis - previousMillis1 > interval*2+val) { // myservo1 moves one interval after myservo
previousMillis1 = currentMillis;
if (servo2.read() > 30)
servo2.write(30);
else
servo2.write(115);

}
}

You want servo1 to move, and once it stops then you want servo2 to move? You could toggle between them with two if statements. I think you might have to reset previousMillis after you move each servo also, but I'm not sure.

if (toggle == 0){
  
    //move servo1
    
    toggle = 1; 

 //reset previousMillis ?? 
}


if (toggle == 1){
  
  //move servo2
  
  toggle = 0;
  
  //reset previous Millis ??
  
}

thanks Big Oil! could not find a way to put the toggle to work yet, will try more.

if (toggle == 0){
  
    //move servo1
    
    toggle = 1;

//reset previousMillis ?? }

if (toggle == 1){    //move servo2    toggle = 0;    //reset previous Millis ??   }

Is the same as

toggle = 1 - toggle