Fluid motion with servo, is it possible?

Hi, I´m working in a project using a servo to move an animatronic tail fish side to side. The servo gave me the move side to side, but not fluid at all.

I want to achive this two things:

1st
I´m trying to achive a fluid tail motion, like a fishswim.

2nd
Need to control the speed of the motion, low-fast.

QUESTION: is it better to try using a DC motor to achive the fluid motion and them try to control speed?, any other suggestion it will be well recieve

Thanks in advance.

KE7GKP, thank for the tip, I followed your advise, and looked for Smoothstep function. do you think it could work with sometihing like this.

for (i = 0; i < N; i++){

v = i / N;
v = SMOOTHSTEP(v);
X = (A * v) + (B * (1 - v));
}

I`m testing the code with a Hitec hs-805BB servo, how I inverse this fuction?

Thanks

Can't see all the source there - could you please post it?

Only an opinion but might be worth consideration.
Ideally you need to use a stepper motor rather than a servo. With the stepper you can define EXACTLY what the motor does with respect to position and speed - two essentials for fluid movement. A servo, unfortunately, is a compromise between position and speed, try to move it too fast or just a little and you will get both overshoot and /or jerkiness. In control system terms, a servo's performance is optimised under one set of conditions, whereas for fluid movement you require optimal performance under many different conditions.

AWOL:
Can't see all the source there - could you please post it?

#define SMOOTHSTEP(x) ((x) * (x) * (3 - 2 * (x))) //SMOOTHSTEP expression.
#include <Servo.h>

Servo myservo; // create servo object to control a servo
int j = 0; //Just an Iterator.
int i = 0; //Just another Iterator.
float A = 0; //Input Min Value
float B = 180; //Input Max Value
float X; //final smoothstepped value
float v; //smoothstep expression variable
float N = 180; //number of steps

void setup() {
Serial.begin(9600); //establish serial connection for debugging
myservo.attach(9); // attaches the servo on pin 9 to the servo object
}

void loop(){

if (i < N) // Keep looping until we hit the pre-defined max number of steps

for (i = 0; i < N; i++){

v = i / N;
v = SMOOTHSTEP(v);
X = (A * v) + (B * (1 - v));
}
{
myservo.write(B); // tell servo to go to position in variable 'B'
}
for (i = 180; i >= N; i++){

v = i / N;
v = SMOOTHSTEP(v);
X = (A * v) + (B * (1 - v));
}
{
myservo.write(A); // move servo1 to 'A'
}
Serial.print(" "); //Puts a space between each line of steps and their corresponding float value
Serial.println(X); // prints the soothstepped value
}

jackrae:
Only an opinion but might be worth consideration.
Ideally you need to use a stepper motor rather than a servo. With the stepper you can define EXACTLY what the motor does with respect to position and speed - two essentials for fluid movement. A servo, unfortunately, is a compromise between position and speed, try to move it too fast or just a little and you will get both overshoot and /or jerkiness. In control system terms, a servo's performance is optimised under one set of conditions, whereas for fluid movement you require optimal performance under many different conditions.

jackrae, thanks for the tips., I ´ll checked about steppers to see if the best option for fluid motion. Any kind of stepper could work, any suggestion?

thanks

You are all doing this the hard way IMO. I would rig up a mechanical bellcrank apparatus, and then a simple constant-speed motor will give perfect sinusoidal motion.

  for (i = 180; i >= N; i++)

Because N = 180, this loop will not end for a LONG time

     {
       myservo.write(A);    // move servo1 to 'A'
     }

These are OUTSIDE the FOR loops so you are doing 180 calculations and moving the servo once? Makes no sense to me.

Serial.print(" "); //Puts a space between each line of steps and their corresponding float value
Serial.println(X); // prints the soothstepped value
}

[/quote]

One could use a continous rotation servo with the bellcrank so the speed of the tail movement could be easily controlled.

johnwasser:

  for (i = 180; i >= N; i++)

Because N = 180, this loop will not end for a LONG time

     {

myservo.write(A);    // move servo1 to 'A'
     }



These are OUTSIDE the FOR loops so you are doing 180 calculations and moving the servo once? Makes no sense to me.

Serial.print(" "); //Puts a space between each line of steps and their corresponding float value
Serial.println(X); // prints the soothstepped value
}

[/quote]

john, your right. I was mixup with the code, I`ll start all over

KE7GKP:

You are all doing this the hard way IMO. I would rig up a mechanical bellcrank apparatus, and then a simple constant-speed motor will give perfect sinusoidal motion.

Exactly what I suggested back in Reply #1. But Pitu never responded or even acknowledged the concept. :~

KE7GKP, as you said, I tried with a mathematical function, like the Smoothstep function. Did you mean something like that?

What you mean with " look-up table to create this more "organic" motion"?

Thanks

KE7GKP:
No, I meant the mechanical solution: the cam or crank or "bellcrank".

Ok, If I use a crank for example, this gives me a sinusoidal motion using a constant speed, but I´m planing to use the motor motion for an animatronic wire tail, so I´m looking to resolve it from the programing instead of using another mechanism, because I have the animatronic wiring already .

Do you think using Smoothstep function could solve that?

Not clear what "that" refers to? Please be more specific.
[/quote]

I mean, If I used in arduino a Smoothstep function for a servo or a stepper gives the same result of sinusoidal motion?, Why you prefer a crank instead of stepper or servo?, is it simpler and gives better results?

Thanks

KE7GKP
I´ll cheked the crank

thanks for the tips