Go Down

Topic: Continuous Rot Servo Sine Sweeping (Read 5453 times) previous topic - next topic



I have begun a project where I need to establish continuous variance of the servo position, specifically a sinusoidal function of rotational rate over time. Rotating clockwise, the servo needs to speed up from position 90 degrees to maximum speed position 180 degrees, then back to 90 in a sine wave form. I need to program the servo to phase clockwise a certain number of times(Example: 4), pause for the same interval of time that the sweep period took between each sweep at neutral position 90, then sine sweep counter clockwise the same number of times in a continuous loop. May I please receive input on how to make this work with my continuous rotation servo?

Thank you,
Devin J-K


Here is a graphical representation of what I'm moving toward:


My bad, here:


Feb 10, 2013, 06:16 am Last Edit: Feb 10, 2013, 06:52 am by JimboZA Reason: 1
Are you sure you have that right?- you actually want the rotation speed to vary with the sin?

Reason I'm asking is that a point on a circle describes a sine path anyway, in the sense that if you project the point over to a graph on the side, with x-axis as angle, then the y height depends on the angle.

For a constant rotation speed w (lower case omega) , and time t, then: y = sin(wt)

Edit.... ok I typed that while you were posting that pic...


But apart from my previous post....

I've never used a continuous servo, but my understanding is that you don't know its position like you do with a normal servo. If I have it right, the value you send to a continuous servo- which would be the angle (or more correctly a pulse representing the angle) of a normal one- is the continuous servo's speed. So you won't know where it is, unless you use some kind of encoder to keep track of the position.


A continuous rotation servo interprets position as clock speed rather than clock position. So, would I use the code format you sent me for pos instead? If you could help me on the actual coding, that would be best. I do not need a feedback on the servo position, I simply need to accurately control the time, which I believe you sent the basics for that. The position over time graph would look like the half cycle of a sine wave. How do I get the position to sweep sinusoidally from 90 degrees to 180 degrees and from 90 to 0 and back?


Well, given this:

A continuous rotation servo interprets position as clock speed rather than clock position.

I don't know how you can

get the position to sweep sinusoidally from 90 degrees to 180 degrees and from 90 to 0 and back

because you don't know where it is, without an encoder of some kind.

But other members have much more experience with continuous servos than mine, which is nil.


You can use the below servo test code to see what control position will produce a stopped servo and the max rotation speeds (typically 1400us and 1600us, with 1500us the stopped value). The servo speed change may not be linear with respect to the control values supplied.

Code: [Select]

// zoomkat 10-22-11 serial servo test
// type servo position 0 to 180 in serial monitor
// or for writeMicroseconds, use a value like 1500
// for IDE 0022 and later
// Powering a servo from the arduino usually *DOES NOT WORK*.

String readString;
#include <Servo.h>
Servo myservo;  // create servo object to control a servo

void setup() {
  myservo.writeMicroseconds(1500); //set initial servo position if desired
  myservo.attach(7);  //the pin for the servo control
  Serial.println("servo-test-22-dual-input"); // so I can keep track of what is loaded

void loop() {
  while (Serial.available()) {
    char c = Serial.read();  //gets one byte from serial buffer
    readString += c; //makes the string readString
    delay(2);  //slow looping to allow buffer to fill with next character

  if (readString.length() >0) {
    Serial.println(readString);  //so you can see the captured string
    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.print("writing Angle: ");

    readString=""; //empty for next input
Google forum search: Use Google Search box in upper right side of this page.
Why I like my 2005 Rio Yellow Honda S2000  https://www.youtube.com/watch?v=pWjMvrkUqX0

Runaway Pancake

winch servo
"Who is like unto the beast? who is able to make war with him?"
When all else fails, check your wiring!


Thank you, Zoomkat. I will give that code a try and get back on the results with you tomorrow. The particular servo I am using is the SM-S4315R.


Might there be a way to adapt "analogwrite()" to operate at 50 Hz pulse width and integrate "servo.pos" into this?:

void loop()
  float something = millis()/1000.0;
  int value = 128.0 + 128 * sin( something * 2.0 * PI  );



A thing to consider is that a modified servo (for continuous rotation) has very poor 'linearity' over it's then resulting control range, which I think will pay havoc with any attempt to have it follow a sine wave movement.

If a standard servo is said to be linear (over at least) it's 1 msec to 2 msec control range, I think you will find that the modified servo will have reached it's maximum speed in either direction at +/- 20% or less of it's control range from it's 1.5msec mid point stopped state.

I haven't mapped this out as I don't own any modified servos, just normal ones, but have read the reports of others that have mapped out actual speed vs pulse width commands. So it would be prudent for anyone contemplating something like the OP is trying here, to actually run some characterising tests to actual find out the actual speed control range Vs pulse width commands to see where on is starting out at before trying to nail down a algorithm or math functions best to use to meet the control objective.



Zoomkat, if the Arduino is externally powered, the servo should work properly, correct?

Go Up

Please enter a valid email to subscribe

Confirm your email address

We need to confirm your email address.
To complete the subscription, please click the link in the email we just sent you.

Thank you for subscribing!

via Egeo 16
Torino, 10131