Long Button Press??

Hi,
I’m pretty new to arduino and I’m working on a code to move a servo. I have everything running properly but, there is one problem.

In my code, I try to accomplish making a servo go all the way clockwise, counterclockwise, and in the middle with 3 buttons. Each does one of those things when I press it. Button two makes the servo go all the way clockwise, and the problem is that when I press button two for two long, it goes back in the center. I have no idea why.

Here’s my code:

//Drive a servo

#include <Servo.h> //includes servo library

#define Button1 0
#define Button2 1
#define Button3 2

Servo motor;

int value = 90;
int buttoni = 0;
int buttonii = 0;
int buttoniii = 0;

void setup()
{
  motor.attach(22);
  pinMode(Button1, INPUT);
  pinMode(Button2, INPUT);
  pinMode(Button3, INPUT);
}

void loop()
{
 buttoni = digitalRead(Button1);
 buttonii = digitalRead(Button2);
 buttoniii = digitalRead(Button3);
 motor.write(value);
 
 if (buttoni == LOW)
 {
   value = 179;
 }
 
 if (buttonii == LOW)
 {
   value = 0;
 }
 if (buttoniii == LOW)
 {
   value = 90;
 }
}

Can anyone help me?

Thanks,
-Dylan

do you have pull-up resistors on the buttons? if not, do some research on them.

What kind of resistor would you suggest using? I read 10k ohm, but I don't have any. is anything close in that range good?

Just use the AVR's built-in pull-up resistors, basically do a digitalWrite to HIGH but keep the pinMode as INPUT.

(1) Do not use pin 0 and 1 - they are connected to the USB/serial. Well, you can use them with some restrictions, but unless you really have to, then do not use them.

(2) Use the internal resistor in the chip. Cheaper (its free) and simpler (no wiring required).

void setup() {
pinMode(5,INPUT) ; // actually redundant, all pins starts as INPUT
digitalWrite(5,HIGH) ; // yes, write to the input pin. There now is a 10k-like resistor to +VE

The switch has to wire pin5 to ground to "pull it low" and digitalRead(5) will return LOW. If the switch is open, your digitalRead(5) will be HIGH.

You are reading the switch states, telling the servo to get to the right place, then figuring out what the right place is. Do you see a problem with that order?

If you want the servo to move only once, for each switch press, you need to compare the current state of the switch to the previous state of the switch, and move the servo only if the current state is not equal to the previous state && the current state IS pressed.

@frank26080115 and Msquare
Thanks SOOOO much! Really helped! I didn’t know that. (the “Getting Started With Arduino Guide” lies!) Totally helped!

@PaulS
Thanks! You’re right!

Do you mean that thing with the old value and new value and the state? I read about that in the Getting started guide book. I’ll keep it in mind, but I don’t see a need for it here.

Here’s my new code. It works flawlessly! :smiley:

//Drive a servo

#include <Servo.h> //includes servo library

#define Button1 3 //assigns the port my buttons are pressed into
#define Button2 4
#define Button3 2

Servo motor; //creates a servo object called "motor"

int value = 90; //starts my variable at 90 so the motor
int buttoni = 0; //won't move or the servo will be in center
int buttonii = 0; //position.
int buttoniii = 0; //These just set variables for the buttons

void setup()
{
  motor.attach(22); //Motor connected to digital port 22
  pinMode(Button1, INPUT); //make these buttons inputs
  pinMode(Button2, INPUT);
  pinMode(Button3, INPUT);
  digitalWrite(Button1, HIGH); //Uses built in pull-up resistor.
  digitalWrite(Button2, HIGH);
  digitalWrite(Button3, HIGH);
}

void loop()
{
 motor.write(value); //send directions to the motor
 buttoni = digitalRead(Button1); //reads the buttons
 buttonii = digitalRead(Button2);
 buttoniii = digitalRead(Button3);
 
 if (buttoni == LOW) //if the first button
 {                   //is pressed then
   value = 179;      //make the motor go clockwise
 }
 
 if (buttonii == LOW) //if second button pressed
 {                    //make motor go counter-clockwise
   value = 0;
 }
 if (buttoniii == LOW) //if third button pressed
 {                     //make motor stop
   value = 90;
 }
}

THANKS SO MUCH FOR YOUR SUPPORT!!!
-Dylan

So, now, you send the motor somewhere, then read the switches, and finally, compute where the servo should be. You're getting closer, but it still isn't right. The LAST thing that should happen is the motor.write() call.

You need to have a look at debouncing, next.

How about this? It doesn’t seem do be working though, I don’t know what’s wrong. I followed the instruction in the Getting Started with Arduino Guide. Here it is:

//Drive a servo

#include <Servo.h> //includes servo library

#define Button1 3 //assigns the port my buttons are pressed into
#define Button2 4
#define Button3 2

Servo motor; //creates a servo object called "motor"

int value = 90; //starts my variable at 90 so the motor
int buttoni = 0; //won't move or the servo will be in center
int buttonii = 0; //position.
int buttoniii = 0; //These just set variables for the buttons

int old_buttoni = 0; //stores old values
int old_buttonii = 0; //of the buttons
int old_buttoniii = 0;

int statei = 0;
int stateii = 0;
int stateiii = 0;

void setup()
{
  motor.attach(22); //Motor connected to digital port 22
  pinMode(Button1, INPUT); //make these buttons inputs
  pinMode(Button2, INPUT);
  pinMode(Button3, INPUT);
  digitalWrite(Button1, HIGH); //Uses built in pull-up resistor.
  digitalWrite(Button2, HIGH);
  digitalWrite(Button3, HIGH);
}

void loop()
{
 buttoni = digitalRead(Button1); //reads the buttons
 buttonii = digitalRead(Button2);
 buttoniii = digitalRead(Button3);
 if ((buttoni == HIGH) && (old_buttoni == LOW)) {
   statei = 1 - statei;
 } 
 if ((buttonii == HIGH) && (old_buttonii == LOW)) {
   stateii = 1 - stateii;
 }
  if ((buttoniii == HIGH) && (old_buttoniii == LOW)) {
   stateiii = 1 - stateiii;
 }
 old_buttoni = buttoni;
 old_buttonii = buttonii;
 old_buttoniii = buttoniii;
 
 if (statei == 1) //if the first button
 {                   //is pressed then
   value = 179;      //make the motor go clockwise
 }
 
 if (stateii == 1) //if second button pressed
 {                    //make motor go counter-clockwise
   value = 0;
 }
 if (stateiii == 1) //if third button pressed
 {                     //make motor stop
   value = 90;
 }
 motor.write(value); //send directions to the motor
}

Thanks for the help!
-Dylan

#define Button1 3 //assigns the port my buttons are pressed into
#define Button2 4
#define Button3 2

Servo motor; //creates a servo object called "motor"

int value = 90; //starts my variable at 90 so the motor
int buttoni = 0; //won't move or the servo will be in center
int buttonii = 0; //position.
int buttoniii = 0; //These just set variables for the buttons

It’s time to get consistent and meaningful in your variable names.

If Button2 represents a pin number, why not make it explicit, using SwitchPin2 as the name?

If Button2 represents a pin number, why does buttonii represent the state of that switch?

Buttons are for shirts. You have switches attached to the Arduino, not buttons.

It doesn’t seem do be working though, I don’t know what’s wrong. I followed the instruction in the Getting Started with Arduino Guide.

First, when you have pullup resistors wired/enabled, the resistor is connected between the +V pin and the digital pin. The switch is between the digital pin and ground. So, when the switch is NOT pressed, there is no circuit from the digital pin to ground, so the digital pin will read HIGH. When the switch IS pressed, there is a circuit from the digital pin to ground. So. the current from the +V source finds a path of least resistance, between the +V pin and ground, along the wire to your switch, through your switch, and along the wire from your switch to ground. None of the electrons will make their way to the digital pin, since there is an easier path to ground, so the pin will read LOW.

Your code is based on the assumption that pressing the switch will result in a HIGH reading, which is not the case.

Second, you have not described what IS happening and what is NOT happening, and you have not described how what IS happening differs from what you want to be happening.

I found out my issue. I used the buttons like I was trying to toggle the motor, and I didn’t plug in the code right. I removed the state and put the value in there. Here it is:

//Drive a servo

#include <Servo.h> //includes servo library

#define BUTTON1 3 //assigns the port my buttons are pressed into
#define BUTTON2 4
#define BUTTON3 2

Servo motor; //creates a servo object called "motor"

int value = 90; //starts my variable at 90 so the motor
int button1 = 0; //won't move or the servo will be in center
int button2 = 0; //position.
int button3 = 0; //These just set variables for the buttons

int old_button1 = 0; //stores old values
int old_button2 = 0; //of the buttons
int old_button3 = 0;

void setup()
{
  motor.attach(22); //Motor connected to digital port 22
  pinMode(BUTTON1, INPUT); //make these buttons inputs
  pinMode(BUTTON2, INPUT);
  pinMode(BUTTON3, INPUT);
  digitalWrite(BUTTON1, HIGH); //Uses built in pull-up resistor.
  digitalWrite(BUTTON2, HIGH);
  digitalWrite(BUTTON3, HIGH);
}

void loop()
{
 button1 = digitalRead(BUTTON1); //reads the buttons
 button2 = digitalRead(BUTTON2);
 button3 = digitalRead(BUTTON3);
 if ((button1 == HIGH) && (old_button1 == LOW)) {
   value = 179;
 } 
 delay(50);
 if ((button2 == HIGH) && (old_button2 == LOW)) {
   value = 0;
 }
 delay(50);
  if ((button3 == HIGH) && (old_button3 == LOW)) {
   value = 90;
 }
 delay(50);
 old_button1 = button1;
 old_button2 = button2;
 old_button3 = button3;
 motor.write(value); //send directions to the motor
}

I also clarified some values, like you said. I know it’s really a switch, but I prefer button instead. :stuck_out_tongue: :stuck_out_tongue:

Actually, I know that when pressed, the value returns low. In the code I am telling it to check If the switch is not pressed and if it was pressed. So if you press it, It will be button = low and old_button = high, so it won’t execute the if. Then it will save the value of button into old_button so that button = low and old_button = low. If you let go it will be button = high and old_button = low, so it will execute the if then.

I don’t understand what you mean by that. If you mean, what do I want it to do, then I want button 1 to move the motor, button 2 to move it the other way, and button 3 to stop it. It will continue moving until another button is pressed. It works now though! :smiley:

Thanks for your help :slight_smile: ,
-Dylan