Search This Blog

Saturday, 21 June 2025

FINAL MONITOR 4 V AC DENGAN WEB MONITOR SETUP PARAMETER VIA WEB DITERIMA ESP k2

#include <Wire.h>

#include <Adafruit_GFX.h>

#include <Adafruit_SSD1306.h>

#include <WiFi.h>

#include <WebServer.h>

#include <Preferences.h>

#include <HTTPClient.h>


#define SCREEN_WIDTH 128

#define SCREEN_HEIGHT 64

Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);


#define NUM_SAMPLES 500

#define VREF 3.3

#define ADC_RES 4095.0

#define noiseThreshold 0.5

#define voltageCalibration 312.0


const int pinUPS1 = 32;

const int pinUPS2 = 33;

const int pinPLN = 34;

const int pinGENSET = 35;


float vUPS1 = 0, vUPS2 = 0, vPLN = 0, vGENSET = 0;


Preferences preferences;

WebServer server(80);


String ssid, password;

String ipStr = "", gwStr = "", subnetStr = "";

int serverPort = 80;

String targetIP = "192.168.1.2";


String msgUPS1 = "UPS1 MATI";

String msgUPS2 = "UPS2 MATI";

String msgPLN = "PLN MATI";

String msgGENSET = "GENSET MATI";


bool ups1Sent = false, ups2Sent = false, plnSent = false, gensetSent = false;


// Fungsi membaca tegangan AC dari pin tertentu

float readVoltageAC(int pin) {

  float offset = 0;

  for (int i = 0; i < NUM_SAMPLES; i++) offset += analogRead(pin);

  offset /= NUM_SAMPLES;


  float sumSq = 0;

  for (int i = 0; i < NUM_SAMPLES; i++) {

    float val = analogRead(pin);

    float centered = val - offset;

    sumSq += centered * centered;

    delayMicroseconds(100);

  }


  float rms = sqrt(sumSq / NUM_SAMPLES);

  float voltageADC = (rms / ADC_RES) * VREF;

  float acVoltage = voltageADC * voltageCalibration;

  return acVoltage < noiseThreshold ? 0.0 : acVoltage;

}


// Tampilkan halaman web

void handleRoot() {

  String html = "<!DOCTYPE html><html><head><meta charset='UTF-8'>"

                "<style>"

                "body { font-family: Arial, sans-serif; background:#f9f9f9; margin:0; padding:20px; }"

                ".container { max-width: 600px; margin: auto; background: white; padding: 20px; border-radius: 10px; box-shadow: 0 2px 10px rgba(0,0,0,0.1); }"

                "h1 { font-size: 22px; color: #333; }"

                "form input[type='text'], form input[type='password'], form input[type='number'] { width: 100%; padding: 8px; margin: 5px 0 10px 0; border: 1px solid #ccc; border-radius: 5px; }"

                "form input[type='submit'] { background-color: #4CAF50; color: white; border: none; padding: 10px 20px; border-radius: 5px; cursor: pointer; font-size: 16px; }"

                "form input[type='submit']:hover { background-color: #45a049; }"

                ".section { margin-top: 30px; }"

                ".nilai { font-size: 24px; font-weight: bold; color: #222; margin: 10px 0; }"

                ".off { color: red; font-weight: bold; }"

                "</style></head><body>";


  html += "<div class='container'>";

  html += "<h1>PUTU-TECKNO - WiFi & Notifikasi Settings</h1>";

  html += "<form action='/save' method='post'>"

          "SSID:<br><input type='text' name='ssid'><br>"

          "Password:<br><input type='password' name='password'><br>"

          "IP Address:<br><input type='text' name='ip' value='" + ipStr + "'><br>"

          "Gateway:<br><input type='text' name='gw' value='" + gwStr + "'><br>"

          "Subnet:<br><input type='text' name='subnet' value='" + subnetStr + "'><br>"

          "Port:<br><input type='number' name='port' value='" + String(serverPort) + "'><br>"

          "Target IP Notifikasi:<br><input type='text' name='target_ip' value='" + targetIP + "'><br>"

          "Pesan UPS1:<br><input type='text' name='msg_ups1' value='" + msgUPS1 + "'><br>"

          "Pesan UPS2:<br><input type='text' name='msg_ups2' value='" + msgUPS2 + "'><br>"

          "Pesan PLN:<br><input type='text' name='msg_pln' value='" + msgPLN + "'><br>"

          "Pesan GENSET:<br><input type='text' name='msg_genset' value='" + msgGENSET + "'><br>"

          "<input type='submit' value='Save Settings'></form>";


  html += "<div class='section'><h1>Monitoring Tegangan Server</h1>";

  html += "<div class='nilai'>UPS1: " + String(vUPS1 < 50.0 ? "<span class='off'>OFF</span>" : String(vUPS1, 1) + "V") + "</div>";

  html += "<div class='nilai'>UPS2: " + String(vUPS2 < 50.0 ? "<span class='off'>OFF</span>" : String(vUPS2, 1) + "V") + "</div>";

  html += "<div class='nilai'>PLN: " + String(vPLN < 50.0 ? "<span class='off'>OFF</span>" : String(vPLN, 1) + "V") + "</div>";

  html += "<div class='nilai'>GENSET: " + String(vGENSET < 50.0 ? "<span class='off'>OFF</span>" : String(vGENSET, 1) + "V") + "</div>";

  html += "</div></div></body></html>";


  server.send(200, "text/html", html);

}


// Simpan konfigurasi dari form

void handleSave() {

  ssid = server.arg("ssid");

  password = server.arg("password");

  ipStr = server.arg("ip");

  gwStr = server.arg("gw");

  subnetStr = server.arg("subnet");

  serverPort = server.arg("port").toInt();

  targetIP = server.arg("target_ip");


  msgUPS1 = server.arg("msg_ups1");

  msgUPS2 = server.arg("msg_ups2");

  msgPLN = server.arg("msg_pln");

  msgGENSET = server.arg("msg_genset");


  preferences.begin("wifi", false);

  preferences.putString("ssid", ssid);

  preferences.putString("password", password);

  preferences.putString("ip", ipStr);

  preferences.putString("gw", gwStr);

  preferences.putString("subnet", subnetStr);

  preferences.putInt("port", serverPort);

  preferences.putString("targetIP", targetIP);

  preferences.putString("msgUPS1", msgUPS1);

  preferences.putString("msgUPS2", msgUPS2);

  preferences.putString("msgPLN", msgPLN);

  preferences.putString("msgGENSET", msgGENSET);

  preferences.end();


  server.send(200, "text/html", "<html><body><h1>Saved! Restarting...</h1></body></html>");

  delay(2000);

  ESP.restart();

}


// Setup WiFi dan baca konfigurasi tersimpan

void setupWiFi() {

  preferences.begin("wifi", true);

  ssid = preferences.getString("ssid", "");

  password = preferences.getString("password", "");

  ipStr = preferences.getString("ip", "");

  gwStr = preferences.getString("gw", "");

  subnetStr = preferences.getString("subnet", "");

  serverPort = preferences.getInt("port", 80);

  targetIP = preferences.getString("targetIP", "192.168.1.2");

  msgUPS1 = preferences.getString("msgUPS1", "UPS1 MATI");

  msgUPS2 = preferences.getString("msgUPS2", "UPS2 MATI");

  msgPLN = preferences.getString("msgPLN", "PLN MATI");

  msgGENSET = preferences.getString("msgGENSET", "GENSET MATI");

  preferences.end();


  if (ssid != "") {

    if (ipStr != "" && gwStr != "" && subnetStr != "") {

      IPAddress ip, gw, sn;

      ip.fromString(ipStr); gw.fromString(gwStr); sn.fromString(subnetStr);

      WiFi.config(ip, gw, sn);

    }

    WiFi.begin(ssid.c_str(), password.c_str());

    for (int i = 0; i < 10; i++) {

      if (WiFi.status() == WL_CONNECTED) break;

      delay(500);

    }

  }


  if (WiFi.status() != WL_CONNECTED) {

    WiFi.softAP("PUTU@TECKNO-4AC", "rejeki88");

  }


  server.on("/", handleRoot);

  server.on("/save", HTTP_POST, handleSave);

  server.begin(serverPort);

}


// Inisialisasi

void setup() {

  Serial.begin(115200);

  analogReadResolution(12);

  if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {

    Serial.println(F("OLED tidak ditemukan")); while (1);

  }

  display.clearDisplay();

  display.setTextColor(WHITE);

  display.setTextSize(1);

  display.setCursor(10, 10);

  display.println("Monitoring 4 Tegangan...");

  display.display();

  delay(1500);

  setupWiFi();

}


// Loop utama monitoring dan notifikasi

void loop() {

  vUPS1 = readVoltageAC(pinUPS1);

  vUPS2 = readVoltageAC(pinUPS2);

  vPLN = readVoltageAC(pinPLN);

  vGENSET = readVoltageAC(pinGENSET);


  display.clearDisplay();

  display.setTextSize(1);

  display.setCursor(0, 0);

  display.printf("UPS1   : %s\n", vUPS1 < 50.0 ? "OFF" : String(vUPS1, 1).c_str());

  display.setCursor(0, 16);

  display.printf("UPS2   : %s\n", vUPS2 < 50.0 ? "OFF" : String(vUPS2, 1).c_str());

  display.setCursor(0, 32);

  display.printf("PLN    : %s\n", vPLN < 50.0 ? "OFF" : String(vPLN, 1).c_str());

  display.setCursor(0, 48);

  display.printf("GENSET : %s\n", vGENSET < 50.0 ? "OFF" : String(vGENSET, 1).c_str());

  display.display();


  server.handleClient();


  if (WiFi.status() == WL_CONNECTED) {

    HTTPClient http;


    if (vUPS1 < 50.0 && !ups1Sent) {

      http.begin("http://" + targetIP + "/notif?src=" + msgUPS1); http.GET(); http.end(); ups1Sent = true;

    } else if (vUPS1 >= 50.0) ups1Sent = false;


    if (vUPS2 < 50.0 && !ups2Sent) {

      http.begin("http://" + targetIP + "/notif?src=" + msgUPS2); http.GET(); http.end(); ups2Sent = true;

    } else if (vUPS2 >= 50.0) ups2Sent = false;


    if (vPLN < 50.0 && !plnSent) {

      http.begin("http://" + targetIP + "/notif?src=" + msgPLN); http.GET(); http.end(); plnSent = true;

    } else if (vPLN >= 50.0) plnSent = false;


    if (vGENSET < 50.0 && !gensetSent) {

      http.begin("http://" + targetIP + "/notif?src=" + msgGENSET); http.GET(); http.end(); gensetSent = true;

    } else if (vGENSET >= 50.0) gensetSent = false;

  }


  delay(1000);

}


No comments:

Post a Comment

Tandon Air Otomatis (ESP32 Master & Display) + Kode Lengkap

  Panduan Lengkap Tandon Air Otomatis (ESP32 Master & Display) + Kode Lengkap Diperbarui: 09 August 2025 Artikel ini memandu Anda memban...