Help with (If) statement

Hello, I am working on my first Arduino project, which will control two servos. I have written several successful sketches with the help of this forum, and a book that i purchased, but I cannot figure out how to get my servos to react the way that i need them to. I need both servos to be activated simultaneously only during the press and hold of a button (HIGH). I also need to each servo to move to separate independent angles.
I am using an Arduino UNO R3. I am powering my servos from an separate power source and i have a 100k resistor at the button. I have written the code that controls the servos, but they run constantly in a loop. My (if) statement on this sketch sets the loop in motion, but it never stops

[code]
/* Sweep
  by BARRAGAN <http://barraganstudio.com>
  This example code is in the public domain.

  modified 8 Nov 2013
  by Scott Fitzgerald
  http://www.arduino.cc/en/Tutorial/Sweep
*/

#include <Servo.h>

Servo myservo1;
Servo myservo2;  // create servo object to control a servo
// twelve servo objects can be created on most boards

int pos = 90;
int pos2 = 90;


void setup()
{
  pinMode(2, INPUT);
  myservo1.attach(9);
  myservo2.attach(6);
}

void loop() {


  if (digitalRead (2) == HIGH) {

    for (pos = 0; pos <= 80; pos ++)  {
      for (pos2 = 60; pos2 >= 0; pos2 --)
      {
        myservo1.write(pos);
        myservo2.write(pos2);
        delay(40);
      }
      for (pos = 0; pos <= 40; pos += 1) {
        myservo2.write(pos);
        delay(80);
      }
      for (pos = 80; pos <= 180; pos += 1) {
        // in steps of 1 degree
        myservo1.write(pos);
        delay(50);

      }

      for (pos = 40; pos >= 120; pos -= 1) {
        myservo2.write(pos);
        delay(50);
      }
      for (pos = 180; pos <= 80; pos += 1) {
        // in steps of 1 degree
        myservo1.write(pos);
        delay(40);
      }
      for (pos = 120; pos <= 40; pos += 1) {
        // in steps of 1 degree
        myservo2.write(pos);
        delay(130);
      }
      for (pos = 80; pos <= 180; pos += 1) {
        // in steps of 1 degree
        myservo1.write(pos);
        delay(50);
      }

      for (pos = 40; pos >= 0; pos -= 1) {
        myservo2.write(pos);
        delay(50);
      }
    }

  }
}
[/code]``

I have a second sketch for a different function, which does function as i would like it to. It moves both servos in opposite directions at the same time only while the button is pushed and held down. My inexperienced mind says that its written the same way but with different outcomes and I have been unable to determine my mistakes. Here is the second one. Thank you for your time, any advice would be appreciated.

[code]
#include <Servo.h>

Servo servo1;
Servo servo2;

int pos = 0;
int pos2 = 0;

void setup()
{
  pinMode(2, INPUT);
  servo1.attach(9);
  servo2.attach(6);
}

void loop()
{

  if (digitalRead (2) == HIGH) {

    for (pos = 90; pos >= 19; pos --) {

      servo1.write(pos);
      servo2.write(180 - pos);
    }
    //delay(50);
    for (pos = 19; pos <= 90; pos ++)    // goes from 19 degrees to 90 degrees
    {
      servo1.write(pos);              // tell servo to go to position in variable 'pos'
      servo2.write(180 - pos);            // tell servo to go to position in variable 'pos'
      delay(15);
    }
  }
}



[/code]

Welcome to the forum!

The two examples are completely different in "for loop" organization.

The first example compounds many for loops, an outer one that starts with
for (pos = 90; pos >= 19; pos --) {

and EIGHT inner loops that run sequentially. For each increment of pos, EIGHT inner loops have to run. That will take a long time to complete.

The second example has two sequential for loops.

The indenting (when you press CTRL-T) shows this organization.

If the code is supposed to run only when the button is pressed, you need to be checking the button constantly, and possibly use a "break" command to exit a loop prematurely.

Thank you for your reply. I will need the loops to run for 2-3 minutes for the first example, but I would like for it to only run as long as the button is pushed and held, like the second example does. I deleted some loops on a new sketch making it much shorter and it still runs indefinitely. Here's what I just tried.

[code]
/* Sweep
  by BARRAGAN <http://barraganstudio.com>
  This example code is in the public domain.

  modified 8 Nov 2013
  by Scott Fitzgerald
  http://www.arduino.cc/en/Tutorial/Sweep
*/

#include <Servo.h>

Servo myservo1;
Servo myservo2;  // create servo object to control a servo
// twelve servo objects can be created on most boards

int pos = 90;
int pos2 = 90;


void setup()
{
  pinMode(2, INPUT);
  myservo1.attach(9);
  myservo2.attach(6);
}

void loop() {


  if (digitalRead (2) == HIGH) {

    for (pos = 0; pos <= 80; pos ++)  {
      for (pos2 = 60; pos2 >= 0; pos2 --)
      {
        myservo1.write(pos);
        myservo2.write(pos2);
        delay(40);
      }
      for (pos = 0; pos <= 40; pos += 1) {
        myservo2.write(pos);
        delay(80);
      }
    }
  }
}




[/code]

I don't think you will get the desired result here. What will happen is it will go
pos 0 pos2 60-->0
pos 0-->40
pos 42 pos2 60-->0
pos 0-->40
pos 42 pos2 60-->0
pos 0-->40
pos 42 pos2 60-->0
pos 0-->40
So pos will never reach 80
See simultaion:

You should not use the for loop nor the delay commands.
Try the simulation and the code below:

/* Sweep
  by BARRAGAN <http://barraganstudio.com>
  This example code is in the public domain.

  modified 8 Nov 2013
  by Scott Fitzgerald
  http://www.arduino.cc/en/Tutorial/Sweep
*/

#include <Servo.h>

Servo myservo1;
Servo myservo2;  // create servo object to control a servo
// twelve servo objects can be created on most boards

int pos = 0;
int pos2 = 0;
byte stateButtonUp = 0;
bool initStateUp = true;
byte stateButtonDown = 0;
bool initStateDown = true;
unsigned int nextTime = 0;

void setup()
{
  Serial.begin(115200);
  pinMode(2, INPUT);
  myservo1.attach(9);
  myservo2.attach(6);
}

void loop() {
  if (digitalRead (2) == HIGH) {
    buttonUpFunction();
  } else {
    buttonDownFunction();
  }
}

void buttonUpFunction() {
  if (millis() > nextTime) {
    Serial.print("Up: ");
    Serial.print(stateButtonUp);
    Serial.print(" pos: ");
    Serial.print(pos);
    Serial.print(" pos2: ");
    Serial.println(pos2);
    switch (stateButtonUp) {
      case 0:
        //for (pos = 0; pos <= 80; pos ++)  {
        //  myservo1.write(pos);
        //  delay(40);
        //}
        if (initStateUp == true) {
          pos = 0;
          initStateUp = false;
        }
        if (pos <= 80) {
          myservo1.write(pos);
          pos++;
        } else {
          stateButtonUp = 1;
          initStateUp = true;
        }
        nextTime = millis() + 40;
        break;
      case 1:
        //for (pos2 = 60; pos2 >= 0; pos2 --) {
        //  myservo2.write(pos2);
        //delay(40);
        //}
        if (initStateUp == true) {
          pos2 = 60;
          initStateUp = false;
        }
        if (pos2 >= 0) {
          myservo1.write(pos);
          pos2 --;
        } else {
          stateButtonUp = 2;
          initStateUp = true;
        }
        nextTime = millis() + 40;
        break;
      case 2:
        //for (pos2 = 0; pos2 <= 40; pos2 += 1) {
        //  myservo2.write(pos2);
        //  delay(80);
        //}
        if (initStateUp == true) {
          pos2 = 0;
          initStateUp = false;
        }
        if (pos2 <= 40) {
          myservo2.write(pos2);
          pos2 += 1;
        } else {
          stateButtonUp = 3;
          initStateUp = true;
        }
        nextTime = millis() + 80;
        break;
      case 3:
        //for (pos = 80; pos <= 180; pos += 1) {
        //  myservo1.write(pos);
        //  delay(50);
        //}
        if (initStateUp == true) {
          pos = 80;
          initStateUp = false;
        }
        if (pos <= 180) {
          myservo1.write(pos);
          pos += 1;
        } else {
          stateButtonUp = 4;
          initStateUp = true;
        }
        nextTime = millis() + 50;
        break;
      case 4:
        //for (pos2 = 40; pos2 >= 120; pos2 -= 1) {
        //  myservo2.write(pos2);
        //  delay(50);
        //}
        if (initStateUp == true) {
          pos2 = 40;
          initStateUp = false;
        }
        if (pos2 <= 120) {
          myservo2.write(pos2);
          pos2 += 1;
        } else {
          stateButtonUp = 5;
          initStateUp = true;
        }
        nextTime = millis() + 50;
        break;
      case 5:
        //for (pos = 180; pos <= 80; pos += 1) {
        //  myservo1.write(pos);
        //  delay(40);
        //}
        if (initStateUp == true) {
          pos = 180;
          initStateUp = false;
        }
        if (pos >= 80) {
          myservo1.write(pos);
          pos -= 1;
        } else {
          stateButtonUp = 6;
          initStateUp = true;
        }
        nextTime = millis() + 40;
        break;
      case 6:
        //for (pos2 = 120; pos2 <= 40; pos2 += 1) {
        //  myservo2.write(pos2);
        //  delay(130);
        //}
        if (initStateUp == true) {
          pos2 = 120;
          initStateUp = false;
        }
        if (pos2 >= 40) {
          myservo2.write(pos2);
          pos2 -= 1;
        } else {
          stateButtonUp = 7;
          initStateUp = true;
        }
        nextTime = millis() + 130;
        break;
      case 7:
        //for (pos = 80; pos <= 180; pos += 1) {
        //  myservo1.write(pos);
        //  delay(50);
        //}
        if (initStateUp == true) {
          pos = 80;
          initStateUp = false;
        }
        if (pos <= 180) {
          myservo1.write(pos);
          pos += 1;
        } else {
          stateButtonUp = 8;
          initStateUp = true;
        }
        nextTime = millis() + 50;
        break;
      case 8:
        //for (pos2 = 40; pos2 >= 0; pos2 -= 1) {
        //  myservo2.write(pos2);
        //  delay(50);
        //}
        if (initStateUp == true) {
          pos2 = 40;
          initStateUp = false;
        }
        if (pos2 >= 0) {
          myservo2.write(pos2);
          pos2 -= 1;
        } else {
          stateButtonUp = 0;
          initStateUp = true;
        }
        nextTime = millis() + 50;
        break;
      default:
        stateButtonUp = 0;
    } // end switch (stateButtonUp) {
  }
}

void buttonDownFunction() {
  if (millis() > nextTime) {
    Serial.print("Down: ");
    Serial.print(stateButtonDown);
    Serial.print(" pos: ");
    Serial.println(pos);
    switch (stateButtonDown) {
      case 0:
        //for (pos = 90; pos >= 19; pos --) {
        //  myservo1.write(pos);
        //  myservo2.write(180 - pos);
        //}
        //delay(50);
        if (initStateDown == true) {
          pos = 90;
          initStateDown = false;
        }
        if (pos >= 19) {
          myservo1.write(pos);
          myservo2.write(180 - pos);
          pos --;
        } else {
          stateButtonDown = 1;
          initStateDown = true;
        }
        nextTime = millis() + 50;
        break;
      case 1:
        //for (pos = 19; pos <= 90; pos ++)    // goes from 19 degrees to 90 degrees
        //{
        //  myservo1.write(pos);              // tell servo to go to position in variable 'pos'
        //  myservo2.write(180 - pos);            // tell servo to go to position in variable 'pos'
        //  delay(15);
        //}
        if (initStateDown == true) {
          pos = 19;
          initStateDown = false;
        }
        if (pos <= 90) {
          myservo1.write(pos);
          myservo2.write(180 - pos);
          pos++;
        } else {
          stateButtonDown = 0;
          initStateDown = true;
        }
        nextTime = millis() + 15;
        break;
      default:
        stateButtonDown = 0;
        break;
    } // end switch (stateButtonDown) {
  }
}

the following moves the servos in opposite directions when the button is pressed and returns them to a default position (90) when button is released. button pin is configure with internal pullup and with switch connected between pin and ground, the pin will be LOW when pressed

/* Sweep
by BARRAGAN <http://barraganstudio.com>
This example code is in the public domain.
modified 8 Nov 2013
by Scott Fitzgerald
http://www.arduino.cc/en/Tutorial/Sweep
*/

#undef MyHW
#ifdef MyHW
char s [80];
struct Servo  {
    int  pin;
    void attach (int p) { pin = p; };
    void write (int pos) {
        sprintf (s, "  %s: pin %d, pos %3d", __func__, pin, pos);
        Serial.println (s);
    };
};

const byte pinBut = A1;

#else
# include <Servo.h>

const byte pinBut = 2;
#endif

Servo myservo1;
Servo myservo2;  // create servo object to control a servo

// twelve servo objects can be created on most boards
const int PosRest = 90;
int pos1;
int pos2;

void setup ()
{
    Serial.begin (9600);
    pinMode (pinBut, INPUT_PULLUP);
    myservo1.attach (9);
    myservo2.attach (6);
}

void loop () {
    if (digitalRead (pinBut) == LOW) {
        Serial.println ("but");
        if (0 < pos1)  {
            pos1--;
            pos2 = PosRest + pos1;
        }
    }
    else {
        pos1 = pos2 = PosRest;
    }

    myservo1.write (pos1);
    myservo2.write (pos2);

    delay (250);    // slow prints
}

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