"Kembali Ke Dasar Elektronika Digital ... "

Rabu, 19 November 2014

[TUTORIAL & SCRIPT BREAKDOWN] RPM - TACHOMETER HONDA dengan ATTINY2313




Akhirnya balik lagi ke blog ini setelah beberapa waktu vakum. Dan kali ini menjawab beberapa request yang masuk untuk membahas lebih lanjut mengenai RPM - TACHOMETER untuk sepeda motor yang pernah dibahas disini . Sebenernya jika selalu mengikuti perkembangan blog ini maka tidak terlalu susah asal dasar pengetahuan timer dan interupt nya lengkap. 

Intinya pada project ini adalah mendeteksi RADIASI pulsa CDI ke BUSI dan dimasukkan ke PIN INTERRUPT dan kemudian dihitung jumlah pulsa yang muncul vs waktu. Dan didapatkanlah RPM yang diinginkan. Kali ini kita juga akan membuat animasi graph / level sehingga tidak bosan dengan angka-angka saja.

Perhatikan skematik dibawah ini dan bahan2nya bisa dilihat dari gambar berikut (klik untuk gambar lebih jelas)



Jangan lupa juga untuk menyediakan motor yang akan di "HIAS" yang kali ini meminjam motor anak buah saya yaitu HONDA SUPRA VIT. Saya memiliki pengalaman jika bebek honda lebih bocor sinyal CDI nya ketimbang motor lain. Jadi jika menggunakan motor lain maka disesuaikan pemilihan resistor sebelum transistor pembaca pulsa (2N3904) dan pengalaman lainnya ketika menggunakan sepeda motor Yamaha Vega maka transistor yg digunakan adalah PNP 2N3906 dengan tanpa menggunakan resistor pada basis dan VCC ke EMITOR sedangkan INTERUPT ke COLECTOR (dibalik).





Langsung aja kita bahas script nya biar ga bingung, agak panjang tapi ga rugi kok



>>>HEADER<<

Attiny 2313 yang digunakan adalah default yg memiliki clock 1MHz. 

#define F_CPU 1000000UL // sesuaikan clock yang digunakan !!
#include <avr/io.h>
#include <util/delay.h>
#include <avr/eeprom.h>
#include <inttypes.h>
#include <avr/interrupt.h>

// ini untuk animasi kata awal, ubah sesuai keinginan atau hapus jika tidak mau
uint8_t angka1=16 ;
uint8_t angka2=17 ;
uint8_t angka3=20 ;
uint8_t angka4=15 ;


uint8_t segstep=0; // untuk pindah segmen

uint8_t kalibrasi=3; // kalibrasi awal

uint8_t valid=0; // variabel untuk mengatasi noise ke tombol

int number=0; // variabel menyimpan jumlah counter



>>>PENERJEMAH ANGKA ke SEGMEN<<

7 segmen yang digunakan merupakan common Anoda sehingga untuk menyalakan segmen dibutuhkan logic "LOW" atau 0 volt / Ground. Untuk animasi dan huruf dapat dikreasikan sendiri dengan kombinasi "LOW" untuk segmen menyala dan "HIGH" untuk segmen mati.

void conv_segmen(uint8_t digit)
// Rutin ini merubah angka dan animasi ke segmen
{
    switch (digit)        
          {
//angka biasa
  case 0 :  
     {
         PORTB &= ~_BV(PB0) & ~_BV(PB1) & ~_BV(PB2) & ~_BV(PB3) & ~_BV(PB4) & ~_BV(PB5); //PORT YG NYALA
         PORTB |= _BV(PB6) ; //PORT YG MATI 
      break;
           }
  case 1 :
     {
         PORTB &= ~_BV(PB1) & ~_BV(PB2) ;
               PORTB |= _BV(PB0) |  _BV(PB3) | _BV(PB4) | _BV(PB5) | _BV(PB6) ;
      break;
           }
  case 2 : 
     {
         PORTB &= ~_BV(PB0) & ~_BV(PB1) &  ~_BV(PB3) & ~_BV(PB4) & ~_BV(PB6) ;
               PORTB |= _BV(PB2) |  _BV(PB5)  ;
      break;
           }  
  case 3 : 
      {
         PORTB &= ~_BV(PB0) & ~_BV(PB1) &  ~_BV(PB2) & ~_BV(PB3) & ~_BV(PB6) ;
               PORTB |= _BV(PB4) |  _BV(PB5)  ;
      break;
           }
  case 4 :
     {
         PORTB &= ~_BV(PB1) & ~_BV(PB2) &  ~_BV(PB5) & ~_BV(PB6)  ;
               PORTB |= _BV(PB0) |  _BV(PB3) |  _BV(PB4) ;
      break;
           }
  case 5 : 
     {
         PORTB &= ~_BV(PB0) & ~_BV(PB2) &  ~_BV(PB3) & ~_BV(PB5)  & ~_BV(PB6)  ;
               PORTB |= _BV(PB1) |  _BV(PB4)  ;
      break;
           }
  case 6 : 
     {
         PORTB &= ~_BV(PB0) & ~_BV(PB2) &  ~_BV(PB3) & ~_BV(PB4)  & ~_BV(PB5) & ~_BV(PB6) ;
               PORTB |= _BV(PB1) ;
      break;
           }
  case 7 : 
     {
         PORTB &= ~_BV(PB0) & ~_BV(PB1) &  ~_BV(PB2)  ;
               PORTB |= _BV(PB3) |  _BV(PB4) |  _BV(PB5)|  _BV(PB6) ;
      break;
           }  
  case 8 : 
     {
         PORTB &= ~_BV(PB0) & ~_BV(PB1) & ~_BV(PB2) & ~_BV(PB3) & ~_BV(PB4) & ~_BV(PB5) & ~_BV(PB6);
      break;
           }
  case 9 : 
     {
         PORTB &= ~_BV(PB0) & ~_BV(PB1) & ~_BV(PB2) & ~_BV(PB3) & ~_BV(PB5) & ~_BV(PB6);
               PORTB |= _BV(PB4) ;
      break;
           }
  case 10 : //kosong
     {
    PORTB |= _BV(PB0) | _BV(PB1) |  _BV(PB2) |  _BV(PB3) | _BV(PB4) | _BV(PB5) | _BV(PB6) ;
      break;
           }
 //11 - 14 khusus untuk animasi level       
  case 11 : 
     {
         PORTB &= ~_BV(PB4); 
               PORTB |= _BV(PB0) | _BV(PB1) | _BV(PB2) | _BV(PB3) | _BV(PB5) | _BV(PB6);
      break;
           } 
   
   case 12 : 
     {
         PORTB &= ~_BV(PB4) & ~_BV(PB2); 
               PORTB |= _BV(PB0) | _BV(PB1)  | _BV(PB3) | _BV(PB5) | _BV(PB6);
      break;
           }
  case 13 : 
     {
         PORTB &= ~_BV(PB4) & ~_BV(PB2) & ~_BV(PB5); 
               PORTB |= _BV(PB0) | _BV(PB1)  | _BV(PB3) | _BV(PB6) ;
         break;
           } 
   
   case 14 : 
     {
         PORTB &= ~_BV(PB4) & ~_BV(PB1) & ~_BV(PB2) & ~_BV(PB5); 
               PORTB |= _BV(PB0) | _BV(PB3) | _BV(PB6) ;
         break;
           }
// kebetulan nama pemilik motor seperti ini, ubah sesuai keinginan
   case 15 : //r
     {
         PORTB &= ~_BV(PB6)  & ~_BV(PB4) ; 
                       PORTB |= _BV(PB0) | _BV(PB1) | _BV(PB3) | _BV(PB2) | _BV(PB5) ;
         break;
           }  

   case 16 : //i
     {
         PORTB &= ~_BV(PB4); 
               PORTB |= _BV(PB0) | _BV(PB1) | _BV(PB3) | _BV(PB2) | _BV(PB5) | _BV(PB6)  ;
         break;
           }   
   
   case 17 : //b
     {
         PORTB &= ~_BV(PB3) & ~_BV(PB4) & ~_BV(PB5) & ~_BV(PB2) & ~_BV(PB6); 
               PORTB |= _BV(PB0) |_BV(PB1)  ;
         break;
           }   

   case 18 : //y
     {

         PORTB &= ~_BV(PB1) & ~_BV(PB2) & ~_BV(PB3) & ~_BV(PB5) & ~_BV(PB6);
               PORTB |= _BV(PB4)| _BV(PB0);
      break;
           } 

   case 19 : //u
     {

         PORTB &= ~_BV(PB2) & ~_BV(PB3) & ~_BV(PB4) ;
               PORTB |= _BV(PB1)| _BV(PB0) | _BV(PB5) | _BV(PB6);
      break;
           } 

   case 20 : //0
     {
         PORTB &= ~_BV(PB3) & ~_BV(PB4) & ~_BV(PB2) & ~_BV(PB6); 
               PORTB |= _BV(PB0) |_BV(PB1) |_BV(PB5)  ;  
      break; 
     }


}

}




>>>ANIMASI LEVEL RPM<<

Nilai RPM akan diterjemahkan dari angka menjadi level / bar graph

void animasi(uint8_t posisi)

{

switch(posisi)  {  
       case 0 :{ angka4=10; angka3=10 ; angka2=10; angka1=10;
              break; }
       case 1 :{ angka4=11; angka3=10 ; angka2=10; angka1=10;
              break; }
       case 2 :{ angka4=12; angka3=10 ; angka2=10; angka1=10;
              break; }
       case 3 :{ angka4=12; angka3=11 ; angka2=10; angka1=10;
              break; }
       case 4 :{ angka4=12; angka3=12 ; angka2=10; angka1=10;
              break; }
       case 5 :{ angka4=12; angka3=12 ; angka2=11; angka1=10;
              break; }
       case 6 :{ angka4=12; angka3=12 ; angka2=12; angka1=10;
              break; }
       case 7 :{ angka4=12; angka3=12 ; angka2=12; angka1=11;
              break; }
       case 8 :{ angka4=12; angka3=12 ; angka2=12; angka1=12;
              break; }
       case 9 :{ angka4=13; angka3=12 ; angka2=12; angka1=12;
              break; }
       case 10 :{ angka4=14; angka3=12 ; angka2=12; angka1=12;
              break; }
       case 11 :{ angka4=14; angka3=13 ; angka2=12; angka1=12;
              break; }
       case 12 :{ angka4=14; angka3=14 ; angka2=12; angka1=12;
              break; }
       case 13 :{ angka4=14; angka3=14 ; angka2=13; angka1=12;
              break; }
       case 14 :{ angka4=14; angka3=14 ; angka2=14; angka1=12;
              break; }
       case 15 :{ angka4=14; angka3=14 ; angka2=14; angka1=13;
              break; }
       case 16 :{ angka4=14; angka3=14 ; angka2=14; angka1=14;
              break; }
       default :{ angka4=14; angka3=14 ; angka2=14; angka1=14;
              break; }
         }

}



>>>INISIALISASI COUNTER<<

Counter 0 adalah counter 8 bit, sedangkan Counter 1 adalah 16 bit. Silahkan membaca terlebih dahulu penjelasan mengenai counter dan timer disini.

void init_ctr(void) //COUNTER 0 8 BIT untuk pindah kolom 7 segmen
{
  
   
   TCCR0A |= (1 << WGM01); // Configure timer 0 for CTC mode
   TIMSK |= (1 << OCIE0A); // Enable CTC interrupt
   OCR0A   = 50; // Set CTC compare value  till blink disapear at 1MHz AVR clock, with a prescaler of 64
   TCCR0B |= (1 << CS01)|(1 << CS00); // Start timer at Fcpu/64
   
   
}


void init_ctr1(void) //COUNTER 1 untuk penghitung pulsa saat 600ms
{
   
   TCCR1B |= (1 << WGM12); // Configure timer 1 for CTC mode
   TIMSK |= (1 << OCIE1A); // Enable CTC interrupt 
   OCR1A  = 586; //compare the CTC A = 600ms =586
   TCCR1B |= ((1 << CS10) | (1 << CS12)); // Start timer at Fcpu/1024

}




>>>INTERRUPT TIMER<<


ISR(TIMER1_COMPA_vect) //interrupt timer 1 (16 bit)  untuk capture jumlah pulsa 

{ uint16_t rpm,anime; //variabel

anime=0;
rpm=0;

switch(kalibrasi) {  //Pemilih kalibrasi
      case 1 :{ 
          rpm=number/100;
    break; }

      case 2 :{ 
          rpm=number/10;
    break; }

      case 3 :{ 
          rpm=number;
    break; }

      case 4 :{ 
          rpm=number*10;
    break; }

      case 5 :{ 
          rpm=number*100;
    break; }
      
   case 6 :{ 
          anime=1;
    break; }
      
   case 7 :{ 
          anime=2;
    break; }

    }

  //Pemilih antara angka rpm atau animasi level
switch(anime) { 

case 0 : { //ANGKA RPM

OCR1A  = 586;
angka1 = rpm%10;

if(rpm>9) angka2 = ((rpm%100) - (rpm%10)) /10 ;
else angka2=10;

if(rpm>99) angka3 = ((rpm%1000) - (rpm%100)) /100 ;
else angka3=10;

if(rpm>999) angka4 = ((rpm%10000) - (rpm%1000)) /1000 ;
else angka4=10;
  
break ; }

case 1 : {  //ANIMASI MODE 1
OCR1A  = 100;
animasi(number/10);
  
break ; }
         
case 2 : {  //ANIMASI MODE 2
OCR1A  = 100;
animasi(number/50);

break ; }

  }


number=0;

}

ISR(TIMER0_COMPA_vect) // timer 0 (8 bit) untuk pindah kolom 7 segmen
{

//tiap segmen yg akan dinyalakan akan diberikan logic High

segstep++;

  switch(segstep) {  
      case 1 :{  conv_segmen(10);
              PORTD |= _BV(PD0);
                 PORTD &= ~_BV(PD1) & ~_BV(PD4) & ~_BV(PD5)  ;  
                    conv_segmen(angka4);
     break;
                  }
 
         case 2 :{  conv_segmen(10);
              PORTD |= _BV(PD1);
                 PORTD &= ~_BV(PD0) & ~_BV(PD4) & ~_BV(PD5)  ;  
                    conv_segmen(angka3);
     break;
                  }
         case 3 :{  conv_segmen(10);
              PORTD |= _BV(PD4);
                 PORTD &= ~_BV(PD1) & ~_BV(PD0) & ~_BV(PD5)  ;  
                    conv_segmen(angka2);
     break;
                  }
         case 4 :{  conv_segmen(10);
              PORTD |= _BV(PD5);
                 PORTD &= ~_BV(PD1) & ~_BV(PD4) & ~_BV(PD0)  ;  
                    conv_segmen(angka1);
     segstep=0;
     break; 
         }

                 }


}


>>>COUNTER INTERRUPT dari BUSI<<

SIGNAL (SIG_INT0) //INTERRUPT 0 menghitung pulsa dari radiasi CDI vs BUSI
{
number++;

}



>>>TOMBOL<<

void tombol(void)
{


if(bit_is_clear(PIND, PIND3)) //pembacaan pada pin D3

{ valid++;  //validasi penekanan
_delay_ms(10);
}

if( valid >= 50) //jika melebihi noise motor/getaran, ubah suai nilai ini
{ 

valid=0;
kalibrasi++; //ubah kalibrasi



if (kalibrasi >= 8) kalibrasi=1;

conv_segmen(10);


//Menulis nilai kalibrasi ke EEPROM 
eeprom_write_byte((uint8_t*)20, kalibrasi); 
_delay_ms(500);


  }
}


>>>MEMBACA EEPROM  nilai KALIBRASI<<

void baca_eeprom(void)
{

kalibrasi = eeprom_read_byte((uint8_t*)20);

if(kalibrasi == 0xFF) kalibrasi=3;


}



>>>MAIN PROGRAM<<

int main(void)
{

//Inisialisasi Interrupt
        GIMSK |= (1<<INT0) ; // inetrupt untuk hitung pulsa busi
   MCUCR |= (1<<ISC01)| (1<<ISC11); //fall edge 
//Inisialisasi PIN ATTINY2313 
 DDRD |= _BV(PD0) | _BV(PD1) | _BV(PD4) | _BV(PD5)  ; // segmen select / common scans
 DDRB |= _BV(PB0) | _BV(PB1) | _BV(PB2) | _BV(PB3) | _BV(PB4) | _BV(PB5) | _BV(PB6) ; // seg a,b,c,d,e,f,g
    
 DDRD &= ~_BV(PD3) ; // Input kalibrasi

init_ctr(); //hidupkan COUNTER0
sei();

_delay_ms(1000);


//tampilan kata ke 2, sesuaikan dengan kebutuhan atau hapus jika tidak mau

angka1=16 ;
angka2=1 ;
angka3=19 ;
angka4=18 ;


_delay_ms(1000);

init_ctr1(); //hidupkan COUNTER 1

baca_eeprom(); // baca nilai kalibrasi 



//muter terussssss
while(1)

{
tombol();

}


}




videonya....seperti dibawah ini





tips: Tegangan pada lampu depan/ langsung dari coil bisa berlebih jika akimu rusak/habis. Jadi usahakan mencari sumber tegangan yg tidak merusak regulator 7805


 Selamat Mencoba
Share:

9 komentar:

  1. Kalau mau pesen jadi brapa ya? soalnya gk bisa isi program

    BalasHapus
  2. .. ato beli ic yg udah terprogram..saja berapa ya?
    gabung di facebook com groups kumpulanskema saja gan.. lebih banyak temen temen kita riset bareng2.. :-)

    BalasHapus
  3. belajar mrogram aja...ga rugi kok daripada ic lgsg pake

    BalasHapus
  4. Klo indikatorny pk led bar & motorny injeksi bs g mas?
    cz nyoba pk rpm meter yg dijual dipasaran kurang akurat cz jd krng 1/2 pembacaanny...

    BalasHapus
  5. Injeksi mungkin lebih susah, dan seinget saya di system injeksi ada electronics nya yg bisa dibaca rpm nya, mungkin ke forum blog otomotif lebih bagus

    Akurasi? Selama belum baca putaran mesin langsung atau tap di pulsa cdi secara langsung dijamin akurasi kurang ..

    BalasHapus
  6. Mas saya bikin tachometer dari arduino..sistemnya sama,
    Tegangan Yg harus ke interupt itu apa harus 5 volt,biar logika high
    Soalx pux saya kurang dari 5 volt,,

    BalasHapus
  7. Mas saya bikin tachometer dari arduino..sistemnya sama,
    Tegangan Yg harus ke interupt itu apa harus 5 volt,biar logika high
    Soalx pux saya kurang dari 5 volt,,

    BalasHapus
  8. Mas nyoman, jika mau merubah menjadi 5digit apa yang perlu dirubah dari skripnya?

    BalasHapus
  9. Mas nyoman kalo 7 segmentnya di janti sma led scrip yang harus dirubah yang mana dan seperti apa.? Terimakasih

    BalasHapus

Kontak Langsung



12179018.png (60×60)
+628155737755

HP: 081331339072
Mail : ahocool@gmail.com

ANTI SPAM !



Blog Ini Mendukung Blogger Indonesia Yang Jujur dan Memberikan Informasi Sebenarnya, Bukan Menyampah Demi $Rp$ Yang Hanya Merendahkan Blogger Indonesia

Site View

Categories

555 (6) 7 segmen (3) adc (3) amplifier (1) analog (9) android (11) attiny (1) attiny2313 (16) blog (1) bluetooth (1) cmos (1) dasar (31) display (2) gcc (1) infrared (2) Input Output (3) jam (6) jualan (10) kereta api (1) keyboard (1) keypad (3) kios pulsa (2) kit (6) komponen (9) komputer (3) komunikasi (1) kontrol (2) lain-lain (8) lcd (2) led (9) led matrix (6) line tracer (1) lm35 (1) memory (1) metal detector (4) microcontroller (48) mikrokontroller (1) mikrotik (4) paket belajar (19) palang pintu otomatis (1) pcb (2) project (33) proyek (1) radio (3) remote (1) revisi (1) rfid (1) robot (1) rpm (2) rs232 (1) script break down (3) sdcard (3) sensor (1) sharing (2) sms (5) software (16) tachometer (2) telepon (7) televisi (16) transistor (1) troubleshoot (3) tulisan (34) tutorial (67) vu meter (1) vumeter (1) wav player (3) wayang (1) wifi (1)

Diskusi


kaskus
Forum Hobby Elektronika