Laman

Rabu, 15 Januari 2014

Menggunakan ping))) secara akurat dengan atmega16

Kali ini kita akan membahas penggunaan sensor ping))). Sensor ping))) adalah sensor yang berguna untuk mengukur jarak dengan memanfaatkan sinyal ultrasonik berfrekuensi (mungkin) 40 kHz. Sinyal ini  akan dipancarkan ping)))  dan dipantulkan benda didepannya. Waktu yang diperlukan sinyal tersebut untuk kembali di baca oleh ping)))  dapat kita konversi menjadi jarak antara sensor ping)))  terhadap benda yang ada didepannya. Untuk dapat mengakses ping))), begini caranya.

1. Pin diatur sebagai output
2. Kita kasih sinyal low selama 2 us (terserah, yang penting sinyal highnya 5 us)
3. Kita kasih sinyal high  selama 5 us
4. Pin kita atur jadi input
5. ping))) memancarkan ultrasonik dan pencacahan dimulai
5. Saat memancarkan ultrasonik, ping))) akan mengeluarkan sinyal high
6. Saat pantulan kembali lagi, ping))) akan bersinyal low
7. Saat pantulan terbaca, kita langsung kembalikan nilai bacaan timer ke fungsi utama.

Berikut gambaran rangkaian sederhananya.



Kode programnya
#include "mega16.h"
#include "delay.h"
#include "stdio.h"

#asm
   .equ __lcd_port=0x15 ;PORTC
#endasm
#include "lcd .h"

unsigned int cycle;
int i;
char yeah[33];
float siklus,waktutempuh;   //detik
float xtall=12000000; //xtal yang digunakan
float bunyi=3434;     //cepat rambat bunyi di udara, 344 m/s
float prescaller=64;     //prescaller yang di pilih
float jarak;

interrupt [TIM0_OVF] void timer0_ovf_isr(void)
{
cycle++;
}
      
unsigned int ping(void){
      DDRB.0 = 1;
      PORTB.0 = 0;
      delay_us(2);
      PORTB.0=1;
      delay_us(5);
      PORTB.0 = 0;
      DDRB.0 = 0;
      while(PINB.0==0){}
      TCNT0 = 0x00;           
      cycle = 0;
      while(PINB.0==1){}
      return (cycle * 256 + TCNT0);
      }

void main(void)
{   
TIMSK = 0x01;
TCCR0 = 0x03;
ACSR=0x80;
SFIOR=0x00;

lcd_init(16);
#asm("sei")
while (1)
      {
      i=ping();
      
      siklus=(float)prescaller/xtall;
      waktutempuh=(float)siklus*i/2;      
      jarak=(float)waktutempuh*340*1000;
      
      lcd_gotoxy(0,0);
      lcd_putsf("   UKUR JARAK   ");
      lcd_gotoxy(0,1);
      sprintf(yeah,"  %f mm  ",jarak);
      lcd_puts(yeah);

      delay_ms(400);                                                                    
      }
}

Disini aku menggunakan timer 0. Pada timer 0, maksimal intervalnya sampai dengan 256. Prescaler (pembagi) yang aku gunakan 64, sehingga TCCR0=0x03 (lihat datasheet). Nah dengan begitu aku mendapatkan frekuensi dari clock tersebut sebesar xtall dibagi prescaler (12MHz/64) yaitu sebesar 187.500 Hz. Untuk mengetahui periodanya, tinggal kiba bagi oleh satu (T = 1/f) sehingga kita dapatkan perioda untuk satu siklus adalah 0.000005333 detik untuk satu siklus. Maksudnya, kan timer satu mencacah dari 0-255, nah tiap cacahan dari 0 ke 1, atau dari 1 ke 2 memerlukan waktu sebanyak perioda.
interrupt [TIM0_OVF] void timer0_ovf_isr(void)
{
cycle++;
}
Kode diatas maksudnya sebagai overflow. Maksudnya, kan timer 0 hanya dapat menghitung sampai 255 (oleh TCNT0). Sehingga ketika sampai 255 dia akan mengulang lagi dari nol. Nah agar sebagai pertanda dia telah menyelesaikan sampai cacahan ke 255, maka kita tandai dengan naiknya nilai cycle sebanyak satu. sehingga dengan begitu timer satu seolah-olah dapat mencacah sampai ratusan ribu (mungkin). Untuk mengetahui berapa total cacahan, kita tinggal masukan kode ini.
return (cycle * 256 + TCNT0);
Nah sekarang kita udah tahu banyak cacahan. Sekarang kita hitung berapa waktu yang diperlukan sinyal tersebut untuk mengenai objek dan kembali lagi. Yaitu dengan mengalikan jumlah cacahan (i) dengan waktu yang diperlukan untuk satu cacahan (siklus). Itu kan waktu bolak-balik sinyal. Untuk mengetahui waktu yang diperlukan dari ping))) ke benda tinggal di bagi 2.
siklus=(float)prescaller/xtall;
waktutempuh=(float)siklus*i/2;
Untuk mengetahui jarak tinggal kita kalikan dengan kecepatan bunyi (s = v . t). Kecepatan bunyinya kita asumsikan saja 340 m/s. Nah, kita telah dapatkan jarak dalam satuan meter. Biar nggak ribet, kalikan aja dengan 1000 biar pengukuran dalam satuan milimeter.
jarak=(float)340*waktutempuh*1000;
Ohiya satu lagi yang penting. Biar presisi, jangan lupa kasih pengaturan di CVAVR-nya dengan cara memilih menu di bagian atas. Project > Configure > C Compiler > Code Generation. Lalu Pada bagian (s)printf Features: pilih bagian yang 'float, width, precision'. Lalu oke. Ini hasil nya.


Untuk program CVAVR lengkapnya dapat didownload disini