CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to CCS Technical Support

Servo controller problem
Goto page 1, 2  Next
 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
filjoa



Joined: 04 May 2008
Posts: 260

View user's profile Send private message

Servo controller problem
PostPosted: Sat May 09, 2009 1:00 pm     Reply with quote

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







PostPosted: Sat May 09, 2009 2:23 pm     Reply with quote

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

View user's profile Send private message

PostPosted: Sat May 09, 2009 8:02 pm     Reply with quote

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

View user's profile Send private message

PostPosted: Mon May 11, 2009 6:30 pm     Reply with quote

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

View user's profile Send private message

PostPosted: Mon May 11, 2009 10:53 pm     Reply with quote

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 Wink
filjoa



Joined: 04 May 2008
Posts: 260

View user's profile Send private message

PostPosted: Sat Sep 12, 2009 10:18 am     Reply with quote

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

View user's profile Send private message

PostPosted: Mon Sep 14, 2009 10:39 am     Reply with quote

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

View user's profile Send private message

PostPosted: Fri Oct 23, 2009 6:06 am     Reply with quote

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

View user's profile Send private message

PostPosted: Fri Oct 23, 2009 2:17 pm     Reply with quote

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 Wink
filjoa



Joined: 04 May 2008
Posts: 260

View user's profile Send private message

PostPosted: Fri Oct 23, 2009 6:34 pm     Reply with quote

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

View user's profile Send private message

PostPosted: Sat Oct 24, 2009 3:41 pm     Reply with quote

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. Wink
filjoa



Joined: 04 May 2008
Posts: 260

View user's profile Send private message

PostPosted: Fri Nov 27, 2009 6:05 am     Reply with quote

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

View user's profile Send private message

PostPosted: Fri Nov 27, 2009 7:47 am     Reply with quote

If TIMER3 can trigger an interrupt on overflow then yes. Wink
filjoa



Joined: 04 May 2008
Posts: 260

View user's profile Send private message

PostPosted: Fri Dec 04, 2009 4:49 pm     Reply with quote

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

View user's profile Send private message

PostPosted: Sat Dec 05, 2009 3:13 pm     Reply with quote

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!
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Goto page 1, 2  Next
Page 1 of 2

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group