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