Penggunaan Timer dan Interrupt pada Mikrokontroler Arduino

Tujuan Pembelajaran
- Memahami konsep timer dan interrupt pada Arduino.
- Mampu mengimplementasikan timer untuk pengukuran waktu dan kontrol sistem.
- Mengaplikasikan interrupt untuk respons cepat dalam pengendalian sistem.
- Menerapkan studi kasus kontrol waktu pada sistem proses kilang migas.
Konsep Timer dan Pengatur Waktu
Apa itu Timer?
- Timer adalah modul hardware di dalam mikrokontroler yang menghitung pulsa clock untuk mengukur interval waktu.
- Arduino (ATmega328P) memiliki 3 timer: Timer0 (8-bit), Timer1 (16-bit), dan Timer2 (8-bit).
- Prescaler: Pembagi frekuensi clock untuk mengatur kecepatan timer (nilai umum: 1, 8, 64, 256, 1024).
Rumus Perhitungan Timer
Interval Waktu (detik) = (Nilai Compare Match × Prescaler) / Frekuensi Clock (16 MHz)
Contoh: Untuk Timer1 dengan prescaler 1024 dan nilai compare match 15624:
Interval = (15624 × 1024) / 16.000.000 = 1 detik
Penjelasan Variabel dalam Rumus
- Nilai Compare Match
- Merupakan nilai yang akan dibandingkan dengan counter timer.
- Saat counter mencapai nilai ini, timer menghasilkan interrupt atau aksi tertentu.
- Prescaler
- Faktor yang digunakan untuk memperlambat frekuensi clock sebelum masuk ke timer.
- Contoh nilai prescaler umum: 1, 8, 64, 256, 1024.
- Frekuensi Clock (Clock Frequency)
- Merupakan kecepatan clock dari mikrokontroler.
- Pada mikrokontroler ATmega328 (Arduino Uno), nilai default adalah 16 MHz (16.000.000 Hz).
Contoh Perhitungan
Misalkan kita menggunakan Timer1 dengan:
- Nilai Compare Match = 15624
- Prescaler = 1024
- Frekuensi Clock = 16 MHz (16.000.000 Hz)
Hitung interval waktu yang dihasilkan:
Bagaimana Timer Bekerja?
- Timer akan menghitung dari 0 hingga 15624.
- Setiap satu langkah perhitungan timer berlangsung selama (prescaler / frekuensi clock) detik.
- Ketika timer mencapai 15624, interrupt akan dipicu atau aksi tertentu dilakukan.
- Proses ini diulang untuk menciptakan interval 1 detik.
Fungsi Bawaan Arduino
-
millis()
millis()
adalah fungsi yang mengembalikan waktu dalam milidetik sejak Arduino mulai berjalan.- Waktu ini tidak akan berhenti atau reset kecuali Arduino di-reset atau mengalami overflow (sekitar 50 hari untuk tipe data
unsigned long
). - Digunakan untuk mengukur waktu tanpa menghentikan program, cocok untuk sistem multitasking atau real-time.
- Keunggulan
millis()
: Tidak menghentikan eksekusi program, sehingga sistem bisa tetap melakukan tugas lain.
-
delay()
delay(ms)
menghentikan sementara eksekusi program selamams
milidetik.- Selama
delay()
, Arduino tidak bisa menjalankan tugas lain. - Tidak disarankan untuk sistem real-time karena membuat sistem tidak responsif terhadap input lain.
- Kelemahan
delay()
: Program terhenti sementara, membuat Arduino tidak bisa menangani input lain seperti sensor atau komunikasi serial.
Kesimpulan
Fungsi | Keunggulan | Kelemahan | Kapan Digunakan? |
millis() | Bisa multitasking, cocok untuk real-time | Harus menggunakan variabel dan logika tambahan | Jika butuh waktu tanpa menghentikan program (misal: LED berkedip, pembacaan sensor berkala) |
delay() | Mudah digunakan, sederhana | Menghentikan eksekusi program, tidak cocok untuk sistem real-time | Jika tidak ada tugas lain yang perlu dijalankan selama delay |
Jadi, untuk sistem real-time seperti kontrol motor, komunikasi serial, atau multitasking, millis() lebih disarankan dibanding delay(). 🚀
Implementasi Timer untuk Pengukuran dan Kontrol Sistem
Contoh 1: Timer dengan Library millis()
unsigned long previousMillis = 0; const long interval = 1000; // 1 detik void setup() { Serial.begin(9600); } void loop() { unsigned long currentMillis = millis(); if (currentMillis - previousMillis >= interval) { previousMillis = currentMillis; Serial.println("1 detik telah berlalu!"); } }
Contoh 2: Timer Menggunakan Register (Mode CTC)
void setup() { Serial.begin(9600); // Atur Timer1 untuk mode CTC (Clear Timer on Compare Match) TCCR1A = 0; TCCR1B = (1 << WGM12) | (1 << CS12) | (1 << CS10); // Prescaler 1024 OCR1A = 15624; // Interval 1 detik TIMSK1 = (1 << OCIE1A); // Aktifkan interrupt compare match } ISR(TIMER1_COMPA_vect) { Serial.println("Interrupt Timer1: 1 detik!"); } void loop() {}
Contoh 3: Timer Menggunakan delay
void setup() { pinMode(13, OUTPUT); } void loop() { digitalWrite(13, HIGH); delay(1000); // Tunggu 1 detik digitalWrite(13, LOW); delay(1000); // Tunggu 1 detik }
Jenis Interrupt & Implementasi di Arduino
Interrupt adalah mekanisme dalam mikrokontroler yang memungkinkan eksekusi suatu fungsi secara otomatis saat ada kejadian tertentu, tanpa harus menunggu dalam loop utama (loop()). Interrupt sangat penting dalam sistem real-time, karena memungkinkan mikrokontroler merespons event secara instan.
1. Jenis Interrupt
A. Hardware Interrupt
🔹 Dipicu oleh sinyal eksternal yang masuk melalui pin khusus di mikrokontroler.
🔹 Contoh pada Arduino Uno:
- INT0 → Pin 2
- INT1 → Pin 3
🔹 Contoh kasus:
- Tombol darurat (emergency stop) pada mesin.
- Sensor yang mendeteksi objek dan langsung menghentikan motor.
- Deteksi pulsa encoder pada motor.
🔹 Contoh Implementasi Hardware Interrupt di Arduino
Kode berikut akan menjalankan fungsi tombolInterrupt() saat tombol ditekan (rising edge).
const int tombolPin = 2; // Menggunakan pin 2 (INT0) volatile bool statusLED = false; void setup() { pinMode(LED_BUILTIN, OUTPUT); pinMode(tombolPin, INPUT_PULLUP); // Mengaktifkan interrupt pada pin 2 saat sinyal berubah dari LOW ke HIGH attachInterrupt(digitalPinToInterrupt(tombolPin), tombolInterrupt, RISING); } void loop() { digitalWrite(LED_BUILTIN, statusLED); // LED nyala/mati sesuai statusLED } // Fungsi yang akan dijalankan saat interrupt terjadi void tombolInterrupt() { statusLED = !statusLED; // Toggle LED }
B. Software Interrupt
🔹 Dipicu oleh event internal, misalnya:
- Timer Overflow (saat timer mencapai nilai maksimum).
- Serial Communication (misalnya, saat ada data masuk dari UART).
🔹 Contoh kasus:
- Menjalankan fungsi setiap 1 detik dengan Timer Interrupt.
- Memproses data secara otomatis saat ada input dari komunikasi serial.
🔹 Contoh Implementasi Timer Interrupt (Timer1) di Arduino
Kode ini menjalankan Timer1 Interrupt setiap 1 detik.
void setup() { noInterrupts(); // Matikan interrupt sementara TCCR1A = 0; // Timer1 mode normal TCCR1B = (1 << WGM12) | (1 << CS12) | (1 << CS10); // Prescaler 1024 OCR1A = 15624; // Nilai Compare Match untuk 1 detik TIMSK1 = (1 << OCIE1A); // Aktifkan Timer1 Compare Match Interrupt interrupts(); // Aktifkan kembali interrupt } ISR(TIMER1_COMPA_vect) { digitalWrite(LED_BUILTIN, !digitalRead(LED_BUILTIN)); // Toggle LED setiap 1 detik }
2. Sintaks attachInterrupt() di Arduino
Digunakan untuk mengaktifkan hardware interrupt pada pin tertentu.
Format:
attachInterrupt(digitalPinToInterrupt(pin), ISR, mode);
Parameter | Penjelasan |
pin | Pin digital tempat interrupt diaktifkan (gunakan digitalPinToInterrupt(pin)) |
ISR | Fungsi yang akan dipanggil saat interrupt terjadi (tanpa parameter & tanpa return) |
mode | Jenis sinyal yang memicu interrupt: |
RISING | Memicu saat sinyal berubah dari LOW ke HIGH |
FALLING | Memicu saat sinyal berubah dari HIGH ke LOW |
LOW | Memicu selama sinyal dalam kondisi LOW |
CHANGE | Memicu saat ada perubahan sinyal (HIGH ke LOW atau LOW ke HIGH) |
HIGH | Memicu selama sinyal dalam kondisi HIGH (tidak didukung di semua board) |
Kesimpulan
🔹 Hardware Interrupt digunakan untuk menangani event eksternal seperti tombol, sensor, atau pulsa encoder.
🔹 Software Interrupt digunakan untuk event internal seperti timer overflow atau komunikasi serial.
🔹 attachInterrupt() digunakan untuk menangani hardware interrupt dengan berbagai mode pemicu (RISING, FALLING, dll).
🔹 Interrupt memungkinkan Arduino merespons event dengan cepat, tanpa perlu polling di loop(), sehingga cocok untuk sistem real-time.
simulasi di Proteus atau implementasi di Arduino Tentang Interupt! 🚀
Studi Kasus: Kontrol Waktu pada Proses Kilang Migas
Deskripsi Sistem
Sebuah reaktor di kilang migas membutuhkan:
- Pembacaan tekanan setiap 5 detik menggunakan sensor tekanan.
- Emergency shutdown jika tekanan melebihi 100 PSI.
- Log data setiap 1 menit.
Implementasi dengan Timer dan Interrupt
#include <SD.h> volatile bool timerFlag = false; volatile bool emergencyFlag = false; const int pressureSensor = A0; const int emergencyPin = 3; const int relayValve = 4; void setup() { Serial.begin(9600); pinMode(relayValve, OUTPUT); // Atur Timer2 untuk interrupt 5 detik TCCR2A = 0; TCCR2B = (1 << CS22) | (1 << CS21) | (1 << CS20); // Prescaler 1024 OCR2A = 78; // 5 detik TIMSK2 = (1 << OCIE2A); // Interrupt emergency attachInterrupt(digitalPinToInterrupt(emergencyPin), emergencyISR, RISING); } ISR(TIMER2_COMPA_vect) { timerFlag = true; } void emergencyISR() { emergencyFlag = true; } void loop() { if (timerFlag) { int pressure = analogRead(pressureSensor); if (pressure > 100) { digitalWrite(relayValve, HIGH); // Buka valve } timerFlag = false; } if (emergencyFlag) { digitalWrite(relayValve, LOW); // Tutup valve darurat emergencyFlag = false; } }
Pertimbangan Keamanan di Kilang Migas
- Gunakan dual redundancy untuk sensor dan interrupt.
- Tambahkan watchdog timer untuk mereset sistem jika terjadi hang.
- Simpan data log ke SD card untuk analisis pasca-insiden.
Evaluasi
- Soal Teori
- Jelaskan perbedaan antara timer dan interrupt!
- Mengapa penggunaan delay() tidak disarankan dalam sistem real-time?
- Soal Praktik
- Buat program untuk menyalakan LED setiap 2 detik menggunakan Timer1.
- Modifikasi studi kasus di atas untuk menambahkan log data suhu setiap 10 detik.
- Analisis Kasus
- Apa yang terjadi jika interrupt emergency tidak menggunakan variabel volatile?
Referensi
- Dokumentasi Resmi Arduino: https://www.arduino.cc/reference/en/
- Buku “Make: AVR Programming” oleh Elliot Williams.
- Standar Keamanan Sistem Kontrol Industri (ISA-84).