View previous topic :: View next topic |
Author |
Message |
Harry Mueller
Joined: 17 Oct 2005 Posts: 116
|
"for" loop problem |
Posted: Fri May 05, 2006 6:20 am |
|
|
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
|
|
Posted: Fri May 05, 2006 6:35 am |
|
|
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
|
|
Posted: Fri May 05, 2006 7:00 am |
|
|
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
|
|
Posted: Fri May 05, 2006 7:20 am |
|
|
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
|
|
Posted: Fri May 05, 2006 7:49 am |
|
|
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
|
|
Posted: Fri May 05, 2006 7:59 am |
|
|
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
|
|
Posted: Fri May 05, 2006 8:14 am |
|
|
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
|
|
Posted: Fri May 05, 2006 8:18 am |
|
|
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
|
|
Posted: Fri May 05, 2006 8:24 am |
|
|
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
|
|
Posted: Fri May 05, 2006 8:32 am |
|
|
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
|
|
Posted: Fri May 05, 2006 8:49 am |
|
|
Thanks Ronald, good point.
Harry |
|
|
|