first commit
This commit is contained in:
commit
1013534212
|
|
@ -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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -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");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,116 @@
|
||||||
|
#include <Wire.h>
|
||||||
|
#include <Adafruit_VL53L0X.h>
|
||||||
|
#include <TinyGPS++.h>
|
||||||
|
#include <WiFi.h>
|
||||||
|
#include <HTTPClient.h>
|
||||||
|
|
||||||
|
// ---- 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; i<n; i++){
|
||||||
|
sumX += i;
|
||||||
|
sumY += data->getIndex(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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -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();
|
||||||
|
}
|
||||||
|
|
@ -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; i<n; i++){
|
||||||
|
sumX += i;
|
||||||
|
sumY += data->getIndex(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
|
||||||
Loading…
Reference in New Issue