New to programming need help with loop()

I am working on a program to control a servo that controls a speed control to a motor. I have been told on the Arduino forum that my code is no good “You do not want to have any calls to loop() in your code,”

my program works as written and I just dont understand what this meens or how to fix it. I am not denying that I need cleaner code but dont know enough to figure out another way to write it.

What I want to do is control a servo with a pot that controls a manual speed controler for a motor and be able to push one of 2 buttons to hold the servo at a given pot position and then be able to move the servo via a push of the buttons by 2* either way. Two other buttons are set to release the servo back to the pot control. this all works the way I have written the code.

the last thing I need is to use a reed switch to measure RPM of the motor and to feed that info back to the arduino to automatically move the servo up or down to maintain the rpm of the motor that the servo is running.

Without “else serloop1(); //returns to SerLoop1 to run again” at the bottom, it will not work.

Here is my code so far.

#include <Servo.h>

Servo myservo; // create servo object to control a servo

int potpin = 0;

int val;

// set pin numbers:

const int buttonPin = 10; // the number of the pushbutton pin

const int buttonPin2 = 8;

const int buttonPin3 = 4;

const int buttonPin4 = 2;

void setup() {

{

myservo.attach(12); // attaches the servo on pin 12 to the servo object

}

{

// initialize the pushbutton pin as an input:

pinMode(buttonPin, INPUT);

pinMode(buttonPin2, INPUT);

pinMode(buttonPin3, INPUT);

pinMode(buttonPin4, INPUT);

}

}

void loop() {

val = analogRead(potpin); //takes reading from pot current position

val = map(val, 0, 1083, 0, 180); //maps pot inputs to servo outputmyservo.write(val); //writes current position to servo to move it

if (digitalRead(buttonPin) == HIGH)

serloop1(); //sends command to SerLoop1

if (digitalRead(buttonPin2) == HIGH)

serloop1(); //sends command to SerLoop1

}

void serloop1(){

int val1 = myservo.read(); //reads current servo location

if (digitalRead(buttonPin) == HIGH)

myservo.write(val1 + 2); //SUBTRACT 2 degrees to servo position for increased motor rpm

delay(100); //allows time for switch ro reset

if (digitalRead(buttonPin2) == HIGH)

myservo.write(val1 - 2); //ADDS 2 degrees to servo position for decreased motor rpm

delay(100); //allows time for switch ro reset

if (digitalRead(buttonPin3) == HIGH)

loop(); //returns to normal pot control of motor

if (digitalRead(buttonPin4) == HIGH)

loop(); //returns to normal pot control of motor

else serloop1(); //returns to SerLoop1 to run again

Your program trace looks like this:

loop → serloop → serloop → serloop → …

That is to say instead of looping over the SAME function repeatedly, you are sequentially creating a NEW call each time. I am very surprised this does not lock up the chip really quickly.

Probably a inadvertant delay is helping you altho that probably also not intended, IDK.

What you really want is to STAY in the same serloop() until you determine to EXIT, at which point code will resume in the loop() function on the next statement AFTER you call the original serloop(). See?

loop() is called automatically when the program is compiled by ardiuno, setup() and loop() are ‘wrapped’ up into a main() by the compiler/builder. This is what is meant by YOU don’t call loop(), because main() is already calling loop() repeatedly.

I would recommend a basic Java, C or arduino book.

void serloop1(){

 while (digitalRead(buttonPin4) == LOW) {  //stay in this function and retry reads until pin4 goes HIGH then exit
  int val1 = myservo.read(); //reads current servo location

  if (digitalRead(buttonPin) == HIGH)
     //without braces only this next line is executed, the delay(100) is ALWAYS executed.
     myservo.write(val1 + 2); //SUBTRACT 2 degrees to servo position for increased motor rpm
  delay(100); //allows time for switch ro reset

  if (digitalRead(buttonPin2) == HIGH)
     myservo.write(val1 - 2); //ADDS 2 degrees to servo position for decreased motor rpm
  delay(100); //allows time for switch ro reset

  //if (digitalRead(buttonPin3) == HIGH)
  //  loop(); //returns to normal pot control of motor

  //if (digitalRead(buttonPin4) == HIGH)
  //  loop(); //returns to normal pot control of motor
  //else serloop1(); //returns to SerLoop1 to run again

 }//end while
 //when the condition is not met the while loop exits here, which happens to
 //be the end of this function, so this func returns to its caller, i.e. loop()

}//end serloop

Here is my latest code.

I am trying to incorporate debounce. I have probably done this in the worst way but with everything I have added, the program still works. I will condense it down later but for now I just would like to know how to add the final part that actually initializes the button push for my application.

Reference http://arduino.cc/en/Tutorial/Debounce

  // set the LED using the state of the button:
   digitalWrite(ledPin, buttonState);
#include <Servo.h> 
Servo throttleServo; // create servo object to control a servo 

// set pin numbers:
const int throttleSetPlusThrottleUp = 10; // the number of the pushbutton pin
const int throttleSetPlusThrottleDn = 8;
const int ReturnToPot = 4;
const int ReturnToPot2 = 2;

 // constants won't change. They're used here to 
// set pin numbers:
int throttlePositionPot = 0;
int val; 

// Variables will change:
int debounceThrottleSetPlusThrottleUp;             // the current reading from the input pin
int debounceThrottleSetPlusThrottleDn;             // the current reading from the input pin
int debounceReturnToPot;             // the current reading from the input pin
int debounceReturnToPot2;             // the current reading from the input pin
int lastdebounceThrottleSetPlusThrottleUp = LOW;   // the previous reading from the input pin
int lastdebounceThrottleSetPlusThrottleDn = LOW;   // the previous reading from the input pin
int lastdebounceReturnToPot = LOW;   // the previous reading from the input pin
int lastdebounceReturnToPot2 = LOW;   // the previous reading from the input pin


// the following variables are long's because the time, measured in miliseconds,
 // will quickly become a bigger number than can be stored in an int.
 long lastDebounceTime = 0;  // the last time the output pin was toggled
  long lastDebounceTime2 = 0;  // the last time the output pin was toggled
   long lastDebounceTime3 = 0;  // the last time the output pin was toggled
    long lastDebounceTime4 = 0;  // the last time the output pin was toggled
 long debounceDelay = 50;    // the debounce time; increase if the output flickers
  long debounceDelay2 = 50;    // the debounce time; increase if the output flickers
   long debounceDelay3 = 50;    // the debounce time; increase if the output flickers
    long debounceDelay4 = 50;    // the debounce time; increase if the output flickers
 
int servoPosition = 0; //Old val1, used to store servo position. Allows use by whole program
 

 
void setup()
{
      throttleServo.attach(12); // attaches the servo on pin 12 to the servo object 
 
     // initialize the pushbutton pin as an input:
     pinMode(throttleSetPlusThrottleUp, INPUT); 
     pinMode(throttleSetPlusThrottleDn, INPUT); 
     pinMode(ReturnToPot, INPUT); 
     pinMode(ReturnToPot2, INPUT);
}
 
void loop()
{ 
     val = analogRead(throttlePositionPot); //takes reading from pot current position 
     val = map(val, 0, 1083, 0, 180); //maps pot inputs to servo output
     throttleServo.write(val); //writes current position to servo to move it
 
     if (digitalRead(throttleSetPlusThrottleUp) == HIGH)
     {
          serloop1(); //Enters button control loop
     }
 
     if (digitalRead(throttleSetPlusThrottleDn) == HIGH)
     {
          serloop1(); //Enters button control loop
     }
}
 
 
/**
 * If button control is enabled, loop and handle control buttons
 * If exit buttons (To return to pot control) are pressed, exit loop and return
 * to pot control
 */
void serloop1()
{
     servoPosition = throttleServo.read(); //reads current servo location
     
       // read the state of the switch into a local variable:
     int reading = digitalRead(throttleSetPlusThrottleUp);
     int reading2 = digitalRead(throttleSetPlusThrottleDn);
     int reading3 = digitalRead(ReturnToPot);
     int reading4 = digitalRead(ReturnToPot2);
     
       // If the switch changed, due to noise or pressing:
     if (reading != lastdebounceThrottleSetPlusThrottleUp) 
     // reset the debouncing timer
     lastdebounceThrottleSetPlusThrottleUp = millis();
          
       // If the switch changed, due to noise or pressing:
     if (reading2 != lastdebounceThrottleSetPlusThrottleDn) 
     // reset the debouncing timer
     lastDebounceTime2 = millis();
          
       // If the switch changed, due to noise or pressing:
     if (reading3 != lastdebounceReturnToPot) 
     // reset the debouncing timer
     lastDebounceTime3 = millis();
               
       // If the switch changed, due to noise or pressing:
     if (reading4 != lastdebounceReturnToPot2) 
     // reset the debouncing timer
     lastDebounceTime4 = millis();
     
       if ((millis() - lastDebounceTime) > debounceDelay) {
     // whatever the reading is at, it's been there for longer
     // than the debounce delay, so take it as the actual current state:
     debounceThrottleSetPlusThrottleUp = reading;
   }
     if ((millis() - lastDebounceTime2) > debounceDelay2) {
     // whatever the reading is at, it's been there for longer
     // than the debounce delay, so take it as the actual current state:
     debounceThrottleSetPlusThrottleDn = reading2;
   }
     if ((millis() - lastDebounceTime3) > debounceDelay3) {
     // whatever the reading is at, it's been there for longer
     // than the debounce delay, so take it as the actual current state:
     debounceReturnToPot = reading3;
   }
     if ((millis() - lastDebounceTime4) > debounceDelay4) {
     // whatever the reading is at, it's been there for longer
     // than the debounce delay, so take it as the actual current state:
     debounceReturnToPot2 = reading4;
   }
   
   
 
     int btnControlEnabled = 1; //If button control is enabled this equals 1, else it equals 0
 
     while(btnControlEnabled == 1)
     {
       if (digitalRead(throttleSetPlusThrottleUp) == HIGH)
       {
          throttleServo.write(servoPosition + 2); //SUBTRACT 2 degrees to servo position for increased motor rpm
          servoPosition = throttleServo.read(); //Read new servo position
          delay(100); //allows time for switch ro reset
       }
       //If first button not pressed, check the next...
       else if (digitalRead(throttleSetPlusThrottleDn) == HIGH) 
       {
          throttleServo.write(servoPosition - 2); //ADDS 2 degrees to servo position for decreased motor rpm
          servoPosition = throttleServo.read(); //Read new servo position
          delay(100); //allows time for switch ro reset
       }
       else if (digitalRead(ReturnToPot) == HIGH) 
       {
          btnControlEnabled = 0; //Set loop exit condition
       }
       else if (digitalRead(ReturnToPot2) == HIGH) 
       {
          btnControlEnabled = 0; //Set loop exit condition
       }
       //If nothing pressed...
       else
       {
         //...do nothing at all, go back to start of loop
       }
     }
     
}

Sorr for the multiple posts here. I changed the debounce instructions to the loop() instead of the serloop1() and added the

  // save the reading.  Next time through the loop,
   // it'll be the lastButtonState:
   lastButtonState = reading;

into the code. Just need to figure out how to translate and use

  // set the LED using the state of the button:
   digitalWrite(ledPin, buttonState);

for my buttons use.

#include <Servo.h> 
Servo throttleServo; // create servo object to control a servo 

// set pin numbers:
const int throttleSetPlusThrottleUp = 10; // the number of the pushbutton pin
const int throttleSetPlusThrottleDn = 8;
const int ReturnToPot = 4;
const int ReturnToPot2 = 2;

 // constants won't change. They're used here to 
// set pin numbers:
int throttlePositionPot = 0;
int val; 

// Variables will change:
int debounceThrottleSetPlusThrottleUp;             // the current reading from the input pin
int debounceThrottleSetPlusThrottleDn;             // the current reading from the input pin
int debounceReturnToPot;             // the current reading from the input pin
int debounceReturnToPot2;             // the current reading from the input pin
int lastdebounceThrottleSetPlusThrottleUp = LOW;   // the previous reading from the input pin
int lastdebounceThrottleSetPlusThrottleDn = LOW;   // the previous reading from the input pin
int lastdebounceReturnToPot = LOW;   // the previous reading from the input pin
int lastdebounceReturnToPot2 = LOW;   // the previous reading from the input pin


// the following variables are long's because the time, measured in miliseconds,
 // will quickly become a bigger number than can be stored in an int.
 long lastDebounceTime = 0;  // the last time the output pin was toggled
  long lastDebounceTime2 = 0;  // the last time the output pin was toggled
   long lastDebounceTime3 = 0;  // the last time the output pin was toggled
    long lastDebounceTime4 = 0;  // the last time the output pin was toggled
 long debounceDelay = 50;    // the debounce time; increase if the output flickers
  long debounceDelay2 = 50;    // the debounce time; increase if the output flickers
   long debounceDelay3 = 50;    // the debounce time; increase if the output flickers
    long debounceDelay4 = 50;    // the debounce time; increase if the output flickers
 
int servoPosition = 0; //Old val1, used to store servo position. Allows use by whole program
 

 
void setup()
{
      throttleServo.attach(12); // attaches the servo on pin 12 to the servo object 
 
     // initialize the pushbutton pin as an input:
     pinMode(throttleSetPlusThrottleUp, INPUT); 
     pinMode(throttleSetPlusThrottleDn, INPUT); 
     pinMode(ReturnToPot, INPUT); 
     pinMode(ReturnToPot2, INPUT);
}
 
void loop()
{ 
  
         // read the state of the switch into a local variable:
     int reading = digitalRead(throttleSetPlusThrottleUp);
     int reading2 = digitalRead(throttleSetPlusThrottleDn);
     int reading3 = digitalRead(ReturnToPot);
     int reading4 = digitalRead(ReturnToPot2);
     
       // If the switch changed, due to noise or pressing:
     if (reading != lastdebounceThrottleSetPlusThrottleUp) 
     // reset the debouncing timer
     lastdebounceThrottleSetPlusThrottleUp = millis();
          
       // If the switch changed, due to noise or pressing:
     if (reading2 != lastdebounceThrottleSetPlusThrottleDn) 
     // reset the debouncing timer
     lastDebounceTime2 = millis();
          
       // If the switch changed, due to noise or pressing:
     if (reading3 != lastdebounceReturnToPot) 
     // reset the debouncing timer
     lastDebounceTime3 = millis();
               
       // If the switch changed, due to noise or pressing:
     if (reading4 != lastdebounceReturnToPot2) 
     // reset the debouncing timer
     lastDebounceTime4 = millis();
     
       if ((millis() - lastDebounceTime) > debounceDelay) {
     // whatever the reading is at, it's been there for longer
     // than the debounce delay, so take it as the actual current state:
     debounceThrottleSetPlusThrottleUp = reading;
   }
     if ((millis() - lastDebounceTime2) > debounceDelay2) {
     // whatever the reading is at, it's been there for longer
     // than the debounce delay, so take it as the actual current state:
     debounceThrottleSetPlusThrottleDn = reading2;
   }
     if ((millis() - lastDebounceTime3) > debounceDelay3) {
     // whatever the reading is at, it's been there for longer
     // than the debounce delay, so take it as the actual current state:
     debounceReturnToPot = reading3;
   }
     if ((millis() - lastDebounceTime4) > debounceDelay4) {
     // whatever the reading is at, it's been there for longer
     // than the debounce delay, so take it as the actual current state:
     debounceReturnToPot2 = reading4;
   }
   
     // save the reading.  Next time through the loop,
   // it'll be the lastButtonState:
   lastdebounceThrottleSetPlusThrottleUp = reading;
     // save the reading.  Next time through the loop,
   // it'll be the lastButtonState:
   lastdebounceThrottleSetPlusThrottleDn = reading2;
     // save the reading.  Next time through the loop,
   // it'll be the lastButtonState:
   lastdebounceReturnToPot = reading3;
     // save the reading.  Next time through the loop,
   // it'll be the lastButtonState:
   lastdebounceReturnToPot2 = reading4;
   
   
     val = analogRead(throttlePositionPot); //takes reading from pot current position 
     val = map(val, 0, 1083, 0, 180); //maps pot inputs to servo output
     throttleServo.write(val); //writes current position to servo to move it
 
     if (digitalRead(throttleSetPlusThrottleUp) == HIGH)
     {
          serloop1(); //Enters button control loop
     }
 
     if (digitalRead(throttleSetPlusThrottleDn) == HIGH)
     {
          serloop1(); //Enters button control loop
     }
}
 
 
/**
 * If button control is enabled, loop and handle control buttons
 * If exit buttons (To return to pot control) are pressed, exit loop and return
 * to pot control
 */
void serloop1()
{
     servoPosition = throttleServo.read(); //reads current servo location   
 
     int btnControlEnabled = 1; //If button control is enabled this equals 1, else it equals 0
 
     while(btnControlEnabled == 1)
     {
       if (digitalRead(throttleSetPlusThrottleUp) == HIGH)
       {
          throttleServo.write(servoPosition + 2); //SUBTRACT 2 degrees to servo position for increased motor rpm
          servoPosition = throttleServo.read(); //Read new servo position
          delay(100); //allows time for switch ro reset
       }
       //If first button not pressed, check the next...
       else if (digitalRead(throttleSetPlusThrottleDn) == HIGH) 
       {
          throttleServo.write(servoPosition - 2); //ADDS 2 degrees to servo position for decreased motor rpm
          servoPosition = throttleServo.read(); //Read new servo position
          delay(100); //allows time for switch ro reset
       }
       else if (digitalRead(ReturnToPot) == HIGH) 
       {
          btnControlEnabled = 0; //Set loop exit condition
       }
       else if (digitalRead(ReturnToPot2) == HIGH) 
       {
          btnControlEnabled = 0; //Set loop exit condition
       }
       //If nothing pressed...
       else
       {
         //...do nothing at all, go back to start of loop
       }
     }
     
}