Buka Senin - Jumat jam 08.30 s/d jam 16.30 , Sabtu Jam 8.30 s/d jam 13.00 , Minggu tutup
  • Selamat Datang di Indomaker ❯ Silahkan pesan produk sesuai kebutuhan anda, kami siap melayani.
  • Selamat Datang di Indomaker ❯ Silahkan pesan produk sesuai kebutuhan anda, kami siap melayani.
Beranda » Blog » Bikin Mobil Parkir Otomatis Pakai Arduino dan PID dengan Budget di Bawah 100 Ribu

Bikin Mobil Parkir Otomatis Pakai Arduino dan PID dengan Budget di Bawah 100 Ribu

Diposting pada 14 September 2026 oleh indo maker / Dilihat: 2 kali / Kategori: ,

Pernah kepikiran nggak sih gimana mobil-mobil modern bisa parkir sendiri dengan sangat presisi tanpa nyenggol tembok? Teknologi itu bukan sihir, melainkan sistem kendali pintar yang menjaga jarak aman secara real-time. Kabar baiknya, kamu nggak perlu beli Tesla buat belajar teknologi ini. Cukup dengan modal minimalis, kita bisa bikin miniatur mobil pintar yang mampu berhenti tepat di jarak 15 cm dari halangan.

Dalam projek ini, kita nggak cuma pakai logika “maju-berhenti” yang kasar, tapi kita akan menerapkan algoritma PID (Proportional-Integral-Derivative). Dengan algoritma ini, mobil kamu bakal melambat secara halus saat mendekati target dan berhenti dengan akurasi tinggi. Yuk, kita bedah rahasianya!

Mengenal Rahasia di Balik Presisi Apa Itu PID?

Kalau kamu baru dengar istilah PID, jangan pusing duluan. Bayangkan PID itu seperti cara kita mengemudikan mobil:

  • Proporsional (P) Ini adalah gas utama. Kalau jarak ke target masih jauh (error besar), gas diinjak dalam. Makin dekat ke target, gas makin dilepas.
  • Integral (I) Ini adalah “pengingat” kesalahan masa lalu. Kalau mobil berhenti tapi masih ada sisa jarak 1-2 cm dari target, si Integral ini bakal ngumpulin sisa error itu dan kasih dorongan pelan sampai posisinya benar-benar pas.
  • Derivatif (D) Ini adalah rem otomatisnya. Komponen ini melihat seberapa cepat mobil bergerak. Kalau mobil melaju terlalu kencang saat mendekati target, si D akan memberikan peredaman supaya mobil nggak kebablasan (overshoot).

Sistem ini bekerja dalam domain diskrit, artinya Arduino kita melakukan perhitungan ulang setiap 100 ms (sampling period). Jeda waktu yang konsisten ini bikin performa kendali tetap stabil dan efisien di mikrokontroler kelas ringan.

Alat dan Bahan Low Budget

Siapa bilang teknologi canggih harus mahal? Seluruh komponen ini bisa kamu dapatkan dengan total biaya sekitar Rp 92.000 (asumsi Arduino Uno sudah tersedia di meja kerja atau pinjam lab).

Alat & Bahan Detail / Fungsi
Arduino Uno R3 Otak utama pemroses logika PID
Sensor HC-SR04 Mata ultrasonik pengukur jarak (cm)
Driver Motor L298N Pengatur arah dan kecepatan motor via PWM
Motor DC Gearbox 6V Aktuator penggerak roda (2 unit)
Protoboard & Jumper Media penghubung rangkaian
Baterai 9V + Clip Sumber tenaga independen untuk motor

Kalau kamu ingin mencoba variasi lain, kamu juga bisa bikin stabilizer 1 axis low budget pakai arduino dan pid untuk mengasah kemampuan kontrol logikamu.

Skematik Rangkaian

Menghubungkan komponennya cukup simpel, tapi pastikan pin-nya nggak tertukar ya:

  1. Sensor HC-SR04 Pin TRIG ke D7 dan ECHO ke D8. Sensor ini akan terus-menerus memantau jarak objek di depan mobil.
  2. Driver Motor L298N Pin ENA (PWM) hubungkan ke D9. Untuk kontrol arah, IN1 & IN2 (Motor Kiri) ke D10 & D11, lalu IN3 & IN4 (Motor Kanan) ke D12 & D6.
  3. Jalur Power Hubungkan baterai 9V ke terminal driver motor. Jangan lupa hubungkan Ground baterai ke Ground Arduino supaya referensi tegangannya sama. Menggunakan power terpisah buat motor itu wajib supaya Arduino nggak restart karena beban motor yang berat.

Driver L298N berfungsi sebagai penghubung antara Arduino dan motor DC karena Arduino tidak bisa langsung memberikan daya yang cukup untuk menggerakkan motor. Untuk melihat spesifikasi, karakteristik, dan informasi teknisnya secara lebih lengkap, kamu bisa membaca datasheet L298 dari STMicroelectronics sebelum merakit rangkaian.

Cara Kerja dan Logika Pintarnya

Sistem ini menggunakan alur closed-loop yang cukup rapi. Ada beberapa teknik yang digunakan agar pergerakan mobil tetap halus dan responsif.

  • Filtering Sensor
    Data dari sensor ultrasonik terkadang mengalami noise atau lonjakan nilai yang tidak stabil. Untuk mengatasinya, sistem menggunakan Exponential Moving Average (EMA) sehingga pembacaan jarak menjadi lebih halus dan tidak mudah berubah secara tiba-tiba.
  • Integral Reset
    Fitur ini digunakan untuk mencegah mobil mengalami respons yang tidak diinginkan saat melewati titik target. Nilai integral akan diatur ulang setiap kali mobil berpindah arah, misalnya dari maju ke mundur atau sebaliknya.
  • Linear PWM Mapping
    Kecepatan motor diatur secara bertahap berdasarkan seberapa jauh posisi mobil dari target. Sistem menggunakan nilai PWM minimum 35 agar motor tetap mampu berputar, sementara nilai maksimumnya dibatasi hingga 70 supaya mobil tidak bergerak terlalu cepat dan tetap mudah dikendalikan.
  • Deadband
    Sistem juga memiliki zona mati sekitar 1 cm dari titik target. Ketika mobil sudah berada di sekitar jarak 14–16 cm, sistem akan menganggap posisinya sudah cukup tepat dan langsung menghentikan motor. Cara ini membantu mencegah mobil terus bergerak maju-mundur atau bergetar di sekitar posisi parkir.

Bedah Kode Program

/*
 * ================================================================
 * SISTEM KENDALI POSISI PARKIR OTOMATIS
 * PID DISKRIT LOOP TERTUTUP
 * ================================================================
 *
 * Hardware
 * Sensor HC-SR04
 * TRIG = D7
 * ECHO = D8
 *
 * Driver L298N
 * ENA = D9 PWM
 * ENA dan ENB menggunakan jalur PWM yang sama
 *
 * Motor Kiri
 * IN1 = D10
 * IN2 = D11
 *
 * Motor Kanan
 * IN3 = D12
 * IN4 = D6
 *
 * LED indikator = D13
 * ================================================================
 */

// Pin sensor ultrasonik
#define TRIG_PIN 7
#define ECHO_PIN 8

// Pin driver motor
#define ENA_PIN 9
#define IN1_PIN 10
#define IN2_PIN 11
#define IN3_PIN 12
#define IN4_PIN 6

// Pin LED indikator
#define LED_PIN 13


// ================================================================
// PARAMETER PID
// ================================================================

float Kp = 4.84f;
float Ki = 2.167f;
float Kd = 3.78f;


// ================================================================
// PENGATURAN SISTEM
// ================================================================

const float SP = 15.0f;
const float DEADBAND = 1.0f;

const int T_MS = 100;


// ================================================================
// BATAS AKTUATOR
// ================================================================

const float INTEGRAL_MAX = 15.0f;

const int PWM_STALL = 35;
const int PWM_MAX = 70;

const float U_MAX = (float)PWM_MAX;


// ================================================================
// FILTER
// ================================================================

const float ALPHA_SENSOR = 0.4f;
const float ALPHA_DERIV = 0.35f;


// ================================================================
// VARIABEL PID
// ================================================================

float e_prev = 0.0f;
float integral = 0.0f;
float d_filtered = 0.0f;

float PV_filtered = SP;

bool prev_maju = false;

unsigned long lastTime = 0;

int appliedPWM = 0;


// ================================================================
// SETUP
// ================================================================

void setup() {

  Serial.begin(115200);

  pinMode(TRIG_PIN, OUTPUT);
  pinMode(ECHO_PIN, INPUT);

  pinMode(ENA_PIN, OUTPUT);

  pinMode(IN1_PIN, OUTPUT);
  pinMode(IN2_PIN, OUTPUT);

  pinMode(IN3_PIN, OUTPUT);
  pinMode(IN4_PIN, OUTPUT);

  pinMode(LED_PIN, OUTPUT);

  stopMotor();

  delay(500);

  lastTime = millis();

  Serial.println(F("=== PID Parkir Otomatis ==="));

  Serial.print(F("Kp = "));
  Serial.print(Kp, 3);

  Serial.print(F(" | Ki = "));
  Serial.print(Ki, 3);

  Serial.print(F(" | Kd = "));
  Serial.print(Kd, 2);

  Serial.print(F(" | Target = "));
  Serial.print(SP, 0);

  Serial.println(F(" cm"));

  Serial.println(F("----------------------------------------"));

  delay(1000);
}


// ================================================================
// LOOP UTAMA
// ================================================================

void loop() {

  unsigned long now = millis();

  // Menjaga periode sampling tetap 100 ms
  if (now - lastTime < (unsigned long)T_MS) {
    return;
  }

  float dt = (now - lastTime) / 1000.0f;

  lastTime = now;


  // ==============================================================
  // 1. MEMBACA SENSOR
  // ==============================================================

  float PV_raw = readDistance();


  // Jika pembacaan sensor tidak valid
  if (PV_raw < 1.0f || PV_raw > 35.0f) {

    stopMotor();

    digitalWrite(LED_PIN, LOW);

    printPlotter(
      SP,
      -1.0f,
      0.0f,
      0.0f,
      0
    );

    return;
  }


  // Filter EMA untuk menghaluskan pembacaan sensor
  PV_filtered =
    ALPHA_SENSOR * PV_raw +
    (1.0f - ALPHA_SENSOR) * PV_filtered;

  float PV = PV_filtered;


  // ==============================================================
  // 2. MENENTUKAN ERROR DAN ARAH MOTOR
  // ==============================================================

  float raw_diff = PV - SP;

  // Nilai error selalu positif
  float e = fabsf(raw_diff);

  // Menentukan arah berdasarkan posisi terhadap target
  bool maju = (raw_diff > 0.0f);


  // ==============================================================
  // 3. PERHITUNGAN PID
  // ==============================================================

  // Reset integral ketika mobil berpindah sisi target
  if (maju != prev_maju) {
    integral = 0.0f;
  }

  prev_maju = maju;


  // Komponen integral
  integral += e * dt;

  integral = constrain(
    integral,
    0.0f,
    INTEGRAL_MAX
  );


  // Komponen derivatif
  float raw_d = (e - e_prev) / dt;

  d_filtered =
    ALPHA_DERIV * raw_d +
    (1.0f - ALPHA_DERIV) * d_filtered;


  // Hasil kendali PID
  float u =
    Kp * e +
    Ki * integral +
    Kd * d_filtered;

  e_prev = e;


  // ==============================================================
  // 4. KENDALI MOTOR
  // ==============================================================

  if (e <= DEADBAND) {

    // Mobil sudah berada di sekitar target
    stopMotor();

    digitalWrite(LED_PIN, HIGH);

  } else {

    // Mobil masih mencari posisi target
    driveMotor(u, maju);

    // LED berkedip saat mobil bergerak
    digitalWrite(
      LED_PIN,
      (millis() / 200) % 2
    );
  }


  // ==============================================================
  // 5. SERIAL PLOTTER
  // ==============================================================

  printPlotter(
    SP,
    PV,
    e,
    u,
    appliedPWM
  );
}


// ================================================================
// MENGUBAH HASIL PID MENJADI PWM
// ================================================================

int velToPWM(float u) {

  float u_abs = constrain(
    fabsf(u),
    0.0f,
    U_MAX
  );

  int pwm =
    (int)(
      PWM_STALL +
      (float)(PWM_MAX - PWM_STALL) *
      u_abs /
      U_MAX
    );

  return constrain(
    pwm,
    PWM_STALL,
    PWM_MAX
  );
}


// ================================================================
// MENGGERAKKAN MOTOR
// ================================================================

void driveMotor(float u, bool maju) {

  int pwm = velToPWM(u);


  if (maju) {

    // Maju
    digitalWrite(IN1_PIN, HIGH);
    digitalWrite(IN2_PIN, LOW);

    digitalWrite(IN3_PIN, HIGH);
    digitalWrite(IN4_PIN, LOW);

  } else {

    // Mundur
    digitalWrite(IN1_PIN, LOW);
    digitalWrite(IN2_PIN, HIGH);

    digitalWrite(IN3_PIN, LOW);
    digitalWrite(IN4_PIN, HIGH);
  }


  analogWrite(
    ENA_PIN,
    pwm
  );

  appliedPWM = pwm;
}


// ================================================================
// MENGHENTIKAN MOTOR
// ================================================================

void stopMotor() {

  digitalWrite(IN1_PIN, LOW);
  digitalWrite(IN2_PIN, LOW);

  digitalWrite(IN3_PIN, LOW);
  digitalWrite(IN4_PIN, LOW);

  analogWrite(
    ENA_PIN,
    0
  );

  appliedPWM = 0;
}


// ================================================================
// MEMBACA JARAK HC-SR04
// ================================================================

float readDistance() {

  digitalWrite(
    TRIG_PIN,
    LOW
  );

  delayMicroseconds(2);

  digitalWrite(
    TRIG_PIN,
    HIGH
  );

  delayMicroseconds(10);

  digitalWrite(
    TRIG_PIN,
    LOW
  );


  long dur =
    pulseIn(
      ECHO_PIN,
      HIGH,
      25000UL
    );


  // Tidak ada pantulan yang diterima
  if (dur == 0) {
    return -1.0f;
  }


  // Mengubah waktu pantulan menjadi jarak
  return (float)dur * 0.034f / 2.0f;
}


// ================================================================
// DATA UNTUK SERIAL PLOTTER
// ================================================================

void printPlotter(
  float sp,
  float pv,
  float err,
  float u,
  int pwm
) {

  Serial.print(F("SP:"));
  Serial.print(sp, 1);

  Serial.print(F(",PV:"));
  Serial.print(pv, 2);

  Serial.print(F(",Error:"));
  Serial.print(err, 2);

  Serial.print(F(",U:"));
  Serial.print(u, 2);

  Serial.print(F(",PWM:"));
  Serial.println(pwm);
}

 

Program dikembangkan dengan bahasa C++ yang efisien. Berikut adalah fungsi-fungsi kuncinya:

  • readDistance(): Mengambil data jarak dan langsung memprosesnya lewat filter EMA agar stabil.
  • velToPWM(): Mengubah sinyal kendali PID (u(k)) menjadi nilai PWM (35-70). Di sini kita pakai nilai absolut error agar perhitungan besarnya tenaga tetap konsisten meski arahnya berbeda.
  • driveMotor(): Fungsi yang menentukan arah (Maju jika PV > SP, Mundur jika PV < SP) dan mengeksekusi kecepatan hasil perhitungan PID.
  • Filtering Derivatif: Komponen D juga diberikan low-pass filter dengan \alpha = 0.35 agar respons remnya nggak kaget saat ada gangguan sensor.

Untuk hasil paling stabil, gunakan parameter yang sudah kita uji: Kp=4.84, Ki=2.167, dan Kd=3.78.

Hasil Pengujian dan Kesimpulan

Saat kamu menyalakan mobil ini, kamu akan melihat pemandangan yang memuaskan di Serial Plotter. Garis jarak aktual (PV) akan perlahan mendekati garis target (SP) di 15 cm tanpa terjadi guncangan hebat atau overshoot yang berlebihan. Mobil akan meluncur cepat saat jauh, lalu melambat secara proporsional, dan akhirnya mengunci posisi dengan presisi tinggi.

Tips Praktis: Kunci dari sistem kendali adalah tuning. Selalu mulai dengan nilai P saja sampai mobil bisa bergerak mendekat, lalu tambahkan D untuk meredam guncangan, dan terakhir masukkan I untuk akurasi titik akhirnya.

Ternyata teknologi parkir otomatis nggak serumit (dan semahal) yang dibayangkan, kan? Dengan sedikit logika PID, kamu sudah bisa menyulap komponen seharga 90 ribuan menjadi robot yang punya insting presisi. Selamat bereksperimen, Sobat Maker!

Bagikan ke

Bikin Mobil Parkir Otomatis Pakai Arduino dan PID dengan Budget di Bawah 100 Ribu

Saat ini belum tersedia komentar.

Silahkan tulis komentar Anda

Bikin Mobil Parkir Otomatis Pakai Arduino dan PID dengan Budget di Bawah 100 Ribu

Produk yang sangat tepat, pilihan bagus..!

Berhasil ditambahkan ke keranjang belanja
Lanjut Belanja
Checkout
Produk Quick Order

Pemesanan dapat langsung menghubungi kontak dibawah: