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

timer2 setup and motor

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



Joined: 27 Apr 2009
Posts: 50

View user's profile Send private message AIM Address

timer2 setup and motor
PostPosted: Fri Jul 29, 2011 4:30 am     Reply with quote

Hi, I'm using pic16f877a with a 20MHz crystal clock. I try to control the angle of the motor by using PWM generated by the pic into h-bridge ic and a potentiometer as my feedback. I have difficulty in determining the setup for the timer. I read from the datasheet timer2 is an 8 bit, thus does it means the highest PR2 can be set is 255 and I dont understand about the PWM resolution. The datasheet for the h-bridge ic states the switching freq up to 5kHz (Do I need to consider this informition when setup the timer). There several configuration been tried for timer2 in term of changing the prescale and period. Some of the configuration make the motor produce noise (high pitch), is it something to do with setup. is there actually rule of thumb determining the PWM freq. The motor datasheet can be view at
https://catalog.precisionmicrodrives.com/order-parts/product/212-404-12mm-dc-gearmotor-24mm-type
temtronic



Joined: 01 Jul 2010
Posts: 9245
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Fri Jul 29, 2011 7:06 am     Reply with quote

Since the H-bridge chip is only good to 5KHz, you should only set your PWM timer to max out at 5KHz.
There is a wealth of info in the datasheet for the PIC to figure it out or just 'google' PIC PWM timer calculator and you'll get several hits for online 'tools' to do all the math for you.Kinda cheating though...
nasbyc



Joined: 27 Apr 2009
Posts: 50

View user's profile Send private message AIM Address

PostPosted: Wed Aug 03, 2011 9:08 am     Reply with quote

Hi this my code for the motor and pot as feedback. The duty cycle can be set up up to 255 and my analog input (pot with single turn) reads 0 -255 counts. I already run the program but I can see that the minimum duty cycle can be supply to the motor is 70 so around 29%. What I don't understand is that the duty cycle (U_Signal) is calculated by pid algorithms, do I need to set the min value for pid is 70 or it just that I have to keep tuning the pid value. fyi: the initial position of the motor will give pot reading about 128 count and I need to program it to move max +-8 deg/0.125sec from the initial position. Some suggestion or ideas might be helpful.
Code:

#include <16f877a.h>
#device adc=8
#use delay(clock=20000000)
#fuses hs,noprotect,nowdt,nolvp
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7, parity=N)

void MotorFish_CW(float U_Signal); void MotorFish_CCW(float U_Signal); void MotorFish_Stop (float U_Signal);

void main ()
{

   set_tris_b(0b11100001); // setting B1,B2,B3,B4 as output and others as input
   int value1,Theta_out;
   int Motor_Status;
   
   setup_port_a(ALL_ANALOG);
   setup_adc(ADC_CLOCK_INTERNAL);
   setup_ccp1(CCP_PWM);
   setup_ccp2(CCP_PWM);
   setup_timer_2(T2_DIV_BY_4, 255, 1);
   set_adc_channel(0);
   delay_us(10);
   Motor_Status = 1;
   
   float P_Error = 0;
   float Prev_Error = 0;
   float Acc_Error = 0;
   float I_Error,D_Error,U_Signal;

   float P = 4;
   float I = 0;
   float D = 0;
   float Desired_Angle;
   int16 pwmduty;
   
   Desired_Angle = 136;
   
   MotorFish_Stop(U_Signal);
   
   for(;;)
   {
     
      Theta_out = read_adc();
      printf("Theta_out:%u\n", Theta_out);
      delay_ms(33);

      I_Error = Acc_Error + P_Error;
      P_Error = Desired_Angle - Theta_out;   
      D_Error = (P_Error - Prev_Error);

      U_Signal = P_Error*P + I_Error*I + D_Error*D;
      //pwmduty = (int16)23*(100/255); // random calculation what value would come out, pwmduty = 0000 for all value
     
      printf("P_Error :%f U_Signal:%f  pwmduty = %LX\n", P_Error ,U_Signal, pwmduty );

      Prev_Error = P_Error;
      Acc_Error = Acc_Error + P_Error;
     
      if(U_Signal > 255)
      {
         U_Signal = 255;
      }
      else if(U_Signal < -255)
      {
         U_Signal = -255;
      }
     
      if(U_Signal > 0)
      {
         MotorFish_CW(U_Signal);
         //printf("CW\n");
      }
      else if(U_Signal < 0)
      {
         U_Signal = -1*U_Signal;
         MotorFish_CCW(U_Signal);
         //printf("CCW\n");
      }
      else
         MotorFish_Stop(U_Signal);
   }
 
}

void MotorFish_CW(float U_Signal)
{
   output_low(PIN_B1);
   output_high(PIN_B2);
   set_pwm2_duty(U_Signal);
   delay_ms(555);
}

void MotorFish_CCW(float U_Signal)
{
   output_high(PIN_B1);
   output_low(PIN_B2);
   set_pwm2_duty(U_Signal);
   delay_ms(555);
   
}

void MotorFish_Stop(float U_Signal)
{
   output_low(PIN_B1);
   output_low(PIN_B2);
   set_pwm2_duty(0);
   delay_ms(555);
}
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