CCS ile Motor Hızı Ölçme

Başlatan kostebek, 29 Ekim 2008, 12:15:57

kostebek

Merhaba arkadaşlar bir Cruise Control(Hız Sabitleyici) projesi yapmaktayım. Motor olarak Fırçasız DC motor kullanacağım. Motorda encoder olmadığı için mecburen motor miline bağlı bir adet karton parçasını CNY70 türünde aletten geçirerek kartonun her CNY70 i tetiklemesinde ortalama hızı ölçüp ekrana yazıcam. Tabi sonra kontrol işlemlerine geçeceğim.

Tavsiyelerini almak için başlık açtım. Benim fikrim şu yönde merak ediyorum siz ne düşünürsünüz:

CNY70 de kesme olduğunda Timer saymaya başlayacak ikinci kesme geldiğinde durum değişkeni diye tanımladığım değerin değişmesi üzerine bu sefer Timer'ın değeri okunacak. Bir devri bu sürede yaparsa, 1 dakikada x devir yapar formülüyle de hızı bulacağım.

Daha pratik veya PROFESYONEL bir fikri olan ?

kostebek



Birşeyler karaladım ama olmadı sanırım. RB dış kesmesi gelmiyor hiç sizce neden ?

#include <16F877.h>

#fuses HS,NOWDT,NOPROTECT,NOLVP

#use delay(clock=20000000)

#priority RB, RTCC, TIMER1

#include <lcd.c>

float T1;
float  sure;
int kesme_sayisi=0; //kesmeleri sayacağız kaç tane gelmiş kontrol edeceğiz.
int durum=0;
int n;

#INT_TIMER1
void timer_kes(void)
{

   kesme_sayisi++;  //eğer kısa sürede taşarsa kaç kez taştığını kontrol edeceğiz.
   n++;
}

#int_ext
void rb_kesme(void)
{
   durum++;
   
   if(durum==1)
   {
   
   set_timer1(0); //ilk hesap başlıyor Timer 0 landı

   }
   
   if(durum==2){
                  //ikici durumdayız şimdi hesaplama başlıyor
 
   T1 = get_timer1();
   
   sure = (kesme_sayisi*104.8576*0.001) + (1.6*0.000001*T1); //saniye olarak
   
   //herbir bilgiyi birdahaki kesme için sıfırla
   

   
   kesme_sayisi=0;
   durum=0;
     
   }



}


void main()
{
   lcd_init();
   
   setup_adc_ports(NO_ANALOGS);    // ANALOG giriş yok
   setup_adc(ADC_OFF);             // ADC birimi devre dışı

   setup_timer_0(RTCC_EXT_L_TO_H|RTCC_DIV_1);     // RTCC harici giriş alır 
   setup_timer_1(T1_INTERNAL|T1_DIV_BY_8);        // 20 Mhz clock ve T1_DIV_BY_8 modunda, Timer1 her 1.6us'de artar ve 104.8576ms'de taşar
   
   set_tris_b(0x01);  
   
   output_b(0x00);     

   ext_int_edge(L_TO_H);   

   enable_interrupts(INT_EXT); 

   enable_interrupts(INT_TIMER1);

   enable_interrupts(GLOBAL);   // Aktif edilen kesmelere izin ver

   set_timer0(0); 
   set_timer1(0);

   while (1)
      {


       printf(lcd_putc,"\f");
       printf(lcd_putc,"Kesme Suresi\n");
       printf(lcd_putc,"n=%.1d T1=%.1f ", n, T1 );
      // printf(lcd_putc,"sure=%.1f ", sure );
       delay_ms(5);
        

      }

}      

ferdem

Kanaati acizanemce:) programınızın genel mantığı iyi, zamanla optimize edersiniz. Yapılacak iş kesmeler arasındaki zaman ölçümü.
RB0 kesmesi gelmez çünkü set_tris_b(0x01);  ile girişe ayarladığınız b0 pinini output_b(0x00); diyerek CCS C ye çıkışa ayarlattırıyorsunuz. Bildiğiniz gibi use fast_io(port_adi) bildirimi yapmazsanız her giriş çıkış komutu için CCS C tris register ini günceller. Çıkışa şartlı B0 dan da kesme gelmez.
Bir de 877de interrupt priority bulunmuyor diye biliyordum.

pato53

bence hız ölçmek için cny gibi ek elemanlara gerek yok. Ben yaptığım projede hız ölçmek için 877 nin analog-dijital portunu kullandım. 877 de analog dijital dönüştürücü var.

Analog-dijital çevrimde değer ne kadar büyükse, hız da o kadar büyüktür demektir.

kostebek

Dün gece kafam daha sağlıklı çalıştığı için birazcık değişiklikler yaptım. Hatta baya değişiklikler yaptım aşağıdaki kod ile sabit hızda dönen motorun /(PWM KULLANMADIM) hızını süper ölçebiliyorsunuz (:

#include <16F877.h>

#fuses HS,NOWDT,NOPROTECT,NOLVP

#use delay(clock=20000000)

#priority RTCC, TIMER1

#include <lcd.c>

float Darbe_SAYISI = 300;    

float T0, T1;
float n;
int ayar;
int pwm;

void yazdir_hiz()
{
         printf(lcd_putc,"\f");
         printf(lcd_putc,"Motor Hizi:\n");
         printf(lcd_putc,"n=%.1f ", n );
         delay_ms(5);
}


void yazdir_kontrol()
{
         printf(lcd_putc,"\f");
         printf(lcd_putc,"Hiz Sabitleme:");
         printf(lcd_putc,"<<-  =%d ->>", ayar );
         delay_ms(5);
}

void main()
{

   lcd_init();

   setup_timer_0(RTCC_EXT_L_TO_H|RTCC_DIV_1);     
   setup_timer_1(T1_INTERNAL|T1_DIV_BY_8);        // 20 Mhz clock ve T1_DIV_BY_8 modunda, Timer1 her 1.6us'de artar ve 104.8576ms'de taşar

   set_timer0(0); 
   set_timer1(0);

   while (1)
      {
      
     

      T0 = get_timer0();
      T1 = get_timer1();

      if ( (T0 > 250) | (T1 > 65500) )
         {
         
         n= ( T0*60*1e6 ) / (T1*1.6*Darbe_SAYISI);      
      
         yazdir_hiz();
         
         set_timer0(0);
         set_timer1(0);
         }




      }

}      





kostebek

Arkadaşlar Yardım!!!!! Valla danayı yüzdük kuyruğuna geldik :lol:

Herbişey tamam sadece bir problem var. hız sabitle fonksiyonumu çalıştırıyorum ama o sırada N devir sayısını alamıyor ve 0 olarak gördüğü için program abuk çalışıyor. Kodlar şu şekilde


Hatta ben size hatayı söyliyeyim direk ordan belkim anlarsınız. şimdi bu devir sayısı olan   n  sayısını sürekli hesaplatıyoruz ya

hiz_sabitle() fonksiyonunun içinde işte o değeri almıyor. 0 olarak görüyor. Dolayısıyla sürekli n<devir_ayar  durumu sağlandığı için PWM sürekli artarak motor hızı sürekli artırılmış oluyor. Problem nerede. Neden n i 0 olarak görüyor


#include <16F877.h>

#fuses HS,NOWDT,NOPROTECT,NOLVP

#use delay(clock=20000000)

#use fast_io(a) //Port yönlendirme komutları A portu için geçerli

#priority RTCC, TIMER1

#include <lcd.c>

#define bt_artir pin_b4

#define bt_azalt  pin_b5

#define bt_set  pin_b3

#define bt_reset  pin_b2

/*baslangic ayarlamalari*/

float Darbe_SAYISI = 300;    

int init=0;

float T0, T1;

float n;

int ayar;

int mode;

int pwm;

//int devir_ayar;

float devir_ayar;

void yazdir_hiz()
{
         printf(lcd_putc,"\f");
         printf(lcd_putc,"MOTOR HIZI  AYAR\n");
         printf(lcd_putc,"%.1f    -  %.1f", n,devir_ayar );
         delay_ms(5);
}


void yazdir_kontrol()
{
         printf(lcd_putc,"\f");
         printf(lcd_putc,"Hiz Sabitleme:\n");
         printf(lcd_putc,"  %.1f ", devir_ayar );
         delay_ms(5);
}


void hiz_hesapla()
{
      T0 = get_timer0();
      T1 = get_timer1();

      if ( (T0 > 250) | (T1 > 65500) )
         {
         
         n= ( T0*60*1e6 ) / (T1*1.6*Darbe_SAYISI);      
      
         yazdir_hiz();
         
         set_timer0(0);
         set_timer1(0);
         }

         //return n;
}

hiz_sabitle()
{
 //hiz sabitleme algoritması burada başlar...
 
 
   if(n>devir_ayar){
 
    while(n>devir_ayar){
    
    pwm--;
    
//!         printf(lcd_putc,"\f");
//!         printf(lcd_putc,"azaltılıyor:\n");
//!         printf(lcd_putc,"  %.1f    %d ", devir_ayar,pwm );
//!         delay_ms(5);
    
    set_pwm1_duty(pwm);
    
    hiz_hesapla();
    
    if(n==devir_ayar) break;
    }
    
    }
    
    
   if(n<devir_ayar){
 
    while(n<devir_ayar){
    
    pwm++;
    
//!         printf(lcd_putc,"\f");
//!         printf(lcd_putc,"artiriliyor:\n");
//!         printf(lcd_putc,"  %.1f    %.1f ", devir_ayar,n );
//!         delay_ms(5);
    
    set_pwm1_duty(pwm);
    
    hiz_hesapla();
    
    
    if(n==devir_ayar) break;
    
    }
   }
 
 

}

void buton_kontrol()
{
         if (input(bt_artir)) {  
         
            while(input(bt_artir)){
            delay_ms(1);   //elini cekinceye kadar bekle
            }
              if(devir_ayar<254){
              delay_ms(20);  
              devir_ayar=devir_ayar+1;
               }
         }
         
         
            if (input(bt_azalt)) {  
             while(input(bt_azalt)){
            delay_ms(1);   //elini cekinceye kadar bekle
            }
               if(devir_ayar>0){
               delay_ms(20);  
               devir_ayar=devir_ayar-1;
               }
          }
}


void set_kontrol()
{

    if (input(bt_set)) { 
         delay_ms(10);
         printf(lcd_putc,"\f");
         printf(lcd_putc,"Hiz Ayari Yapildi!\n");
         delay_ms(50);
         
      hiz_sabitle();
    
    //Burada kontrol algoritması başlayacak
    
    }
}


void reset_kontrol()
{

    if (input(bt_reset)) { 
    delay_ms(10);
    
    set_pwm1_duty(0);
    printf(lcd_putc,"\f");
    printf(lcd_putc,"Ayarlar Sifirlandi!\n");
    delay_ms(50);
    devir_ayar=0;
   // goto main;
    
    
    
    //Burada herşey eski haline getirilecek
    
    }
}

void ust_sinir_kontrol()
{

if(pwm==255){

    printf(lcd_putc,"\f");
    printf(lcd_putc,"Max. PWM Sinirina!\nUlasildi.");
    delay_ms(50);

}


}







void main()
{

   lcd_init();

   setup_timer_0(RTCC_EXT_L_TO_H|RTCC_DIV_1);     
   setup_timer_1(T1_INTERNAL|T1_DIV_BY_8);        // 20 Mhz clock ve T1_DIV_BY_8 modunda, Timer1 her 1.6us'de artar ve 104.8576ms'de taşar
   setup_timer_2(T2_DIV_BY_16,255,1);
   setup_ccp1(CCP_PWM); 
   set_pwm1_duty(init); 
   
   set_timer0(0); 
   set_timer1(0);

   while (1)
      {

      hiz_hesapla();
      
      buton_kontrol();
      
      set_kontrol();
      
      reset_kontrol();
      
      }//while

}//main        








Şunu bir bitirsek çok güzel olcak hemen baskı devresini çıkartacam. Videosunu da koyarım buraya (:

JKramer

Timer2'yi nerede kullanacaktınız?

kostebek

Alıntı yapılan: "JKramer"Timer2'yi nerede kullanacaktınız?

PWM için ayar yapıyoruz. Sonuçta kesme usulü çalışıyor ;)

kostebek

http://www.harmankaya.org/yazi-285-PIC-ile-Motor-Hiz-Kontrolu-Projem.html



daha hiz sabitleme yapamıyorum. ++++ ayrıca enkoderimde bir problem var sanırım ::S

ovarol

Merhabalar... Ben de senin projeyi yapmaya başlıyorum kostebek. Projeyi tamamlayabildin mi merak ettim. Konu açılalı 2 yıl olmuş da  :)