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 Multiple servo control...setting expectations
  • 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 36 replies
  • Subscribers 383 subscribers
  • Views 4022 views
  • Users 0 members are here
  • arduino_code
  • code
  • servo_motor_control
Related

Multiple servo control...setting expectations

colporteur
colporteur over 1 year ago

image

Can six servos all operate independent using and Arduino and PCA9685 PWM driver?

I am creating an model railroad barn yard animation scene. Six different animal perform movements using SG90 servos.

The cows in ellipse A tails moves left to right.

The cow in ellipse B moves its head left to right

The cow in ellipse C moves its head up and down

The pig in ellipse D moves it head up and down

The pig in ellipse E moves its head from left to right.

The modeller has asked that all animals perform motion at the same time. Cow tails swing. Cow heads move and pigs heads move. Each animal would complete a pattern. i.e. Cow C dips it head to gather feed and then raises it head to chew. 

I'm confident I can create the servo action to simulate the motion individually. I'm not so sure if this is possible simultaneously.

I stuck on the concept of a thread. If the cows tails are moving that has to stop for the other animals to move.

Can some Arduino aficionados provide me some guidance? Is it possible to do this all with one Arduino or does it have to be broken down to be done by one or more Arduino?

  • Sign in to reply
  • Cancel

Top Replies

  • colporteur
    colporteur over 1 year ago +11
    community.element14.com/.../IMG_5F00_2571.MOV Here is a short video using the code shabaz provided. I made a few tweaks in array values to get the desired effect.
  • shabaz
    shabaz over 1 year ago +7
    Hi Sean, It can certainly be done with a single Arduino as mentioned by others, but it takes a different code structure than just the basic loop. The luxury method would be to use a real-time operating…
  • michaelkellett
    michaelkellett over 1 year ago in reply to colporteur +6
    Slightly scary - I keep expecting one to take its first step ! MK
Parents
  • shabaz
    shabaz over 1 year ago

    Hi Sean,

    It can certainly be done with a single Arduino as mentioned by others, but it takes a different code structure than just the basic loop.
    The luxury method would be to use a real-time operating system, which would most likely be easiest with a Pi Pico. But that requires time to learn the features of it.

    The non-RTOS approach is usually to use a timer and perform updates on tick intervals, but it could be an uphill struggle to develop from scratch if you've not needed to do this before.

    Anyway, I had a look and there are various ready-made libraries that could help. Not all the libraries will require the PCA9685; some will require the servos to be directly connected to the Arduino GPIO pins.

    Since I have an Arduino Mega, I thought I'd give one library a quick try.

    image

    I assumed there were 6 servos for my quick test.

    image

    I decided to connect the six servos directly to Digital pins 2-7, i.e. no PCA9685 chip used:

    image

    The animation is defined by events. I figured 10 events is more than enough (it needs to be 20 or less because that is a limit of the library):

    image

    Now comes the tricky bit, For each servo, key-frame times need to be defined. There are 10 times for each servo, because EVENT_TOTAL is 10.

    You can see below that for the first servo (servo 0, i.e. cow), I want something to occur every second (the values are in milliseconds) from 0 to 9 seconds.

    For the second servo, I don't want anything to happen until 5 seconds have elapsed, and then I want activity to happen every half a second.

    For the third servo (servo 2), I want something to happen at 0, 2 and 4 seconds, but because there are 10 events, I kind of cheated and set a lot of the event times to be just spaced 1 msec apart as you can see, just to pad things out with sane values.

    image

    Next, the positions (i.e. angles) need defining. I did some various things just to experiment a bit. 

    image

    You can also define how slowly or quickly a servo can move; this too would need experimentation to see how it behaves:

    image

    Next, the setup function which you probably would not need to change. It does three main things:

    (1) calls the servo attach function to tie the digital pins to servo functionality

    (2) sets up the timelines with the three arrays that were defined above (i.e. eventTime, eventPosition and travelTime)

    (3) moves all the servos to the start position (angle).

    image

    Now the main loop is very simple. All it does is forever go through each timeline, to see if any servo position needs updating, and it performs the update.

    image

    The entire code is here, which you could examine and modify to suit your needs, it is also pasted below.

    /********* animation test *************
     * tested with an Arduino Mega
     **************************************/
    #include <Servo.h>
    #include <animationTools.h>
    
    // ********** definitions ************************
    // total number of servos
    #define SERVO_TOTAL 6
    // enumerate the servos from 0 to SERVO_TOTAL-1
    #define SERVO_COW 0
    #define SERVO_SHEEP 1
    #define SERVO_PIG 2
    #define SERVO_CHICKEN 3
    #define SERVO_DOG 4
    #define SERVO_CAT 5
    
    // total number of events, set to 20 or less (20 is the limit of the arduinoAnimation library)
    #define EVENT_TOTAL 10
    
    // ******* global variables **********************
    // Arduino pins for the servos
    const int servoPin[SERVO_TOTAL] = {2, 3, 4, 5, 6, 7};
    // animation defined in terms of event time, position(angle), and travel time
    // Times are in milliseconds, positions are in degrees
    const int eventTime[SERVO_TOTAL][EVENT_TOTAL] = {
      {0, 1000, 2000, 3000, 4000, 5000, 6000, 7000, 8000, 9000}, /* servo 0 */
      {5000, 5500, 6000, 6500, 7000, 7500, 8000, 8500, 9000, 9500}, /* servo 1 */
      {0, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 4000}, /* servo 2 */
      {0, 1000, 2000, 3000, 4000, 5000, 6000, 7000, 8000, 9000}, /* servo 3 */
      {0, 1000, 2000, 3000, 4000, 5000, 6000, 7000, 8000, 9000}, /* servo 4 */
      {0, 1000, 2000, 3000, 4000, 5000, 6000, 7000, 8000, 9000}, /* servo 5 */
    };
    const int eventPosition[SERVO_TOTAL][EVENT_TOTAL] = {
      {0, 30, 60, 30, 90, 120, 150, 180, 180, 180}, /* servo 0 */
      {0, 90, 100, 110, 120, 140, 120, 110, 100, 90}, /* servo 1 */
      {0, 90, 90, 90, 90, 90, 90, 90, 90, 0}, /* servo 2 */
      {0, 90, 0, 90, 0, 90, 0, 90, 0, 90}, /* servo 3 */
      {0, 90, 0, 90, 0, 90, 0, 90, 0, 90}, /* servo 4 */
      {0, 90, 0, 90, 0, 90, 0, 90, 0, 90}, /* servo 5 */
    };
    const int travelTime[SERVO_TOTAL] = {
      1000, /* servo 0 */
      500, /* servo 1 */
      1000, /* servo 2 */
      1000, /* servo 3 */
      1000, /* servo 4 */
      1000, /* servo 5 */
    };
    
    Servo servo[SERVO_TOTAL];
    Timeline timeline[SERVO_TOTAL];
    
    // ********** setup function *********************
    void setup() {
      int i, j;
      Serial.begin(9600);
      // initialize the servos
      for (i = 0; i < SERVO_TOTAL; i++) {
        servo[i].attach(servoPin[i]);
      }  
      // initialize the timelines
      for (i = 0; i < SERVO_TOTAL; i++) {
        timeline[i].totalKeys = EVENT_TOTAL;
        timeline[i].travelTime = travelTime[i];
        timeline[i].loop = true;
        for (j = 0; j < EVENT_TOTAL; j++) {
          timeline[i].timeKey[j] = eventTime[i][j];
          timeline[i].valKey[j] = eventPosition[i][j];
        }
      }
      // set all the servos to the start value
      for (i = 0; i < SERVO_TOTAL; i++) {
        servo[i].write(timeline[i].valKey[0]);
        delay(100); // give the servo time to get there
      }
    }
    
    void loop() {
      int i;
      int angle;
      for (i=0; i<SERVO_TOTAL; i++) {
        angle = getTimelineValue(timeline[i]);
        servo[i].write(angle);
      }
    }
    

    I have tested it with a single servo, just manually patching it into Digital pins 2, 3, 4 etc., and it seems to work. But I know nothing much about this library, so you'd need to experiment with it to see how to adjust it to your needs. Maybe you could offload some of the animation effort by building a simple testbed and telling the modeller to write the three arrays, i.e. eventTime, eventPosition and travelTime, i.e. show the modeller where to click to build and upload the code, so they can quickly tweak the arrays and see the results.

    image

    The photo of my test setup is above.. really crude, and would need a better supply for more servos! I used just the USB connection to power the single servo for now.

    • Cancel
    • Vote Up +7 Vote Down
    • Sign in to reply
    • Cancel
  • shabaz
    shabaz over 1 year ago in reply to shabaz

    Incidentally, for really nice animations, it would be better to use stepper motors, they are near-silent, and their motion can look more interesting.

    However stepper solutions cost a lot more and can't directly replace a servo, so it is maybe only worthwhile for shows or where the model-making effort/cost is high already.

    • Cancel
    • Vote Up +2 Vote Down
    • Sign in to reply
    • Cancel
Reply
  • shabaz
    shabaz over 1 year ago in reply to shabaz

    Incidentally, for really nice animations, it would be better to use stepper motors, they are near-silent, and their motion can look more interesting.

    However stepper solutions cost a lot more and can't directly replace a servo, so it is maybe only worthwhile for shows or where the model-making effort/cost is high already.

    • Cancel
    • Vote Up +2 Vote Down
    • Sign in to reply
    • Cancel
Children
No Data
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