Berawal ketika mendapatkan sensor ultrasonic untuk ranging/deteksi jarak, jenis Ping)) (buatan paralax) dan berdasarkan datasheet diketahui bahwa sensor memiliki response terhadap jarak setelah diberikan trigger seperti gambar dibawah ini :
Setelah sinyal mendapatkan perintah melalui pulsa 10us pada pin SIG kemudian bagian Transmit dari ping)) akan mengeluarkan sinyal burst 20us dengan frekuensi 40khz, dan ketika mendapatkan halangan sebuah benda didepannya maka suara ultrasonic ini akan dipantulkan kembali dan kemudian dapat dibaca oleh sensor penerima ultrasonic.Penghitungan jarak berbanding terbalik dengan lama sinyal echo atau pantulan yang ditangkap oleh sensor, sehingga kita perlu menghitung lebar pulsa yang diterima balik oleh penerima ultrasonik.
Salah satu fungsi yang digunakan adalah fasilitas INPUT CAPTURE PIN (ICP) yang selalu dimiliki oleh fasilitas counter dari AVR. Maksudnya ICP adalah pin ini akan menangkap (melalui interupt) perubahan logic yg diberikan kepadanya. Saat capture terjadi maka sebuah register yaitu ICR akan mengambil timestamp dari sebuah timer yang sedang berjalan yaitu pada register TCNT . Prescaller dari timer masih berfungsi seperti halnya pada tutorial mengenai timer
Untuk mencobanya, perhatikan PIN dari ATTINY2313 berikut :
ICP berada paka pin no 11 (PD6) dan dapat dihubungkan menjadi input dari suatu frekuensi / sinyal pulsa TTL yang akan diukur. Permasalahannya adalah ketika ICP hanya mendeteksi satu sisi perubahan logic yaitu rising (0-1) atau falling (1-0) . Cara yang biasa dilakukan untuk mendapatkan frekuensi dari sinyal :
1. Mendeteksi 2 buah timestamp dan kemudian mencari selisihnya
2. Memanfaatkan pin INT (external interupt) sebagai pendeteksi edge yang arahnya berlawanan dengan ICP
sebelumnya kita akan memanfaatkan LCD 16x2 sebagai output dan tombol sebagai input pulsa yang akan kita baca lebarnya. Perhatikan terlebih dahulu tutorial menulis di LCD karena output akan kita tulis di LCD.
scriptnya seperti ini, kita akan membaca lebar dari ICP pada counter 16bit, dimana nilai yg muncul adalah 0-65335 , dimana tiap angka mewakili :
tick dari TCNT = 1 / (frekuensi xtal / prescaler) = prescaler / frek xtal
Code:
/* ==================== ICP TEST ATTINY2313 ahocool@gmail.com www.aisi555.com =====================*/ #define F_CPU 4000000UL //frek xtal #include <avr/io.h> #include <avr/interrupt.h> #include <string.h> #include <util/delay.h> #include "lcd.h" //baca dulu tutorial menulis di LCD //variabel tulisan char text1[]= " LEBAR PULSA"; char text2[]= " START "; char clear[]= " "; //fungsi sederhana untuk merubah angka ke ASCII void reverse(char s[]) { int c, i, j; for (i = 0, j = strlen(s)-1; i < j; i++, j--){ c = s[i]; s[i] = s[j]; s[j] = c; } } void itoa(uint16_t n, char s[]) { uint16_t i, sign; if ((sign = n) < 0) // record sign n = -n; // make n positive i = 0; do { // generate digits in reverse order s[i++] = n % 10 + '0'; // get next digit } while ((n /= 10) > 0); // delete it if (sign < 0) s[i++] = '-'; s[i] = '\0'; // add null terminator for string reverse(s); } //tulis menulis di LCD , kreasi sendiri oprekan pfleury library void tulis(uint8_t pos,uint8_t posx,uint8_t posy,uint16_t tulisan) { char dum; if(pos == 1) lcd_gotoxy(posx,posy); itoa(tulisan,&dum); lcd_puts(&dum); } //saat capture terjadi ISR(TIMER1_CAPT_vect) { uint16_t capture; capture = ICR1; //pindahkan nilai hasil capture lcd_gotoxy(0,1); lcd_puts(clear); tulis(1,0,1,capture); //hasil capture BCD tulis di LCD //yang dibawah ini gunakan jika ingin menampilkan detik sebenarnya //hilangkan yg diatas dan buka blok yg dibawah jika mau /* tulis(0,1,1,(capture / 62500) ); lcd_putc(','); tulis(0,6,1,(capture % 62500) ); lcd_puts(" detik"); */ } //pendeteksi edge logic yang lainnya SIGNAL (SIG_INT0) { TIFR |= (1<<ICF1); //clear interrupt-flag TCNT1=0; lcd_gotoxy(0,1); lcd_puts(text2); } int main(void) { //PIN OUTPUT ke LCD , liat skematik DDRD |= (1<<PD4)|(1<<PD5)|(1<<PD3); DDRB |= (1<<PB0)|(1<<PB1)|(1<<PB2)|(1<<PB3); //Input tombol paralel di ICP dan INT0 //yang ini menyatakan kalau INT0 akan mendeteksi ketika pulsa turun MCUCR |= (1<<ISC01) ; // faling edge GIMSK |= (1<<INT0); //yang ini menyatakan kalau ICP akan mendeteksi ketika pulsa naik //silahkan baca di datasheet ..lengkap broo TIMSK |=(1<<ICIE1); //enable input capture interrupt TCCR1B |=(1<<ICNC1)|(1<<ICES1)|(1<<CS11)|(1<<CS10); //Noise canceller, with 64 prescaler , rising edge icp sei();//hidupkan interupt lcd_init(LCD_DISP_ON); lcd_gotoxy(0,0); lcd_puts(text1); while(1) { } return 0; }
Mudah bukan ? selanjutnya penjelasan diatas dapat digunakan ke applikasi penghitung frekuensi, phase sinyal dan membaca ranging dari sensor pengukur jarak ultrasonic seperti PING)))
mas, icp dapat digunakan untuk mengukur rpm.
BalasHapus