Short answer: don't use delay()
if you want to do anything other than waiting, so rewrite your code without that call.
Long answer follows.
Instead of asking the Arduino to go to sleep (1) until a certain amount of time has passed, you should write your code to run continuously and do certain things whenever enough time has passed since the last time they have been executed.
If the previous statement makes sense to you, then the following piece of code translates to C language what I just stated in English:
unsigned long time; // stores the time when the last motor movement happened, in ms
boolean clockwise; // stores the wanted direction: true CW, false CCW
unsigned byte counter; // stores how many time the wanted movement has occurred so far
unsigned long ledTimer; // stores the last time we changed the LED state
boolean ledIsOn; // stores the current LED state
void setup() {
pinMode(1, OUTPUT); // makes pin 1 an output
pinMode(13, OUTPUT); // makes pin 13 (onboard LED pin) an output
}
void loop() {
if (time - millis() >= 19) { // has enough time passed since the last time we executed a step motor movement?
time = millis(); // reset the timer for next pass
if (counter < 31) { // have we moved in the same direction enough?
if (clockwise) {
moveCW();
} else {
moveCCW();
}
counter++;
} else { // we moved enough times in the same direction: reset the counter and switch direction
counter = 0;
clockwise = !clockwise;
}
}
// do anything else, but don't use delay()!!!
// the following does the same as above, but on the LED
// blinking at 1Hz (500 ms on, 500ms off)
if (millis() - ledTimer >= 500) {
if (ledIsOn) {
digitalWrite(13, LOW);
} else {
digitalWrite(13, HIGH);
}
ledIsOn = !ledIsOn;
ledTimer = millis();
}
// need to do something more? go ahead and try
// but remember not to use delay() and not to waste too much time
// in complex calcs or the loop will take too long to wrap
}
void moveCW() {
digitalWrite(1, HIGH); //turns the servo pin to HIGH
delayMicroseconds(1000); //sets the servo to move clockwise
digitalWrite(1, LOW); //turns the servo pin to LOW
}
void moveCCW() {
digitalWrite(1, HIGH); // turns the servo pin to HIGH
delayMicroseconds(2000); //sets the servo to move anti-clockwise
digitalWrite(1, LOW); //turns the servo pin to LOW
}
There is a beautiful library called elapsedMillis
(reference) which can reduce a bit the boilerplate code regarding subtracting millis()
and all that stuff, but the code above is practically the same and, probably, more straightforward to begin with.
(1) The term sleep it's incorrect as it implies some sort of power reduction. Instead sleep()
is just wasting time at full power.