Pada artikel ini diuraikan pembuatan lampu kedip berbasis mikrokontroler Arduino Nano ATmega328 dengan model Finite State Machine (FSM). Lampu kedip sebenarnya dapat juga dibuat dengan menggunakan model flowchart biasa. Tujuan tulisan ini untuk menunjukkan teknik implementasi FSM yang sederhana. Untuk sistem yang sangat sederhana seperti lampu kedip biasa, penggunaan FSM mungkin berlebihan (overkill). Pada sistem yang kompleks, penggunaan FSM akan sangat memudahkan. Implementasi FSM dalam bentuk perangkat lunak agak rumit, memerlukan latihan. Untuk itu pada artikel ini ditunjukkan tahap implementasi FSM yang sederhana dulu. Setelah dapat memahami artikel ini, dapat dilanjutkan dengan membuat FSM yang lebih kompleks.
Daftar Isi
Spesifikasi
Sistem yang dibuat adalah lampu kedip, dengan perioda 2 detik.
Perangkat Keras
Perangkat lunak dengan Arduino Nano ATmega328. Output dengan LED yang diseri dengan resistor pembatas arus. Nilai resistor tidak kritis. Pada percobaan ini dipakai nilai resistor 1000 ohm. LED disambung ke port D3 pada Arduino Nano.
Model Sistem
Model FSM untuk lampu kedip adalah sebagai berikut.
Pada sistem ini tidak ada input.
FSM dievaluasi setiap detik.
Notasi FSM pada gambar ini diadopsi dari buku Lee & Seshia “Introduction to Embedded Systems”.
Kondisi awal sistem adalah state OFF, dengan lampu mati. Pada state OFF, state berikutnya adalah ON, tanpa syarat. Maka pada panah dari OFF ke ON diberi syarat ‘true’, artinya transisi ini selalu terjadi tanpa syarat apapun. Transisi ini menyebabkan state berganti menjadi ON, dan lampu output menyala. Output aktif ditandai dengan ‘out=1’.
Pada state ON, state selanjutnya adalah OFF tanpa syarat. Maka syarat transisi dari ON ke OFF adalah ‘true’. Setiap kali transisi ini, output sistem adalah 1, maka ditulis sebagai ‘out=0’.
Perangkat Lunak
Pada sistem ini diperlukan pewaktuan (timing) agar lampu berkedip dengan frekuensi 0,5 Hz. Untuk itu diperlukan FSM yang dihitung/dipanggil setiap 1 detik. Untuk membuat pemanggilan periodik seperti ini dapat dilakukan dengan beberapa cara sebagai berikut:
- delay pada Arduino atau library lain
- interupsi timer
- delay pada Real Time Operating System misal FreeRTOS
Pada implementasi ini yang dibuat adalah menggunakan delay dengan Arduino
Model diagram alir (flowchart) software adalah sebagai berikut.
Implementasi perangkat lunak dapat dilihat di file berikut ini: https://github.com/waskita/embedded/blob/master/kedip/nano-fsm/nano-fsm.ino
Penjelasan isi source code sebagai berikut.
Pendefinisian state
#define ON 100
#define OFF 101
Inisialisasi FSM
void fsm_init(int *state, int *out) {
*state = OFF;
*out = 0;
}
Implementasi Finite State Machine
Finite State Machine diimplementasikan di fungsi fsm(). Pada fungsi ini ada 2 state yang ditangani yaitu ON dan OFF. Pemilihan state dilakuan dengan perintah switch() di bahasa C. Pada setiap case diimplementasikan setiap transisi yang ada pada model FSM di atas.
Fungsi ini tidak menggunakan global variabel maupun static variabel, supaya didapat kode yang lebih aman.
Output dari fungsi diberikan dengan passing pointer pada fungsi. Ada 2 parameter yaitu state (state dari FSM) dan out (output). Kedua parameter diberikan menggunakan pointer.
void fsm(int *state, int *out) {
switch (*state) {
case ON: {
*state = OFF;
*out = 0;
break;
}
case OFF: {
*state = ON;
*out = 1;
break;
}
}
}
Implementasi FSM ini menggunakan kode C standar yang dapat dijalankan di semua mikrokontroler. Akses ke port output dipisahkan ke fungsi fsm_output(). Tujuannya agar fungsi ini dapat dengan mudah diporting ke mikrokontroler lain.
Inisialisasi sistem
void setup() {
pinMode(LED_BUILTIN, OUTPUT);
pinMode(LED_OUTPUT, OUTPUT);
Serial.begin(115200);
int output = 0;
fsm_init(&state);
fsm_output(output);
}
Superloop / Main loop
Berikut ini potongan kode dari main loop.
void loop() {
int output = 0;
fsm(&state, &output);
fsm_output(output);
Serial.print("state: ");
Serial.print(state);
Serial.print(" output: ");
Serial.print( output);
Serial.println();
delay(500);
digitalWrite(LED_BUILTIN, LOW);
delay(500); //
digitalWrite(LED_BUILTIN, HIGH);
}
Proses yang dilakukan di main loop adalah sebagai berikut:
- Perhitungan nilai state di FSM
- Output ke pin output digital dengan fungsi fsm_output()
- mencetak status FSM ke port serial. Data yang dicetak meliputi state dan output. Jika FSM memiliki input ataupun variabel pada extended state machine, maka nilai-nilai ini juga perlu dicetak.
- Melakukan delay selama 1 detik. Pada implementasi delay ini ditambahkan fitur lampu kedip, sehingga LED_BUILTIN akan berkedip dengan frekuensi sekitar 1 Hz. Lampu kedip 1 Hz ini fungsinya untuk menunjukkan waktu terjadinya perubahan state. Frekuensinya tidak akan tepat sekali di 1 Hz, namun untuk sistem ini sudah dapat dianggap cukup baik.
Output FSM
Fungsi fsm_output() adalah menerjemahkan output dari FSM ke pin output pada mikrokontroler.
void fsm_output(int output_value) {
if (output_value == 1) {
digitalWrite(LED_OUTPUT, HIGH);
} else {
digitalWrite(LED_OUTPUT, LOW);
}
}
Pengujian
Pengujian dilakukan dengan menjalankan program, kemudian mengamati kedipan lampu dan output ke port serial.
Pada output serial akan muncul tampilan seperti berikut ini
11:08:45.511 -> state: 100 output: 1
11:08:46.493 -> state: 101 output: 0
11:08:47.517 -> state: 100 output: 1
11:08:48.492 -> state: 101 output: 0
Dari output serial tersebut dapat diamati perubahan state dan output serta waktu kejadiannya. Dari output di atas dapat disimpulkan bahwa lampu berkedip dengan perioda sekitar 2 detik. Perubahan state juga sesuai dengan model FSM.
Video
Under construction