Pengukuran kecepatan objek (dua arah) dengan Arduino dan photo dioda menggunakan metode interupsi serta timer

Manfaat mengukur kecepatan benda menggunakan arduino antara lain : pengukuran laju kendaraan/mobil, mencari kecepatan bandul, menentukan kecepatan benda jatuh, mengukur laju pukulan dan lain-lain.

Prinsip kerja menentukan kecepatan benda pada arduino adalah mendeteksi objek melewati dua sensor photodioda yang disinari dengan infra merah dari LED dengan jarak yang diketahui. Ketika sebuah objek melewati photodioda dan menghalangi sinar sumbernya, maka photodioda akan memberikan sinyal aktif ke arduino melalui jalur interupsi sebagai nilai awal, demikian pula ketika objek melewati photodioda kedua yang disimpan sebagai nilai akhir. Pembagian antara jarak sensor dengan waktu ini akan diperoleh kecepatan.

Pengukuran kecepatan dengan arduino (dalam meter/detik atau km/jam) mengharuskan perhitungan waktu yang efektif guna memperoleh hasil pengukuran yang akurat. Kesalahan 1 mili detik saja akan menghasilkan perbedaan kecepatan yang cukup jauh. untuk mengurangi resiko ini bisa dilakukan dengan menambah jarak sensor.

berikut skema perancangan mencari kecepatan objek dengan arduino:

catatan: photodioda dipasang terbalik (plus ke ground dan minus ke pin Arduino pullup) agar menghasilkan output berupa digital signifikan.

program atau sketch menentukan kecepatan benda menggunakan arduino :

#define sensor1 2
#define sensor2 3
#define jarakSensor 0.05 //meter
#define waktuTick 1/8000000 //detik
#define mpsKekmph 3.6

volatile uint16_t waktuA;
volatile uint16_t waktuB;
volatile uint16_t overflowTimer;
volatile bool dariA;
volatile bool dariB;
volatile bool sampaiA;
volatile bool sampaiB;
double Kecepatan;

void setup() {
  Serial.begin(9600);
  Serial.println("Pengukuran kecepatan objek (dua arah) dengan Arduino");
  Serial.println("dan photo dioda menggunakan metode interupsi serta timer");
  Serial.println("https://www.project.semesin.com");

  pinMode(sensor1, INPUT_PULLUP);
  pinMode(sensor2, INPUT_PULLUP);
  
  EIFR |= _BV(INTF1) |_BV(INTF0);
  TIMSK1 |= _BV(TOIE1);
  TCCR1A = 0;

  attachInterrupt(digitalPinToInterrupt(sensor1), objekMelewatiA, RISING);
  attachInterrupt(digitalPinToInterrupt(sensor2), objekMelewatiB, RISING);
}

void loop() {
  if(dariA && sampaiB)
  {
    Kecepatan = 1.0 * jarakSensor / ((double)waktuTick * ((uint32_t)waktuB + (overflowTimer * 65535)));
    Serial.print("Kecepatan = ");
    printDouble(Kecepatan, 6);
    Serial.print(" meter/detik (");
    printDouble(Kecepatan * mpsKekmph, 6);
    Serial.println(" km/jam) dari A ke B");
    dariA = false;  
    sampaiB = false;  
  }
  else if(dariB && sampaiA)
  {
    Kecepatan = 1.0 * jarakSensor / ((double)waktuTick * ((uint32_t)waktuA + (overflowTimer * 65535)));
    Serial.print("Kecepatan = ");
    printDouble(Kecepatan, 6);
    Serial.print(" meter/detik (");
    printDouble(Kecepatan * mpsKekmph, 6);
    Serial.println(" km/jam) dari B ke A");
    dariB = false;  
    sampaiA = false;  
  }
  else if(dariA || dariB)
  {
    if(overflowTimer > 5000)
    {
      dariA = false;
      dariB = false;
      TCCR1B = 0;
      Serial.println("Terlalu lambat");
    }
  }
}

void objekMelewatiA()
{
  if(dariB)
  {
    waktuA = TCNT1;
    TCCR1B = 0;
    sampaiA = true;
  }
  else
  {
    TCNT1 = 0;
    TCCR1B = _BV(CS10);
    TIFR1 |= _BV(TOV1);
    overflowTimer = 0;
    dariA = true;
  }
}
void objekMelewatiB()
{
  if(dariA)
  {
    waktuB = TCNT1;
    TCCR1B = 0;
    sampaiB = true;
  }
  else
  {
    TCNT1 = 0;
    TCCR1B = _BV(CS10);
    TIFR1 |= _BV(TOV1);
    overflowTimer = 0;
    dariB = true;
  }
}

ISR(TIMER1_OVF_vect)
{
  overflowTimer++;
}

void printDouble(double nilai, byte belakangKoma)
{
  if(nilai < 0.0)
  {
    Serial.print('-');
    nilai = -nilai;
  }
  
  Serial.print ((long)nilai);
  if( belakangKoma > 0) 
  {
    Serial.print(".");
    unsigned long frac;
    unsigned long mult = 1;
    byte padding = belakangKoma - 1;
    while(belakangKoma--)
    {
      mult *=10;
    }
    if(nilai >= 0)
    {
      frac = (nilai - int(nilai)) * mult;
    }
    else
    {
      frac = (int(nilai)- nilai ) * mult;
    }
    unsigned long frac1 = frac;
    while( frac1 /= 10 )
    {
      padding--;
    }
    while(  padding--)
    {
      Serial.print("0");
    }
    Serial.print(frac,DEC) ;
 }
}

16 thoughts on “Pengukuran kecepatan objek (dua arah) dengan Arduino dan photo dioda menggunakan metode interupsi serta timer

    1. Tampilannya di serial monitor (arduino) baud 9600

      contohnya


      Pengukuran kecepatan objek (dua arah) dengan Arduino
      dan photo dioda menggunakan metode interupsi serta timer
      https://www.project.semesin.com
      Kecepatan = 30.1125 meter/detik (108.405 km/jam) dari B ke A

  1. EIFR |= _BV(INTF1) |_BV(INTF0);
    TIMSK1 |= _BV(TOIE1);
    TCCR1A = 0;

    ini dapat drimana ya bang
    bisa dijelasin istilah istilah singkatan di program ini

  2. bang bisa dibuatkan video hasilnya bang ? atau video simulasi dengan menggunakan radio control. mungkin bisa buat youtube atau di masukin videonya di blog ini. terima kasih

  3. Bang,

    Kalau saya dibikinkan alat utk mengukur kecepatan dalam m/s dengen tampilan 2-3 digit dibelakang koma, kecepatan max 10.00 m/s, apakah bisa ?

    terimakasih

  4. Bang Asep,

    pada baris:
    attachInterrupt(digitalPinToInterrupt(sensor1), objekMelewatiA, RISING);
    attachInterrupt(digitalPinToInterrupt(sensor2), objekMelewatiB, RISING);

    dibilang kalau objekMelewatiA dan objekMelewatiB belum di define sebelumnya, apakah harus di define terlebih dahulu ?
    Kalau mau define objekMelewatiA atau B, ditulis apa Bang

    mohon saran

    terimakasih

    1. bisa saja, hapus bagian-bagian yang tidak diperlukan pada blok program ini

      Serial.print("Kecepatan = ");
      printDouble(Kecepatan, 6);
      Serial.print(" meter/detik (");
      printDouble(Kecepatan * mpsKekmph, 6);
      Serial.println(" km/jam) dari B ke A");

Leave a Reply to megiantoro Cancel reply

Your email address will not be published. Required fields are marked *