Continuous Rot Servo Sine Sweeping

Hello,

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:

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.

// 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() {
  Serial.begin(9600);
  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.println(n);
      myservo.writeMicroseconds(n);
    }
    else
    {   
      Serial.print("writing Angle: ");
      Serial.println(n);
      myservo.write(n);
    }

    readString=""; //empty for next input
  } 
}

winch servo

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 );
analogWrite(ledPin,value);
}

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.

Lefty

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