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

PWM: no way to move a servo

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
navajo



Joined: 21 Apr 2006
Posts: 4
Location: Spain

View user's profile Send private message Visit poster's website

PWM: no way to move a servo
PostPosted: Tue May 02, 2006 2:00 pm     Reply with quote

Hello everybody,

After check many post in this and other forums I still can not move my servo with the program I have written.

I have a breadboad with a PIC 16F877A and a 4MHz xtal. I
I want to move the servo left and right depending of the state of inputs RA0 and RA1. If I have the combination 01 the servo should move in one way and 01 in the other way.

I would appreciate if somebody could take a look into my code. It is built with 0 error and it is my first C program for a PIC.

#include <16F877A.h>

void main()
{
set_tris_a(0x03); // Input (0000 0011). Left-right control
set_tris_c(0x00);
setup_ccp1(CCP_PWM); // CCP as PWM
while (1)
{
switch (PIN_A0, PIN_A1)
{
case (PIN_A0==0) & (PIN_A1==1): // 01 turn right
{
output_low(PIN_C2);
setup_timer_2(T2_DIV_BY_4, 499, 1);
output_low(PIN_C2); // PIN C2=0 set_pwm1_duty(70);
output_high(PIN_C2); // PIN C2=1
}
case (PIN_A0==1) & (PIN_A1==0): // 10 turn left
{
output_low(PIN_C2);
setup_timer_2(T2_DIV_BY_4, 249, 1);
output_low(PIN_C2); // PIN C2=0
set_pwm1_duty(70);
output_high(PIN_C2); // PIN C2=1
}
default: // If 01 or 10 then STOP
{
output_low(PIN_C2);
setup_timer_2(T2_DIV_BY_4, 249, 1);
set_pwm1_duty(70);
output_high(PIN_C2);
} //default
} //switch
} //while
} //void


I have an old oscilloscope and I get a period signal but very different to what I am expecting to have.

Thank you for your help.
andreluizeng



Joined: 04 Apr 2006
Posts: 117
Location: Brasil

View user's profile Send private message Send e-mail MSN Messenger

PostPosted: Tue May 02, 2006 2:17 pm     Reply with quote

what kind of servo are you using ?
aeromodelling position servo ?

for a aeromodelling servo you have to respect the pulse periods if you want to move it to the right or to the left.

the periods is about 20ms and the pulse have to be between 1 and 2ms.

at 1ms it will move to the left, 2ms move to the right, and every step between 1 and 2ms is a position.

ex: a pulse with 1.5ms will position at the center.

got it ?

make sure that your pwm's period is in that range and if ur duty cicle corresponds of a 1~2ms pulse.

regards.
_________________
Andre
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Tue May 02, 2006 2:30 pm     Reply with quote

Look at the .LST file for your program. It's in the project directory.
Most of your switch() statement doesn't produce any code.
Only the default statement produces code. You should not use a
constant in a switch statement, and also don't use a comma.
Look at some C tutorials on the net:

http://www.its.strath.ac.uk/courses/c/subsection3_8_2.html#SECTION0008200000000000000

http://cslibrary.stanford.edu/101/EssentialC.pdf
navajo



Joined: 21 Apr 2006
Posts: 4
Location: Spain

View user's profile Send private message Visit poster's website

PostPosted: Tue May 02, 2006 2:40 pm     Reply with quote

Hi,

Yes I am using a RC servo.
So andreluizeng you mean that to move the servo left I should use something like:

while (1)
{
output_low(PIN_C2);
setup_timer_2(T2_DIV_BY_4, 1(it refers to 1ms), 1);
set_pwm1_duty(70);
output_high(PIN_C2);
}

What I did was to calculate the value of PR2

PR2 = (f_osc / (4*f_pwm*(prediv_TMR2)))-1

using a f_pwm. of 1ms, that is, PR2=(4Mhz / (4*1000*4))-1

and set the result as period, that is why I have 249

About the set_pwm1_duty(70) I dont know how to calculate. I have read many manuals but no explanation.

Thank you andreluizeng
andreluizeng



Joined: 04 Apr 2006
Posts: 117
Location: Brasil

View user's profile Send private message Send e-mail MSN Messenger

PostPosted: Tue May 02, 2006 2:42 pm     Reply with quote

PCM Programmer is right, i forgot to talk about that,

you just use SWITCH if you want to teste the possible values to a variable not for constants.

example of code:

Code:


char Var;

Var = getchar (); // value from rs232

switch (Var)
{
     case 'a'  : bla bla bla bla;
                    break;
     case 'b'  : ble ble ble ble;
                    break;

     default   : bli bli bli bli;
                    break;
}



regards.



[/code]
_________________
Andre
andreluizeng



Joined: 04 Apr 2006
Posts: 117
Location: Brasil

View user's profile Send private message Send e-mail MSN Messenger

PostPosted: Tue May 02, 2006 2:53 pm     Reply with quote

You better write a specific routine for this, i dont like very much to use ccs's pwm to control this type of application.

try to use something like this:

Code:

#define SERVO PIN_X  (you choose which pin)


// values for Direction 1 to 3
void MoveServo (int Direction)
{
     int i;

     if (Direction == 1) // move to the left
     {
           // generate a pwm with period of 20ms and a pulse with 1ms
           for (i = 0; i < 50; i++)
           {
                  output_high (SERVO);
                  delay_ms (1);
                  output_low (SERVO);
                  delay_ms (19);
            }
      }

     if (Direction == 2) // move to the center
     {
           // generate a pwm with period of 20ms and a pulse with 1,5ms
           for (i = 0; i < 50; i++)
           {
                  output_high (SERVO);
                  delay_ms (1); 
                  delay_us (500); // note this is microseconds

                  output_low (SERVO);
                  delay_ms (18);
                  delay_us (500);
            }
      }

     if (Direction == 3) // move to the right
     {
           // generate a pwm with period of 20ms and a pulse with 2ms
           for (i = 0; i < 50; i++)
           {
                  output_high (SERVO);
                  delay_ms (2); 

                  output_low (SERVO);
                  delay_ms (18);
            }
      }

      return;
}


regards.
_________________
Andre
Guest








PostPosted: Tue May 02, 2006 4:33 pm     Reply with quote

Thank you very much andreluizeng and PCM programmer, nice links and much much more easy to work with delay than wirh CCS applications functions.

I will try a new code version.

Thanks again
tavioman



Joined: 22 Feb 2006
Posts: 65

View user's profile Send private message

PostPosted: Tue May 02, 2006 4:33 pm     Reply with quote

PCM programmer wrote:


http://www.its.strath.ac.uk/courses/c/subsection3_8_2.html#SECTION0008200000000000000

http://cslibrary.stanford.edu/101/EssentialC.pdf


Very good tutorials.
Thanks for this links.
navajo



Joined: 21 Apr 2006
Posts: 4
Location: Spain

View user's profile Send private message Visit poster's website

Still no PWM signal generated
PostPosted: Mon May 08, 2006 1:20 am     Reply with quote

Hello again people,

I was working in the idea of andreluizeng. I used his PWM function into my program. I think the main progam section fails. What I want to do is, if pins RA1 and RA0 have 0v or 5v, (that is what I call in the program PIN_A0==1 or PIN_A0==0), the servo should move left , right or stop.

I have check the .lst file and there is almost no code on it.

I would appreciate if you could take a look to ma code and tell me any idea to keep working.

Thanks a lot everybody



#include <16F877A.h>
#define SERVO PIN_C2
#use delay(clock=4000000)


void MoveServo (int Direction);



/*------------------ Main Program --------------------*/

void main(void)
{
while (1)
{
if (PIN_A0==1 && PIN_A1==0) //if pin RA0=1 and RA1=0 turn left
MoveServo(1);

if (PIN_A0==0 && PIN_A1==1) //if pin RA0=1 and RA1=1 turn right
MoveServo(3);

if (PIN_A0==0 && PIN_A1==0) //if pin RA0=0 and RA1=0 stop
MoveServo(2);
}
}



/*-------------------- FUNCTIONS ---------------------*/

void MoveServo (int Direction) // values for Direction 1 to 3
{
int i;

if (Direction == 1) // move to the left
{
// generate a pwm with period of 20ms and a pulse with 1ms
for (i = 0; i < 50; i++)
{
output_high (SERVO);
delay_ms (1);
output_low (SERVO);
delay_ms (19);
}
}

if (Direction == 2) // move to the center
{
// generate a pwm with period of 20ms and a pulse with 1,5ms
for (i = 0; i < 50; i++)
{
output_high (SERVO);
delay_ms (1);
delay_us (500); // note this is microseconds

output_low (SERVO);
delay_ms (18);
delay_us (500);
}
}

if (Direction == 3) // move to the right
{
// generate a pwm with period of 20ms and a pulse with 2ms
for (i = 0; i < 50; i++)
{
output_high (SERVO);
delay_ms (2);

output_low (SERVO);
delay_ms (18);
}
}

return;
}
[/code]
ckielstra



Joined: 18 Mar 2004
Posts: 3680
Location: The Netherlands

View user's profile Send private message

PostPosted: Mon May 08, 2006 3:16 am     Reply with quote

Did you have a look at your compiler output messages? Compiling your program i got:
Quote:
>>> Warning 203 "C:\Mijn progs\Test_0\main.c" Line 16(1,1): Condition always TRUE
>>> Warning 204 "C:\Mijn progs\Test_0\main.c" Line 18(1,1): Condition always FALSE
>>> Warning 204 "C:\Mijn progs\Test_0\main.c" Line 21(1,1): Condition always FALSE
>>> Warning 204 "C:\Mijn progs\Test_0\main.c" Line 24(1,1): Condition always FALSE


All your if statements fail because you are comparing the constant value PIN_Ax instead of the value at the input pin. Change these lines to
Code:
if ((input(PIN_A0)==1) && (input(PIN_A1)==0))
etc
navajo



Joined: 21 Apr 2006
Posts: 4
Location: Spain

View user's profile Send private message Visit poster's website

Working
PostPosted: Mon May 08, 2006 3:34 am     Reply with quote

ckielstra, thank you very much to you and all people how helped me. The servo is now working.

Thank you very much.
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
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