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.

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
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?
    – Utsav
    Sep 19, 2017 at 13:15
  • 1
    @Utsav ... it was a type and I updated it, thanks for the notification 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.

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.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.