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 support@ccsinfo.com

How to operate DC motor and Servo motor simultaneously?

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



Joined: 04 Feb 2012
Posts: 20

View user's profile Send private message

How to operate DC motor and Servo motor simultaneously?
PostPosted: Sat Mar 10, 2012 10:38 am     Reply with quote

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

View user's profile Send private message

PostPosted: Sat Mar 10, 2012 2:54 pm     Reply with quote

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

View user's profile Send private message AIM Address

PostPosted: Sat Mar 10, 2012 3:26 pm     Reply with quote

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

View user's profile Send private message

PostPosted: Sun Mar 11, 2012 2:05 am     Reply with quote

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

View user's profile Send private message

PostPosted: Sun Mar 11, 2012 2:25 am     Reply with quote

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

View user's profile Send private message

Interrupts and delay()
PostPosted: Sun Mar 11, 2012 10:33 am     Reply with quote

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

View user's profile Send private message

PostPosted: Sun Mar 11, 2012 11:10 am     Reply with quote

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