Struktur Program Arduino: Fungsi setup() dan loop()

Struktur program Arduino selalu bertumpu pada dua fungsi wajib, yaitu setup() dan loop(). Memahami peran keduanya sejak awal menghemat banyak kebingungan, karena hampir semua kesalahan pemula berakar dari menaruh kode di tempat yang salah. Artikel ini membedah kerangka program Arduino secara lengkap, mulai dari bagian di luar kedua fungsi tersebut sampai urutan eksekusinya dari detik pertama papan menyala.

Arduino Program Structure Infographic

Kerangka Minimum Program Arduino

Setiap sketch, sesederhana atau serumit apa pun, memiliki bentuk dasar berikut.

void setup() {
  // dijalankan satu kali
}

void loop() {
  // dijalankan berulang tanpa henti
}

Kedua fungsi ini wajib ada. Menghapus salah satunya membuat proses compile gagal, bahkan ketika isinya kosong.

Fungsi setup()

Fungsi setup() dijalankan satu kali saja, tepat setelah papan mendapat daya atau setelah tombol reset ditekan. Di sinilah seluruh persiapan dilakukan.

Yang Ditaruh di setup()

PerintahFungsi
pinMode(pin, MODE)Menentukan sebuah pin bekerja sebagai INPUT, OUTPUT, atau INPUT_PULLUP
Serial.begin(9600)Memulai komunikasi serial dengan komputer
dht.begin()Menyiapkan sensor atau modul sebelum dipakai
lcd.init()Menyalakan dan menyiapkan layar
Nilai awal variabelMemberi kondisi awal sebelum program utama berjalan

Patokannya sederhana: apa pun yang cukup dikerjakan sekali dan tidak perlu diulang, letakkan di setup().

Kapan setup() Dijalankan Ulang

  • Saat papan pertama kali diberi daya.
  • Saat tombol reset pada papan ditekan.
  • Saat Serial Monitor dibuka, karena tindakan ini memicu reset pada sebagian besar papan Arduino.
  • Saat daya tidak stabil sehingga papan restart sendiri, misalnya karena motor menarik arus berlebih.

Poin terakhir penting untuk diagnosis. Apabila Serial Monitor menampilkan pesan pembuka berulang kali, berarti papan Anda restart terus-menerus dan masalahnya hampir pasti pada catu daya.

Fungsi loop()

Setelah setup() selesai, loop() dijalankan berulang tanpa henti. Begitu baris terakhir dieksekusi, program kembali ke baris pertama dan mengulang, terus-menerus selama papan mendapat daya.

Seberapa Cepat loop() Berputar

Pada Arduino Uno yang berjalan di 16 MHz, sebuah loop() sederhana dapat berputar puluhan ribu kali per detik. Kecepatan inilah yang membuat pembacaan tombol terasa seketika.

Perlu diperhatikan, kecepatan tersebut langsung anjlok begitu Anda memakai delay(). Perintah delay(1000) membuat seluruh program berhenti total selama satu detik, dan selama itu tidak ada masukan yang terbaca.

Bagian di Luar setup() dan loop()

Kode di luar kedua fungsi tersebut bukan sekadar pelengkap. Bagian ini menentukan apa yang tersedia bagi seluruh program.

Baris #include

Selalu berada di paling atas, berfungsi memanggil library yang akan dipakai.

#include <Servo.h>
#include <Wire.h>

Baris #define dan const

Memberi nama pada nilai tetap. Memberi nama pada nomor pin membuat kode jauh lebih mudah dirawat, karena saat pin dipindah Anda cukup mengubah satu baris.

#define PIN_LED 13
const int PIN_TOMBOL = 2;
const unsigned long JEDA = 500;

Perbedaan keduanya: #define menggantikan teks sebelum proses compile, sedangkan const adalah variabel sungguhan yang memiliki tipe data. Untuk pemakaian sehari-hari, const lebih aman karena kesalahan tipe data akan terdeteksi saat compile.

Variabel Global

Variabel yang dideklarasikan di luar kedua fungsi dapat diakses dari mana saja dan nilainya bertahan antar putaran loop(). Ini yang membedakannya dari variabel lokal.

int jumlahKlik = 0;          // global, nilainya bertahan

void loop() {
  int bacaan = digitalRead(2);   // lokal, hilang tiap putaran
}

Karena SRAM Arduino Uno hanya 2 KB, jangan berlebihan membuat variabel global, terutama array berukuran besar.

Fungsi Buatan Sendiri

Ketika loop() mulai panjang, pindahkan bagiannya menjadi fungsi terpisah agar alur utamanya tetap mudah dibaca.

void nyalakanLampu(int durasi) {
  digitalWrite(PIN_LED, HIGH);
  delay(durasi);
  digitalWrite(PIN_LED, LOW);
}

void loop() {
  nyalakanLampu(500);
}

Variabel Lokal, Global, dan static

Tempat sebuah variabel dideklarasikan menentukan dua hal sekaligus: siapa yang dapat mengaksesnya, dan berapa lama nilainya bertahan.

JenisTempat DeklarasiUmur Nilai
GlobalDi luar semua fungsiBertahan selama papan menyala
LokalDi dalam sebuah fungsiHilang setiap fungsi itu selesai
Static lokalDi dalam fungsi, diberi kata kunci staticBertahan, tetapi hanya dikenali di fungsi itu

Variabel static sering menjadi jalan tengah yang rapi. Nilainya bertahan antar putaran seperti variabel global, tetapi tidak dapat diubah dari bagian lain program sehingga lebih aman.

void loop() {
  static int hitungan = 0;   // hanya dibuat sekali, nilainya bertahan
  hitungan++;
  Serial.println(hitungan);
  delay(1000);
}

Aturan praktisnya: pakai variabel lokal sebagai kebiasaan, naikkan menjadi static ketika nilainya perlu bertahan, dan jadikan global hanya ketika benar-benar diakses dari beberapa fungsi. Semakin sedikit variabel global, semakin mudah program Anda ditelusuri ketika bermasalah.

Urutan Eksekusi Lengkap

  1. Papan mendapat daya atau di-reset.
  2. Bootloader berjalan sesaat, menunggu apakah ada program baru yang dikirim.
  3. Library yang di-include dimuat, variabel global dibuat dan diberi nilai awal.
  4. setup() dijalankan sampai selesai, satu kali.
  5. loop() dijalankan berulang tanpa henti sampai daya diputus.

Aturan Penulisan yang Wajib Diingat

  • Setiap pernyataan diakhiri titik koma. Lupa menuliskannya adalah penyebab error compile paling umum bagi pemula.
  • Kurung kurawal harus berpasangan. Arduino IDE menyorot pasangannya saat kursor berada di salah satunya.
  • Penulisan bersifat case sensitive. Perintah digitalWrite berbeda dari digitalwrite.
  • Komentar diabaikan saat compile. Gunakan // untuk satu baris dan /* */ untuk beberapa baris.

Masalah delay() dan Alternatifnya

Perintah delay() menghentikan seluruh program. Untuk program sederhana hal itu tidak masalah, tetapi begitu alat harus membaca tombol sambil menyalakan LED, tombol tidak akan terbaca selama jeda berlangsung.

Solusinya memakai millis(), yang mengembalikan jumlah milidetik sejak papan menyala. Alih-alih menghentikan program, Anda memeriksa apakah waktunya sudah tiba.

const int PIN_LED = 13;
const unsigned long JEDA = 1000;

unsigned long waktuTerakhir = 0;
bool nyala = false;

void setup() {
  pinMode(PIN_LED, OUTPUT);
}

void loop() {
  unsigned long sekarang = millis();

  if (sekarang - waktuTerakhir >= JEDA) {
    waktuTerakhir = sekarang;
    nyala = !nyala;
    digitalWrite(PIN_LED, nyala ? HIGH : LOW);
  }

  // baris lain di sini tetap berjalan tanpa terhambat
}

Perhatikan tipe data unsigned long untuk menampung nilai millis(). Memakai int akan menyebabkan nilainya meluap dalam waktu kurang dari satu menit.

Kesalahan Sintaks yang Paling Sering

Pesan ErrorArtinya
expected ; before …Ada titik koma yang tertinggal pada baris sebelumnya
was not declared in this scopeNama variabel salah ketik, atau dideklarasikan di dalam fungsi lain
expected } at end of inputAda kurung kurawal penutup yang kurang
redefinition of …Nama variabel atau fungsi yang sama dideklarasikan dua kali
no matching function for callJumlah atau tipe argumen tidak sesuai dengan definisi fungsinya

Tips membaca error: selalu perbaiki pesan error yang paling atas terlebih dahulu. Satu kesalahan sering memicu belasan pesan turunan yang hilang dengan sendirinya setelah penyebab aslinya diperbaiki.

Contoh Program Lengkap yang Terstruktur

// Tombol menyalakan LED, dengan hitungan klik ke Serial Monitor

const int PIN_TOMBOL = 2;
const int PIN_LED    = 13;

int jumlahKlik = 0;
bool kondisiSebelumnya = HIGH;

void setup() {
  Serial.begin(9600);
  pinMode(PIN_TOMBOL, INPUT_PULLUP);
  pinMode(PIN_LED, OUTPUT);
  Serial.println(F("Siap menerima klik"));
}

void loop() {
  bool kondisi = digitalRead(PIN_TOMBOL);

  if (kondisi == LOW && kondisiSebelumnya == HIGH) {
    jumlahKlik++;
    digitalWrite(PIN_LED, HIGH);
    Serial.print(F("Klik ke-"));
    Serial.println(jumlahKlik);
    delay(50);   // meredam pantulan kontak tombol
  }

  if (kondisi == HIGH) {
    digitalWrite(PIN_LED, LOW);
  }

  kondisiSebelumnya = kondisi;
}

Program ini memperlihatkan seluruh bagian sekaligus: konstanta di atas, variabel global yang nilainya bertahan, persiapan di setup(), dan logika utama di loop().

Pertanyaan yang Sering Diajukan

Apakah setup() dan loop() bisa dihapus salah satu?

Tidak. Keduanya wajib ada meski isinya kosong, karena framework Arduino memanggil keduanya secara otomatis.

Bisakah menulis fungsi lain di luar keduanya?

Bisa, dan justru dianjurkan ketika program mulai panjang. Fungsi tersebut dipanggil dari setup() maupun loop().

Apa yang terjadi kalau loop() dikosongkan?

Program tetap berjalan tetapi tidak melakukan apa pun setelah setup() selesai. Ini wajar untuk alat yang hanya perlu mengatur sesuatu sekali lalu diam.

Apakah bahasa Arduino sama dengan C++?

Pada dasarnya iya. Yang Anda tulis adalah C/C++ yang dibungkus framework dan library Arduino agar lebih sederhana.

Berapa lama millis() sebelum meluap?

Sekitar 49 hari, setelah itu hitungannya kembali ke nol. Untuk alat yang menyala terus-menerus, pola pengurangan seperti pada contoh di atas sudah menangani kondisi tersebut dengan benar.

Langkah Selanjutnya

Setelah memahami kerangkanya, langkah berikutnya adalah mengenali pin mana yang bisa dipakai untuk apa. Urutan belajar lengkapnya ada di panduan belajar Arduino dari nol.

Belum memasang Arduino IDE? Ikuti cara install Arduino IDE. Ingin langsung praktik dengan pendampingan? Lihat kursus Arduino bisaioti.

Related Articles

Chat Langsung dengan Kami
Staff bisaioti 1 — +62 823-3306-4821 E-Course, Offline Course, Hardware & Teknis IoT/OT Staff bisaioti 2 — +62 823-3306-4821 Training Korporat & Toko Hardware