1

Apparently using delay() commands locks the Arduino during the delay period and there are better ways to control a servo that free the Arduino to do other things at the same time as running the servo.

At this point my code consists of a servo going forwards and backwards like this:

void setup()
{
 pinMode(1, OUTPUT); // makes pin 1 an output
}
void loop()
{
for(int i = 0; i<31; ++i) { //keeps in this position for about 400ms
 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
 delay(19); 
}
for(int i = 0; i<31; ++i) { // keeps in this position for about 400ms
 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
 delay(19);
}}

Where and how will I add some code that will allow the arduino to carry out another task for example blinking an led light during the approximately 20ms between servo pulses.

NOTE: The arduino is using the ATtiny 85 Processor.

asked Sep 19, 2017 at 5:51

3 Answers 3

2

Before and after the delay of 19 ms?

In setup add:

pinMode(2, OUTPUT); // LED pin output

Than changen in both cases:

 delay(19); 

into

 digitalWrite(2, HIGH); // LED on
 delay(19); 
 digitalWrite(2, LOW); // LED off
answered Sep 19, 2017 at 8:48
2
  • 1
    When you say digitalWrite(2, HIGH); // LED on, you use pin 2 but when you say digitalWrite(1, LOW); // LED off, you use pin one. Is this a typo or what? Commented Sep 19, 2017 at 13:15
  • 1
    @Utsav ... it was a type and I updated it, thanks for the notification Commented Sep 19, 2017 at 13:39
2

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.

answered Sep 19, 2017 at 16:52
1

I'm not sure exactly what you mean with "between servo pulses" but I am assuming it means you want to blink the led while the servo is turning.

Use the Arduino Timer library: https://playground.arduino.cc/Code/Timer

Add this at top of the sketch:

#include "Timer.h"
Timer t;
#define BLINK_TIME 20

in setup, add:

t.oscillate(LED_PIN, BLINK_TIME, HIGH);

inside the two for-loops, add:

t.update();

This will make the led on LED_PIN turn on and off every 20 milliseconds.

answered Sep 19, 2017 at 9:11

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.