View previous topic :: View next topic |
Author |
Message |
Jent
Joined: 04 Feb 2012 Posts: 20
|
How to operate DC motor and Servo motor simultaneously? |
Posted: Sat Mar 10, 2012 10:38 am |
|
|
Hi, I am using PIC18f4550 to control servo motor and dc motor. At first, I testing one by one, they are working well, but when I require to combine the coding together, I'm facing problem.
Either the dc motor can be working or servo motor only... I double check for my coding, I realize the problem because I applied "if and else if" for dc motor and servo motor put together...that's why one can be functional whereas another is not..
But i have no idea to make both working together..below is my coding...Hope someone can guide me...thanks so much....
Code: |
void main()
{
set_tris_b(0b00000011);
set_tris_a(0b00001111);
output_low(SERVO_CONTROL);
output_low(PIN_B2);
output_low(PIN_B3);
set_tris_c(0x00);
output_low(PIN_C1); // Set CCP2 output low
output_low(PIN_C2); // Set CCP1 output low
setup_ccp1(ccp_PWM); // Configure CCP1 in Port C_2 as a PWM
setup_ccp2(ccp_PWM); // Configure CCP2 in Port C_1 as a PWM
setup_timer_2(T2_DIV_BY_4, 150, 1); // Setup for 12.376kHz
set_pwm1_duty(0); // DC mmotor remain 0 duty cycle or stop
set_pwm2_duty(0);
delay_ms(500);
while(true)
{
heading=(HMC6352_read_heading())/10;
lcd_init();
printf(lcd_putc, "\fHead degree=%Lu", heading);
printf(lcd_putc, "\n#Press SW1/2/3/4");
delay_ms(300);
///////////////////////////////control the servo motor turning
if(heading<=10)
{
for(a=0; a<50; a++)
{
output_high(SERVO_CONTROL);
delay_us(1500);
output_low(SERVO_CONTROL);
delay_us(18500);
}
}
else if(heading<=35)
{
for(a=0; a<50; a++)
{
output_high(SERVO_CONTROL);
delay_us(1250);
output_low(SERVO_CONTROL);
delay_us(18750);
}
}
else if(heading<=180)
{
for(a=0; a<50; a++)
{
output_high(SERVO_CONTROL);
delay_us(1125);
output_low(SERVO_CONTROL);
delay_us(18875);
}
}
else if(heading<=325)
{
for(a=0; a<50; a++)
{
output_high(SERVO_CONTROL);
delay_us(1875);
output_low(SERVO_CONTROL);
delay_us(18125);
}
}
else if(heading<=349)
{
for(a=0; a<50; a++)
{
output_high(SERVO_CONTROL);
delay_us(1750);
output_low(SERVO_CONTROL);
delay_us(18250);
}
}
else
{
for(a=0; a<50; a++)
{
output_high(SERVO_CONTROL);
delay_us(1500);
output_low(SERVO_CONTROL);
delay_us(18500);
}
}
/////////////////////////////////////////control dc motor speed
if(!input(SW1)==1) //press SW1 for forward turning 70% duty cycle
{
set_pwm2_duty(70);
set_pwm1_duty(0);
output_high(Green_LED);
output_low(Red_LED);
}
if(!input(SW2)==1) //press SW2 for forward turning 100% duty cycle
{
set_pwm2_duty(100);
set_pwm1_duty(0);
output_high(Green_LED);
output_low(Red_LED);
}
if(!input(SW3)==1) //press SW3 for reverse turning 70% duty cycle
{
set_pwm2_duty(0);
set_pwm1_duty(70);
output_high(Green_LED);
output_low(Red_LED);
}
if(!input(SW4)==1) // press SW4 for dc and servo motor stopped
{
set_pwm2_duty(0);
set_pwm1_duty(0);
output_low(Green_LED);
output_high(Red_LED);
for(a=0; a<50; a++)
{
output_high(SERVO_CONTROL);
delay_us(1500);
output_low(SERVO_CONTROL);
delay_us(18500);
}
}
}
}
|
|
|
|
Mike Walne
Joined: 19 Feb 2004 Posts: 1785 Location: Boston Spa UK
|
|
Posted: Sat Mar 10, 2012 2:54 pm |
|
|
Hi Jent,
Two things:-
(1) A response to the questions asked on your compass topic would be nice.
(2) Your standing so close this one, you can't see the wood for the trees.
Your servo code is sprinkled with delay_us(xxxxx). Delay_us(xxxxx) locks up the processor so that it twiddles is thumbs waiting for the delay to end. You need some means of allowing the processor to do all its tasks is small bites, one after the other. The effect is that the processor APPEARS to be doing all of the tasks at the same time. There's more than one way to do this. My preferred option is to use interrupts.
Mike |
|
|
asmboy
Joined: 20 Nov 2007 Posts: 2128 Location: albany ny
|
|
Posted: Sat Mar 10, 2012 3:26 pm |
|
|
The correct way to produce the delays you want is by using a system timer.
This can be accomplished either by interrupts or polling,
using the overflow flag bit of a given timer, when driven by a suitable
pre- scaled signal from your master clock. |
|
|
Jent
Joined: 04 Feb 2012 Posts: 20
|
|
Posted: Sun Mar 11, 2012 2:05 am |
|
|
thanks so much for Mike Walne and asmboy...
I am totally not good in C programming, can you guide me how to use INTERRUPT? since I've ever learnt with assembly langguage in Motorola 6811, but i never try in PIC..... |
|
|
Jent
Joined: 04 Feb 2012 Posts: 20
|
|
Posted: Sun Mar 11, 2012 2:25 am |
|
|
Quote: |
Your servo code is sprinkled with delay_us(xxxxx). Delay_us(xxxxx) locks up the processor so that it twiddles is thumbs waiting for the delay to end. You need some means of allowing the processor to do all its tasks is small bites, one after the other. The effect is that the processor APPEARS to be doing all of the tasks at the same time. There's more than one way to do this. My preferred option is to use interrupts.
|
Mike, you are totally get my problem.... because of delay, my controller is really to respond quite slow....>.< |
|
|
Mike Walne
Joined: 19 Feb 2004 Posts: 1785 Location: Boston Spa UK
|
Interrupts and delay() |
Posted: Sun Mar 11, 2012 10:33 am |
|
|
The CCS manual gives several examples of how to do interrupts.
In your case you are wanting to eliminate the delay_us(big_number).
Basically you set up the interrupt in your initialisation routine, and write an interrupt routine.
So the whole thing COULD be of the form:-
Code: |
int taskc_counter; // counter for delays in taskc
bit flag; // one bit variable, tells main that action is required
initialise()
{
set_your_timer_of_choice_to_overflow_at_say_~1ms_intervals();
set_your_timer_of_choice_interrupt_on;
set_global_interrupts_on;
}
interrupt_routine_ISR()
{
set_flag;
}
Main()
{
initialise();
while (true)
{
taska();
taskb();
taskc();
}
}
|
Suppose that taska and taskb are quite short, and taskc has the delay in it.
You can leave taska and taskb alone, there is no need to do anything with them, taskc is of the form:-
Code: |
taskc()
{
if (flag_set)
{
reset_flag;
if (taskc_counter == 0)
{
perform_taskc_function();
taskc_counter = required_delay_in_ms;
}
else
{
taskc_counter--;
}
}
}
|
If you've got several routines which need delay_ms(xx), they each have their own counter.
And we're still waiting for a response to the compass issue!!!!!!!
Mike
Last edited by Mike Walne on Sun Mar 11, 2012 2:17 pm; edited 2 times in total |
|
|
SherpaDoug
Joined: 07 Sep 2003 Posts: 1640 Location: Cape Cod Mass USA
|
|
Posted: Sun Mar 11, 2012 11:10 am |
|
|
If you don't really know what interrupts ARE, you should read the interrupt section of the datasheet of your favorite PIC. It will give you the behind-the-scenes understanding to know what interrupts are all about. _________________ The search for better is endless. Instead simply find very good and get the job done. |
|
|
|