multi servo sweep in opposite directions.

hello, I'm a noob when it comes to arduino, so I'm not sure how to get my current project to do what I want. If I understood how to program arduinos better I'm sure I wouldn't have this problem, but usually I'm able to use pre existing programs. the project I'm working on is a robotic hand, for the eventual build there are plenty of pre existing programs I can use since for the final build I'll be using a control glove. currently though I'm wanting to test the servo movement in the hand without having to plug and unplug each servo on the servo tester each time. the way my hand is designed 2 servos sweep 0-180 to open and close the fingers they are attached to, and the other 2 fingers and thumb sweep from 180-0. I've found a program that allows multiple servos to sweep, but they all sweep 0-180. my question is how do I set up a sweep program to allow these 3 servos to sweep in the opposite direction from the other 2?

servo1.write(angle);
servo2.write(180 - angle);

thank you, is there anything I'd need to do to the void loop?

wimismith:
thank you, is there anything I'd need to do to the void loop?

I can't tell what you might need to change because I can't see any of your code. Please post what you have now.

Steve

I don't have any code yet, because I'm still trying to plan out what I'm doing. what I'm doing right now is trying to read various tutorials, and I'm starting to understand that I'll have to have the sweep library on a separate page, but I'm still not sure how to format the program. I know what I want the code to do, which is to open and close the fingers and thumb at the same speed. I'm pretty sure once I've gotten everything figured out, I'll be kicking myself because it'll have turned out to be a really simple program.

Rather than hurting your brain with silly tutorials. Spend your time writing out what you actually want the thing to do and how you'd like to have it do it.

-jim lee

I'm starting to understand that I'll have to have the sweep library on a separate page

What do you mean by "sweep library" ?
What do you mean by "separate page" ?

I assume that you have looked the Servo Sweep example in the IDE and have tried that with 1 servo. If not, then do it now. The next step would seem to be to change the example to sweep all 5 servos at the same time. Once that is working you can think about incorporating that code into another sketch, probably as a function that you can call when required

ok, so I tried to write a simple program copping a lot from another program someone else had written. I tried compiling it and got some errors, tried doing what the section at the bottom said to fix the errors, and got as far as I could before I couldn't understand what it was telling me. it tells me,

hand:13:1: error: expected initializer before 'int'
int Servo_pins[SERVOS] = {3,5,6,9,10};
^~~
C:\Users\Fuzzy\Desktop\hand\hand.ino: In function 'void setup()':

then it gives me other things on the following lines. can y'all tell me what I'm doing wrong here? here is the program I've put together so far.

#include <Servo.h>

// Define the number of servos
#define SERVOS 5

// Define number of states
#define STATES 3

//Create the servo objects.
Servo myservo[SERVOS]

// Attach servos to digital pins on the Arduino
int Servo_pins[SERVOS] = {3,5,6,9,10};

// Potential angle values of the servos in degrees
int angle_states[STATES] = {180,90,0};

void setup() {
 for (int i = 90; i < SERVOS; i++) {
  // Attach the servo to the servo object
  Servo[i].attach(servo_t[i]);

  // Wait 500 milliseconds
  delay(500);
 }
}

void loop() {

//Move in one direction.
for(int i=0; i < STATES; i++) {

  Servo[0].write(angle_states[i]);
  delay(100);
  Servo[1].write(angle_states[i]);
  delay(100);
  Servo[2].write(angle_states[i]);
  delay(100);
  Servo[3].write(angle_states[i]);
  delay(100);
  Servo[4].write(angle_states[i]);
  delay(100);
}

//Move in the other direction.
for(int i = (STATES - 1); i >= 0: i--) {

  Servo[0].write(angle_states[i]);
  delay(100);
  Servo[1].write(angle_states[i]);
  delay(100);
  Servo[2].write(angle_states[i]);
  delay(100);
  Servo[3].write(angle_states[i]);
  delay(100);
  Servo[4].write(angle_states[i]);
  delay(100);
}
}

can y'all tell me what I'm doing wrong here?

The most obvious thing is that you have created an array of servos named myservo then you refer to it wrongly later. To use one of the servos in the array you need to do

    myservo[servoNumber].attach(Servo_pins[servoNumber]);

Also, why does your for loop start at 90 ?

It is difficult to see what else might be wrong because of your mangled code

Please follow the advice on posting code given in Read this before posting a programming question in order to make your sketch easy to follow, download and test

In particular note the advice to Auto format code in the IDE and to use code tags when posting code here as it prevents some combinations of characters in code being interpreted as HTML commands such as italics, bold or a smiley character, all of which render the code useless

If the code exceeds the 9000 character inline limit then attach it to a post

Hi,
Welcome to the forum.

Please read the post at the start of any forum , entitled "How to use this Forum".
OR
https://forum.arduino.cc/index.php?topic=712198.0

Then look down to "code problems" about how to post your code.
Can I suggest you try and control ONE servo, disconnect all but one servo.
Write code JUST for that servo, that way you will learn the program strategy needed to control it.

Have you looked at the Example codes in the Example part of the IDE under SERVO?

Thanks.. Tom... :slight_smile:

thank you UKHeliBob and TomGeorge for telling me where to look to find out how to format my post when sharing code.

Try this as an example of how you might smoothly move multiple servos at a time. It's commented and reasonably understandable:

/*
 * Sketch:  sketch_mar17b.ino
 * Target:  Uno
 *
 */
#include <Servo.h>

#define NUM_SERVOS      5               // Define the number of servos

// Create the servo objects.
Servo myservo[NUM_SERVOS];

// Attach servos to digital pins on the Arduino
uint8_t Servo_pins[NUM_SERVOS] = { 3, 5, 6, 9, 10 };

// Max, min and initial angles and direction of travel
uint8_t grMaxAngles[NUM_SERVOS] = { 180, 180, 180, 180, 180 };
uint8_t grMinAngles[NUM_SERVOS] = { 0, 0, 0, 0, 0 };
uint8_t grInitAngles[NUM_SERVOS] = { 0, 20, 60, 90, 120 };
bool grInitDirs[NUM_SERVOS] = { true, false, true, false, true };

typedef struct
{
    Servo       *servo;
    uint8_t     pin;
    uint8_t     maxAngle;
    uint8_t     minAngle;
    uint8_t     currAngle;
    bool        bDir;
    uint32_t    timeServo;    
    
}sServos_t;

sServos_t 
    servoCmd[NUM_SERVOS];

void setup() 
{    
    initServoStruct();

}//setup

void loop() 
{
    static uint8_t
        servoIndex = 0;
    uint32_t
        timeNow = micros();

    //each servo is updated every 20mS
    if( (timeNow - servoCmd[servoIndex].timeServo) >= 20000ul )
    {
        //save the time for the next update
        servoCmd[servoIndex].timeServo = timeNow;
        //are we counting up?
        if( servoCmd[servoIndex].bDir == true )
        {            
            //yes; bump the current servo angle
            servoCmd[servoIndex].currAngle += 1;
            //if we reach the limit, change the direction            
            if( servoCmd[servoIndex].currAngle == servoCmd[servoIndex].maxAngle )
                servoCmd[servoIndex].bDir = false;
        }//if
        else
        {
            //we're decreasing the servo angle so decrement each pass
            servoCmd[servoIndex].currAngle -= 1;
            //when we reach the minimum angle, change the direction
            if( servoCmd[servoIndex].currAngle == servoCmd[servoIndex].minAngle )
                servoCmd[servoIndex].bDir = true;
            
        }//else

        //update the servo with the updated current angle
        servoCmd[servoIndex].servo->write( servoCmd[servoIndex].currAngle );
                
    }//if

    //each pass through loop() we service another servo
    servoIndex++;
    if( servoIndex == NUM_SERVOS )
        servoIndex = 0;

}//loop

void initServoStruct( void )
{
    //initialize the servo control structure
    for( uint8_t i=0; i<NUM_SERVOS; i++ )
    {
        //pointer to the servo object
        servoCmd[i].servo = (Servo *)&myservo[i];
        //the servo object's assigned pin
        servoCmd[i].pin = Servo_pins[i];
        //attach the pin to the servo
        servoCmd[i].servo->attach( servoCmd[i].pin );
        //set the max and min angles for each servo
        servoCmd[i].maxAngle = grMaxAngles[i];
        servoCmd[i].minAngle = grMinAngles[i];
        //set the initial position
        servoCmd[i].currAngle = grInitAngles[i];
        //and the direction of travel
        servoCmd[i].bDir = grInitDirs[i];
        //initialize each servo's adjustment timer to zero
        servoCmd[i].timeServo = 0ul;

        servoCmd[i].servo->write( servoCmd[i].currAngle );
        
    }//for
    
}//initServoStruct

hello all, I want to thank everyone for their input on helping me figure out a way to fix the programing issues I was having. a few days ago I had been speaking with a coworker about the programing issue I was having and he had suggested that I not try to modify the available programs, but just modify the servos. and I decided to look into it this morning. From what I saw it's not actually possible to modify the servos in the manner that was suggested to me, but there is an inline device that can be hooked to the servo that reverses the signal sent to the servo, so instead of it going 0-180, it goes 180-0. Since that fixes the issue I was running into without having to make a custom program, I'm going to go that route and use a standard program that is readily available online. This makes things simpler and more in compliance with the K.I.S.S. principle.

Hi,
Why don't you do it in software?
Did you read the solution in post#1?

Have you loaded a Servo library example and played with the code on a single servo?

JUST try ONE servo with a simple code.

Tom.. :slight_smile:

Blackfin, I just tried your program, it looks to be working fairly well too, thank you. I hadn't tried it because so many other things going on. I hooked the servos for my mark 5 prototype to the nano and they are moving great so far. I'll hook my mark 4 prototype and see how well it works. I'll try to link a video if it forks well.

Incase y'all are wondering, there's about 10 or so design changes between these 2 versions, most of them involved in stabilizing the servos to allow the fingers to open and close smoothly.

edit
here is a link to a video of the fingers moving.
testing the program suggested by Blackfin

wimismith:
Blackfin, I just tried your program, it looks to be working fairly well too, thank you. I hadn't tried it because so many other things going on. I hooked the servos for my mark 5 prototype to the nano and they are moving great so far. I'll hook my mark 4 prototype and see how well it works. I'll try to link a video if it forks well.

Incase y'all are wondering, there's about 10 or so design changes between these 2 versions, most of them involved in stabilizing the servos to allow the fingers to open and close smoothly.

edit
here is a link to a video of the fingers moving.
testing the program suggested by Blackfin

Thanks for the vid/feedback. Looks like there's some mechanical interference between the "thumb" and the index finger.

There may also be some non-linearities or play in the linkages that might be causing some of the "jerky" motion. But overall it looks cool. Nice work.

i think that's just because the servos looked like they were moving randomly. i finally got a program thrown together that "works" the fingers in unison, and the thumb doesn't interfere with the index with that program. i think the only issues i'm seeing now are caused by the servo to the bird finger not seeming to have a full range of motion. i think the servo arm has worked loose, but i'll have to do a full teardown to be sure. in the meantime i'm going to finish building the mark 5 hand, which uses servos with metal gears, so they should be able to hold up better.

This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.