element14 Community
element14 Community
    Register Log In
  • Site
  • Search
  • Log In Register
  • About Us
  • 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 Boards Community
    • Dev Tools
    • Manufacturers
    • Multicomp Pro
    • Product Groups
    • Raspberry Pi
    • RoadTests & Reviews
  • 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
      •  Korea (Korean)
      •  Malaysia
      •  New Zealand
      •  Philippines
      •  Singapore
      •  Taiwan
      •  Thailand (Thai)
      • 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 Activating Servos Simultaneously
  • 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 13 replies
  • Subscribers 396 subscribers
  • Views 2216 views
  • Users 0 members are here
Related

Activating Servos Simultaneously

Former Member
Former Member over 9 years ago

Hello...I need help...and I don't think it is a difficult issue, but I just can't seem to get it yet.

 

I am trying to push a button that makes a servo move 90 degrees for 10 seconds, then turn back. I have this working fine. The problem happens when I try to do this for more than one servo.

 

I can make it work for two servos, but not while the first one is still counting off its 10 second period.

 

Here is my code...CAN SOMEONE GUIDE ME TO A SOLUTION?

 

/*

  SweepTwoServos

  By Philip van Allen <philvanallen.com> for the VarSpeedServo.h library (October 2013)

  This example code is in the public domain

*/

 

#include <VarSpeedServo.h>

 

VarSpeedServo myservo_1;            // create servo object to control a servo

VarSpeedServo myservo_2;            //a maximum of eight servo objects can be created

 

const int servoPin1 = 9;                     // the digital pin used for the first servo

const int servoPin2 = 10;                     // the digital pin used for the second servo

 

unsigned long startTime_1 = 0;     // will store last time servo was opened

unsigned long startTime_2 = 0;     // will store last time servo was opened

int valveOpenPeriod_1 = 10000;    // sets the period the servo should be opened - 10 seconds

int valveOpenPeriod_2 = 5000;     // sets the period the servo should be opened - 5 seconds

 

void setup() {

  myservo_1.attach(servoPin1);  // attaches the servo on pin 9 to the servo object

  myservo_1.write(90,30,false);  // set the intial position of the servo, move slowly, run in background

  myservo_2.attach(servoPin2);  // attaches the servo on pin 10 to the servo object

  myservo_2.write(90,30,false);  // set the intial position of the servo, move slowly, run in background

}

 

void loop()

{

  unsigned long currentMillis = millis(); // start counting

 

  if(digitalRead(3) == HIGH)              // if inflation button is pushed

  {   

    startTime_1 = currentMillis;          // reset start time to current time

    while(millis() - startTime_1 < valveOpenPeriod_1)

    {

      myservo_1.write(180,30,false);   // tell servo to go to position 180 to open valve

      delay(10);                                    // waits 10ms for the servo to reach the position

    }

     myservo_1.write(90,30,false);     // tell servo to go to back to original position 90 to close valve

     delay(10);                                    // waits 10ms for the servo to reach the position

  }

 

/* THE PROBLEM

The two blocks of code, one above and one below, work independently but not simultaneously.

How do I get them to work simultaneously. In other words, I need each servo to move 90 degrees

for a period of time, then move back to its original position. I need this to work for

each servo whenever I press the putton.

*/

 

  if(digitalRead(5) == HIGH)              // if inflation button is pushed

  {   

    startTime_2 = currentMillis;           // reset start time to current time

    while(millis() - startTime_2 < valveOpenPeriod_2)

    {

      myservo_2.write(180,127,true);   // tell servo to go to position 180 to open valve

      delay(10);                               // waits 10ms for the servo to reach the position

    }

     myservo_2.write(90,127,true);    // tell servo to go to position 90 to close valve

     delay(10);                               // waits 10ms for the servo to reach the position

  }

}

  • Sign in to reply
  • Cancel

Top Replies

  • Robert Peter Oakes
    Robert Peter Oakes over 9 years ago +3
    So everyone is saying the right words but to help you categorically (But you will still have to read and learn as im not giving you a direct solution ) https://www.arduino.cc/en/Tutorial/BlinkWithoutDelay…
  • shabaz
    shabaz over 9 years ago +2
    Hi Remo, As John says, typically expect one processor to do one thing at a time. There are methods to make it appear that multiple things are occurring at the same time, but you need to structure your…
  • neilk
    neilk over 9 years ago +1
    Hi Remo, have a look here: http://www.doctormonk.com/2012/01/arduino-timer-library.html This describes a timer library which allows the arduino to perform tasks at different time intervals, without "blocking…
  • jw0752
    jw0752 over 9 years ago

    Hi Remo,

    Since you are dealing with a single processor there is no way for it to do 2 things simultaneously. One option would be to have a separate processor for each servo or you could trigger and latch a driver circuit to actually move the servo. If it is important for the servos to operate simultaneously you could use the enable on the driver to delay the start of the first servo until the second one is activated. I do not know exactly what you are doing and the fact of the matter is that there are other guys on the forum who have better knowledge than me. Your question interests me so I will continue to follow this thread.

    John

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • Cancel
  • shabaz
    shabaz over 9 years ago

    Hi Remo,

     

    As John says, typically expect one processor to do one thing at a time. There are methods to make it appear that multiple things are occurring at the same time, but you need to structure your code entirely differently to do that (using timer 'ticks') or to make use of an operating system which will make it transparent to your user code. This is all a massive subject so I can't explain all in the space of a discussion response. To see what you need to research and read up on, and to get a hint on some ways you might achieve it, see here:

    Multiple Arduino functions without delay

    • Cancel
    • Vote Up +2 Vote Down
    • Sign in to reply
    • Cancel
  • clem57
    clem57 over 9 years ago

    The real problem is the delay. This is deadly in multiple events like you want. I will point at a possible process that you need to understand. If I go to sleep for ten hours, I am not conscious of anything ( delay(10) ). But it a setup an alarm clock say every hour( delay(1) ), I can check something before going to sleep another hour until 10 hours are finished. But realize, on average things will wait about 30 minutes before I get around to it.

    Clem

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • Cancel
  • Robert Peter Oakes
    Robert Peter Oakes over 9 years ago

    So everyone is saying the right words but to help you categorically (But you will still have to read and learn as im not giving you a direct solution image )

     

    https://www.arduino.cc/en/Tutorial/BlinkWithoutDelay

     

    This explains how to do it with an example, try it out, see how it works and im sure you may have other questions but is will show yo what everyone is hinting at

     

    Regards

    Peter

    • Cancel
    • Vote Up +3 Vote Down
    • Sign in to reply
    • Cancel
  • mudz
    mudz over 9 years ago

    Well you can't do it with arduino but there are other microcontrollers which are capable of performing such tasks i.e. have multitasking capabilities with less coding. For example: check this :XK-STK-A8DEV XK-STK-A8DEV

    It's a basic development kit by XMOS i.e. Xmos startkit & features a multitasking microcontroller. If you take a look at its code you'll understand how easy is to do : XMOS startkit basic Multitasking code

    Hope this helps image

     

    mudz

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • Cancel
  • neilk
    neilk over 9 years ago

    Hi Remo, have a look here: http://www.doctormonk.com/2012/01/arduino-timer-library.html

     

    This describes a timer library which allows the arduino to perform tasks at different time intervals, without "blocking" - ie waiting for one task to finish before it's possible to start another task.

     

    I have used this library myself and found it extremely valuable.

     

    Hope this helps

     

    Neil

    • Cancel
    • Vote Up +1 Vote Down
    • Sign in to reply
    • Cancel
  • mcb1
    mcb1 over 9 years ago

    I would like to comment here, that the concept you have could work with some tweaks.

     

    1. You only have a 10mSec timer using delay.

    2. The while statement is what is stopping it from leaving and doing the other things.

     

    You need to construct it using an if statement, and in my programming I often use a variable to know if I should do something or not. (I call it a flag but that's probably wrong)

    I don't think you need extra libraries, but you've done the right thing and proved each piece of your code works, but combined they don't.

     

    The Blinkwithoutdelay (stupid name) gives you the idea, but you are already using the millis() timer, and I find the example a little lacking as it's usually two tasks you want to do.

     

    Without loading it, you might try something like ....

        if ((millis() - startTime_1 < valveOpenPeriod_1) && Valve1Open == 1)

        {

          myservo_1.write(180,30,false);   // tell servo to go to position 180 to open valve

          delay(10);                                    // waits 10ms for the servo to reach the position

        }

    Obviously you'll need to set the Valve1Open = 1 or 0 as appropriate in your code.

     

     

    Mark

    edit ... minor typo.

    • Cancel
    • Vote Up +1 Vote Down
    • Sign in to reply
    • Cancel
  • Former Member
    Former Member over 9 years ago in reply to neilk

    Well, yes Neil...I think I will need to check this out...

     

    But with all your help I actually have it working...at least I have 3 servos responding to 3 pushbuttons that start their valve open period.

     

    And they do work simultaneously. Here it is...

     

    // I am using this library...

    #include <VarSpeedServo.h>

     

    // I am creating 3 servo objects

    VarSpeedServo myservo_1;

    VarSpeedServo myservo_2

    VarSpeedServo myservo_3;

     

    // 3 digital pins

    const int servoPin1 = 9;

    const int servoPin2 = 10;

    const int servoPin3 = 11;

     

    // 3 valves can be set to 3 different open time

    const long valveOpenPeriod_1 = 7000;      // 7 seconds

    const long valveOpenPeriod_2 = 5000;      // 5 seconds

    const long valveOpenPeriod_3 = 2000;      // 2 seconds

     

    // store state of 3 servos, HIGH is open

    int valveOpen_1;

    int valveOpen_2;

    int valveOpen_3;

     

    // store last time servo was open

    unsigned long startTime_1 = 0;

    unsigned long startTime_2 = 0;

    unsigned long startTime_3 = 0;

     

    // attaches servos & pins to the servo object

    void setup() {

      myservo_1.attach(servoPin1);

      myservo_2.attach(servoPin2);

      myservo_3.attach(servoPin3);

    }

     

    void loop()

    {

      unsigned long currentMillis = millis();   // start counting

     

      if(digitalRead(2) == HIGH)                    // if inflation button #1 is pushed

      {   

        startTime_1 = currentMillis;                // reset start time to current time

      } 

      if(digitalRead(3) == HIGH)

      {   

        startTime_2 = currentMillis;

      }

      if(digitalRead(4) == HIGH)

      {   

        startTime_3 = currentMillis;

      }

     

    // subtract startTime from current time and compare it to the valve period

      if(millis() - startTime_1 >= valveOpenPeriod_1)

      {

        myservo_1.write(180,30,false);        // valve opens until period is reached

      }

      else

      {

        myservo_1.write(90,30,false);           // valve closed when period reached

      }

     

    // same for valve #2

      if(millis() - startTime_2 >= valveOpenPeriod_2)

      {

        myservo_2.write(180,30,false);      

      }

      else

      {

        myservo_2.write(90,30,false); 

      }

     

    // same for valve #3

      if(millis() - startTime_3 >= valveOpenPeriod_3)

      {

        myservo_3.write(180,30,false);

      }

      else

      {

        myservo_3.write(90,30,false);

      }

    }

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

    In the code above, there is an issue that I can't explain.

     

    Then I send the code to the Arduino, it thinks all the buttons have been pressed. In other words, all three valves open for the period they are supposed to be open, then they close.

     

    This does not bother me except for the fact that I don't know why it does that.

     

    Can anyone explain it to me?

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

    // store state of 3 servos, HIGH is open

    int valveOpen_1;

    int valveOpen_2;

    int valveOpen_3;

     

    where is initial value = ???

    • 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