View previous topic :: View next topic |
Author |
Message |
filjoa
Joined: 04 May 2008 Posts: 260
|
Servo controller problem |
Posted: Sat May 09, 2009 1:00 pm |
|
|
Hi
I start now my experience with servos, but I have some problems.
How I can calculate delays? I think which my servos work like that 0º=1.5ms; -90º=1ms; 90º=2ms.
I make this simple program, it work but I don't know if my delays stay correct:
Code: |
#include <18F252.h>
#fuses HS,NOWDT,NOPROTECT,NOLVP,BROWNOUT,STVREN
#use delay(clock=20000000)
#use rs232(baud=115200,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=8)
#define servo PIN_B6
void main ()
{
int8 i;
while (TRUE)
{
for (i=0;i<=30;i++) //+- 0º 1.5ms
{
output_high(servo);
delay_us(1250);
output_low(servo);
delay_ms(10);
}
delay_ms(2000);
for (i=0;i<=30;i++) //+- -90º 1ms
{
output_high(servo);
delay_us(750);
output_low(servo);
delay_ms(10);
}
delay_ms(2000);
for (i=0;i<=30;i++) //+- +90º 2ms
{
output_high(servo);
delay_us(1750);
output_low(servo);
delay_ms(10);
}
delay_ms(2000);
}
}
|
My idea is I can move servo 90º forward slowly and after for example 2 seconds it return back slowly, but now it stay move very quickly.
Someone can help me? |
|
|
Ttelmah Guest
|
|
Posted: Sat May 09, 2009 2:23 pm |
|
|
Your delays will be fine, but the problem is that when you change the value, the servo will move as fast as it can to the 'new' position. To get a slow movement, you will need to send a sequence of changing delays. You also need to send servo pulses _all the time_. Depending on the servo involved, some will stay still if you stop sending. but most will drift if pulses are not being received. The time between pulses is not generally that critical, so just have an array of different pulse lengths required, and setp through this as you want the servo to change position. So if you wanted to move from -90 to +90, over about a second, then you would need to send 750, then 761, then 772 etc., for your loop. So something like:
Code: |
int 16 delay=750;
while (delay<1750) {
output_high(servo);
delay_us(delay);
output_low(servo);
delay_ms(10);
delay+=11;
}
|
This won't by any means be 'perfect', but will get very close (the servo will move a fraction faster at the start than the end).
Best Wishes |
|
|
filjoa
Joined: 04 May 2008 Posts: 260
|
|
Posted: Sat May 09, 2009 8:02 pm |
|
|
Hi
thanks Ttelmah, now servo work -90 to 90 perfect servo is FUTABA S3001, I need make some adjusts on delays for it make this trajectory.
I write here my code for can help someone:
Code: |
while (TRUE)
{
for (i=0;i<=100;i++) //+- -90º 1ms
{
output_high(servo);
delay_us(300);
output_low(servo);
delay_ms(10);
}
while (delay<2200) {
output_high(servo);
delay_us(delay);
output_low(servo);
delay_ms(10);
delay+=11;
}
delay=300;
delay_ms(2000);
}
|
|
|
|
filjoa
Joined: 04 May 2008 Posts: 260
|
|
Posted: Mon May 11, 2009 6:30 pm |
|
|
Hi
Now I like with two switches move servo step by step.
I have one switch for right and oder for left.
My program now move 180º for right and if I press other switch go 180º for left.
Code: |
#define servo PIN_B7
int16 delay=300;
void right ()
{
while (delay<2200) {
output_high(servo);
delay_us(delay);
output_low(servo);
delay_ms(10);
delay+=11;
}
}
void left ()
{
while (delay>300) {
output_high(servo);
delay_us(delay);
output_low(servo);
delay_ms(10);
delay-=11;
}
}
void main ()
{
int8 i;
while (TRUE)
{
if (input(PIN_B5)==1)
{
right();
}
if (input(PIN_B4)==1)
{
left();
}
}
}
|
I try for it move step by step make this program but it have a strange moviment, sometimes for left and after for right.
Code: |
#define servo PIN_B7
int16 delay=300;
void right ()
{
if (delay<=2200) {
output_high(servo);
delay_us(delay);
output_low(servo);
delay_ms(10);
}
}
void left ()
{
if (delay>=300){
output_high(servo);
delay_us(delay);
output_low(servo);
delay_ms(10);
}
}
void main ()
{
int8 i;
while (TRUE)
{
if (input(PIN_B5)==1)
{
delay+=10;
right();
}
if (input(PIN_B4)==1)
{
delay-=10;
left();
}
}
}
|
Someone can help me? I like press right switch and it move little for right. Press other time and it move more little for right... the same for the left.
kind regards |
|
|
bungee-
Joined: 27 Jun 2007 Posts: 206
|
|
Posted: Mon May 11, 2009 10:53 pm |
|
|
filjoa wrote: |
I try for it move step by step make this program but it have a strange moviment, sometimes for left and after for right.
|
You don't have debounce for your switch inputs, so the strange movement is result of that.
Use code supplied here |
|
|
filjoa
Joined: 04 May 2008 Posts: 260
|
|
Posted: Sat Sep 12, 2009 10:18 am |
|
|
Hi
How I can put servos move slowly on my program? Someone can explain me?
Code: |
#include <18F252.h>
#fuses HS,NOWDT,NOPROTECT,NOLVP,BROWNOUT,STVREN
#use delay(clock=20000000)
#use rs232(baud=115200,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=8)
#define servo PIN_B1
int16 delay;
void one ()
{
int8 i;
delay=300;
for (i=0;i<=100;i++)
{
output_high(servo);
delay_us(delay);
output_low(servo);
delay_ms(10);
}
}
void two ()
{
int8 i;
delay=775;
for (i=0;i<=100;i++)
{
output_high(servo);
delay_us(delay);
output_low(servo);
delay_ms(10);
}
}
void tree ()
{
int8 i;
delay=1250;
for (i=0;i<=100;i++)
{
output_high(servo);
delay_us(delay);
output_low(servo);
delay_ms(10);
}
}
void four ()
{
int8 i;
delay=1725;
for (i=0;i<=100;i++)
{
output_high(servo);
delay_us(delay);
output_low(servo);
delay_ms(10);
}
}
void five ()
{
int8 i;
delay=2200;
for (i=0;i<=100;i++)
{
output_high(servo);
delay_us(delay);
output_low(servo);
delay_ms(10);
}
}
//################################ MAIN #############################
void main ()
{
while (TRUE)
{
one();
delay_ms(2000);
two();
delay_ms(2000);
tree();
delay_ms(2000);
four();
delay_ms(2000);
five();
delay_ms(2000);
four();
delay_ms(2000);
tree();
delay_ms(2000);
two();
delay_ms(2000);
}
}
|
kind regards |
|
|
filjoa
Joined: 04 May 2008 Posts: 260
|
|
Posted: Mon Sep 14, 2009 10:39 am |
|
|
Hi
I edit main function to this:
Code: |
void main ()
{
char C;
while (TRUE)
{
C=getc();
switch (C) {
case '1' :one(); break;
case '2' :two(); break;
case '3' :tree(); break;
case '4' :four(); break;
case '5' :five(); break;
}
}
}
|
all the program stay the same...
is possible I move my servo more slowly? some one can help me?
kind regards |
|
|
filjoa
Joined: 04 May 2008 Posts: 260
|
|
Posted: Fri Oct 23, 2009 6:06 am |
|
|
hi
To not open other topic with the same subject I put my question on this topic...
Is possible I block servo on a position but continue work with PIC on other functions?
On servo stay connect an coil and if I disconnect power servo rotate...
I like move coil to an position and make other operation at send information to servo for move to other position... is possible with only one PIC?
best regards |
|
|
bungee-
Joined: 27 Jun 2007 Posts: 206
|
|
Posted: Fri Oct 23, 2009 2:17 pm |
|
|
Depending on how much servos you would like to have, the minimal step for servos and how fast your PIC is.
One of better ways to controll servos is interrupt service for servos (timer interrupt)... and in between you do other tasks |
|
|
filjoa
Joined: 04 May 2008 Posts: 260
|
|
Posted: Fri Oct 23, 2009 6:34 pm |
|
|
Hi
PIC is an 18F252 with 20Mhz and I only need control one servo, but need make more processes.
Interrupts to control servos? Interrupts don't only inputs?
You can explain me better this options?
For example:
If I have a cycle while(TRUE) where I read ADC value and print it on terminal when I press key "A"(interrupt on serial port)... how I can fix servo an position?
Code: |
#int_rda
void serial_isr()
{
char C;
int16 adc;
adc=read_adc();
C=getc();
switch(C)
{
case 'A': printf("ADC: %3u",adc); breake;
}
}
void main()
{
enable_interrupts(INT_RB);
enable_interrupts(GLOBAL);
while(TRUE)
{
printf("wait...\n\r");
}
}
|
I write this example direct on forum. I don't compile to see if it don't have errors... but it is to you can explain in this example where I put servo fix on one position.
Best regards |
|
|
bungee-
Joined: 27 Jun 2007 Posts: 206
|
|
Posted: Sat Oct 24, 2009 3:41 pm |
|
|
I have posted an PIC18F4550 Example for driving 8 servos with Timer interrupt. Search for that.
Basically all you do is check on which part of your servo pulse you are. If you're running just one servo that that's even easier and you can get quite good resolution with that if you want.
P.S.: I found the post: http://www.ccsinfo.com/forum/viewtopic.php?p=115112#115112
Look at that, I think you can easily convert that code for your need. |
|
|
filjoa
Joined: 04 May 2008 Posts: 260
|
|
Posted: Fri Nov 27, 2009 6:05 am |
|
|
hi
now I make some changes on my program and use TIMER2 to PWM control.
is possible use TIMER3 to servor control?
best regards |
|
|
bungee-
Joined: 27 Jun 2007 Posts: 206
|
|
Posted: Fri Nov 27, 2009 7:47 am |
|
|
If TIMER3 can trigger an interrupt on overflow then yes. |
|
|
filjoa
Joined: 04 May 2008 Posts: 260
|
|
Posted: Fri Dec 04, 2009 4:49 pm |
|
|
hi
For I have an interruption after x time, what I need find on datasheet? What specification on timers who indicate this?
I read 18f252 datasheet and I don't know what is important to make this interruption. For example on timer0, timer1 and timer3 stay write "asynchronous counter" and "interrupt-on-overflow", this is important to my case?
Only on timer2 I don't see important information...
How I can configure timer1 to have for example an interrupt each 1seg? Don't have any formula?
best regards |
|
|
bungee-
Joined: 27 Jun 2007 Posts: 206
|
|
Posted: Sat Dec 05, 2009 3:13 pm |
|
|
What is the frequency of your PIC. <--- this is the base number for timers then, except if you are using external clock for timer1 or timer3.
The formula for timers is simple.
One timer tick is (1/Frequency)*4
Overflow with prescaler/postscaler=1 is 2^(timer resolution)*Timer tick
You really should buy some book on micro controllers cause from your writing I deducted that you need to learn the micro controller basics! |
|
|
|