0

I have a code problem. I need to turn a servo clockwise or counter clockwise using 2 microswitches.

The problem is that my code is fine on startup, but when i press the button the servo continues to spin.

How do i make this so it only spins while the buttons are pressed and turn off when they are not pressed?

#include <Servo.h>

Servo myservo; // create servo object to control a servo

// CONSTANTS

// PINS
const int crServo = 12; // sets pin 12 as servo
const int buttonPinCW = 2; // sets pin 2 as button; CW => clockwise => FOCUS FAR
const int buttonPinCC = 3; // sets pin 3 as button; CC => counterclockwise => FOCUS NEAR

// SERVO PROPERTIES
const int crSpeedDefault = 0; // is the stay still position, motor should not turn
const int crSpeedCW = 110; // turns the motor full speed clockwise
const int crSpeedCC = 70; // turns the motor full speed counter-clockwise

// SET BUTTON STATES
int buttonStateCW = 0; //sets button 1 as off
int buttonStateCC = 0; // sets button 2 as off

void setup()
{
  myservo.attach(crServo); // attaches the servo on pin 12 to the servo object
  pinMode (crServo, OUTPUT);
  pinMode (buttonPinCW, INPUT); // sets button as input
  pinMode (buttonPinCC, INPUT); // sets button as input
  myservo.write(crSpeedDefault); // default servo to crSpeedDefault
}

void loop()
{
  crServo = digitalRead(crSpeedDefault);
  buttonStateCW = digitalRead(buttonPinCW);
  buttonStateCC = digitalRead(buttonPinCC);
  // clockwise rotation
  if (buttonStateCW == HIGH) {
    myservo.write(crSpeedCW);
    // counterclockwise rotation
  } 
  if (buttonStateCC == HIGH) {
    myservo.write(crSpeedCC);
  }
}
  • Do you have an external pull-down on your buttons? – Maximilian Gerhardt May 10 '18 at 16:48
  • Hi Maximilian, Yes, i have a wheel which spins manually by a user. The idea is that when the steering wheel spins 180 degrees a microswitch is pushed. This turns the servo one direction, the opposite is to turn the servo in the opposite direction. – Richard May 10 '18 at 16:54
  • I meant a pull-down resistor. Your firmware logic is that if the button pin reads "HIGH" it is pressed. Thus you must have a button via pull-down to GND and other side to +5V connected right? Also: Why is the line crServo = digitalRead(crSpeedDefault); there? With const int crServo = 12 the variable cannot be changed. It doesn't make sense to re-write the servo pin to 0 or 1 using the result of digitalRead, which reads from pin 0 which is the Serial TX of the Arduino. – Maximilian Gerhardt May 10 '18 at 17:02
2

If you want the logic "if none of the two buttons are pressed, stop the servo immediately", then you'd express this in your loop as a if expression where you check if both buttons read LOW:

void loop()
{
  buttonStateCW = digitalRead(buttonPinCW);
  buttonStateCC = digitalRead(buttonPinCC);
  // clockwise rotation
  if (buttonStateCW == HIGH) {
    myservo.write(crSpeedCW);
    // counterclockwise rotation
  } 
  if (buttonStateCC == HIGH) {
    myservo.write(crSpeedCC);
  }

  //Are both buttons not pressed? 
  if(buttonStateCC == LOW && buttonStateCW == LOW) {
    //Stop the servo.
    myservo.write(0);
  }
}

This assumes your buttons are with pull-down resistors to GND on one side and with +5V on the other side, as detailed in the Arduino tutorial. In short this means that an unpressed button reads as 0 and a pressed on reads as 1 (HIGH). This is unusual because we usually use the internal pullup resistors via the INPUT_PULLUP pinMode parameter with a switched logic (1 = unpressed, 0 = pressed).

I've also removed the line crServo = digitalRead(crSpeedDefault); because that doesn't make sense in my opinion, as I've detailed in my comment.

  • thank you, Maximilian i think this must be in my switch wiring, the code edit you sent makes them spin continuously in either direction when the button is pressed. I think i need to have a look at quite how i wire these up to the Uno as something is a-miss here i think. – Richard May 10 '18 at 17:29
  • Please edit your question to show your circuit then. – Maximilian Gerhardt May 10 '18 at 17:35
  • sorry for the delay, ok the buttons go to GND and to the input pins 2 & 3 (there are 2 buttons 1 to 2 and 1 to 3) – Richard May 10 '18 at 19:10
  • then the servo comes off 12 and is also connected to GND and +5v – Richard May 10 '18 at 19:10
  • @Richard When you edit your question you will notice a "Schematic" tool button with which you can accurately present your circuit. – Maximilian Gerhardt May 10 '18 at 20:32
1

This solution is similar to @Maximilian Gerhardt's solution. So his comments on the pull-up/down resistors apply.

I assume that you only want to turn either CW or CC and not oscillate between the two.

Then you should cater for 4 button conditions:
None pressed, CW only press, CC only press, both pressed.

We only need to worry about the "only pressed" conditions and a default state when coding.

Here is my solution:

void loop()
{
  buttonStateCW = digitalRead(buttonPinCW);
  buttonStateCC = digitalRead(buttonPinCC);

  // CW button pressed only
  if (buttonStateCW == HIGH && buttonStateCC == LOW) {
    myservo.write(crSpeedCW); // clockwise rotation
  }
  // CC button pressed only
  else if (buttonStateCW == LOW && buttonStateCC == HIGH) {
    myservo.write(crSpeedCC); // counterclockwise rotation
  }
  // Default condition
  else {
    myservo.write(crSpeedDefault);
  }
}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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