From 10135342127360544069ed4bd0841161b38a7095 Mon Sep 17 00:00:00 2001 From: Nashich Date: Tue, 21 Jul 2026 11:57:01 +0700 Subject: [PATCH] first commit --- kode program alat/GPS.ino | 10 ++ kode program alat/VL53L0X.ino | 48 ++++++++++ kode program alat/kode1di_pisah.ino.ino | 116 ++++++++++++++++++++++++ kode program alat/komunikasi.ino | 52 +++++++++++ kode program alat/prediksi.h | 84 +++++++++++++++++ 5 files changed, 310 insertions(+) create mode 100644 kode program alat/GPS.ino create mode 100644 kode program alat/VL53L0X.ino create mode 100644 kode program alat/kode1di_pisah.ino.ino create mode 100644 kode program alat/komunikasi.ino create mode 100644 kode program alat/prediksi.h diff --git a/kode program alat/GPS.ino b/kode program alat/GPS.ino new file mode 100644 index 0000000..21fb97c --- /dev/null +++ b/kode program alat/GPS.ino @@ -0,0 +1,10 @@ +void updateGPS() { + while (gpsSerial.available() > 0) { + if (gps.encode(gpsSerial.read())) { + if (gps.location.isValid()) { + lat = gps.location.lat(); + lon = gps.location.lng(); + } + } + } +} \ No newline at end of file diff --git a/kode program alat/VL53L0X.ino b/kode program alat/VL53L0X.ino new file mode 100644 index 0000000..046e9bb --- /dev/null +++ b/kode program alat/VL53L0X.ino @@ -0,0 +1,48 @@ +// Fungsi untuk memulai dan menyetel sensor ke Long Range +void initVL53L0X() { + Serial.println("Menginisialisasi sensor VL53L0X (Mode Long Range)..."); + + // Proses mengenalkan dan membangunkan sensor + if (!lox.begin()) { + Serial.println(F("VL53L0X Error / Tidak Terdeteksi!")); + while (1); + } + + // Mengaktifkan mode Long Range dengan memperlama budget waktu baca (50ms) + lox.setMeasurementTimingBudgetMicroSeconds(50000); + + Serial.println("Sensor VL53L0X Berhasil Dikonfigurasi ke Long Range."); +} + +// Fungsi pembacaan data (SUDAH DIKALIBRASI KE 90 CM) +void bacaSensorJarak() { + VL53L0X_RangingMeasurementData_t measure; + lox.rangingTest(&measure, false); + + if (measure.RangeStatus != 4) { + // 1. Ambil data asli dari sensor lalu ubah ke centimeter + int jarak_pantul_asli = measure.RangeMilliMeter / 10; + + // 2. Prosedur Kalibrasi (Offset): Dikurangi 2 cm karena sensor membaca kelebihan 2 cm + int jarak_pantul_terkalibrasi = jarak_pantul_asli - 2; + + // Antisipasi jika jarak sangat dekat agar nilai kalibrasi tidak minus + if (jarak_pantul_terkalibrasi < 0) jarak_pantul_terkalibrasi = 0; + + // 3. Hitung Ketinggian Air Real menggunakan panjang pipa 90 cm + ketinggian_air = 90 - jarak_pantul_terkalibrasi; + + // Pembatasan nilai atas dan bawah sesuai panjang pipa 90 cm + if (ketinggian_air < 0) ketinggian_air = 0; + if (ketinggian_air > 90) ketinggian_air = 90; + + // Tampilkan di Serial Monitor + Serial.print("Jarak Sensor (Sebelum Kalibrasi): "); Serial.print(jarak_pantul_asli); Serial.println(" cm"); + Serial.print("Jarak Sensor (Setelah Kalibrasi): "); Serial.print(jarak_pantul_terkalibrasi); Serial.println(" cm"); + Serial.print("Tinggi Air Real: "); Serial.print(ketinggian_air); Serial.println(" cm"); + Serial.println("----------------------------------------"); + + } else { + Serial.println("Sensor: Out of Range / Terhalang"); + } +} \ No newline at end of file diff --git a/kode program alat/kode1di_pisah.ino.ino b/kode program alat/kode1di_pisah.ino.ino new file mode 100644 index 0000000..1dfa659 --- /dev/null +++ b/kode program alat/kode1di_pisah.ino.ino @@ -0,0 +1,116 @@ +#include +#include +#include +#include +#include + +// ---- PROTOTYPE FUNGSI (Agar Compiler Mengenal Fungsi di Tab Lain) ---- +void initVL53L0X(); +void bacaSensorJarak(); +void updateGPS(); +void setupWiFi(); +void kirimKeServerWiFi(); + +// ---- KONFIGURASI WIFI ---- +const char* ssid = "orangsopan"; +const char* password = "12345678"; + +// ---- KONFIGURASI PIN ---- +#define RXD1 14 +#define TXD1 12 + +// ---- OBJEK & SERIAL ---- +HardwareSerial gpsSerial(1); +Adafruit_VL53L0X lox = Adafruit_VL53L0X(); +TinyGPSPlus gps; + +// ---- STRUKTUR LOGIKA PREDIKSI ---- +class LinkedList { + public: + LinkedList(int max_size){ + max_length = max_size; + data = new float[max_size]; + } + size_t size(){ return length; } + void update(float new_data){ + data[last_p] = new_data; + last_p = (last_p + 1) % max_length; + if(length < max_length) { + length++; + } else { + first_p = (first_p + 1) % max_length; + } + } + float getIndex(int index){ return data[(index + first_p) % max_length]; } + private: + float* data; + size_t length = 0; + size_t max_length; + int first_p = 0; + int last_p = 0; +}; + +class LinearRegression { + public: + LinearRegression(int max_size){ data = new LinkedList(max_size); } + void update(float new_data){ data->update(new_data); } + float predict(int n_next = 1){ + int n = data->size(); + if(n < 2) return (n == 1) ? data->getIndex(0) : 0; + float sumX = 0, sumY = 0, sumXY = 0, sumX2 = 0; + for(int i=0; igetIndex(i); + sumXY += i * data->getIndex(i); + sumX2 += i * i; + } + float denominator = (n * sumX2 - sumX * sumX); + if (denominator == 0) return data->getIndex(n - 1); + float m = (n * sumXY - sumX * sumY) / denominator; + float c = (sumY - m * sumX) / n; + return (m * n_next) + c; + } + private: + LinkedList* data; +}; + +LinearRegression LR(5); // Inisialisasi Objek Prediksi + +// ---- KONFIGURASI SERVER & ALAT ---- +const String IP_VPS = "202.155.19.245"; +const int TINGGI_TOTAL_ALAT = 95; + +// ---- VARIABEL GLOBAL ---- +float lat = 0, lon = 0; +int ketinggian_air = 0; +float hasil_prediksi = 0; +unsigned long lastTime = 0; +const long timerDelay = 60000; // Tiap 1 Menit + +void setup() { + Serial.begin(115200); + gpsSerial.begin(9600, SERIAL_8N1, RXD1, TXD1); + Wire.begin(21, 22); + + initVL53L0X(); + setupWiFi(); // Koneksi ke WiFi orangsopan + + Serial.println("Sistem Siap (Mode Murni WiFi)..."); +} + +void loop() { + updateGPS(); + + if ((millis() - lastTime) > timerDelay) { + bacaSensorJarak(); + + LR.update((float)ketinggian_air); + hasil_prediksi = LR.predict(9); + if (hasil_prediksi < 0) hasil_prediksi = 0; + + // Pengiriman data murni lewat internet WiFi + kirimKeServerWiFi(); + + lastTime = millis(); + } +} \ No newline at end of file diff --git a/kode program alat/komunikasi.ino b/kode program alat/komunikasi.ino new file mode 100644 index 0000000..e9abf0f --- /dev/null +++ b/kode program alat/komunikasi.ino @@ -0,0 +1,52 @@ +void setupWiFi() { + Serial.println("\n--- Menghubungkan ke WiFi ---"); + WiFi.begin(ssid, password); + + int timeout_counter = 0; + while (WiFi.status() != WL_CONNECTED && timeout_counter < 30) { + delay(500); + Serial.print("."); + timeout_counter++; + } + + if (WiFi.status() == WL_CONNECTED) { + Serial.println("\n[OK] WiFi Terhubung!"); + Serial.print("IP Address: "); + Serial.println(WiFi.localIP()); + } else { + Serial.println("\n[GAGAL] WiFi tidak ditemukan/gagal konek."); + } +} + +void kirimKeServerWiFi() { + if (WiFi.status() != WL_CONNECTED) { + Serial.println("[ERROR] Gagal kirim via WiFi: Tidak terhubung ke jaringan."); + return; + } + + Serial.println("\n--- PROSES KIRIM DATA VIA WIFI ---"); + String payload = "{\"elevasi_air\":" + String(ketinggian_air) + + ",\"prediksi\":" + String(hasil_prediksi, 2) + + ",\"lat\":" + String(lat, 6) + + ",\"lon\":" + String(lon, 6) + "}"; + + HTTPClient http; + String url = "http://" + IP_VPS + "/update-sensor"; + + http.begin(url); + http.addHeader("Content-Type", "application/json"); + + int httpResponseCode = http.POST(payload); + + if (httpResponseCode > 0) { + String response = http.getString(); + Serial.print("HTTP Response code WiFi: "); + Serial.println(httpResponseCode); + Serial.print("Respons Server: "); + Serial.println(response); + } else { + Serial.print("Error saat mengirim POST via WiFi: "); + Serial.println(httpResponseCode); + } + http.end(); +} \ No newline at end of file diff --git a/kode program alat/prediksi.h b/kode program alat/prediksi.h new file mode 100644 index 0000000..ed1d59c --- /dev/null +++ b/kode program alat/prediksi.h @@ -0,0 +1,84 @@ +#ifndef PREDIKSI_H +#define PREDIKSI_H + +// --- 1. Kelas untuk Mengelola Antrean Data (FIFO) --- +class LinkedList { + public: + LinkedList(int max_size){ + max_length = max_size; + data = new float[max_size]; + } + + size_t size(){ return length; } + + // Mekanisme: Masukkan data baru, buang data paling lama jika penuh + void update(float new_data){ + data[last_p] = new_data; + last_p = (last_p + 1) % max_length; // Geser posisi data terakhir + + if(length < max_length) { + length++; // Tambah jumlah data jika belum mencapai batas (5) + } else { + first_p = (first_p + 1) % max_length; // Buang/geser data paling lama + } + } + + float getIndex(int index){ + return data[(index + first_p) % max_length]; + } + + private: + float* data; + size_t length = 0; + size_t max_length; + int first_p = 0; // Menunjuk ke data paling lama + int last_p = 0; // Menunjuk ke data paling baru +}; + +// --- 2. Kelas untuk Perhitungan Matematika Regresi Linear --- +class LinearRegression { + public: + LinearRegression(int max_size){ + data = new LinkedList(max_size); + } + + // Fungsi untuk memasukkan data ketinggian air terbaru + void update(float new_data){ + data->update(new_data); + } + + // Fungsi untuk menghitung prediksi n-menit ke depan + float predict(int n_next = 1){ + int n = data->size(); + + // Jika data kurang dari 2, belum bisa menghitung tren (kembalikan data terakhir) + if(n < 2) return (n == 1) ? data->getIndex(0) : 0; + + float sumX = 0, sumY = 0, sumXY = 0, sumX2 = 0; + + // Hitung komponen rumus Regresi Linear (y = mx + c) + for(int i=0; igetIndex(i); + sumXY += i * data->getIndex(i); + sumX2 += i * i; + } + + float denominator = (n * sumX2 - sumX * sumX); + if (denominator == 0) return data->getIndex(n - 1); + + // m = kemiringan (tren kenaikan/penukuran) + float m = (n * sumXY - sumX * sumY) / denominator; + // c = titik potong + float c = (sumY - m * sumX) / n; + + // --- PERBAIKAN LOGIKA DI SINI --- + // Hasil prediksi langsung merujuk pada nilai n_next sebagai variabel X + return (m * n_next) + c; + } + + private: + LinkedList* data; +}; + +#endif \ No newline at end of file