Kembali|

Kod Arduino — SmartPark

Papan Disokong

ESP8266 (NodeMCU) atau ESP32

Sensor

HC-SR04 Ultrasonic × 12 unit

Protokol

HTTP POST ke API endpoint

Library Arduino Diperlukan

Pasang library berikut melalui Arduino IDE → Sketch → Include Library → Manage Libraries:

ArduinoJson (bblanchon)ESP8266WiFi (built-in)ESP8266HTTPClient (built-in)

Jadual Wiring Sensor (Contoh)

SlotPin TRIGPin ECHO
A1D1 (GPIO5)D2 (GPIO4)
A2D3 (GPIO0)D4 (GPIO2)
A3D5 (GPIO14)D6 (GPIO12)
B1D7 (GPIO13)D8 (GPIO15)
B2D0 (GPIO16)D9 (GPIO3)
B3GPIO17GPIO18
C1–C3 / D1–D3Pin tambahanESP32 atau I2C expander

Untuk 12 slot, gunakan ESP32 (lebih banyak pin GPIO tersedia) atau tambah I2C GPIO expander seperti PCF8574.

Format Data yang Dihantar

Arduino menghantar HTTP POST ke /api/parking/update dengan body JSON:

{
  "readings": [
    { "slotId": 1, "distance": 8 },
    { "slotId": 2, "distance": 120 },
    { "slotId": 3, "distance": 5 },
    ...
  ]
}

Jarak ≤ 15 cm = slot TERISI (lampu merah). Jarak > 15 cm = slot KOSONG (lampu hijau).

smartpark_parking.ino
/*
 * SmartPark — Sistem Pengesanan Parking Arduino
 * Papan: ESP8266 (NodeMCU) atau ESP32
 * Sensor: HC-SR04 Ultrasonic x12
 *
 * Sambungan wiring (contoh untuk 2 sensor pertama):
 *   Sensor 1 TRIG -> D1 (GPIO5)
 *   Sensor 1 ECHO -> D2 (GPIO4)
 *   Sensor 2 TRIG -> D3 (GPIO0)
 *   Sensor 2 ECHO -> D4 (GPIO2)
 *   VCC -> 5V, GND -> GND
 *
 * Ulang pattern TRIG/ECHO untuk slot 3-12 mengikut pin yang tersedia.
 */

#include <ESP8266WiFi.h>     // Guna <WiFi.h> untuk ESP32
#include <ESP8266HTTPClient.h> // Guna <HTTPClient.h> untuk ESP32
#include <ArduinoJson.h>

// =====================
//  KONFIGURASI WIFI
// =====================
const char* WIFI_SSID     = "NAMA_WIFI_ANDA";
const char* WIFI_PASSWORD = "KATA_LALUAN_WIFI";

// =====================
//  KONFIGURASI SERVER
// =====================
// Guna IP awam jika di Vercel, atau IP LAN jika server tempatan
const String SERVER_URL = "https://YOUR_APP.vercel.app/api/parking/update";

// =====================
//  KONFIGURASI SENSOR
// =====================
#define NUM_SLOTS 12
#define OCCUPIED_THRESHOLD_CM 15   // Jarak <= 15cm = slot terisi
#define SEND_INTERVAL_MS 2000      // Hantar data setiap 2 saat

// Pin TRIG dan ECHO untuk setiap slot
// Laraskan mengikut wiring sebenar anda
const int TRIG_PINS[NUM_SLOTS] = {5, 0, 14, 12, 13, 15, 3,  1,  9,  10, 4,  2};
const int ECHO_PINS[NUM_SLOTS] = {4, 2, 12, 13, 15, 3,  1,  16, 10, 9,  2,  14};

// =====================
//  FUNGSI UKUR JARAK
// =====================
float measureDistance(int trigPin, int echoPin) {
  // Hantar pulse ultrasonic
  digitalWrite(trigPin, LOW);
  delayMicroseconds(2);
  digitalWrite(trigPin, HIGH);
  delayMicroseconds(10);
  digitalWrite(trigPin, LOW);

  // Baca masa echo kembali (timeout 30ms)
  long duration = pulseIn(echoPin, HIGH, 30000);

  if (duration == 0) {
    return 999.0;  // Tiada objek dikesan
  }

  // Tukar ke cm (kelajuan bunyi = 343 m/s)
  float distanceCm = (duration * 0.0343) / 2.0;
  return distanceCm;
}

// =====================
//  SETUP
// =====================
void setup() {
  Serial.begin(115200);
  delay(100);

  // Set pin sensor
  for (int i = 0; i < NUM_SLOTS; i++) {
    pinMode(TRIG_PINS[i], OUTPUT);
    pinMode(ECHO_PINS[i], INPUT);
  }

  // Sambung WiFi
  Serial.print("Menyambung ke WiFi: ");
  Serial.println(WIFI_SSID);
  WiFi.begin(WIFI_SSID, WIFI_PASSWORD);

  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }

  Serial.println();
  Serial.println("WiFi bersambung!");
  Serial.print("IP Address: ");
  Serial.println(WiFi.localIP());
}

// =====================
//  LOOP UTAMA
// =====================
void loop() {
  if (WiFi.status() != WL_CONNECTED) {
    Serial.println("WiFi terputus. Cuba sambung semula...");
    WiFi.reconnect();
    delay(5000);
    return;
  }

  // Baca semua sensor dan bina JSON
  StaticJsonDocument<512> doc;
  JsonArray readings = doc.createNestedArray("readings");

  for (int i = 0; i < NUM_SLOTS; i++) {
    float dist = measureDistance(TRIG_PINS[i], ECHO_PINS[i]);

    JsonObject reading = readings.createNestedObject();
    reading["slotId"]   = i + 1;
    reading["distance"] = (int)dist;

    Serial.print("Slot ");
    // Section: A=1-3, B=4-6, C=7-9, D=10-12
    char sections[] = "AABBCCDD";
    char sec = (i < 3) ? 'A' : (i < 6) ? 'B' : (i < 9) ? 'C' : 'D';
    int secSlot = (i % 3) + 1;
    Serial.print(sec);
    Serial.print(secSlot);
    Serial.print(": ");
    Serial.print(dist);
    Serial.print(" cm — ");
    Serial.println(dist <= OCCUPIED_THRESHOLD_CM ? "TERISI" : "KOSONG");

    // Delay kecil antara sensor untuk elak interferens
    delay(30);
  }

  // Serialkan JSON
  String jsonBody;
  serializeJson(doc, jsonBody);

  // Hantar ke API
  WiFiClient client;
  HTTPClient http;
  http.begin(client, SERVER_URL);
  http.addHeader("Content-Type", "application/json");

  int httpCode = http.POST(jsonBody);

  if (httpCode == HTTP_CODE_OK) {
    Serial.println("Data berjaya dihantar!");
  } else {
    Serial.print("Ralat HTTP: ");
    Serial.println(httpCode);
  }

  http.end();

  delay(SEND_INTERVAL_MS);
}