Swinging servo doesn't always switches off

Hi guys,

I’m new in the Arduino-world, starting out with the starterkit and trying something of my own for the first time.

When I press the button on my project a servo starts to swing between a certain number of degrees and two leds start to burn.

Now, when I press the button again, the servo stops swinging and the leds stop burning.

At least, that’s what I intended, strange thing though, turning everything on works just fine every time, turning it off not, sometimes when I push the button it switches off immediately but most of the time I have to push it a few times, or a few seconds before it switches off.

Anybody who’s got an idea what I did wrong?
Thanks a lot!

#include <Servo.h>
Servo myServo;
const int button = 2;
const int servoOn = 9;
const int led1 = 3;
const int led2 = 4;
int onOff = 0;
int previousOnOff = 0;
int servoEnabled = 0;

void setup(){
  myServo.attach(9);
  pinMode(button, INPUT);
  pinMode(servoOn, OUTPUT);
  pinMode(led1, OUTPUT);
  pinMode(led2, OUTPUT);
  digitalWrite(servoOn,LOW);
}
void loop(){
  onOff = digitalRead(button);
  delay(1);
  if(onOff != previousOnOff){
    if(onOff == HIGH){
      servoEnabled = !servoEnabled;
    }  
  }
  if (servoEnabled == 1){
    digitalWrite(3, HIGH);
    digitalWrite(4, HIGH);
    myServo.write(65);
    delay(500);
    myServo.write(115);
    delay(500);
  }
  if (servoEnabled == 0){
    digitalWrite(3, LOW);
    digitalWrite(4, LOW);
  previousOnOff = onOff;
  }
}

I'm just going to guess it's the 500mS delays... You are not reading the switch while delay() is "running".

The Blink Without Delay example shows you how to set-up a timer, and check if the time is up every time through a fast-loop without holding everything up with a delay().

Thank you!

I'l probably try this tomorrow. With all the different topics etc. here I couldn't find a solution myself, that's why I asked. Like I said, new in Arduino-world and didn't come up with the "delay"-problem myself. Thanks a lot!

Look at the demo several things at a time

...R

Thanks a lot both of you, i’ve studied the “several things at a time” topic, and then rewrote all of my code for my own project based on that one.

Now everything works except for one small problem:

When I push the button I want the leds to turn on and the servo to begin swinging and it does that.

The problem is that the moment I push the butten the servo doesn’t start to swing slowly but first “jumps” a part of it’s movement and then sings slowly.

Any idea what this could be?

Thanks!

// LIBRARIES

#include <Servo.h>

// CONSTANTS

const int buttonLed_Pin = 3;
const int buttonPin = 2;
const int servoPin = 9;
const int buttonInterval = 300;
const int servoMinDegrees = 65;
const int servoMaxDegrees = 115;

//VARIABLES

byte buttonLed_State = LOW;
Servo myservo;
int servoPosition = 90;
int servoSlowInterval = 80;
int servoFastInterval = 10;
int servoInterval = servoSlowInterval;
int servoDegrees = 2;

unsigned long currentMillis = 0;
unsigned long previousButtonMillis = 0;
unsigned long previousServoMillis = 0;

//====================================================

void setup(){
  pinMode(buttonLed_Pin, OUTPUT);
  pinMode(buttonPin, INPUT_PULLUP);
  myservo.write(servoPosition);
  myservo.attach(servoPin);
}

//====================================================

void loop(){
  currentMillis = millis();
  readButton();
  switchLeds();
  servoSweep();
}

//=====================================================

void switchLeds(){
  digitalWrite(buttonLed_Pin, buttonLed_State);
}

//=====================================================

void readButton(){
  if (digitalRead(buttonPin) == LOW){
    buttonLed_State = LOW;
  }
  else{
    buttonLed_State = HIGH;
  }
}

//======================================================

void servoSweep(){
  if (digitalRead(buttonPin) == HIGH){
  if(currentMillis - previousServoMillis >= servoInterval){
    previousServoMillis += servoInterval;
    servoPosition = servoPosition + servoDegrees;
    if(servoInterval == servoSlowInterval){
      servoInterval = servoFastInterval;
    }
    else{
      servoInterval = servoSlowInterval;
    }
  }
  
  if ((servoPosition >= servoMaxDegrees) || (servoPosition <= servoMinDegrees)){
    servoDegrees = - servoDegrees;
    servoPosition = servoPosition + servoDegrees;
  }
  myservo.write(servoPosition);
}
}

if the servo is not already at the location that is the first step in your swing it will rush to the first position at full speed.

There isn't really any answer to this apart from being careful to stop the servo at the location from which you want it to start next time.

...R

Ok, thought someting like that. I suspect it needs a fixed start position, I can't just let it start where it stopped i guess?

MaartenCal:
I can't just let it start where it stopped i guess?

You can, but I thought you did not want to.

...R

Starting position doesn't matter as long as it swings between 65 and 115 degrees and back.

MaartenCal:
Starting position doesn't matter as long as it swings between 65 and 115 degrees and back.

I'm lost now. Maybe I misunderstood Reply #4. I thought what you meant was that (for example) the servo would be at 85deg and would jump to 65 before smoothly moving to 115.

...R

No, when I push the button I want it to smoothly move betweet 65 & 115 all the time, it can just stop where it is at the point I release the button and start from there when I push it again.

MaartenCal:
No, when I push the button I want it to smoothly move betweet 65 & 115 all the time, it can just stop where it is at the point I release the button and start from there when I push it again.

And does it do that now?

If not what does it do that you don't want it to do?

...R