element14 Community
element14 Community
    Register Log In
  • Site
  • Search
  • Log In Register
  • Community Hub
    Community Hub
    • What's New on element14
    • Feedback and Support
    • Benefits of Membership
    • Personal Blogs
    • Members Area
    • Achievement Levels
  • Learn
    Learn
    • Ask an Expert
    • eBooks
    • element14 presents
    • Learning Center
    • Tech Spotlight
    • STEM Academy
    • Webinars, Training and Events
    • Learning Groups
  • Technologies
    Technologies
    • 3D Printing
    • FPGA
    • Industrial Automation
    • Internet of Things
    • Power & Energy
    • Sensors
    • Technology Groups
  • Challenges & Projects
    Challenges & Projects
    • Design Challenges
    • element14 presents Projects
    • Project14
    • Arduino Projects
    • Raspberry Pi Projects
    • Project Groups
  • Products
    Products
    • Arduino
    • Avnet & Tria Boards Community
    • Dev Tools
    • Manufacturers
    • Multicomp Pro
    • Product Groups
    • Raspberry Pi
    • RoadTests & Reviews
  • About Us
  • Store
    Store
    • Visit Your Store
    • Choose another store...
      • Europe
      •  Austria (German)
      •  Belgium (Dutch, French)
      •  Bulgaria (Bulgarian)
      •  Czech Republic (Czech)
      •  Denmark (Danish)
      •  Estonia (Estonian)
      •  Finland (Finnish)
      •  France (French)
      •  Germany (German)
      •  Hungary (Hungarian)
      •  Ireland
      •  Israel
      •  Italy (Italian)
      •  Latvia (Latvian)
      •  
      •  Lithuania (Lithuanian)
      •  Netherlands (Dutch)
      •  Norway (Norwegian)
      •  Poland (Polish)
      •  Portugal (Portuguese)
      •  Romania (Romanian)
      •  Russia (Russian)
      •  Slovakia (Slovak)
      •  Slovenia (Slovenian)
      •  Spain (Spanish)
      •  Sweden (Swedish)
      •  Switzerland(German, French)
      •  Turkey (Turkish)
      •  United Kingdom
      • Asia Pacific
      •  Australia
      •  China
      •  Hong Kong
      •  India
      • Japan
      •  Korea (Korean)
      •  Malaysia
      •  New Zealand
      •  Philippines
      •  Singapore
      •  Taiwan
      •  Thailand (Thai)
      • Vietnam
      • Americas
      •  Brazil (Portuguese)
      •  Canada
      •  Mexico (Spanish)
      •  United States
      Can't find the country/region you're looking for? Visit our export site or find a local distributor.
  • Translate
  • Profile
  • Settings
Arduino
  • Products
  • More
Arduino
Arduino Forum need help, new to programming
  • Blog
  • Forum
  • Documents
  • Quiz
  • Events
  • Polls
  • Files
  • Members
  • Mentions
  • Sub-Groups
  • Tags
  • More
  • Cancel
  • New
Join Arduino to participate - click to join for free!
Actions
  • Share
  • More
  • Cancel
Forum Thread Details
  • Replies 9 replies
  • Subscribers 402 subscribers
  • Views 784 views
  • Users 0 members are here
Related

need help, new to programming

Former Member
Former Member over 12 years ago

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

  • Sign in to reply
  • Cancel
Parents
  • cookieglitch
    cookieglitch over 12 years ago

    What they mean is, you cannot try to use loop() as a function anywhere in your code. Putting your code inside loop() is the same as putting it inside while(1) { //code }, so when you try calling it, you are trying to run an infinite loop inside an infinite loop which causes some interesting problems. When your function, in this case serloop1(), is finished, you don't need to tell it to go back to executing loop(), it will do that naturally. Think of serloop, or any such function, as a diversion like answering the phone. Once the call is over, you go back to where you were and carry on. So, with this in mind, the first step to fixing your program would be to remove all the uses of loop(); You will also find it easier when starting out to use { } on if statements, they help make code much clearer, especially when sharing.

     

    #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) 
         {
              //Nothing, just exit
         }
    
         if (digitalRead(buttonPin4) == HIGH) 
         {
              //Nothing, just exit
         }
    
         else
         {
              serloop1(); //returns to SerLoop1 to run again
         }
    }

     

    With your code, are you trying to test all the conditions to see what happens or are you trying to do something with the first true condition before exiting? If you are dealing with only the first true condition, I would suggest you have a look at else if statements. Having a look at the structure of your if statement(s) should help get the rest of your program working. A trick that you might find useful for problems like this is to write your if statements in pseudocode first. Having it in front of you like a recipe can make it a bit easier to translate it into code rather than doing it all from your head. Hope this helps get you going!

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • Cancel
  • Former Member
    Former Member over 12 years ago in reply to cookieglitch

    Thank you cookie, the program works exacly as it did before but I guess it removes the endless loop in loop issue if I understand that correctly. I dont understand the

    if (digitalRead(buttonPin4) == HIGH), with nothing behind it but it works.

     

    I do need the else serloop1() still though right? It does not work withought it there.

     

    --------------------------------------------------

     

    OK so now I need to start to understand a way to sense the motor speed and input it back into the arduino to be able to toggle the servo up/down to maintain the rpm on the motor like if it were under a load for example.

     

    I am thinking a reed switch on a part the motor drives, when the switch changes state count the time to the next change in state and somehow use that to tell the servo to bump up or down to increase/decrease motor speed.

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • Cancel
  • cookieglitch
    cookieglitch over 12 years ago in reply to Former Member

    In regards to if (digitalRead(buttonPin4) == HIGH) and if (digitalRead(buttonPin3) == HIGH), as these are currently doing nothing you could simply remove them. However if you intend to have a function relying on the button being pressed it might require keeping them. Depending on the function involved they could be moved. To help keep track of what each of them are, try to keep variable names relevant to what they do. For example, if a button increases the servo position you could name it something like btnPosInc or whatever makes the most sense to you.

     

    You do still need the serloop1() function in this case. If I am understanding your aim here, there may be a nicer way to do this using the while statement. In your code you are forcing it to repeat by calling the function again, this same functionality can be achieved by adding a variable and making the loop dependant on that. Assuming buttonPin3 and buttonPin4 return the program to the pot control and not button control, it would look something like

     

    #include <Servo.h> 
    Servo myservo; // create servo object to control a servo 
    
    int potpin = 0;
    int val; 
    
    int servoPosition = 0; //Old val1, used to store servo position. Allows use by whole program
    
    // 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 output
         myservo.write(val); //writes current position to servo to move it
    
         if (digitalRead(buttonPin) == HIGH)
         {
              serloop1(); //Enters button control loop
         }
    
         if (digitalRead(buttonPin2) == 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 = myservo.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(buttonPin) == HIGH)
           {
              myservo.write(val1 + 2); //SUBTRACT 2 degrees to servo position for increased motor rpm
              servoPosition = myservo.read(); //Read new servo position
              delay(100); //allows time for switch ro reset
           }
           //If first button not pressed, check the next...
           else if (digitalRead(buttonPin2) == HIGH) 
           {
              myservo.write(val1 - 2); //ADDS 2 degrees to servo position for decreased motor rpm
              servoPosition = myservo.read(); //Read new servo position
              delay(100); //allows time for switch ro reset
           }
           else if (digitalRead(buttonPin3) == HIGH) 
           {
              btnControlEnabled = 0; //Set loop exit condition
           }
           else if (digitalRead(buttonPin4) == HIGH) 
           {
              btnControlEnabled = 0; //Set loop exit condition
           }
           //If nothing pressed...
           else
           {
             //...do nothing at all, go back to start of loop
           }
         }
         
    }

     

    I have made a few minor changes to this that you may notice, particularly making the servo position a global variable (Meaning your whole program can use it not just the portion handling the position buttons), making the statements use the else if format, and a couple of tiny formatting bits (Nothing that would particularly change how the program works, but a good habit to get into. When you start doing your next projects it can be a huge help much like comments).

     

    One thing you will need to consider is switch debouncing (http://arduino.cc/en/Tutorial/Debounce), when you press a button it can look like you pressed it more than once. In some cases that can cause some unwanted behaviour, for example pressing buttonPin3 once could behave as if you had pressed it several times.

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • Cancel
  • Former Member
    Former Member over 12 years ago in reply to cookieglitch

    the while, If works very well thank you and puts all the command into the serloop1(),

     

    I have tried to incorporate the debounce but dont get how to integrate the debounce loop into my program. Sorry, i am struggling to get the programming language but your explenations have been of great assistance.

     

    Here is how I tried to incorporate debounce, minus the debounce loop() part.

     

    [code]

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

    // 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;

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

    // Variables will change:
    int buttonState;             // the current reading from the input pin
    int lastButtonState = 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 debounceDelay = 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()
    {
          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 output
         myservo.write(val); //writes current position to servo to move it

         if (digitalRead(buttonPin) == HIGH)
         {
              serloop1(); //Enters button control loop
         }

         if (digitalRead(buttonPin2) == 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 = myservo.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(buttonPin) == HIGH)
           {
              myservo.write(servoPosition + 2); //SUBTRACT 2 degrees to servo position for increased motor rpm
              servoPosition = myservo.read(); //Read new servo position
              delay(100); //allows time for switch ro reset
           }
           //If first button not pressed, check the next...
           else if (digitalRead(buttonPin2) == HIGH)
           {
              myservo.write(servoPosition - 2); //ADDS 2 degrees to servo position for decreased motor rpm
              servoPosition = myservo.read(); //Read new servo position
              delay(100); //allows time for switch ro reset
           }
           else if (digitalRead(buttonPin3) == HIGH)
           {
              btnControlEnabled = 0; //Set loop exit condition
           }
           else if (digitalRead(buttonPin4) == HIGH)
           {
              btnControlEnabled = 0; //Set loop exit condition
           }
           //If nothing pressed...
           else
           {
             //...do nothing at all, go back to start of loop
           }
         }
        
    }

    [/code]

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • Cancel
Reply
  • Former Member
    Former Member over 12 years ago in reply to cookieglitch

    the while, If works very well thank you and puts all the command into the serloop1(),

     

    I have tried to incorporate the debounce but dont get how to integrate the debounce loop into my program. Sorry, i am struggling to get the programming language but your explenations have been of great assistance.

     

    Here is how I tried to incorporate debounce, minus the debounce loop() part.

     

    [code]

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

    // 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;

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

    // Variables will change:
    int buttonState;             // the current reading from the input pin
    int lastButtonState = 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 debounceDelay = 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()
    {
          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 output
         myservo.write(val); //writes current position to servo to move it

         if (digitalRead(buttonPin) == HIGH)
         {
              serloop1(); //Enters button control loop
         }

         if (digitalRead(buttonPin2) == 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 = myservo.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(buttonPin) == HIGH)
           {
              myservo.write(servoPosition + 2); //SUBTRACT 2 degrees to servo position for increased motor rpm
              servoPosition = myservo.read(); //Read new servo position
              delay(100); //allows time for switch ro reset
           }
           //If first button not pressed, check the next...
           else if (digitalRead(buttonPin2) == HIGH)
           {
              myservo.write(servoPosition - 2); //ADDS 2 degrees to servo position for decreased motor rpm
              servoPosition = myservo.read(); //Read new servo position
              delay(100); //allows time for switch ro reset
           }
           else if (digitalRead(buttonPin3) == HIGH)
           {
              btnControlEnabled = 0; //Set loop exit condition
           }
           else if (digitalRead(buttonPin4) == HIGH)
           {
              btnControlEnabled = 0; //Set loop exit condition
           }
           //If nothing pressed...
           else
           {
             //...do nothing at all, go back to start of loop
           }
         }
        
    }

    [/code]

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • Cancel
Children
  • Former Member
    Former Member over 12 years ago in reply to Former Member

    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
    [code] 
      // set the LED using the state of the button:
       digitalWrite(ledPin, buttonState);[/code]


    [code]#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
           }
         }
        
    }[/code]

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • Cancel
  • cookieglitch
    cookieglitch over 12 years ago in reply to Former Member

    If you haven't already, a series you might want to watch is Jeremy Blum's Arduino tutorials. It covers many of the basics which you will use.

    You don't have permission to edit metadata of this video.
    Edit media
    x
    image
    Upload Preview
    image

     

    To get button debouncing working on your project you will need to duplicate a few variables. In the example on the arduino site, it is using one button, however because yours is using four, it will need some variables specific to each button. In the method being used you are taking the state for each button at the start of the loop and comparing it to a stored value, if it is not the same (i.e. it has been pressed or released) you start a timer. On the next run of the loop, you compare the time it between the last state change and the current one (if it has occured). If the time is bigger than the set debounce time, it will interpret it as a button press or release, leaving it up to the programmer to deal with the state. As you start to add more buttons however, this method can start to get very complicated as you have seen. There are however easier ways to do some tasks. As you have seen with the servo, there are libraries available to help, such as the Bounce libary. Although using a library like this can use up a little more memory than you would otherwise, the headaches it reduces can be worth it. In the case of this program, I doubt memory space will be an issue for you. As you get used to the language (Won't take you long at all I'm sure!), you'll learn than for some tasks having a quick google or look around the Arduino playground site, can give you some useful libraries or code snippets.

     

    So, with the Bounce library downloaded and installed (Instructions on the page), you may end up with something like this. Note, the debounce tool provides it's own read option so for reading the buttons you need to use the bouncer.read() method rather than digitalRead()

    #include <Bounce.h>
    
    #include <Servo.h> 
    Servo myservo; // create servo object to control a servo 
    
    int potpin = 0;
    int val; 
    
    int servoPosition = 0; //Old val1, used to store servo position. Allows use by whole program
    
    // 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;
    
    long debounceDelay = 50;    // the debounce time; increase if the output flickers
    
    //Debounce objects
    // Instantiate a Bounce object with a 5 millisecond debounce time
    Bounce bouncer1 = Bounce(buttonPin, debounceDelay);
    Bounce bouncer2 = Bounce(buttonPin2, debounceDelay);
    Bounce bouncer3 = Bounce(buttonPin3, debounceDelay);
    Bounce bouncer4 = Bounce(buttonPin4, debounceDelay);
    
    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 output
         myservo.write(val); //writes current position to servo to move it
    
         //Update debounce tool
         bouncer1.update();
         bouncer2.update();
    
         //Do not need to update these here are they are not used
         //bouncer3.update();
         //bouncer4.update();
    
    
         if (bouncer1.read() == HIGH)
         {
              serloop1(); //Enters button control loop
         }
    
         if (bouncer2.read() == 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 = myservo.read(); //reads current servo location
    
         int btnControlEnabled = 1; //If button control is enabled this equals 1, else it equals 0
    
         while(btnControlEnabled == 1)
         {
           //Update all debounce tools
           bouncer1.update();
           bouncer2.update();
           bouncer3.update();
           bouncer4.update();
    
           if (bouncer1.read() == HIGH)
           {
              myservo.write(servoPosition + 2); //SUBTRACT 2 degrees to servo position for increased motor rpm
              servoPosition = myservo.read(); //Read new servo position
              delay(100); //allows time for switch ro reset
           }
           //If first button not pressed, check the next...
           else if (bouncer2.read() == HIGH)
           {
              myservo.write(servoPosition - 2); //ADDS 2 degrees to servo position for decreased motor rpm
              servoPosition = myservo.read(); //Read new servo position
              delay(100); //allows time for switch ro reset
           }
           else if (bouncer3.read() == HIGH)
           {
              btnControlEnabled = 0; //Set loop exit condition
           }
           else if (bouncer4.read() == HIGH)
           {
              btnControlEnabled = 0; //Set loop exit condition
           }
           //If nothing pressed...
           else
           {
             //...do nothing at all, go back to start of loop
           }
         }
    }

     

     

    Just seen your new attempt while writing this, it looks good! If you can get it working, go with it. One way you could make it tidier is to check where variables are being used, if they are being read in more than one place (and not changing), you can use just one. For example, in your new code you have

    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

    In your program, debounceDelay is read at multiple points, but is the same value throughout. This means that you could safely reduce these down to long debounceDelay = 50; and reference that rather than using 4 different variables. The advantage of this is that if you find 50 milliseconds is too long or too short for whatever reason, you only need to change one line of code not four.  Similarly, it is also only one variable and not four, when you get into writing much larger programs, things like this can help keep the size down. As you get used to the language, many things like this are just tricks that you will pick up with experience, much like the formatting tips.  Good luck learning the language, you'll be used to it in no time.

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • Cancel
  • Former Member
    Former Member over 12 years ago in reply to cookieglitch

    Thanks John for all the help. I am learning a lot. It is hard to wrap your head around this stuff. I had my code working but did something and not now. I actually really like the simplicity of the bounce library though I dont understand its workings yet.

     

    This latest version worked right off except for one thing. when i push button 1 and 2 to do the 2* servo movement, I need it to hold that position until button 3 or 4 is pushed. With this it is returning to the servo position as soon as button one or 2 is released.

     

    I have been doing the Blum"s tutorials but having a hard time getting it. I am however making headway.

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • Cancel
  • Former Member
    Former Member over 12 years ago in reply to Former Member

    turns out the bounce library program works perfectly. I was having interference problems with the loose, temp test bed wires. I soldered everything and it now works without flaw, except for small servo glitch.

     

    I am now finally ready to figure out the speed sensor, control. I have decided to use a hall effect speed sensor to try and do this. Ill do some research and attempts to build this into the program.

     

    How do I properly display the code on this web site?

     

    [code]

    #include <Bounce.h>

     

    #include <Servo.h>

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

     

    int throttlePot = 0;

    int val;

     

    int servoPosition = 0; //Old val1, used to store servo position. Allows use by whole program

     

    // set pin numbers:

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

    const int throttlePositionSet_Dn = 8;

    const int relaseToPot1 = 4;

    const int relaseToPot2 = 2;

     

    long debounceDelay = 50;    // the debounce time; increase if the output flickers

     

    //Debounce objects

    // Instantiate a Bounce object with a 5 millisecond debounce time

    Bounce bouncer1 = Bounce(throttlePositionSet_Up, debounceDelay);

    Bounce bouncer2 = Bounce(throttlePositionSet_Dn, debounceDelay);

    Bounce bouncer3 = Bounce(relaseToPot1, debounceDelay);

    Bounce bouncer4 = Bounce(relaseToPot2, debounceDelay);

     

    void setup()

    {

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

     

         // initialize the pushbutton pin as an input:

         pinMode(throttlePositionSet_Up, INPUT);

         pinMode(throttlePositionSet_Dn, INPUT);

         pinMode(relaseToPot1, INPUT);

         pinMode(relaseToPot2, INPUT);

    }

     

    void loop()

    {

         val = analogRead(throttlePot); //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

     

         //Update debounce tool

         bouncer1.update();

         bouncer2.update();

     

         //Do not need to update these here are they are not used

         //bouncer3.update();

         //bouncer4.update();

     

     

         if (bouncer1.read() == HIGH)

         {

              serloop1(); //Enters button control loop

         }

     

         if (bouncer2.read() == 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)

         {

           //Update all debounce tools

           bouncer1.update();

           bouncer2.update();

           bouncer3.update();

           bouncer4.update();

     

           if (bouncer1.read() == 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 (bouncer2.read() == 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 (bouncer3.read() == HIGH)

           {

              btnControlEnabled = 0; //Set loop exit condition

           }

           else if (bouncer4.read() == HIGH)

           {

              btnControlEnabled = 0; //Set loop exit condition

           }

           //If nothing pressed...

           else

           {

             //...do nothing at all, go back to start of loop

           }

         }

    }

    [/code]

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • Cancel
  • cookieglitch
    cookieglitch over 12 years ago in reply to Former Member

    There are two ways to embed code, you can use the Syntax Highlight option in the advanced editor option, or use the "Gist" feature described here

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • Cancel
element14 Community

element14 is the first online community specifically for engineers. Connect with your peers and get expert answers to your questions.

  • Members
  • Learn
  • Technologies
  • Challenges & Projects
  • Products
  • Store
  • About Us
  • Feedback & Support
  • FAQs
  • Terms of Use
  • Privacy Policy
  • Legal and Copyright Notices
  • Sitemap
  • Cookies

An Avnet Company © 2025 Premier Farnell Limited. All Rights Reserved.

Premier Farnell Ltd, registered in England and Wales (no 00876412), registered office: Farnell House, Forge Lane, Leeds LS12 2NE.

ICP 备案号 10220084.

Follow element14

  • X
  • Facebook
  • linkedin
  • YouTube