View previous topic :: View next topic |
Author |
Message |
sonu2die4
Joined: 10 Aug 2009 Posts: 9
|
Simple Servo Question |
Posted: Mon Sep 21, 2009 12:16 am |
|
|
Hi,
I have tweaked a Futaba S3003servo for continuous rotation. I have created a simple program to turn the servo backwards and then forward.
The forward functions works fine with me when I individually test it. However when I test the backwards function gives a jittery rotation and waits for 1 sec in between the rotation. Also when I try to turn the turn the motor backwards and then forwards it continuously turns backward. For backwards I am using an on time of 0.5ms and an off time of 16 second as it is what works for me.Please help me on this.
Thank You
Vivek
Code: |
#include <16f877a.h>
#fuses HS, NOWDT, NOPROTECT // Set Fuses
#use delay(clock = 1000000) // Synchronize with the Oscillator
#define servo PIN_C0
void forward();
void backwards();
void main()
{
while(1)
{
backwards();
delay_ms(5000);
forward();
delay_ms(5000);
}
}
void forward()
{
output_high(servo);
delay_ms(2);
output_low(servo);
delay_ms(18);
}
void backwards()
{
output_high(servo);
delay_ms(.5);
output_low(servo);
//delay_ms(19.5); // it did not work
delay_ms(16);
}
|
|
|
|
mbradley
Joined: 11 Jul 2009 Posts: 118 Location: California, USA
|
|
Posted: Mon Sep 21, 2009 12:34 am |
|
|
Well first a couple things, servo control is from 1.0 to 2.0 ms, most standards are 1.1 to 1.9. most all with center being 1.5ms
Next use uSeconds instead, so center (off in your case) is 1500, backward will be 1100, and forward will be 1900.
Now, as to your puting pausing for 5seconds, servos only move when commanded, you can not send 1 pulse to it and expect it to go to position, you need to continualy send it pulses at a rate of aprox 50hz, or 20ms that is.
So try this, remember pulses have to be coninious or the servo stops moving.
Code: |
void servoPulse(int16 pw)
{
output_high(servo);
delay_us(pw);
output_low(servo);
delay_us(20000 - pw);
}
void pulseBackward(void)
{
servoPulse(1100);
}
void pulseForward(void)
{
servoPulse(1900);
}
void main(void)
{
int16 cnt;
while (true)
{
cnt = 0;
while (cnt<100) // forward for 2 seconds (2 / .020 = 100)
{
pulseForward(void);
cnt++;
}
cnt = 0;
while (cnt<100) // backward for 2 seconds
{
pulseBackward(void);
cnt++;
}
}
}
|
|
|
|
Guest
|
|
Posted: Mon Sep 21, 2009 6:17 pm |
|
|
Thank You so much mbradley. I really appreciate the prompt reply. However I still have the same problem with which I started. The servo keeps on moving in the forward direction i.e clockwise. I tested the individual backward function. Still the servo keeps on moving in the forward direction. Please help me on this.
Thank You
Vivek |
|
|
vinniewryan
Joined: 29 Jul 2009 Posts: 154 Location: at work
|
|
Posted: Tue Sep 22, 2009 9:55 am |
|
|
I had this problem with a servo in the past, it turned out that the plastic shaft connecting the servos motor to its potentiometer broke.
Try making a simple code like this, to test that the servo is not broken:
Code: |
void main()
{
while (1)
{
// X=1100 to 1900, change based on which direction of rotation you're testing
output_high(servo);
delay_us(X);
output_low(servo);
delay_ms(20);
}
}
|
Also if your #use delay(clock=XXXXXXXXX) is set wrong, then the MS and US delays will be incorrect and the servo will react differently than it's supposed to. |
|
|
ckielstra
Joined: 18 Mar 2004 Posts: 3680 Location: The Netherlands
|
|
Posted: Tue Sep 22, 2009 10:23 am |
|
|
vinniewryan wrote: | Also if your #use delay(clock=XXXXXXXXX) is set wrong, then the MS and US delays will be incorrect and the servo will react differently than it's supposed to. | Which might very well be the cause of the problem: Code: | #fuses HS, NOWDT, NOPROTECT // Set Fuses
#use delay(clock = 1000000) // Synchronize with the Oscillator | The HS fuse is to be used for crystals of 4MHz and higher. For 1 MHz, like here, use the XT fuse. Using the wrong fuse setting can cause the oscillator to work at unexpected frequencies. |
|
|
sonu2die4
Joined: 10 Aug 2009 Posts: 9
|
|
Posted: Wed Sep 23, 2009 10:00 am |
|
|
Thank You vinniewryan and ckielstra. I have changed the fuse to HS and used clock crystal of 8Mhz and 10Mhz for this purpose. It now runs in the reverse direction. I tried
Code: |
#use delay(clock = 10000000) // Synchronize with the Oscillator
|
and
Code: |
#use delay(clock = 8000000) // Synchronize with the Oscillator
|
I have used the values for X from 1700 to 2700. However it still rotates in the reverse direction.
Code: |
void pulseForward(void)
{
servoPulse(X);
}
|
Thank You
Vivek |
|
|
Ttelmah Guest
|
|
Posted: Wed Sep 23, 2009 2:37 pm |
|
|
You do understand, that the value in the #USE DELAY statement, _must_ be set to match your actual hardware. It is not a value you just change to anything you want. You need to look on the crystal that is fitted to _your_ board, and put the value of this into the statement. Unless this is right, the code will effectively develop garbage, in terms of it's timings.
Once that is done, have you verified that your modified servo, works correctly, with a real RC receiver?. Rotating backwards if the stick is in the bottom half of it's travel, and forwards if it is in the top half of the travel.
Vinniewryan's code, should work, if the clock settings are right.
Best Wishes |
|
|
simonrash
Joined: 24 Sep 2009 Posts: 3
|
|
Posted: Thu Sep 24, 2009 6:03 am |
|
|
Just a thought but when you modified the servo and removed the drive from the pot have you set it to a mid point. Even if this is not connected the servo will use the value as a target. |
|
|
sonu2die4
Joined: 10 Aug 2009 Posts: 9
|
Solved |
Posted: Sat Dec 05, 2009 2:13 am |
|
|
The Servos are working Fine now. It was just that they are moving in the opposite directions. I tested them with a servo tester and It appears be fine. Thank You all for your valuable suggestions.
Vivek |
|
|
|