Pages: [1] 2 3 4   Go Down
Author Topic: 2 servos (or any functions) operating simultaneously?  (Read 12656 times)
0 Members and 1 Guest are viewing this topic.
denver
Offline Offline
Newbie
*
Karma: 0
Posts: 35
...no matter where you go, there you are
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hello Everyone,

I have an UNO R3 with an Ardumoto shield (just got a seeed MotorShield v1.2 but haven't hooked it up yet) and am working on a prototype for an autonomous hexapod.  I'm trying to get at least two servos (eventually 5-8) to operate at the same time, executing different parameters for one 'smooth' leg movement.  In other words, pedal movement that traces a path more like an arch than a jerky rectangle.  I'm fairly new to programming and totally new to arduino and micro-controllers.  So far none of the code I've written will control two servos simultaneously, I'm thinking I probably need to incorporate an IC into the circuit and coding to accomplish this, but so far I haven't found much info on this particular problem.  
Any input would be great!
**********************************************************************************
 1/5/13                                                     I need help!

       Here's what I'm trying to do:
1) Store strings to PROGMEM
2) Retrieve strings from PROGMEM using Serial()
3) Write strings to multiple servos in sequence/s

      Purpose:
Mainly to have simultaneous operation of multiple servos and sensors, the other would be to conserve memory for functions.

I've made too many changes, additions, omissions to the code to remember everything I've tried.  I can't really go much further with my project without solving this problem.
  The code I'm working on is post #27.

                             Any suggestions or additional info will be greatly appreciated!
« Last Edit: January 06, 2013, 12:12:58 am by evolion » Logged

Global Moderator
UK
Offline Offline
Brattain Member
*****
Karma: 303
Posts: 26354
I don't think you connected the grounds, Dave.
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
So far none of the code I've written will control two servos simultaneously
What code?
Logged

"Pete, it's a fool looks for logic in the chambers of the human heart." Ulysses Everett McGill.
Do not send technical questions via personal messaging - they will be ignored.

0
Offline Offline
Tesla Member
***
Karma: 145
Posts: 9637
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

A place to start would be to look at hex projects others are working on like below.

http://www.lynxmotion.net/viewtopic.php?f=8&t=8409
Logged

Consider the daffodil. And while you're doing that, I'll be over here, looking through your stuff.   smiley-cool

denver
Offline Offline
Newbie
*
Karma: 0
Posts: 35
...no matter where you go, there you are
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

                    Here is some of the code I've used so far:

Code:
//I have rewritten the 'sweep' example from the 'getting started' section of the site.
//My arduino is mounted on a robot kit and I am using the 'bumper' sensors (whiskers) as switches
//to start/stop the servo functions mounted on another stationary platform.

#include <Wire.h>
#include <Servo.h>
 
Servo myservo;   //create servo object to control a servo
int pos = 0;              
Servo myservo2;                
int pos2 = 0;     //variable to store the servo position

const int bumperPinR = 2;   // the number of the bumper pin
const int bumperPinL = 4;   // the number of the bumper pin

int bumperStateR = 0;       // variable for reading the bumper status
int bumperStateL = 0;       // variable for reading the bumper status

void setup()
{
  myservo.attach(9);   //attaches the servo on pin 9 to the servo object
  myservo2.attach(8);

  pinMode(bumperPinR, INPUT);  //sets the bumper pins as an inputs
  pinMode(bumperPinL, INPUT);

 Wire.begin();        //initializes/activates voltage sensing from bumper?
}
 
 void loop()
{
  bumperStateR = digitalRead(bumperPinR);  //read state of the bumper values
  bumperStateL = digitalRead(bumperPinL);
 
 while (bumperStateR == LOW)        // begin a loop within 'void loop'
 {
   for(pos = 31; pos < 168; pos += 3)  // goes from 31 degrees to 168 degrees
   {                                   // in steps of 3 degrees (faster)
     myservo.write(pos);               // tell servo to go to position in variable 'pos'
     delay(15);                        // waits 15ms for the servo to reach the position
   }
   for(pos2 = 6; pos2 < 171; pos2 += 3)  // goes from 6 degrees to 171 degrees
   {                                     // in steps of 3 degrees (faster)
     myservo2.write(pos2);          
     delay(15);                      
   }    
   for(pos = 167; pos >= 32; pos -= 3)   // goes from 167 degrees to 32 degrees (keeping servo from
   {                                     // ends of range seems to fix its jerking)
     myservo.write(pos);              
     delay(15);                        
   }
   for(pos2 = 170; pos2 >= 5; pos2 -= 3)  // goes from 170 degrees to 5 degrees
   {                                  
     myservo2.write(pos2);            
     delay(15);                        
   }  
//   if (bumperStateL == LOW)        // condition that breaks out of loop
//   { pos = 3 || 177;                      
//      break;
//   }
 }
  if (bumperStateL == LOW)   //this doesn't seem to do anything, supposed to stop the
  {                          //the code above from running - this part can be ignored for now
    int pos = 90;
    {
      myservo.write(pos);              
       delay(15);
    }
    int pos2 = 90;
    {
      myservo2.write(pos2);              
       delay(15);
    }    
  }
}

 ~Thank you for the link, I'll check it out.

I guess my specific project here may be beside the point, in that, it probably doesn't matter what the functions are, but just how to make any two (or more) of them run at the same time, not one after the other. ~2 servos moving at the same time using completely different parameters.
« Last Edit: December 27, 2012, 02:17:49 am by evolion » Logged

Johannesburg. UTC+2
Online Online
Faraday Member
**
Karma: 99
Posts: 4435
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

To make the code look like code, just highlight it and hit the # button above the smilies
Logged

The Elders of the Internet know who I am
I'm on LinkedIn: http://www.linkedin.com/in/jimbrownza

Global Moderator
UK
Offline Offline
Brattain Member
*****
Karma: 303
Posts: 26354
I don't think you connected the grounds, Dave.
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

OP, have you looked at the blink without delay example sketch?
You should.
Logged

"Pete, it's a fool looks for logic in the chambers of the human heart." Ulysses Everett McGill.
Do not send technical questions via personal messaging - they will be ignored.

denver
Offline Offline
Newbie
*
Karma: 0
Posts: 35
...no matter where you go, there you are
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Thank you for the tip,

Upon examining 'blink wo delay', it appears that every time the defined interval is reached and the led blinks, the previousmillis is redefined to be currentmillis so that the iteration gets continually restarted, thus creating a kind of loop that apparently runs in the background.  (if that makes any sense)

So I gather that any function that can be set up without a delay won't interrupt other functions.  I'll have to think about this a bit.

I found a routine here  <http://scolton.blogspot.com/2010/07/arduino-interrupt-driven-servo-routine.html>  that uses PWM, resets one of the board's timers, and uses interrupts to control the servos.  The concept seems to make sense but I don't really understand the code so I'll have to experiment to see what it does.

I also want the servos to operate in sync with each other so as to produce what appears a 'single' movement of the leg.
Logged

Global Moderator
UK
Offline Offline
Brattain Member
*****
Karma: 303
Posts: 26354
I don't think you connected the grounds, Dave.
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
I found a routine here  <http://scolton.blogspot.com/2010/07/arduino-interrupt-driven-servo-routine.html>  that uses PWM, resets one of the board's timers, and uses interrupts to control the servos
That's exactly what the Servo library does.
No need to reinvent that particular wheel.
Logged

"Pete, it's a fool looks for logic in the chambers of the human heart." Ulysses Everett McGill.
Do not send technical questions via personal messaging - they will be ignored.

denver
Offline Offline
Newbie
*
Karma: 0
Posts: 35
...no matter where you go, there you are
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

So, is it that i need to map the variable values (degrees) of one servo to the other so that the position of one is dependent on the position of the other ~one would basically 'follow' the other using a conversion between ranges?
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 46
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

What are you using to control the servo's ?  If you are running a full 18 or more you may want to look at a dedicated Servo controller which will give you much more flexibility in managing your servos.  The Lynxmotion one allows for group moves others have servo speed control etc.
Logged

Left Coast, CA (USA)
Offline Offline
Brattain Member
*****
Karma: 361
Posts: 17294
Measurement changes behavior
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
I also want the servos to operate in sync with each other so as to produce what appears a 'single' movement of the leg.

I think you fail to understand that any 'coordination' between the servos motion will always strictly be a task your software has to perform. Servos move fairly slow relative to program execution and any 'simultaneous movement' will be the result of your the 'step size' you issue each servo to move and how quick you issue the next step size movement to each servo. The smaller your servo step size commands are the more smooth the apparent 'coordinated movement' will be. Any coordination between your servos movement is a software burden on you, there is no hardware assistance you can use.

Lefty
Logged

0
Offline Offline
Tesla Member
***
Karma: 145
Posts: 9637
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
I guess my specific project here may be beside the point, in that, it probably doesn't matter what the functions are, but just how to make any two (or more) of them run at the same time, not one after the other. ~2 servos moving at the same time using completely different parameters.

Code:
//zoomkat 11-22-12 simple delimited ',' string parse
//from serial port input (via serial monitor)
//and print result out serial port
//multi servos added

String readString;
#include <Servo.h>
Servo myservoa, myservob, myservoc, myservod;  // create servo object to control a servo

void setup() {
  Serial.begin(9600);

  //myservoa.writeMicroseconds(1500); //set initial servo position if desired

  myservoa.attach(6);  //the pin for the servoa control
  myservob.attach(7);  //the pin for the servob control
  myservoc.attach(8);  //the pin for the servoc control
  myservod.attach(9);  //the pin for the servod control
  Serial.println("multi-servo-delimit-test-dual-input-11-22-12"); // so I can keep track of what is loaded
}

void loop() {

  //expect single strings like 700a, or 1500c, or 2000d,
  //or like 30c, or 90a, or 180d,
  //or 30c,180b,70a,120d,

  if (Serial.available())  {
    char c = Serial.read();  //gets one byte from serial buffer
    if (c == ',') {
      if (readString.length() >1) {
        Serial.println(readString); //prints string to serial port out

        int n = readString.toInt();  //convert readString into a number

        // auto select appropriate value, copied from someone elses code.
        if(n >= 500)
        {
          Serial.print("writing Microseconds: ");
          Serial.println(n);
          if(readString.indexOf('a') >0) myservoa.writeMicroseconds(n);
          if(readString.indexOf('b') >0) myservob.writeMicroseconds(n);
          if(readString.indexOf('c') >0) myservoc.writeMicroseconds(n);
          if(readString.indexOf('d') >0) myservod.writeMicroseconds(n);
        }
        else
        {   
          Serial.print("writing Angle: ");
          Serial.println(n);
          if(readString.indexOf('a') >0) myservoa.write(n);
          if(readString.indexOf('b') >0) myservob.write(n);
          if(readString.indexOf('c') >0) myservoc.write(n);
          if(readString.indexOf('d') >0) myservod.write(n);
        }
         readString=""; //clears variable for new input
      }
    } 
    else {     
      readString += c; //makes the string readString
    }
  }
}
Logged

Consider the daffodil. And while you're doing that, I'll be over here, looking through your stuff.   smiley-cool

denver
Offline Offline
Newbie
*
Karma: 0
Posts: 35
...no matter where you go, there you are
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

rgallant:
I'm using an UNO r3 with an ardumoto shield (just using 2 pinouts for 2 servos on a homegrown proto leg ~very simplistic).  I just got a seeed studio motor sheild but haven't tried to hook it up yet.  I have a couple of different plans to use a total of only 6 to 8 servos to control 6 legs.  I don't really know what I'm doing but I'm determined to figure it out.

retrolefty:
I'm beginning to understand that the arduino only runs one command at a time.  But it's the speed at which it sends incremental pulses to the motors, switching back and forth between them that will produce an impression of simultaneous operation.  The coordinated 'x' and 'y' motor movements, which are basically linear, will appear as a diagonal or curved path ~sort of like a digital representation of an analog wave.

zoomkat:
Thank you for the code example, although I'm not sure that I understand what it's doing.  Please correct me if I'm wrong, but it appears that the serial function is being used to produce the bit information that gets redefined and sent out to the servos.  And the serial function is quick enough to supply the info in time for each pulse to a servo which is happening within microsecond intervals.
   Does this particular routine only control 4 servos?  Can more servos be added?
   Does the 'n' variable need to be defined as an integer value?  or is the code doing this on its own as it continually loops? 
Logged

Global Moderator
UK
Offline Offline
Brattain Member
*****
Karma: 303
Posts: 26354
I don't think you connected the grounds, Dave.
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
Does this particular routine only control 4 servos?
Yes.

Quote
Can more servos be added?
Yes, though I'd advise using an array of Servos, rather than individual named instances.
With a regular Arduino, you ought to be able to control up to twelve, more with a Mega.

Quote
Does the 'n' variable need to be defined as an integer value?
It needs to be an integer datatype, because that is what the Servo write methods expect.

Quote
or is the code doing this on its own as it continually loops? 
Sorry, don't understand the question
Logged

"Pete, it's a fool looks for logic in the chambers of the human heart." Ulysses Everett McGill.
Do not send technical questions via personal messaging - they will be ignored.

denver
Offline Offline
Newbie
*
Karma: 0
Posts: 35
...no matter where you go, there you are
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
Quote
or is the code doing this on its own as it continually loops?
Sorry, don't understand the question
I'm not sure if I understand it either.

So the integers n are the microsecond values given by the readString.index?

I am working now to adapt this routine to my prototype setup and see if it works.
Logged

Pages: [1] 2 3 4   Go Up
Jump to: