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);
}
}
2 Answers 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– Richard2018年05月10日 17:29:50 +00:00Commented May 10, 2018 at 17:29
-
Please edit your question to show your circuit then.Maximilian Gerhardt– Maximilian Gerhardt2018年05月10日 17:35:05 +00:00Commented May 10, 2018 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– Richard2018年05月10日 19:10:09 +00:00Commented May 10, 2018 at 19:10
-
then the servo comes off 12 and is also connected to GND and +5vRichard– Richard2018年05月10日 19:10:36 +00:00Commented May 10, 2018 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– Maximilian Gerhardt2018年05月10日 20:32:46 +00:00Commented May 10, 2018 at 20:32
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);
}
}
crServo = digitalRead(crSpeedDefault);
there? Withconst 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 ofdigitalRead
, which reads from pin 0 which is the Serial TX of the Arduino.