4 Temmuz 2014 Cuma

Analog joystick İle Motor Hız Kontrol Ve RPM Sayıcı Projesi

 
 
  Bu çalışmam da bir önceki çalışmamda(PWM Motor Hız Kontrol Ve RPM Sayıcı Projesi) yapmış olduğum projede bir değişiklik yaparak potansiyometreyi çıkararak yerine playstation kollarından da aşina olduğumuz analog pot kısmını ekleyerek, o analog  joystick ile motorun sağ ve sol dönüşlerini kontrol edeceğim Bunu yaparken analog pot'un sadece x-eksenini kullanacağım y-ekseni boş kalacak. Aynı zamanda LCD ekranda motorun dakikadaki dönüş hızı gösterilecektir. Fakat motoru tam sabitleyemediğimden tam RPM sonuç alamadım ama motor sabit olursa tam sonuca yakın değer çıkabilir.


Analog pot'un giriş, çıkışları ve eksenleri

 
 
 
 

 
Devre şeması bir önceki uygulamadakinin aynısı olup sadece orada bulunan 10K pot yerine bu uygulamada yukarıdaki analog pot kullanılmıştır.
 
 
 

 MikroC kodu;


sbit LCD_RS at RC0_bit;
sbit LCD_EN at RC1_bit;
sbit LCD_D7 at RD3_bit;
sbit LCD_D6 at RD2_bit;
sbit LCD_D5 at RD1_bit;
sbit LCD_D4 at RD0_bit;
sbit LCD_RS_Direction at TRISC0_bit;
sbit LCD_EN_Direction at TRISC1_bit;
sbit LCD_D7_Direction at TRISD3_bit;
sbit LCD_D6_Direction at TRISD2_bit;
sbit LCD_D5_Direction at TRISD1_bit;
sbit LCD_D4_Direction at TRISD0_bit;

volatile unsigned int rpm_deger=0;
void interrupt(){
 static unsigned char darbe_durumu=0;
 unsigned int rpm_zaman_sayici;


   if(INTCON.TMR0IF){
    rpm_deger=0;
    INTCON.TMR0IF=0;                       // Clear TIMER0 interrupt flag
   }
/*Eger sensörden beyaz işaretden yansımayı alınca fototransistör anlık 1 olur olur ve INTCON.INT0IF=1 olarak
 ilk önce zamanlayıcı sıfırlanır sonra tekrar 1 oluncaya kadaar geçen süreyi TMR0 sayar ve tekra INTCON.INT0IF=1 olunca ,
 RPM hesaplamaya geçer*/
  if (INTCON.INT0IF){                      // Check for External INT0 Interrupt
   portc.Rc7=1;
   switch(darbe_durumu) {
      case 0:                       // First Low to High Pulse
        TMR0H = 0;                  // Zero the high byte in TMR0H Buffer
        TMR0L = 0;                  // Clear 16-bit TIMER0 Counter
        darbe_durumu=1;
        break;
      case 1:                       // Second Low to High Pulse
        rpm_zaman_sayici=TMR0L;            // Get the first 8-bit TIMER0 Counter
        rpm_zaman_sayici+=(TMR0H << 8);    // Get the last 8-bit TIMER0 Counter
        // RPM HESAPLA = 60 x (1/Periyot) periyot sensörün ilk beyzı gördüğü andan sonraki beyazı gördüğü ana geçtiği zaman
        // RPM degeri = 60000 (1 / (0.032 ms x rpm_zaman_sayici))
        rpm_deger=(60000.0/(0.032 * rpm_zaman_sayici));
        darbe_durumu=0;
    }
    INTCON.INT0IF = 0;                     // Clear INT0 interrupt flag
  }
}


void init(){
// LCD AYARLARI//
  Lcd_Init();                        // Initialize LCD
  Lcd_Cmd(_LCD_CLEAR);               // Clear display
  Lcd_Cmd(_LCD_CURSOR_OFF);          // Cursor off

//ADC AYARLARI//
  TRISA=0X03;
  ADCON0  =0x03;
  ADCON1 =0b00001110;
  TRISA   =0X03;
  ADCON2=0b00101011;   // Left justify result, 12 TAD, Select the FRC for 16 MHz

//ECCP MODUL AYARLARI//
/* pwm için 4.975Hzlik sinyal üretilip sinyalin 1 kalma oranıyla ADC ile ayarlanıp
motoru hızlandırıp veya yaşlatabiliriz */
     TRISC.RC2=0;  // FULL-BRIDGE CIKISLARI ICIN  AYARLAMALAR
     PORTC.RC2=0;
     TRISD.RD5=0;
     TRISD.RD6=0;
     TRISD.RD7=0;
     PORTD.RD5=0;
     TRISD.RD6=0;
     TRISD.RD7=0;
     CCP1CON= 0b11001100;  // Full Bridge Forward; P1A, P1C active-high; P1B, P1D active-high
     CCPR1L=0;            // Start with zero Duty Cycle
  // PWM Period = 4 x Tosc x (PR2 + 1) x TMR2 Prescale Value
  // Tosc = 1/16 Mhz = 0.0000000625
  // PWM Period = 4 x 0.0000000625 x 201 x 4 = 0.000201
  // PWM Frequency = 1/PWM Period = 1/0.000201 = 4.975 kHz
     T2CON=0b00000101;    // Postscale: 1:1, Timer2=On, Prescale = 1:4
     PR2=200;             // Frequency: 4.975 kHz
     TMR2=0;              // Start with zero Counter

//TMR0 AYARLARI RPM İÇİN ZAMAN SAYACAK//
  // Init TIMER0: Period: 4 x Tosc x Prescale for each counter
  // Tosc = 1/16 Mhz = 0.0000000625
  // TIMER0 Period: 4 x 0.0000000625 x 128 = 0.000032 Second = 0.032 ms
  INTCON=0XC0;
  T0CON = 0b10000110;   // TIMER0 Enable, use 16-bit timer and prescale 1:128
  TMR0H = 0X00;            // Zero the high byte in TMR0H Buffer
  TMR0L = 0X00;            // Clear 16-bit TIMER0 Counter
  INTCON.TMR0IE = 1;           // Enable TIMER0 Overflow Interrupt
    //INT KESME AYARI//
    // Set the External Interrupt on INT0 (RC0) Port
  INTCON.INT0IE = 1;          // Enables the INT0 external interrupt
  INTCON2.INTEDG0 = 1;         // Interrupt on rising edge
 
  TRISB=0X01;
  trisc.Rc7=0;
  portc.Rc7=0;
}


unsigned int duty_cycle;
unsigned int x_axis_ham; // Analog joystick sadece bir eksedenki pot kullanlıyor bunun
                                         //ile motor sag veya sol dönüş kontrol edilecek ve motorun hızı ayarlanacak.
unsigned int x_axis;
char kelime[4];
char kelime1[4];
char kelime2[7];


void main() {
     init();
     while(1){
             x_axis_ham=adc_read(0);
          if  ((x_axis_ham>=511)  & (x_axis_ham<=515)){
                      CCPR1L = 0;
                      duty_cycle=0;
                      lcd_out(1,1," MOTOR DURDU !      ");
          }else{
              if (x_axis_ham<500){
                  Lcd_Cmd(_LCD_CLEAR);               // Clear display
                  P1M1_BIT=0;
                  P1M0_BIT=1;
                  lcd_out(1,1," SOLA %   RPM");
                  while(x_axis_ham<500){
                      x_axis_ham=adc_read(0);
                      x_axis =(500-x_axis_ham)/2 ;
                      CCPR1L=x_axis;
                      duty_cycle=(x_axis/250.0) * 100.0;
                      bytetostr(duty_cycle,kelime);
                      lcd_out(2,2,kelime);
                      inttostr(rpm_deger,kelime2);
                      lcd_out(2,9,kelime2);
                  }
                   Lcd_Cmd(_LCD_CLEAR);               // Clear display
               }
               if (x_axis_ham>516){
                  Lcd_Cmd(_LCD_CLEAR);               // Clear display
                  P1M1_BIT=1;
                  P1M0_BIT=1;
                  lcd_out(1,1," SAGA%    RPM");
                  while(x_axis_ham>516){
                      x_axis_ham=adc_read(0);
                      x_axis=(x_axis_ham-517)/2;
                      CCPR1L=x_axis;
                      duty_cycle=(x_axis/250.0) * 100.0;
                      bytetostr(duty_cycle,kelime1);
                      lcd_out(2,2,kelime1);
                      inttostr(rpm_deger,kelime2);
                      lcd_out(2,9,kelime2);
                  }
                   Lcd_Cmd(_LCD_CLEAR);               // Clear display
               }
          }
     }
}


                                                                       Sonuç

Hiç yorum yok:

Yorum Gönder