Arduino Programming for Servo motor

Click For Summary
SUMMARY

This discussion focuses on programming an Arduino microcontroller to control a servo motor's motion using a sinusoidal function rather than linear increments. The original code utilizes the Servo library and demonstrates how to create smooth motion by modifying the position variable with a sine function. Key suggestions include using the formula myservo.write(40 * sin(PI * pos / 80)) to achieve the desired motion from 0 to 40 degrees and back. Additionally, the frequency of the servo's operation can be adjusted by changing the number of increments or the delay time in the loop.

PREREQUISITES
  • Arduino programming basics
  • Understanding of the Servo library in Arduino
  • Knowledge of trigonometric functions, specifically sine
  • Familiarity with control structures in programming (e.g., loops)
NEXT STEPS
  • Research how to implement non-linear motion control in Arduino projects
  • Learn about the Arduino delay() function and its impact on servo performance
  • Explore advanced servo control techniques using PID controllers
  • Investigate how to optimize loop execution time for real-time applications
USEFUL FOR

Arduino enthusiasts, hobbyists working on robotics projects, and developers looking to implement smooth motion control for servo motors.

pyroknife
Messages
611
Reaction score
4
Hi all. I am working on a project that requires using an arduino microcontroller to control the motion of a servo motor.

The original code is of the form:
#include <Servo.h>

Servo myservo; // create servo object to control a servo
// a maximum of eight servo objects can be created

int pos = 0; // variable to store the servo position

void setup()
{
myservo.attach(9); // attaches the servo on pin 9 to the servo object
}


void loop()
{
for(pos = 0; pos <= 40; pos += 1) // goes from 0 degrees to 180 degrees
{ // in steps of 1 degree
myservo.write(pos); // tell servo to go to position in variable 'pos'
delay(15); // waits 15ms for the servo to reach the position
}
for(pos = 40; pos>=0; pos-=1) // goes from 180 degrees to 0 degrees
{
myservo.write(pos); // tell servo to go to position in variable 'pos'
delay(15); // waits 15ms for the servo to reach the position
}
}


but the problem is I don't want the motor's motion to behave linearly (constant increments of the pos variable). My desired motion is a sinusoidal like function.
Does anyone have any suggestions on how to approach this?
I am quite new to programming, especially with microcontrollers.
 
Engineering news on Phys.org
If you want to keep it taking 40 increments from 0 to 180 and 40 increments from 180 back to 0 then

for(pos = 0; pos < 80; pos ++)
{
float pos_sin = abs(sin(2*PI*pos/80))
myservo.write(pos_sin)
}

Might want to double check what scaling myservo.write wants, as this is it will get a floating point 0 .. 1 where before you were giving it an integer 0..40
 
Floid said:
If you want to keep it taking 40 increments from 0 to 180 and 40 increments from 180 back to 0 then

for(pos = 0; pos < 80; pos ++)
{
float pos_sin = abs(sin(2*PI*pos/80))
myservo.write(pos_sin)
}

Thanks for the reply!
I actually want the servo motor to go from 0deg to 40deg and back to 0 deg and then repeat. That is what I am calling one full cycle.
 
Well in that case basically just multiply pos_sin * 40 once you calculate it. Also just use PI so that you go from sin(0) -> sin(PI/2) -> sin(PI) which takes you from 0*40 -> 1*40 -> 0*40 (full cycle from 0 to 40 to back again.

for(pos = 0; pos < 80; pos ++)
{
float pos_sin = sin(PI*pos/80)
myservo.write(40*pos_sin)
}

Depending on if you want to end on 0 or right before 0 make pos <= 80 instead of pos < 80.

Also the 80 really has no significance now, you could make it any number depending on the resolution you want (be sure to change it in both places if you did change it).
 
Floid said:
Well in that case basically just multiply pos_sin * 40 once you calculate it. Also just use PI so that you go from sin(0) -> sin(PI/2) -> sin(PI) which takes you from 0*40 -> 1*40 -> 0*40 (full cycle from 0 to 40 to back again.

for(pos = 0; pos < 80; pos ++)
{
float pos_sin = sin(PI*pos/80)
myservo.write(40*pos_sin)
}
By using this, it is difficult to specify the frequency of operation?
 
Well, the frequency is going to be dependent on how fast the for loop gets called. I left out the delay you had in your original program but if you need it for servo settling time then if you assume each iteration of the loop has a 15ms delay:

80 increments per cycle (from my code) * 15ms delay = 1.2 seconds to make a fully cycle so you are at a little less than 1Hz operation. If you want to increase / decrease that frequency then you either need to change the increments per cycle or the delay per cycle. So for example if you want to double the frequency cut the increments per cycle in half.

Like most systems you end up trading resolution (a bunch of increments) for speed. You have to find the happy medium you need.
 
Floid said:
Well, the frequency is going to be dependent on how fast the for loop gets called. I left out the delay you had in your original program but if you need it for servo settling time then if you assume each iteration of the loop has a 15ms delay:

80 increments per cycle (from my code) * 15ms delay = 1.2 seconds to make a fully cycle so you are at a little less than 1Hz operation. If you want to increase / decrease that frequency then you either need to change the increments per cycle or the delay per cycle. So for example if you want to double the frequency cut the increments per cycle in half.

Like most systems you end up trading resolution (a bunch of increments) for speed. You have to find the happy medium you need.

Okay, thanks a bunch. I'll give this a try.
 
The abs is not necessary right, for my case?
 
Out of curiosity, instead of using a for loop, could you just write a sin function and have that drive the motion instead of using a loop?
 

Similar threads

  • · Replies 5 ·
Replies
5
Views
4K
  • · Replies 8 ·
Replies
8
Views
7K
Replies
1
Views
4K
  • · Replies 2 ·
Replies
2
Views
3K
  • · Replies 4 ·
Replies
4
Views
3K
  • · Replies 3 ·
Replies
3
Views
7K
Replies
1
Views
2K
  • · Replies 85 ·
3
Replies
85
Views
10K
  • · Replies 1 ·
Replies
1
Views
3K
  • · Replies 8 ·
Replies
8
Views
2K