# How to make a stepper motor's speed follow a sine wave

I'm trying to have the rotational speed of a stepper follow that of a sine wave with a period of x seconds. So it starts at a speed of 0 at 0°, picks up and peaks at 90°, slows back down to 0 at 180°, back up to peak speed at 270°, and back to 0 at 360°, if that makes sense. I'm trying to have the period of the rotation adjustable as well.

Right now I'm having trouble even getting it to spin with what I have now. if I start at 0 speed it doesn't step and therefore doesn't continue with the sketch, or at least I think that's what's happening. Any advice on how to do this would be appreciated.

I'm using the equation (topSpeed) * sin((pi * time) / period) for the wave.

``````#include <Stepper.h>

const int stepsPerRevolution = 200.000;
const float pi = 3.14159265358979;
const int period = 5; // Seconds
const int topSpeed = 100; // RPM

Stepper myStepper(stepsPerRevolution, 8, 9, 10, 11);

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

void loop() {
for (int tStart = millis(); (millis()-tStart) < period;) {
float speed = topSpeed * (sin((pi * (millis() / 1000.000)) / period));

if (speed = 0) {
myStepper.setSpeed(1);
myStepper.step(1);
} else {
myStepper.setSpeed(speed);
myStepper.step(1);
}
}
}
``````
• Checking for equality in an if statement needs `==`, not `=`, which is a assignment Commented Mar 11 at 7:53

Disclaimer: This is not intended to be a complete answer, it is only meant to help you with the math.

I find a contradiction in the problem statement:

it starts at a speed of 0 at 0°, picks up and peaks at 90°, slows back down to 0 at 180° [...]

If the speed is a sinusoidal function, then at this point you have completed the positive part of the period. The speed will now become negative (i.e. the stepper will move backwards), and remain negative for the second half of the period.

back up to peak speed at 270°, and back to 0 at 360°

No. It will reach peak (negative) speed at 90°, and back to zero speed at 0°.

If you really want the stepper to turn always in the same direction, the speed cannot be sinusoidal. What you can do instead is use a sinusoidal function with an offset, such that the speed fluctuates between zero and some maximum, instead of fluctuating between ±maximum.

The graph below represents speed as a function of time. The first curve (“sine”) is a movement that rocks back and forth like: 0° → 90° → 180° → 90° → 0°. The “shifted sine” curve is a continuous rotation doing a full revolution with a speed that is always non-negative.

If you want to properly describe the movement, you should integrate the speed in order to find the (angular) position as a function of time. You will find a continuous ramp (because of the shift in the speed) superimposed with a sinusoidal movement, as in this graph:

If that may help, I did the integration for you and found this formula:

angle = 360° × (t/T − sin(4πt/T)/(4π))

where t is the current time and T the rotational period. This can then be differentiated to get the speed:

speed = 360°/T × (1 − cos(4πt/T))