Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

How to control rpm of dc motors by using pwm module in pic16f877a ?

Status
Not open for further replies.

rangerskm

Full Member level 4
Joined
Jan 23, 2013
Messages
199
Helped
0
Reputation
2
Reaction score
0
Trophy points
1,296
Activity points
2,663
I started to study PWM module ,can u explain me about PR,CCP1L ,CCP1H,TIMER2 and the relation between frequency,time period and rpm
 

hi,

i made a project in high schooll like that. but i used ccs c compiler and pic18f4550, but as far as i remember. the frequency doesnt affect your rpm, it just gives an option for your switching devices such as h-bridge mosfets or transistors. you can set your frequency according to your h-bridge devices.

the only thing that changes the rpm of dc motor is duty cycle of pwm. duty cycle is the time your square wave signal stay high. here is a simple example; if duty cycle of a pwm signal is %50; the measured voltage is 2.5v (assuming your supply is 5v) and if it is %60 your voltage is 3v. it is directly proportional.

here is my projects source code, i hope it works for you.

Code:
#include <18F4550.h>
#device ADC=10
#fuses HSPLL,USBDIV,PLL5,PUT,CPUDIV1,VREGEN,NOWDT,NOPROTECT,NOLVP,NODEBUG,NOMCLR
#use delay(clock=20000000)

#define USB_HID_DEVICE     FALSE             
#define USB_EP1_TX_ENABLE  USB_ENABLE_BULK    //Uçnokta1'de Yığın transferi aktif
#define USB_EP1_RX_ENABLE  USB_ENABLE_BULK    
#define USB_EP1_TX_SIZE    64                 //Uçnokta1 için maksimum alınacak ve gonderilecek
#define USB_EP1_RX_SIZE    64                 //veri boyutu (64 byte)

#include <pic18_usb.h>     
#include <USB_Konfigurasyon.h>                //USB konfigurasyon bilgileri bu dosyadadır.
#include <usb.c>   


#define UcNokta1       1
#define Komut          gelen_paket[0]


//Komutlar
#define bilgi_oku      0x03         //Mikrokontrolör içindeki yazılımın sürüm numarasını oku
#define bilgi_yaz      0x02
//#define olcum_al       0x02         // ADC girişilerindeki değerleri ve manuel çalışmadaki parametreli al
//#define pwm_1_ayarla   0x04         //dc motor için pwm1 çıkışını ayarla
//#define pwm_2_ayarla   0x05         //dc motor için pwm2 çıkışını ayarla


//Değişkenler
static unsigned int16 ADC_deger1 = 0;  //DC motor için gerekli ADC girişi, pwm çıkışları ve yön değerini
static unsigned int8 pwm_deger1 = 0;  //tutan değişkenler
static unsigned int8 pwm_deger2 = 0;
static unsigned int8 dc_yon_degisim = 0;

static unsigned int16 ADC_deger2 = 0;  //Step Motor için gerekli ADC girişi, yön , hiz ve adim değerlerini
static unsigned int8 step_yon = 0;   //tutan değişkenler
static byte step_hiz= 0;
static byte adim_durum = 0;
byte const adimlar[] = {10,12,5,3}; //Tam Adım unipolar stepmotor adımları yarım adım[]={2,10,8,12,4,5,1,3}
unsigned int8 step_yon_degisim = 0;

void step_motor_sur();
/*#int_TIMER1
void TIMER1_isr(){

  step_motor_sur();
}*/
#int_EXT
void ext_isr()
{
while(!input(Pin_B0));  //Buton bırakılana kadar bekle
dc_yon_degisim++;
}
#int_EXT1
void ext1_isr()         //Buton bırakılana kadar bekle
{
while(!input(Pin_B1));
step_yon_degisim++;
}


void user_init(void)                   //Pic açılırken ayarlanacak temel özellikler
{
   set_tris_a(0x03);                   //RA0,RA1 giriş
   set_tris_b(0x03);                   //RB0,RB1 giriş 
   set_tris_d(0x00);
   setup_adc_ports(AN0_TO_AN1);        //A0 ve A1 pinleri analog-dijital çevirici girişleri
   setup_adc(ADC_CLOCK_INTERNAL);      //ADC ölçümü için dahili osilatörü kullan

    port_b_pullups(TRUE); 
    enable_interrupts(GLOBAL);
    enable_interrupts(INT_EXT);
    enable_interrupts(INT_EXT1);
    ext_int_edge(0,H_TO_L);
    ext_int_edge(1,H_TO_L);
    setup_timer_2(T2_DIV_BY_16, 255, 1); //pwm için timer2'yi ayarla
    setup_ccp1(CCP_PWM);                //CCP1 ve
    setup_ccp2(CCP_PWM);                //CCP2 pinlerini PWM üretimi için ayarla
}
unsigned int16 ADC_Oku(byte kanal)     // ADC pinlerideki voltaj değerlerini okuyan fonksiyon
{
   unsigned int16 olcum=0;
   set_adc_channel(kanal);
   delay_us(20);
   olcum = read_adc();
   return olcum;
}



void main(void)
{

   byte sayac=0;
   byte gelen_paket[64];               //gelen paket
   byte gond_paket[64];                //gönderilecek paket

 //Sistemi başlat
   user_init();
   usb_init();                      
   usb_task(); 
   set_pwm1_duty(pwm_deger1); 
   set_pwm2_duty(pwm_deger2);

   usb_wait_for_enumeration();         //Cihaz, hazır olana kadar bekle
   if(usb_enumerated())
   output_high(Pin_A2);                //USB bağlantısı kurulduysa LED'i yak.

   for (;;)
   {
      while(usb_enumerated())
      {
         if (usb_kbhit(1))             //Eğer pc'den yeni bir paket geldiyse
         {
            usb_get_packet(UcNokta1, gelen_paket, 64); //paketi oku
            switch(Komut)              // Paketin ilk elemanındaki komutu oku ve ilgili göreve git
               {

                           
                  case bilgi_oku:                      
                           ADC_deger1=ADC_Oku(0);
                           ADC_deger2=ADC_Oku(1);
                           gond_paket[0] =  Komut;
                           gond_paket[1] = ADC_deger1/4;
                           gond_paket[2] = dc_yon_degisim;
                           gond_paket[3] = ADC_deger2/4;
                           gond_paket[4] = step_yon_degisim;
                           sayac = 0x05;
                           break;
                  case bilgi_yaz:
                           pwm_deger1 = gelen_paket[1];
                           set_pwm1_duty(pwm_deger1);
                           pwm_deger2 = gelen_paket[2];
                           set_pwm2_duty(pwm_deger2);
                           step_yon = gelen_paket[3];
                           step_hiz = gelen_paket[4];
                          break;
                                        
                  default: ; break;
                           
               }
         }
         if(sayac!=0)
         {
         usb_put_packet(UcNokta1, gond_paket, sayac, USB_DTS_TOGGLE);
         sayac = 0;
         Komut = 0;
         }
         step_motor_sur();

      }
   }
}
void step_motor_sur()
{
  if((step_hiz != 0) && (step_yon != 0)){
    output_d(adimlar[adim_durum]*4);                  //çıkışı ötelemek için 4 ile çarpılır
    Delay_Ms(257-step_hiz);
     if(step_yon == 1)
     adim_durum = (adim_durum+1)&(sizeof(adimlar)-1);
     else 
     adim_durum = (adim_durum-1)&(sizeof(adimlar)-1);
  }
if(step_yon==0)
output_d(0);
}
 

suppose i want to control a motor of speed 20 rpm,50, and 100 rpm , can u explain it with an example ,it will be so kind of u.
 

first you have to know your dc motor's characteristics. for example which voltage level it starts to run and the minimum rpm. you cannot use the motor this minimum rpm. and of course the full speed rmp has to be measured. this measurements are your reference points to control your dc motor.

for example your dc (assuming it is a 12v motor) motor starts to rotate at 4v and 200 rpm, and when you supply 12 volt to your motor it reaches 1200 rpm. now you know your min and max rpm, and min and max voltage levels.

the pwm output i used in my project is 8 bit pwm. (0 -> MAX DUTY = 0x00 -> 0xFF)

that means it can change it duty cycle 0 to 255 valu so, one increment is 12/256= 0.46875v, now calculate your rpm rate:

your max rpm is 1200 and max voltage is 12 volt so the pwm duty is 255 or 0xFF

and your min rpm 200 and min voltage is 4 volt or so pwm duty is 64 or 0x40

(1200-200)/(255-64)=5.23rpm
now every increment between 0x40 and 0xFF changes your rpm 5.23 more or less.

i think it is clear enough to your project, the only thing you should do is to put your dc motor values and voltage supply in the equations. and write it in your codes;

set_pwm1_duty(your_value);
set_pwm2_duty(your_value);

these are your pwm channels and if you want to change the direction you have to use both channels.
 

i am searching for a good tutorial for pwm for the past few days ,thank you very much you really helped me..

is there any formula to find all these ?

how we are getting the value 0x40 /64 for 4 v pwm?

can you say the rating specifications mentioned in a motor with an example ?

i found a motor on website can u explain each specifications with reference to this..thanking you in advance

10 rpm Side Shaft Motor

10RPM high quality industrial grade metal Gearbox Motor with offset shaft 12VDC. Very easy to use and available in standard size.

Features

· 10RPM 12V DC motors with Gearbox

· 4500RPM base motor

· 6mm shaft diameter with internal hole

· 125gm weight

· 12kgcm torque

· No-load current = 100 mA(Max), Load current = 1000 mA(Max)
 
Last edited:

hi again,

the basic thing you have to know about dc motors is the only way of controlling speed is to control supply voltage. pwm function produces square wave signals with variable duty cycle. if you change the duty cycle, you can change the speed it is that simple

if you give full duty cyclde (in my case it is 0xFF) you supply 12 volt. if you give 0xFF the supply is 0 volt. any change in duty cycle rate means 1/256 voltage change.

i made a mistake in my previous post, sorry about that. the voltage should be 3 volts. means 1/4 of 12v (0x40 is 1/4 of 0xFF) i hope you can figure out this simple aquations.
 

Status
Not open for further replies.

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top