Trying to change the position of a servo using two click buttons

hey, i'm trying to increase the angle by clicking one button and then I want the second button to decrease the angle to previous angle. I'm struggling to get this code work. I have other code that sort of works but is very messy. any help would be appreciated as I'm relative new to coding

</>
#include <Servo.h>
Servo servo;
int buttonPin = 12;
int buttonPin1 = 11;
int buttonPushCounter1 = 0;
int buttonPushCounter = 0;
int buttonState = 0;
int buttonState1 = 0;
int lastButtonState = 0;
int lastButtonState1 = 0;
int ang = 20;
int Startang = 0;
int newang = ang + Startang;

void setup() {
Serial.begin(9600);
pinMode(buttonPin, INPUT);
pinMode(buttonPin, INPUT);
servo.attach(9);
servo.write(0);
}

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

if (buttonState != lastButtonState) {
if (buttonState == HIGH) {
buttonPushCounter ++;
if (buttonPushCounter == 0) {

    buttonPushCounter = 9;
    servo.write(180);
  }
  Serial.println("on");
  Serial.print("number of button pushes: ");
  Serial.println(buttonPushCounter);
}
else {
  Serial.println("off");
}

}
lastButtonState = buttonState;

if (buttonState == HIGH) {
servo.write(newang);
//newang = Startang + ang;
}
if (buttonState == HIGH) {
servo.write(newang + ang);
}

Serial.println(buttonState);
}

Do you have a question?

Code tags?

Please follow the advice given in the link below when posting code. Use code tags (the </> icon above the compose window) to make it easier to read and copy for examination

yeah, i'm trying to increase the angle by clicking one button and then I want the second button to decrease the angle to previous angle. I'm struggling to get this code work.

where do you read and process the 2nd button, "buttonPin1"?

where do you change "newang" depending on the button being pressed?

it would make sense for one button to increase the value of "newang" up to some maximum (e.g. 180) and similarly for the other button to decrease the value to some minimum (e.g. 0) and for some other piece of code to simply servo.write (newang); regardless if it changed or not

Hello
In short words:

  1. button1 pressed and released --> move servo to position one
  2. button2 pressed and released --> move servo to position two

Is this summaraztion correct?

I haven't included that as i'm struggling with to get this bit of code to work. I have other code increases the angle but doesn't decrease it. However that code is messy. Every time you press the button the angle should increase for 'buttonPin' and every time 'buttonPin1' is pressed the angle should decrease to the previous angle

every time button1 is pressed and released the servo move to a new position. when button 2 is pressed the servo should move back to the previous angle

Hello
I´ll check it to find a similar sketch in my sketch box tomorow after breakfast time.

Describing it in a way that it can be put into code is an important part of writing code, but it is not easy. If that is done right, then half the sketch is already written.

This is what I came up with, but I doubt if that what you want:

#include <Servo.h>

Servo servo;

const int buttonUpPin = 11;
const int buttonPreviousPin = 12;

int lastButtonUpState = LOW;
int lastButtonPreviousState = LOW;

int angle = 0;
int previousAngle = 0;

void setup() {
  Serial.begin(9600);

  pinMode(buttonUpPin, INPUT);
  pinMode(buttonPreviousPin, INPUT);

  servo.attach(9);
  servo.write(angle);
}

void loop() {
  int buttonUpState = digitalRead(buttonUpPin);
  int buttonPreviousState = digitalRead(buttonPreviousPin);

  if (buttonUpState != lastButtonUpState) {
    if (buttonUpState == HIGH) {
      previousAngle = angle; 
      angle += 20;
      if( angle > 180)
        angle = 180;
      servo.write(angle);
    }
    lastButtonUpState = buttonUpState;
  }

  if (buttonPreviousState != lastButtonPreviousState) {
    if (buttonPreviousState == HIGH) {
      servo.write(previousAngle);
    }
    lastButtonPreviousState = buttonPreviousState;
  }

  delay( 20);          // slow down the sketch, and also a debounce
}

This sketch in Wokwi:

Instead of just saying it doesn't work it might help if you say exactly what your code DOES do and what's wrong with that.

Steve

but you never change "newang"

Hello
As promised yesterday here comes the sketch I´ve found in my sketch box. I´ve made already some mods to met the requierements given by you.
The sketch isn´t coded in standard C. I´ve use some CPP instructions like ENUM, STRUCT and so on to build generic objects. The declaration and initialization of user defined datatypes (UDT) makes the coding more easy. I have left some addational comments to understand what happens.

//BLOCK COMMENT
/* 
 * every time button1 is pressed and released the servo move to a new position. 
 * when button 2 is pressed the servo should move back to the previous angle
*/
// https://forum.arduino.cc/t/trying-to-change-the-position-of-a-servo-using-two-click-buttons/902047
#define ProjectName "Trying to change the position of a servo using two click buttons"
// LIBARIES INCLUSION - I don´t like libaries
#include <Servo.h>
// CONSTANT DEFINITION
// you may need to change these constants to your hardware and needs
constexpr byte Input_[] {A0, A1}; // buttons connected to GND 
constexpr byte ServoPin {A3}; // connections for servo, one servo is serviced only
// VARIABLE DECLARATION AND DEFINTION
unsigned long currentTime;
// the declaration and initialization of user defined datatypes (UDT) makes the coding more easy
// this coding makes an object for the buttons in use
enum {Up, Down}; // names for buttons
struct BUTTON { 
  int name_;
  byte pin;
  bool state_;
} buttons [] {
  {Up, Input_[Up], 0},
  {Down, Input_[Down], 0},
};
an object for timers
struct TIMER {
  unsigned long duration;
  unsigned long stamp;
};
TIMER buttonScan{20, 0};
an object for the servo related data
struct DRIVE {
  int pin;
  int minAngle;
  int maxAngle;
  int deltaAngle;
  int angle;
  Servo servo;
} drive {ServoPin, 0, 180, 5, 90};

// FUNCTIONS
// this function takes care for the timer objects in use
bool checkTimer(TIMER & time_) {
  if (currentTime - time_.stamp < time_.duration) return false;
  time_.stamp = currentTime;
  return true;
}
void setup() {
  Serial.begin(9600);
  Serial.println(F("."));
  Serial.print(F("File   : ")), Serial.println(__FILE__);
  Serial.print(F("Date   : ")), Serial.println(__DATE__);
  Serial.print(F("Project: ")), Serial.println(ProjectName);
  pinMode (LED_BUILTIN, OUTPUT);
  for (auto Input : Input_) pinMode(Input, INPUT_PULLUP);
  drive.servo.attach(drive.pin);
  drive.servo.write(drive.angle);
  Serial.print(F("deltaAngle ")),  Serial.print(drive.deltaAngle), Serial.println(F("°"));
  Serial.print(F("Angle ")),  Serial.print(drive.angle), Serial.println(F("°"));
}
void loop () {
  currentTime = millis();
  digitalWrite(LED_BUILTIN, (currentTime / 500) % 2);
  if (checkTimer(buttonScan)) {
    // the compiler builds based on the addressed array a loop by using "range-based for loop" instruction
    for (auto &button_ : buttons) {
      bool stateNew = !digitalRead(button_.pin);  
      if (button_.state_ != stateNew) {
        button_.state_ = stateNew;
        if (stateNew) {
          switch (button_.name_) {
            case Up:
              drive.angle += drive.deltaAngle;
              if (drive.angle > drive.maxAngle) drive.angle = drive.maxAngle;
              break;
            case Down:
              drive.angle -= drive.deltaAngle;
              if (drive.angle < drive.minAngle) drive.angle = drive.minAngle;
              break;
          }
        } else {
          Serial.print(F("Angle ")),  Serial.print(drive.angle), Serial.println(F("°"));
          drive.servo.write(drive.angle);
        }
      }
    }
  }
}

Have a nice day and enjoy coding in CPP :slight_smile:

This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.