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

"for" loop problem

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



Joined: 17 Oct 2005
Posts: 116

View user's profile Send private message

"for" loop problem
PostPosted: Fri May 05, 2006 6:20 am     Reply with quote

I've got a couple of "for" loops that I think should run one after the other but they seem to form some type of nested loop that runs forever. If printf statements are substituted for the two servo position functions the for loops run as expected. Also, if either for loop is removed , the remaining loop runs as expected.

Any idea on what I'm doing wrong here?

Thanks, Harry
Code:
#include <16F877A.h>
#fuses HS, NOWDT, NOPROTECT, PUT, NOLVP
#use delay(clock=20000000)
#use RS232(BAUD=38400,XMIT=PIN_C6,RCV=PIN_C7)

#define servo PIN_B4

void centre_servo()
{
  output_high(servo);
  delay_us(1500);
  output_low(servo);
  delay_ms(18);
}

void move_servo()
{
  output_high(servo);
  delay_us(1000);
  output_low(servo);
  delay_ms(18);
}
//Main Program============================================

main()
{
 int i, j;

 for(i=0;i<25;i++)
  centre_servo();
 
 for(j=0;j<25;j++)
  move_servo();
}
ckielstra



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

View user's profile Send private message

PostPosted: Fri May 05, 2006 6:35 am     Reply with quote

A single call to either of the servo routines takes about 20ms. You call each function 25 times in succession: 25 * 20ms = 450ms.
It must be a fast servo you are using. Try increasing the loop counters from 25 to a larger value, for example 100.

It is good practice in embedded microcontroller software to add an endless loop at the end of your main. You never know what kind of code your program is going to run into when it reaches the end of main. Most CCS compiler versions add a sleep instruction at the end of your program but you can't count on this and sometimes this is unwanted behavior.
Code:
void main()
{
  // Do your stuff

  while(1) ;    // loop forever
}
Harry Mueller



Joined: 17 Oct 2005
Posts: 116

View user's profile Send private message

PostPosted: Fri May 05, 2006 7:00 am     Reply with quote

ckielstra wrote:
A single call to either of the servo routines takes about 20ms. You call each function 25 times in succession: 25 * 20ms = 450ms.

I'm sorry, I don't understand your point here. The servo should move to the position indicated and then hold. This should take 450 mS or roughly 1/2 second. Then the code should move to the second function and the servo should move to the new position, again in 450 mS.

ckielstra wrote:

It must be a fast servo you are using. Try increasing the loop counters from 25 to a larger value, for example 100.

It's actually a very slow servo.....22sec./60deg. I've found that this type of servo will move from one extreme position to another in less than 25 pulses. BTW, I tried 100 and it didn't change the outcome.

ckielstra wrote:

It is good practice in embedded microcontroller software to add an endless loop at the end of your main. You never know what kind of code your program is going to run into when it reaches the end of main. Most CCS compiler versions add a sleep instruction at the end of your program but you can't count on this and sometimes this is unwanted behavior.


Thanks, I've put that in my code.
ckielstra



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

View user's profile Send private message

PostPosted: Fri May 05, 2006 7:20 am     Reply with quote

I have to admit I don't know a lot about servo's.

Quote:
Thanks, I've put that in my code.
And did it help to improve things?
If not, is it possible the PIC is resetting due to voltage spikes caused by the servo's?
treitmey



Joined: 23 Jan 2004
Posts: 1094
Location: Appleton,WI USA

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

PostPosted: Fri May 05, 2006 7:49 am     Reply with quote

If you have CCP1 and CCP2 available you may be better off using the IRQ approach to producing the wavformes.
Look at servos.c in the drivers section. I riped it appart and remade it to
make waveform for the 1mS to 2mS pulse in a 20mS period type of servo.

I would post my redesigned code to the library,.. but I don't know the extent of my copy or re-write.. so I don't know if it falls under the CCS copyright.

The timing stuff at the top is what is cool. I then toggle the pin high for
1-2mS and off for the rest of the 20mS. 1-2mS selects the position of the servo.
Harry Mueller



Joined: 17 Oct 2005
Posts: 116

View user's profile Send private message

PostPosted: Fri May 05, 2006 7:59 am     Reply with quote

ckielstra wrote:
And did it help to improve things?
If not, is it possible the PIC is resetting due to voltage spikes caused by the servo's?


No, The while(1) statement didn't change anything. But possibly the PIC is resetting, that might explain the behavior.

The puzzle then becomes why does the PIC reset on the second servo function but not the first.

Harry
TIMT



Joined: 02 Sep 2005
Posts: 49
Location: Nottingham, UK

View user's profile Send private message

PostPosted: Fri May 05, 2006 8:14 am     Reply with quote

Hi I'm a bit of a newbe myself, but don't you need to declare prototypes for each of your two functions before MAIN before using them?


Tim.
_________________
Tim
Harry Mueller



Joined: 17 Oct 2005
Posts: 116

View user's profile Send private message

PostPosted: Fri May 05, 2006 8:18 am     Reply with quote

I guess the PIC was resetting.

I was powering the servo off the board. I tried powering the servo with a separate battery and common ground and it started working.

Thanks for pointing me in the right direction. Harry
Harry Mueller



Joined: 17 Oct 2005
Posts: 116

View user's profile Send private message

PostPosted: Fri May 05, 2006 8:24 am     Reply with quote

treitmey wrote:
If you have CCP1 and CCP2 available you may be better off using the IRQ approach to producing the wavformes.


Thanks Treitmey, I've actually got code that does that. I was just playing around with some servo timing functions when I ran into this problem.

TIMT, the functions only have to be declared if they follow the main() program. I agree, it's probably neater that way.

Regards, harry
rnielsen



Joined: 23 Sep 2003
Posts: 852
Location: Utah

View user's profile Send private message

PostPosted: Fri May 05, 2006 8:32 am     Reply with quote

One word of advice, don't use delay commands unless absolutely necessary. It is better to have the timers taking care of the output_high's and output_low's. I've written code to control a step/direction servo and the timers made it easy to keep the pulse frequency steady and also create a ramp up/down sequence.

Anytime you use a delay you are causing the PIC to simply sit there and twiddle it's 'thumbs' while it waits for the delay to finish. Use your timers to keep track of the time so the PIC can be off doing other things while it waits.

Ronald
Harry Mueller



Joined: 17 Oct 2005
Posts: 116

View user's profile Send private message

PostPosted: Fri May 05, 2006 8:49 am     Reply with quote

Thanks Ronald, good point.

Harry
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