Servo controlled by Button and Pot

Hi

I’ve been trying during some weeks achieve and make that a common servo responds to a button and a potentiometer at once. I’ve used the part of code of Knob example with some adds but the servo only works with the pot and not obey the button related lines.

I would like to move the servo to 90 degrees after a push button . When it reaches that position it would be desirable to be able to perform fine tunnings with the pot. Ten degrees less , ten degrees more. As you may see,. I’ve include “While” control structure which should made the sketch works once the button had been pressed and stay there. If the button is pressed during this while loop the expresion buttonState and press becomes different “the whille loop” and the sketch should continue and make the servo return to 0. I don’t know what else to try!!

Thanks!!

#include <Servo.h>

Servo myservo;  // create servo object to control a servo
const int potpin = 0;  // analog pin used to connect the potentiometer
const int servoPin = 9; // The number of the Servo pin
const int buttonPin = 5; // The number of the button
int val;                         // Variable to read the value from the analog pin
int buttonState = 0;     // Variable 
int press = 0;


void setup() {
  pinMode (buttonPin, INPUT);
  myservo.attach(9); // attaches the servo on pin 9 to the servo object
  myservo.write(0);
}
void loop() {
  press = digitalRead (buttonPin);  //read the digital state of buttonPin
  if (press == HIGH); {
    buttonState = 1;
    myservo.write (90);                 // Sets the initial servo position
    while (( buttonState == 1 ) && (press != HIGH))  // Potentimeter activated to perform fine positioning on servo
    {
      val = analogRead(potpin);               // Reads the value of the potentiometer
      val = map(val, 0, 1023, 80, 110);     // "Scaled range" ???? to use it with the servo (this case between 80 and 110) ten less ten more
      myservo.write(val);                  // Set the servo to the new adjusted position
      delay(10);                           // waits for the servo to get there
    }
   
    myservo.write (0);                // Returns the servo to its parking position from "while loop" exit
    delay (100);
    buttonState = 0;  // Reset ButtonState to 0

  }
}

I would use the button to update the variable val.

Then use the pot to add or subtract a little bit from that value in val. Something like this (assuming val is an int

valAdj = analogRead(potPin); // range 0 - 1023
valAdj = valAdj >> 5 // divide by 32 range 0 - 31
valAdj = valAdj - 16; // range -16 - 15
val = val + valAdj;

myServo.write(val)

...R

Thanks Robin2!!

I’ve made changes to the sketch and is working better. The pot respond to the tiny gap established by valAdj but the button is skipped :frowning: . Of course I’ve already ckecked the connections and also I made a test with another button sketch and it is OK. The servo moves on start up to the expresion in “val” and then allow movements with the pot. Just on start up. :frowning: :frowning:

#include <Servo.h>

Servo myservo;  // create servo object to control a servo
const int potpin = 0;  // analog pin used to connect the potentiometer
const int servoPin = 9; // The number of the Servo pin
const int buttonPin = 5;
int val;    // variable to read the value from the analog pin
int valAdj;
int press = 0;


void setup() {
  pinMode (buttonPin, INPUT);
  myservo.attach(9); // attaches the servo on pin 9 to the servo object
}
void loop() {
  press = digitalRead (buttonPin);  //read the digital state of buttonPin
  if (press == HIGH); {
    val = 90;
    myservo.write (val);                 // Sets the initial servo position
    valAdj = analogRead(potpin);      // range 0 - 1023  // Reads the value of the potentiometer
    valAdj = valAdj >> 5;            // divide by 32 range 0 - 31
    valAdj = valAdj - 16;              // range -16 - 15
    val = val + valAdj;
    myservo.write(val);                  // Set the servo to the new adjusted position
    delay(30);                           // waits for the servo to get there
  }
}

[code/]

jbellavance:
Hi,

#include <Servo.h>

Servo myservo;  // create servo object to control a servo
const int potpin = 0;  // analog pin used to connect the potentiometer
const int servoPin = 9; // The number of the Servo pin
const int buttonPin = 5;
int val;    // variable to read the value from the analog pin
int valAdj;
int press = 0;

void setup() {
 pinMode (buttonPin, INPUT);
 myservo.attach(9); // attaches the servo on pin 9 to the servo object
}
void loop() {
 press = digitalRead (buttonPin);  //read the digital state of buttonPin
 if (press == HIGH); {
   val = 90;
   myservo.write (val);                 // Sets the initial servo position
   delay(30);                           // waits for the servo to get there
 }
 valAdj = analogRead(potpin);      // range 0 - 1023  // Reads the value of the potentiometer
 valAdj = valAdj >> 5;            // divide by 32 range 0 - 31
 valAdj = valAdj - 16;              // range -16 - 15
 val = val + valAdj;
 myservo.write(val);                  // Set the servo to the new adjusted position
}




Jacques

Thank you Jacques!!

I've noted that that delay line is missing. I've included it but nothing happens now,... so,.. so far the sketch goes better without that line. I don't know :confused: :wink: . What else could be making the button not being working??? :frowning:

The button does not bring the servo at 90 degrees?

Juliso35:
Thanks Robin2!!

I’ve made changes to the sketch and is working better.

Try this version - study the changes I have made

#include <Servo.h>

Servo myservo;  // create servo object to control a servo
const int potpin = 0;  // analog pin used to connect the potentiometer
const int servoPin = 9; // The number of the Servo pin
const int buttonPin = 5;
int val;    // variable to read the value from the analog pin
int valAdj;
int press = 0;


void setup() {
  pinMode (buttonPin, INPUT);
  myservo.attach(9); // attaches the servo on pin 9 to the servo object
}

void loop() {
     // button code
  press = digitalRead (buttonPin);  //read the digital state of buttonPin
  if (press == HIGH); {
    val = 90;
  }

     // potentiometer code
  valAdj = analogRead(potpin);      // range 0 - 1023  // Reads the value of the potentiometer
  valAdj = valAdj >> 5;            // divide by 32 range 0 - 31
  valAdj = valAdj - 16;              // range -16 - 15
  val = val + valAdj;


     // servo code
  myservo.write(val);                  // Set the servo to the new adjusted position
  delay(30);                           // waits for the servo to get there

}

…R

No Jacques. It doesn’t. and as I said… I also checked connections just in case. Other button sketchs runs fine. I’m going to try changing initial var values.

Could you try to make sure that the pot is in the middle of it’s course before you press the switch?

Hi and thank you guys!

Let me see Jacques. I think no matther where is the pot on its course. The button is skipped

The pot part is working fine as I need, but the button seem not exist for this sketch. The value in val is only taken when the board is reset. I'd need the button takes the servo there first and... after another push, it returns to 0 or start position.

I'll keep trying.

The value in val is only taken when the board is reset.

What is this value?

I'd need the button takes the servo there first

is it the same there than my previous question?

after another push, it returns to 0 or start position

What is the first push supposed to do?

HI Jacques!!

The value of variable “val” is the desired preset position (on the sketch) where… after first press, servo should move.

Yes,… Is the same after your previous question. And… its very difficult to find the exact center of the pot

After the first push, the servo moves to the preset position and then… the pot should take control for fine adjustings in that range written by @Robin2 until another push that would make return the servo into a preset parking position. Maybe,… I don’t know…it may not be possible with a single button but the project requires only one.

Thanks

At reset: ? degrees

I ask this becauseint val;                        // Variable to read the value from the analog pinThis variable is not initialised.

on first press: 90 degrees

on second press: 0 degrees is that right?

EDIT: And what about third an susequent presses?

The "desired preset position" is unknown to me right now.
EDIT : and so is: "preset parking position".

Jacques

Hi Jacques

I'll perform some testings... initializing that val variable.

Yes 90 degrees on first push.. and then the pot controls the servo for fine adjustments until a second push which should take it back to 0. If there's a third push it should take again the servo to 90 degrees and so on.

The desired positions for me are those written previously on the sketch and only can be changed until you upload another modified sketch!!

Then your switch has two states. Just like a toggle switch.

You will need a variable that will remember in which state it is. And you should initialise it with either 0 or 90.

When you read the switch, use that variable to decide what value to assign to "val". Also, remember to change the variable to it's new state.

byte currentState = 0;

press = digitalRead (buttonPin);  //read the digital state of buttonPin
  if (press == HIGH); {
    if (currentState == 90) { val =  0; currentState =  0; }
    else                    { val = 90; currentState = 90; }
  }

EDIT: When you set val to 0, "valAdj" will bring the value of "val" in the negative zone if the potentiometer is below half point. You might use "currentState" to decide if you want "valAdj" to be added (or not). I modified the code so that currentState makes more sense.

Jacques

Hi Jacques.

Sincerely I got lost in this one. :confused: :confused: The sketch was uploaded like this and nothing happened. Excuse me!!

#include <Servo.h>

Servo myservo;  // create servo object to control a servo
const int potpin = 0;  // analog pin used to connect the potentiometer
const int servoPin = 9; // The number of the Servo pin
const int buttonPin = 5;
int val;    // variable to read the value from the analog pin
// int valAdj;
int press = 0;
byte currentState = 0;


void setup() {
  pinMode (buttonPin, INPUT);
  myservo.attach(9); // attaches the servo on pin 9 to the servo object

void loop() {
  // button code
  press = digitalRead (buttonPin);            //read the digital state of buttonPin
  if (press == HIGH); {
    if (currentState == 90){
      val = 90;
      currentState = 0;
                                                              // potentiometer code
    currentState = analogRead(potpin);      // range 0 - 1023  // Reads the value of the potentiometer
    currentState = currentState >> 5;            // divide by 32 range 0 - 31
    currentState = currentState - 16;              // range -16 - 15
    val = val + currentState;
    // servo code
    myservo.write(val);                  // Set the servo to the new adjusted position
    delay(30);}                         // waits for the servo to get there
    else {
      val = 0;
      currentState = 90;
    }
  }
}

I notice that you're not using the internal pull-up resistors

pinMode (buttonPin, INPUT);

And you expect the button to read backwards, HIGH when pressed instead of LOW.

if (press == HIGH); {

(P.S. Should an if statement have a semicolon?)

Do you have an external pull-down resistor to keep that button reading LOW when it's not pressed? It would be much easier to wire the button the normal way where it reads LOW when pressed because then you can use the built in internal pull-up resistors in the chip instead of having to use an external resistor.

Hi

Yes. I have an external 10K resistor and constantly check with other button sketches if everything is ok with this.

I'm feel a little bit frustrated with this project. It seemed easy >:( :confused:

So..what is better for this? internal or external resistor?.

Thanks

What about the semicolon on the if statement. Does that belong? Hint Hint.

Somehow, you thought that you should replace valAdj with currentState. valAdjust is used for the offset obtained by the pot. Don’t touch it.

current State is only concerned with the state of the switch and to decide where the servo should go next.

This is what I had in mind:

#include <Servo.h>

Servo myservo;  // create servo object to control a servo
const int potpin = 0;  // analog pin used to connect the potentiometer
const int servoPin = 9; // The number of the Servo pin
const int buttonPin = 5;
int val;    // variable to read the value from the analog pin
int valAdj;
int press = 0;
byte currentState = 0;


void setup() {
  pinMode (buttonPin, INPUT);
  myservo.attach(9); // attaches the servo on pin 9 to the servo object
}

void loop() {
  // button code
  press = digitalRead (buttonPin);            //read the digital state of buttonPin
  if (press == HIGH){
    if (currentState == 90){                  //The toggle code I suggested
      val = 0;
      currentState = 0;
    }  
    else {
      val = 90;
      currentState = 90;  
    }
       valAdj= analogRead(potpin);      // range 0 - 1023  // Reads the value of the potentiometer
       valAdj = valAdj >> 5;            // divide by 32 range 0 - 31
       valAdj = valAdj - 16;              // range -16 - 15

    if (currentState == 90) {         //Decide if you want to add valAdj to val.
      val = val + valAdj;
    }
    
    // servo code
    myservo.write(val);                  // Set the servo to the new adjusted position
    delay(30);}                         // waits for the servo to get there
  }