Search This Blog

Sunday, 15 June 2025

sim800 led tes call tambahan ping ke gaetwai

 #include <HardwareSerial.h>

#include <Wire.h> // Untuk komunikasi I2C OLED

#include <Adafruit_GFX.h>

#include <Adafruit_SSD1306.h>

#include <WiFi.h> // Pustaka untuk konektivitas WiFi

#include <WiFiClient.h> // Untuk melakukan koneksi TCP sebagai "ping"


// Definisikan pin RX dan TX untuk komunikasi serial antara ESP32 dan SIM800L

#define SIM800L_RX_PIN 16 // Pin RX ESP32 terhubung ke TX SIM800L

#define SIM800L_TX_PIN 17 // Pin TX ESP32 terhubung ke RX SIM800L


// Definisikan pin untuk LED indikator

#define LED_PIN 2 // Contoh pin GPIO2 untuk LED, bisa diganti sesuai kebutuhan


// Definisikan pin untuk tombol fisik

#define BUTTON_PIN 4 // Contoh pin GPIO4 untuk tombol, bisa diganti sesuai kebutuhan

                     // Sambungkan satu sisi tombol ke pin ini, dan sisi lain ke GND.

                     // Resistor pull-up internal akan diaktifkan.


// Ukuran layar OLED (128x64)

#define SCREEN_WIDTH 128 // Lebar piksel OLED

#define SCREEN_HEIGHT 64 // Tinggi piksel OLED


// Kredensial WiFi Anda

const char* WIFI_SSID = "Dara@home";

const char* WIFI_PASSWORD = "rejeki88";


// Deklarasi objek SSD1306 (OLED I2C address 0x3C atau 0x3D)

// Ganti 0x3C jika OLED Anda menggunakan alamat 0x3D

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


// Buat objek HardwareSerial untuk SIM800L

HardwareSerial sim800lSerial(1); // Gunakan UART1 pada ESP32 (UART0 digunakan untuk Serial debugging)


// --- Deklarasi Fungsi Prototipe ---

String sendATCommand(String command);

void getAndDisplaySignalStrength();

void sendSMS(String phoneNumber, String message);

void setLedStatus(bool pingSuccess);

void makeCall(String phoneNumber, int callDurationSeconds);

void connectWiFi(); // Fungsi baru untuk menghubungkan ke WiFi

bool testGatewayPing(); // Fungsi baru untuk menguji ping ke gateway


// Variabel untuk debouncing tombol

long lastButtonPressTime = 0; // Waktu terakhir tombol ditekan

const long debounceDelay = 50; // Waktu debounce dalam milidetik


void setup() {

  // Inisialisasi komunikasi serial untuk debugging (monitor serial)

  Serial.begin(115200);

  Serial.println("Memulai pengujian koneksi ESP32 dengan SIM800L, OLED, LED, Tombol, dan WiFi...");


  // Inisialisasi pin LED sebagai output

  pinMode(LED_PIN, OUTPUT);

  digitalWrite(LED_PIN, LOW); // Pastikan LED mati di awal inisialisasi


  // Inisialisasi pin tombol sebagai input dengan resistor pull-up internal

  // Tombol harus disambungkan untuk menghubungkan pin ini ke GND saat ditekan.

  pinMode(BUTTON_PIN, INPUT_PULLUP);

  Serial.println("Pin tombol diinisialisasi dengan INPUT_PULLUP.");


  // Inisialisasi OLED

  if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) { // Alamat I2C umum untuk OLED

    Serial.println(F("Alokasi SSD1306 gagal"));

    for (;;) ; // Jangan lanjutkan jika gagal, berhenti di sini

  }

  display.display(); // Tampilkan logo boot-up Adafruit

  delay(2000);

  display.clearDisplay(); // Hapus tampilan

  display.setTextSize(1); // Ukuran teks 1

  display.setTextColor(SSD1306_WHITE); // Warna teks putih


  // Tampilkan pesan inisialisasi di OLED

  display.setCursor(0, 0);

  display.println("ESP32 + SIM800L");

  display.println("Inisialisasi...");

  display.display();

  delay(2000);


  // Inisialisasi komunikasi serial untuk SIM800L

  // Baud rate 9600, 8 bit data, tanpa paritas, 1 bit stop

  sim800lSerial.begin(9600, SERIAL_8N1, SIM800L_RX_PIN, SIM800L_TX_PIN);

  delay(1000); // Beri waktu modul untuk stabil


  // --- Pengujian Modul SIM800L dan Indikator LED ---


  Serial.println("Mengirim AT command untuk memeriksa koneksi SIM800L...");

  display.clearDisplay();

  display.setCursor(0, 0);

  display.println("Cek Koneksi GSM...");

  display.display();

  String atResponse = sendATCommand("AT");

  setLedStatus(atResponse.indexOf("OK") != -1);

  delay(1000);


  Serial.println("Mengirim AT+CSQ untuk memeriksa kualitas sinyal SIM800L...");

  display.clearDisplay();

  display.setCursor(0, 0);

  display.println("Mengecek Sinyal GSM...");

  display.display();

  getAndDisplaySignalStrength();

  delay(2000);


  Serial.println("Mengirim AT+CREG? untuk memeriksa pendaftaran jaringan SIM800L...");

  display.clearDisplay();

  display.setCursor(0, 0);

  display.println("Mendaftar Jaringan GSM...");

  display.display();

  String cregResponse = sendATCommand("AT+CREG?");

  setLedStatus(cregResponse.indexOf("OK") != -1);

  delay(2000);


  Serial.println("Mencoba mengirim SMS dengan SIM800L...");

  display.clearDisplay();

  display.setCursor(0, 0);

  display.println("Mengirim SMS...");

  display.display();

  sendSMS("+628112508805", "Halo dari ESP32 dan SIM800L!");

  delay(3000);


  // --- Koneksi WiFi Awal ---

  connectWiFi(); // Lakukan koneksi WiFi di awal


  // Final test message on OLED

  display.clearDisplay();

  display.setCursor(0, 0);

  display.println("Inisialisasi Selesai!");

  display.println("Tekan Tombol utk Panggil.");

  display.println("Cek PING Gateway.");

  display.display();

}


void loop() {

  // Logic ping SIM800L dan kekuatan sinyal

  static unsigned long lastSim800lPingTime = 0;

  static unsigned long sim800lPingInterval = 10000; // Ping SIM800L setiap 10 detik


  if (millis() - lastSim800lPingTime >= sim800lPingInterval) {

    lastSim800lPingTime = millis();

    Serial.println("Melakukan ping SIM800L (AT command) untuk indikator LED...");

    String atResponseLoop = sendATCommand("AT");

    setLedStatus(atResponseLoop.indexOf("OK") != -1);

    getAndDisplaySignalStrength(); // Memperbarui kekuatan sinyal di OLED dan LED

  }


  // --- Logic Koneksi WiFi dan Ping Gateway ---

  static unsigned long lastGatewayPingTime = 0;

  static unsigned long gatewayPingInterval = 30000; // Cek gateway setiap 30 detik

  static bool callInitiatedDueToPingFailure = false;

  static unsigned long lastCallDueToPingTime = 0;

  const unsigned long callCooldown = 5 * 60 * 1000; // Cooldown 5 menit untuk panggilan yang dipicu kegagalan ping


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

    Serial.println("WiFi tidak terhubung. Mencoba menyambung kembali...");

    connectWiFi(); // Coba sambungkan kembali jika tidak terhubung

  }


  if (WiFi.status() == WL_CONNECTED && (millis() - lastGatewayPingTime >= gatewayPingInterval)) {

    lastGatewayPingTime = millis();

    Serial.println("Melakukan Uji Ping Gateway...");

    display.clearDisplay();

    display.setCursor(0, 0);

    display.println("Memeriksa Gateway...");

    display.display();


    if (testGatewayPing()) { // Jika ping berhasil

      Serial.println("Ping Gateway Berhasil (koneksi WiFi baik).");

      display.clearDisplay();

      display.setCursor(0, 0);

      display.println("Gateway OK!");

      display.println("WiFi Connected.");

      display.display();

      callInitiatedDueToPingFailure = false; // Reset flag panggilan jika gateway dapat dijangkau

    } else { // Jika ping timeout

      Serial.println("Ping Gateway Timeout! Memulai panggilan via SIM800L...");

      display.clearDisplay();

      display.setCursor(0, 0);

      display.println("Gateway Timeout!");

      display.println("Memanggil via SIM800L...");

      display.display();


      if (!callInitiatedDueToPingFailure || (millis() - lastCallDueToPingTime >= callCooldown)) {

        makeCall("+628112508805", 15); // Lakukan panggilan 15 detik

        callInitiatedDueToPingFailure = true;

        lastCallDueToPingTime = millis();

      } else {

        Serial.println("Panggilan telah dipicu baru-baru ini karena kegagalan ping. Menunggu cooldown...");

      }

    }

  }


  // --- Logic Pengecekan Tombol ---

  int buttonState = digitalRead(BUTTON_PIN);


  if (buttonState == LOW && (millis() - lastButtonPressTime) > debounceDelay) {

    if (lastButtonPressTime == 0) { // Hanya picu jika ini penekanan baru

      Serial.println("Tombol Ditekan! Memulai panggilan...");

      display.clearDisplay();

      display.setCursor(0,0);

      display.println("Tombol Ditekan!");

      display.println("Memanggil...");

      display.display();

      delay(500); // Penundaan singkat untuk update display


      makeCall("+628112508805", 15); // Durasi panggilan 15 detik saat tombol ditekan

      

      display.clearDisplay();

      display.setCursor(0,0);

      display.println("Panggilan Dipicu.");

      display.println("Siap untuk tekan lagi.");

      display.display();

    }

    lastButtonPressTime = millis(); // Rekam waktu penekanan ini

  } else if (buttonState == HIGH) {

      lastButtonPressTime = 0; // Reset timer debounce jika tombol dilepas

  }

}


// Fungsi untuk mengirim perintah AT ke SIM800L dan membaca responsnya

String sendATCommand(String command) {

  Serial.print("Mengirim: ");

  Serial.println(command);

  sim800lSerial.println(command);


  String response = "";

  long timeout = millis();

  while (millis() - timeout < 2000) {

    if (sim800lSerial.available()) {

      char c = sim800lSerial.read();

      Serial.write(c);

      response += c;

    }

  }

  Serial.println();

  return response;

}


// Fungsi untuk mengontrol status LED berdasarkan hasil "ping"

// Jika pingSuccess TRUE (modul merespons "OK"), LED menyala stabil.

// Jika pingSuccess FALSE (modul tidak merespons "OK" atau timeout), LED berkedip cepat.

void setLedStatus(bool pingSuccess) {

  if (pingSuccess) {

    digitalWrite(LED_PIN, HIGH); // LED ON (menyala stabil)

    Serial.println("LED ON: Modul merespons dengan OK.");

  } else {

    Serial.println("LED BLINK: Modul tidak merespons OK (timeout atau error).");

    for (int i = 0; i < 5; i++) { // Berkedip cepat 5 kali

      digitalWrite(LED_PIN, HIGH); // LED menyala

      delay(100); // Jeda singkat

      digitalWrite(LED_PIN, LOW); // LED mati

      delay(100); // Jeda singkat

    }

    digitalWrite(LED_PIN, LOW); // Pastikan LED mati setelah berkedip

  }

}


// Fungsi untuk mendapatkan dan menampilkan kekuatan sinyal (RSSI) di OLED

void getAndDisplaySignalStrength() {

  String response = sendATCommand("AT+CSQ");

  setLedStatus(response.indexOf("OK") != -1); // Perbarui status LED berdasarkan respons AT+CSQ


  int rssi = -1;

  int commaIndex = response.indexOf(',');

  if (response.indexOf("+CSQ:") != -1 && commaIndex != -1) {

    String rssiStr = response.substring(response.indexOf(":") + 1, commaIndex);

    rssi = rssiStr.toInt();

  }


  display.clearDisplay();

  display.setCursor(0, 0);

  display.setTextSize(1);

  display.println("Kekuatan Sinyal:");

  display.setTextSize(2);


  if (rssi >= 0 && rssi <= 31) {

    display.print("RSSI: ");

    display.print(rssi);

    display.print(" (");

    display.print(-113 + rssi * 2);

    display.println(" dBm)");


    display.setTextSize(1);

    display.print("Status: ");

    if (rssi >= 20) {

      display.println("Sangat Baik");

    } else if (rssi >= 10) {

      display.println("Baik");

    } else if (rssi >= 2) {

      display.println("Cukup");

    } else {

      display.println("Lemah/Tidak Ada");

    }

  } else {

    display.println("Tidak Diketahui");

  }

  display.display();

}


// Fungsi untuk mengirim SMS ke nomor telepon tertentu dengan pesan tertentu

void sendSMS(String phoneNumber, String message) {

  Serial.println("Mengatur mode SMS ke Text Mode...");

  String modeResponse = sendATCommand("AT+CMGF=1");

  setLedStatus(modeResponse.indexOf("OK") != -1);

  delay(1000);


  Serial.print("Mengirim SMS ke: ");

  Serial.println(phoneNumber);

  sim800lSerial.print("AT+CMGS=\"");

  sim800lSerial.print(phoneNumber);

  sim800lSerial.println("\"");

  delay(100);


  sim800lSerial.print(message);

  sim800lSerial.write(0x1A);

  Serial.println("Pesan dikirim. Menunggu konfirmasi...");


  String smsConfirmation = "";

  long timeout = millis();

  while (millis() - timeout < 10000) {

    if (sim800lSerial.available()) {

      char c = sim800lSerial.read();

      Serial.write(c);

      smsConfirmation += c;

    }

  }

  Serial.println();

  setLedStatus(smsConfirmation.indexOf("OK") != -1 || smsConfirmation.indexOf("+CMGS:") != -1);

}


// Fungsi untuk melakukan panggilan telepon ke nomor yang ditentukan

// Panggilan akan otomatis diputus setelah callDurationSeconds

void makeCall(String phoneNumber, int callDurationSeconds) {

  Serial.print("Melakukan panggilan ke: ");

  Serial.println(phoneNumber);

  display.clearDisplay();

  display.setCursor(0,0);

  display.println("Memanggil:");

  display.println(phoneNumber);

  display.display();


  String callResponse = sendATCommand("ATD" + phoneNumber + ";");

  setLedStatus(callResponse.indexOf("OK") != -1);


  if (callResponse.indexOf("OK") != -1) {

    Serial.println("Panggilan dimulai. Menunggu koneksi atau timeout...");

    display.clearDisplay();

    display.setCursor(0,0);

    display.println("Panggilan Berlangsung...");

    display.println(phoneNumber);

    display.display();


    delay(callDurationSeconds * 1000);


    Serial.println("Mengakhiri panggilan...");

    display.clearDisplay();

    display.setCursor(0,0);

    display.println("Mengakhiri Panggilan...");

    display.display();

    String hangupResponse = sendATCommand("ATH");

    setLedStatus(hangupResponse.indexOf("OK") != -1);

    delay(1000);


    Serial.println("Panggilan diakhiri.");

  } else {

    Serial.println("Gagal memulai panggilan atau nomor tidak valid.");

    display.clearDisplay();

    display.setCursor(0,0);

    display.println("Panggilan Gagal!");

    display.println("Periksa Sinyal/No.");

    display.display();

  }

}


// Fungsi untuk menghubungkan ESP32 ke WiFi

void connectWiFi() {

  Serial.print("Menghubungkan ke WiFi SSID: ");

  Serial.println(WIFI_SSID);

  display.clearDisplay();

  display.setCursor(0, 0);

  display.println("Menghubungkan WiFi:");

  display.println(WIFI_SSID);

  display.display();


  WiFi.begin(WIFI_SSID, WIFI_PASSWORD);

  int attempts = 0;

  while (WiFi.status() != WL_CONNECTED && attempts < 20) { // Coba 20 kali (sekitar 10 detik)

    delay(500);

    Serial.print(".");

    display.print(".");

    display.display();

    attempts++;

  }

  display.clearDisplay();

  display.setCursor(0, 0);


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

    Serial.println("\nWiFi Terhubung!");

    Serial.print("Alamat IP: ");

    Serial.println(WiFi.localIP());

    display.println("WiFi Terhubung!");

    display.print("IP: ");

    display.println(WiFi.localIP());

  } else {

    Serial.println("\nGagal Terhubung ke WiFi!");

    display.println("Gagal Terhubung!");

    display.println("Cek SSID/Sandi.");

  }

  display.display();

  delay(2000);

}


// Fungsi untuk menguji koneksi ke IP gateway menggunakan koneksi TCP

// Mengembalikan TRUE jika koneksi berhasil (ping reply), FALSE jika gagal (timeout)

bool testGatewayPing() {

  IPAddress gatewayIP = WiFi.gatewayIP();

  Serial.print("Mencoba koneksi ke Gateway IP: ");

  Serial.print(gatewayIP);

  Serial.println(" di port 80...");


  WiFiClient client;

  bool connected = client.connect(gatewayIP, 80); // Coba terhubung ke port 80


  if (connected) {

    Serial.println("Koneksi Gateway Berhasil.");

    client.stop(); // Hentikan koneksi

    return true;

  } else {

    Serial.println("Koneksi Gateway Gagal (Timeout).");

    client.stop(); // Hentikan koneksi

    return false;

  }

}


No comments:

Post a Comment

CARGER AKI CONTROLER INA226-LIBARY WE ROTARI SW+OLED 0.96 SUKSES TAMPILAN LEBIH BAIK

 #include <Wire.h>  #include <Adafruit_GFX.h>    // Library grafis Adafruit #include <Adafruit_SSD1306.h> // Library untuk...