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 :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
#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

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