ON/OFF Switch and Servo

Hi. I am fairly new to the arduino so please bare with me. I am trying to connect a 3 pin toggle switch to the arduino to turn the servo on/off. When the servo is on I want it to sweep back and forth. The sweep sketch works fine before I tried to add the switch.

I tried to modify the Sweep code from what I could find on the net. This is what I have:

#include <Servo.h>

const int buttonPin = 2;

int buttonState = 0;
int pos = 0;

Servo myservo;

void setup() {

myservo.attach(9);

pinMode(buttonPin, INPUT);
digitalWrite(buttonPin, HIGH);       // turn on pullup resistors

}

void loop() {
  buttonState = digitalRead(buttonPin);
  if(buttonState ==HIGH){

for(pos = 0; pos <= 120; pos += 1)  // goes from 0 degrees to 90 degrees
  {                                  // in steps of  degree
    myservo.write(pos); {              // tell servo to go to position in variable 'pos'
    delay(10);    // waits 10ms for the servo to reach the position
  
  for(pos = 120; pos>= 0; pos-= 1)     // goes from 90 degrees to 0 degrees                               
     myservo.write(pos);              // tell servo to go to position in variable 'pos'
     delay(10);     // waits 10ms for the servo to reach the position

delay(5);

if(buttonState == LOW && pos<= 0){

myservo.write(pos);

delay(5);

        }

      }
  
    }
  }  
}

When the switch is in the OFF position the servo is off and so are the lights on the arduino (maybe a short or correct operation?) and when I flick the toggle to ON the servo just freaks out.

This is how I have it wired:

Any help would be much appreciated.

Thanks.

Well whatever I did seems to have blown the servo so I am in dire need of help.

Comment is not matching with the command.

digitalWrite(buttonPin, HIGH);       // turn on pullup resistors

You might need to take below approach.

pinMode(buttonPin,  INPUT_PULLUP);

In IDE, format the code using CTRL+T and post it.

Also handraw a schema and post it instead of fritzing.

Thanks for you reply. This is the code with your suggestion.

#include <Servo.h>

const int buttonPin = 2;

int buttonState = 0;
int pos = 0;

Servo myservo;

void setup() {

  myservo.attach(9);

  pinMode(buttonPin, INPUT);
  pinMode(buttonPin,  INPUT_PULLUP);       // turn on pullup resistors

}

void loop() {
  buttonState = digitalRead(buttonPin);
  if (buttonState == HIGH) {

    for (pos = 0; pos <= 120; pos += 1) // goes from 0 degrees to 90 degrees
    { // in steps of  degree
      myservo.write(pos); {              // tell servo to go to position in variable 'pos'
        delay(10);    // waits 1s for the servo to reach the position

        for (pos = 120; pos >= 0; pos -= 1)  // goes from 90 degrees to 0 degrees
          myservo.write(pos);              // tell servo to go to position in variable 'pos'
        delay(10);     // waits 50ms for the servo to reach the position

        delay(5);

        if (buttonState == LOW && pos <= 0) {

          myservo.write(pos);

          delay(5);

        }

      }

    }
  }
}

Again the servo just flips out. I wire the toggle switch to pin 2 and GND on the arduino, yeah?

Why have you 3 wires going to the switch?

For a simple ON/OFF switch you just need a connection to GND and a connection to the digital I/O pin (pin2 in your case). On the switch one of these connections will go to the centre pin and one of the side pins will have no connection.

...R

Yeah, I thought my wiring was wrong. Even when wired correctly the switch still doesn't turn the servo ON/OFF and the servo just jitters back and forth.

Do you have any suggestions for the code I posted above?

Thanks for your help.

When switch is thrown to right it short circuits 5V to GND.

Get rid of the yellow wire. What do you want the switch to do?

tarff:
Do you have any suggestions for the code I posted above?

It is badly screwed up because you have FOR loops within FOR loops. Your closing } are mostly in the wrong place.

Try this. And study the changes carefully so you understand the difference.

#include <Servo.h>

const int buttonPin = 2;

int buttonState = 0;
int pos = 0;

Servo myservo;

void setup() {

  myservo.attach(9);

  pinMode(buttonPin, INPUT);
  pinMode(buttonPin,  INPUT_PULLUP);       // turn on pullup resistors

}

void loop() {
  buttonState = digitalRead(buttonPin);
  if (buttonState == HIGH) {

      for (pos = 0; pos <= 120; pos += 1) // goes from 0 degrees to 120 degrees
      { 
        myservo.write(pos);            // tell servo to go to position in variable 'pos'
        delay(10);    // waits for the servo to reach the position
      }
   }
   else {
      for (pos = 120; pos >= 0; pos -= 1) // goes from 120 degrees to 0 degrees
       {
          myservo.write(pos);              // tell servo to go to position in variable 'pos'
          delay(10);     // waits for the servo to reach the position   
       }
  }
 
}

...R

I've removed that wire, cheers. Basically I want it to behave like an on/off switch so when you flick it one way the servo starts moving back and forth like in the sweep sketch then when you flick it the other the servo stops. Preferably when it stops it moves back to a certain position but that's not essential.

Robin2:
It is badly screwed up because you have FOR loops within FOR loops. Your closing } are mostly in the wrong place.

Try this. And study the changes carefully so you understand the difference.

#include <Servo.h>

const int buttonPin = 2;

int buttonState = 0;
int pos = 0;

Servo myservo;

void setup() {

myservo.attach(9);

pinMode(buttonPin, INPUT);
  pinMode(buttonPin,  INPUT_PULLUP);      // turn on pullup resistors

}

void loop() {
  buttonState = digitalRead(buttonPin);
  if (buttonState == HIGH) {

for (pos = 0; pos <= 120; pos += 1) // goes from 0 degrees to 120 degrees
      {
        myservo.write(pos);            // tell servo to go to position in variable 'pos'
        delay(10);    // waits for the servo to reach the position
      }
  }
  else {
      for (pos = 120; pos >= 0; pos -= 1) // goes from 120 degrees to 0 degrees
      {
          myservo.write(pos);              // tell servo to go to position in variable 'pos'
          delay(10);    // waits for the servo to reach the position 
      }
  }

}




...R

Thanks for that, I see what I had done. However, the servo doesn't stop. It just move to and position and keeps sweeping.

when you flick it one way the servo starts moving back and forth like in the sweep sketch then when you flick it the other the servo stops

Here is what you need to do in pseudo code assuming that you have got the servo wired, the library included, a servo instance created, the switch wired and the switch pin set as INPUT_PULLUP. All of these steps are taken care of previously in this thread.

start of loop()
  read the switch pin
  if the switch is closed
    use the sweep code to move the servo from 0 to 180 and back to 0
  end if
end of loop()

Note that this is not the best way to do it because the switch is only read at the end of the sweep but get this working first then you can improve it..

Thank you for your time and patience.

Here is what I have now:

#include <Servo.h>

const int buttonPin = 2;

int buttonState = 0;
int pos = 0;

Servo myservo;

void setup() {
  myservo.attach(9);
  pinMode(buttonPin,  INPUT_PULLUP);       // turn on pullup resistors
}

void loop() {
  buttonState = digitalRead(buttonPin);
  
  if (buttonState == HIGH) {
    for (pos = 0; pos <= 120; pos += 1)  // goes from 0 degrees to 180 degrees
      // in steps of 1 degree
      myservo.write(pos);              // tell servo to go to position in variable 'pos'
    delay(5);                       // waits 15ms for the servo to reach the position
  
    for (pos = 120; pos >= 0; pos -= 1)  // goes from 180 degrees to 0 degrees
      myservo.write(pos);              // tell servo to go to position in variable 'pos'
    delay(5); // waits 15ms for the servo to reach the position

  }   else {
    myservo.write(pos);              // tell servo to go to position in variable 'pos'
    delay(5);
  }
}

This is closer. The switch turns the servo off but when turned on, the motor doesn't move smoothly. It jitters. Should I use the debouncing or is my code still wrong?

Does it do what you want ?
How do you have the switch wired now ?

If you are happy that the servo resting position should be at zero then you don't need the else clause as that is where the servo will be anyway as pos will have a value of zero. If you want the resting position to be somewhere else then move the servo there in the else clause.

The switch is wired to GND and pin 2. The switch turns the servo off like I want it to but when the servo is running its not a smooth movement, its a jittery movement. The servo and arduino are powered separately and the voltage is fine. When using the sweep sketch in the IDE, the servo runs fine.

Try increasing the delay() to 15 milliseconds as in the sweep example.
Do the 2 power supplies have a common GND connection ?

It still jitters with the delay() set to 15ms. The GND on my power supply is connected to the servo GND and the GND pin on the arduino. I've tried powering the arduino through usb and a power pack but the problem is the same.

Just spotted something.

You have

    for (pos = 0; pos <= 120; pos += 1)  // goes from 0 degrees to 180 degrees
      // in steps of 1 degree
      myservo.write(pos);              // tell servo to go to position in variable 'pos'
    delay(5);                       // waits 15ms for the servo to reach the position

The delay only happens at the end of the sweep because the only command in the for loop is the servo.write()
Try

    for (pos = 0; pos <= 120; pos += 1)  // goes from 0 degrees to 120 degrees <<< corrected comment
      // in steps of 1 degree
      {
        myservo.write(pos);              // tell servo to go to position in variable 'pos'
        delay(5);                       // waits 15ms for the servo to reach the position
      }

Ah, yes! That did it. Thank you so much or your time and help!

In the end my code ended up like this:

#include <Servo.h>

const int buttonPin = 2;

int buttonState = 0;
int pos = 0;

Servo myservo;

void setup() {
  myservo.attach(9);
  pinMode(buttonPin,  INPUT_PULLUP);       // turn on pullup resistors
}

void loop() {
  buttonState = digitalRead(buttonPin);

  if (buttonState == HIGH) {
    for (pos = 0; pos <= 120; pos += 1)  // goes from 0 degrees to 180 degrees
      // in steps of 1 degree
    {
      myservo.write(pos);              // tell servo to go to position in variable 'pos'
      delay(5);                       // waits 15ms for the servo to reach the position
    }
    for (pos = 120; pos >= 0; pos -= 1)// goes from 180 degrees to 0 degrees
    {
      myservo.write(pos);              // tell servo to go to position in variable 'pos'
      delay(5); // waits 15ms for the servo to reach the position
    }
  }
}

I'm still getting my head around the formatting and I get lost with all of those }.

Here is your loop() function formatted in my normal style which I did by using Ctrl/T in the IDE

void loop()
{
  buttonState = digitalRead(buttonPin);
  if (buttonState == HIGH)
  {
    for (pos = 0; pos <= 120; pos += 1)  // goes from 0 degrees to 180 degrees
      // in steps of 1 degree
    {
      myservo.write(pos);              // tell servo to go to position in variable 'pos'
      delay(5);                       // waits 15ms for the servo to reach the position
    }
    for (pos = 120; pos >= 0; pos -= 1)// goes from 180 degrees to 0 degrees
    {
      myservo.write(pos);              // tell servo to go to position in variable 'pos'
      delay(5); // waits 15ms for the servo to reach the position
    }
  }
}

The braces {} enclose a block of code that will be executed (or not) and the indenting to the same level also helps in seeing the code blocks. When only one statement follows a conditional statement or a for loop then the braces can be omitted but personally I think that confuses things, particularly if changes are made later. Putting each brace on its own line is a personal choice and not everyone will agree, but to me it helps identify the code blocks.

Incidentally, although it does not matter in terms of the code working, it is good practice to make the comments match what the code does.

tarff:
Ah, yes! That did it.

Is it not basically the same as the code I suggested in Reply #7 ?

...R