Sunday, September 29, 2024

Sistem Monitoring Berbasis GPS Menggunakan LiliGO Board dan Node-RED untuk Menampilkan Data Sensor dan Mengirim Notifikasi ke Bot Telegram

 

A.    Kompetensi

3.1 Menguraikan Konsep Dasar Sistem Monitoring Menggunakan Teknologi GPS dan Prinsip Kerja Sensor GPS

3.2 Mengidentifikasi Jenis-jenis Perangkat Keras dan Perangkat Lunak yang digunakan dalam Sistem Monitoring Berbasis GPS, termasuk LiliGO Board, Sensor Analog dan Digital, Modul RS485, dan Node-RED

4.1 Memasang dan Mengonfigurasi Sensor GPS, Sensor Analog dan Digital, dan Modul RS485 pada LiliGO Board

4.2 Mengoperasikan Sistem Monitoring Menggunakan Sensor GPS untuk Mengirim Data ke Node-RED dan Bot Telegram

B.     Dasar Teori

Sensor GPS NEO-6M

Sensor GPS NEO-6M adalah modul penerima sinyal satelit yang digunakan untuk menentukan lokasi geografis dengan akurasi tinggi. Modul ini bekerja dengan menerima sinyal dari satelit GPS dan mengolah data tersebut untuk menghasilkan informasi tentang latitude, longitude, dan waktu. NEO-6M sering digunakan dalam aplikasi pelacakan dan navigasi, serta dalam sistem IoT untuk mengumpulkan data lokasi secara real-time. Dalam proyek ini, data yang diperoleh dari sensor GPS akan digunakan untuk memantau posisi kendaraan listrik dan menampilkan informasi lokasi kepada pengguna melalui antarmuka Node-RED.

Sensor Analog

Sensor analog adalah perangkat yang menghasilkan sinyal kontinu yang berbanding lurus dengan nilai fisik yang diukur, seperti suhu, kelembapan, atau resistansi. Contoh sensor analog yang umum digunakan adalah potensiometer, yang memberikan output variabel berdasarkan posisi mekanisnya. Dalam proyek ini, sensor analog digunakan untuk mengukur parameter tertentu dan mengirimkan data tersebut ke sistem untuk diproses. Nilai analog yang diperoleh akan ditampilkan di Node-RED, memberikan pengguna informasi yang bermanfaat mengenai kondisi lingkungan atau status perangkat.

Sensor Digital

Sensor digital adalah perangkat yang memberikan output dalam bentuk sinyal biner, yaitu 0 atau 1, yang merepresentasikan status aktif atau non-aktif dari suatu kondisi. Contoh sensor digital termasuk tombol atau saklar yang digunakan untuk mendeteksi perintah dari pengguna. Dalam konteks proyek ini, sensor digital berfungsi untuk mengumpulkan informasi mengenai status perangkat atau kondisi tertentu dan mengirimkan data tersebut ke sistem. Informasi yang diperoleh dari sensor digital akan diproses dan ditampilkan di Node-RED, memberikan umpan balik langsung kepada pengguna tentang status sistem.

Modul RS485

Modul RS485 adalah perangkat yang memungkinkan komunikasi data antara beberapa perangkat dalam jaringan dengan menggunakan protokol komunikasi serial. RS485 memiliki keunggulan dalam ketahanan terhadap gangguan elektromagnetik dan kemampuan untuk berkomunikasi pada jarak yang lebih jauh dibandingkan dengan protokol serial lainnya. Dalam proyek ini, modul RS485 digunakan untuk menghubungkan berbagai sensor dan perangkat lain dalam sistem, memungkinkan pengiriman data secara efisien. Data yang diterima dari modul RS485 akan dikirimkan ke Node-RED untuk ditampilkan dan diproses lebih lanjut.

Node-RED

Node-RED adalah alat pemrograman berbasis aliran yang memungkinkan pengguna untuk menghubungkan perangkat keras, API, dan layanan online dengan cara yang mudah dan intuitif. Dengan antarmuka grafis yang sederhana, pengguna dapat merancang alur data dan kontrol dalam sistem IoT tanpa perlu menulis kode kompleks. Dalam proyek ini, Node-RED digunakan untuk menampilkan data dari sensor GPS, analog, digital, dan RS485. Selain itu, Node-RED juga mengintegrasikan fungsi pengiriman data ke bot Telegram, memudahkan pengguna untuk menerima informasi dan notifikasi secara langsung melalui aplikasi chat.

Bot Telegram

Bot Telegram adalah aplikasi yang berfungsi sebagai penghubung antara pengguna dan layanan tertentu melalui platform Telegram. Dengan menggunakan BotFather, pengguna dapat membuat bot yang dapat mengirim dan menerima pesan. Dalam konteks proyek ini, bot Telegram digunakan untuk mengirimkan data dari sistem kepada pengguna, memberikan notifikasi dan informasi penting secara real-time. Integrasi bot Telegram dalam sistem memungkinkan pengguna untuk mendapatkan akses cepat terhadap data yang dikumpulkan, serta memberikan kemudahan dalam memantau dan mengendalikan perangkat dari jarak jauh.

C.    Alat dan Bahan:

·  Board LilyGO

·  Modul GPS NEO-6M

·  Sensor analog (misalnya, potensiometer)

·  Input digital (misalnya, tombol)

·  Modul RS485

·  Koneksi internet (SIM card atau Wi-Fi)

·  Node-RED

·  Bot Telegram

D.    Rangkaian

E.     Program

1.      Arduino IDE

#include <Wire.h>

#include <PubSubClient.h>

#include <TinyGPSPlus.h>

#include <SoftwareSerial.h>

#include <WiFi.h>

 

// WiFi credentials

const char* ssid = "Ototronik"; // Ganti dengan SSID WiFi Anda

const char* password = "ototronik2024"; // Ganti dengan password WiFi Anda

 

// MQTT Broker

const char *mqtt_broker = "broker.emqx.io";

const char *topic = "MapelPilihan/tracker";

const char *mqtt_username = "";

const char *mqtt_password = "";

const int mqtt_port = 1883;

String client_id = "lilygo-MapelPilihan";

 

// TTGO T-Call pins

#define I2C_SDA              21

#define I2C_SCL              22

 

#define SerialMon Serial

#define SerialAT Serial1

 

TinyGPSPlus gps;

WiFiClient wifiClient;

PubSubClient mqtt(wifiClient);

SoftwareSerial GPSSerial(18, 19);

SoftwareSerial RS485(22, 23);

 

unsigned long curMill = 0;

unsigned long prevMill = 0;

const unsigned long interval1 = 1250;

const unsigned long interval2 = 2500;

const unsigned long interval3 = 3500;

 

// Pin Input

int digitalPin_1 = 32;

int digitalPin_2 = 33;

int analogPin_1 = 34;

int analogPin_2 = 35;

 

int digital_1, digital_2, analog_1, analog_2;

float lngi, lati, spd, sat;

int tahun, bulan, hari, jam, menit, detik;

String payload, rs485;

 

void setup() {

  SerialMon.begin(9600);

  GPSSerial.begin(9600);

  RS485.begin(9600);

 

  pinMode(digitalPin_1, INPUT);

  pinMode(digitalPin_2, INPUT);

  pinMode(analogPin_1, INPUT);

  pinMode(analogPin_2, INPUT);

 

  // Connect to WiFi

  connectWiFi();

 

  // Set MQTT server

  mqtt.setServer(mqtt_broker, mqtt_port);

  mqtt.setCallback(callback);

}

 

void loop() {

  while (GPSSerial.available() > 0) {

    curMill = millis();

 

    if (gps.encode(GPSSerial.read())) {

      if (curMill - prevMill < interval1) {

        waktuHandler();

        GPSHandler();

      }

      else if (curMill - prevMill > interval1 && curMill - prevMill < interval2) {

        bacaInp();

      }

      else if (curMill - prevMill > interval2 && curMill - prevMill < interval3) {

        RSHandler();

      }

      else if (curMill - prevMill > interval3) {

        if (!mqtt.connected()) {

          reconnect();

        }

        publishData();

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

          connectWiFi();

        }

        prevMill = curMill;

      }

    }

  }

}

 

void connectWiFi() {

  SerialMon.print("Connecting to ");

  SerialMon.println(ssid);

  WiFi.begin(ssid, password);

 

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

    delay(500);

    SerialMon.print(".");

  }

  SerialMon.println("");

  SerialMon.println("WiFi connected");

  SerialMon.println("IP address: ");

  SerialMon.println(WiFi.localIP());

}

 

void setupMqtt() {

  while (!mqtt.connected()) {

    SerialMon.printf("The client %s connects to the public MQTT broker\n", client_id.c_str());

    if (mqtt.connect(client_id.c_str())) {

      SerialMon.println("Public EMQX MQTT broker connected");

    } else {

      SerialMon.print("failed with state ");

      SerialMon.print(mqtt.state());

      delay(2000);

    }

  }

}

 

void callback(char *topic, byte *payload, unsigned int length) {

  SerialMon.print("Message arrived in topic: ");

  SerialMon.println(topic);

  SerialMon.print("Message:");

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

    SerialMon.print((char) payload[i]);

  }

  SerialMon.println();

  SerialMon.println("-----------------------");

}

 

void reconnect() {

  while (!mqtt.connected()) {

    SerialMon.print("Menghubungkan ulang ke MQTT...");

    if (mqtt.connect(client_id.c_str())) {

      SerialMon.println("connected");

    } else {

      SerialMon.print("Gagal, rc=");

      SerialMon.print(mqtt.state());

      SerialMon.println(" mencoba kembali dalam 5 detik");

      delay(5000);

    }

  }

}

 

void waktuHandler() {

  tahun = gps.date.year();

  bulan = gps.date.month();

  hari = gps.date.day();

  jam = gps.time.hour();

  menit = gps.time.minute();

  detik = gps.time.second();

 

  jam += 7;

 

  if (jam >= 24) {

    jam -= 24;

    hari++;

  }

  if (hari > 31) {

    hari = 1;

    bulan++;

  }

  if (bulan > 12) {

    bulan = 1;

    tahun++;

  }

}

 

void GPSHandler() {

  lngi = gps.location.lng();

  lati = gps.location.lat();

  sat = gps.satellites.value();

  spd = gps.speed.kmph();

}

 

void RSHandler(){

  if (RS485.available() > 0){

    char data = RS485.read();

    rs485 = String(data);

  }

  else{

    rs485 = "no data";

  }

}

 

void bacaInp() {

  digital_1 = digitalRead(digitalPin_1);

  digital_2 = digitalRead(digitalPin_2);

  analog_1 = analogRead(analogPin_1);

  analog_2 = analogRead(analogPin_2);

}

 

void publishData() {

  payload = "";

  payload += String(tahun);

  payload += "/";

  if (bulan < 10) payload += "0";

  payload += String(bulan);

  payload += "/";

  if (hari < 10) payload += "0";

  payload += String(hari);

  payload += "/";

  if (jam < 10) payload += "0";

  payload += String(jam);

  payload += ":";

  if (menit < 10) payload += "0";

  payload += String(menit);

  payload += ":";

  if (detik < 10) payload += "0";

  payload += String(detik);

  payload += ",";

  payload += String(lngi, 6);

  payload += ",";

  payload += String(lati, 6);

  payload += ",";

  payload += String(sat, 0);

  payload += ",";

  payload += String(digital_1);

  payload += ",";

  payload += String(digital_2);

  payload += ",";

  payload += String(analog_1);

  payload += ",";

  payload += String(analog_2);

  payload += ",";

  payload += String(spd, 2);

  payload += ",";

  payload += rs485;

  mqtt.publish(topic, String(payload).c_str());

  SerialMon.print("Data terkirim: ");

  SerialMon.println(payload);

}

2.      Flow Node Red

[

    {

        "id": "59cb847666d51e6f",

        "type": "mqtt in",

        "z": "ca465c84cb9eed23",

        "name": "",

        "topic": "MapelPilihan/tracker",

        "qos": "2",

        "datatype": "auto-detect",

        "broker": "d108aae0a6964fed",

        "nl": false,

        "rap": true,

        "rh": 0,

        "inputs": 0,

        "x": 130,

        "y": 80,

        "wires": [

            [

                "361b44f39d7d49bc"

            ]

        ]

    },

    {

        "id": "d108aae0a6964fed",

        "type": "mqtt-broker",

        "name": "emqx",

        "broker": "broker.emqx.io",

        "port": "1883",

        "clientid": "",

        "autoConnect": true,

        "usetls": false,

        "protocolVersion": "4",

        "keepalive": "60",

        "cleansession": true,

        "autoUnsubscribe": true,

        "birthTopic": "",

        "birthQos": "0",

        "birthRetain": "false",

        "birthPayload": "",

        "birthMsg": {},

        "closeTopic": "",

        "closeQos": "0",

        "closeRetain": "false",

        "closePayload": "",

        "closeMsg": {},

        "willTopic": "",

        "willQos": "0",

        "willRetain": "false",

        "willPayload": "",

        "willMsg": {},

        "userProps": "",

        "sessionExpiry": ""

    }

]

F.     Langkah-langkah:

1.      Siapkan alat dan bahan yang dibutuhkan

2.      Koneksikan pin GPS NEO-6M pada Mikrokontroler LilyGO sebagai berikut:

§  Pin RX ke Pin 19 LilyGO

§  Pin TX ke Pin 18 LilyGO

§  Pin VCC ke 3V3 LilyGO

§  Pin GND ke GND LilyGO

3.      Koneksikan pin Sensor Analog sebagai berikut:

§  Pin 3V3 ke 3V3 LilyGO

§  Pin Analog 1 ke Pin 34 LilyGO

§  Pin Analog 2 ke Pin 35 LilyGO

§  Pin GND ke GND LilyGO

4.      Koneksikan pin Sensor Digital sebagai berikut:

§  Pin 3V3 ke 3V3 LilyGO

§  Pin Digital 1 ke Pin 32 LilyGO

§  Pin Digital 2 ke Pin 33 LilyGO

§  Pin GND ke GND LilyGO

5.      Koneksikan pin RS485 sebagai berikut:

§  Pin 3V3 ke 3V3 LilyGO

§  Pin RX ke Pin 22 LilyGO

§  Pin TX ke Pin 23 LilyGO

§  Pin GND ke GND LilyGO

6.      Upload program ke LilyGO menggunakan Arduino IDE:

·         Download dan Instal Arduino IDE: Jika belum memiliki Arduino IDE, unduh dan instal dari situs resmi Arduino.

7.      Tambahkan Board LilyGO T-Call:

·         Buka Arduino IDE.

·         Pergi ke File > Preferences.

·         Di bagian "Additional Boards Manager URLs", tambahkan URL berikut: https://dl.espressif.com/dl/package_esp32_index.json.

·         Klik OK.

·         Pergi ke Tools > Board > Boards Manager.

·         Cari "ESP32" dan instal paket "esp32 by Espressif Systems".

·         Pilih board yang sesuai, misalnya "TTGO T1" atau "ESP32 Dev Module" di menu Tools > Board.

8.      Hubungkan LilyGO ke PC: Gunakan kabel USB untuk menghubungkan board LilyGO ke komputer.

·         Pilih Port yang Benar: Pergi ke Tools > Port dan pilih port yang sesuai dengan LilyGO.

·         Tulis atau buka program yang sudah disiapkan untuk LilyGO.

·         Klik tombol "Upload" untuk mengunggah program ke LilyGO.

9.      Instal Node-Red pada laptop/PC jika belum terpasang:

·         Buka link berikut untuk panduan instalasi Node-Red.

·         Ikuti langkah-langkah instalasi yang dijelaskan di situs tersebut.

10.  Jika Node-Red sudah terpasang, buka Command Prompt (cmd) dan ketikkan “node-red”:

·         Buka Command Prompt di laptop/PC.

·         Ketik "node-red" dan tekan Enter.

·         Tunggu sampai Node-Red berjalan dan menampilkan pesan bahwa server sudah berjalan.

11.  Selanjutnya, buka browser dan ketikkan http://127.0.0.1:1880/ pada kolom pencarian:

·         Buka browser favorit Anda.

·         Masukkan URL "http://127.0.0.1:1880/" pada kolom alamat.

·         Tekan Enter untuk membuka antarmuka Node-Red.


12.  Tampilan Node-Red akan terbuka. Klik pada ikon tiga garis dan pilih "Import". Masukkan program flow JSON yang telah disiapkan sebelumnya:

·         Klik ikon tiga garis di sudut kanan atas antarmuka Node-Red.

·         Pilih "Import" dari menu yang muncul.

·         Salin dan tempel flow JSON yang telah disiapkan sebelumnya ke dalam kotak teks yang muncul.

·         Klik tombol "Import" untuk menambahkan flow ke Node-Red.

13.  Setelah itu, tekan tombol "Deploy":

·         Klik tombol "Deploy" di sudut kanan atas antarmuka Node-Red.

·         Tunggu sampai proses deploy selesai dan semua perubahan diterapkan.

14.  Buka tab baru di browser dan ketikkan http://127.0.0.1:1880/ui pada kolom pencarian untuk membuka antarmuka pengguna Node-Red:

·         Buka tab baru di browser.

·         Masukkan URL "http://127.0.0.1:1880/ui" pada kolom alamat.

·         Tekan Enter untuk membuka antarmuka pengguna Node-Red.

15.  Tampilan dashboard Node-Red akan terbuka:

·         Setelah URL dimasukkan, dashboard Node-Red akan muncul di browser.

·         Anda sekarang bisa melihat dan berinteraksi dengan dashboard yang telah dibuat.

16.  Untuk menjalankan bot Telegram, ketikkan “MaPelPilihanSMKN1Seyegan” pada kolom pencarian di aplikasi Telegram:

·         Buka aplikasi Telegram di perangkat Anda.

·         Pada kolom pencarian, ketik “MaPelPilihanSMKN1Seyegan”.

·         Pilih bot yang muncul dari hasil pencarian.

17.  Setelah itu, ketikkan /start. Akan muncul pilihan menu:

·         Di jendela chat dengan bot, ketikkan "/start" dan kirim pesan.

·         Bot akan merespon dengan menampilkan pilihan menu yang tersedia.

G.    Tugas

1.      Jelaskan bagaimana cara kerja rangkaian ini?

2.      Selanjutnya paste program untuk mengganti jaringan WiFi menjadi SIM card yang ada di board LilyGo!

        Program :

const char apn[] = "3gprs.net";
const char gprsUser[] = "3gprs"; // GPRS User
const char gprsPass[] = "3gprs"; // GPRS Password
const char simPIN[]   = "";

// TTGO T-Call pins
#define MODEM_RST            5
#define MODEM_PWKEY          4
#define MODEM_POWER_ON       23
#define MODEM_TX             27
#define MODEM_RX             26
#define I2C_SDA              21
#define I2C_SCL              22

#define SerialMon Serial
#define SerialAT Serial1
// Configure TinyGSM library
#define TINY_GSM_MODEM_SIM800
#define TINY_GSM_RX_BUFFER   1024  // Set RX buffer to 1Kb

#include <Wire.h>
#include <TinyGsmClient.h>
#include <PubSubClient.h>
#include <TinyGPSPlus.h>
#include <SoftwareSerial.h>

#ifdef DUMP_AT_COMMANDS
#include <StreamDebugger.h>
StreamDebugger debugger(SerialAT, SerialMon);
TinyGsm modem(debugger);
#else
TinyGsm modem(SerialAT);
#endif

// I2C for SIM800 (to keep it running when powered from battery)
TwoWire I2CPower = TwoWire(0);
TinyGsmClient client(modem);
PubSubClient  mqtt(client);
SoftwareSerial GPSSerial(18, 19);
SoftwareSerial RS485(25, 26);
TinyGPSPlus gps;

#define uS_TO_S_FACTOR 1000000UL
#define TIME_TO_SLEEP  3600
#define IP5306_ADDR          0x75
#define IP5306_REG_SYS_CTL0  0x00

// MQTT Broker
const char *mqtt_broker = "broker.emqx.io";
const char *topic = "MapelPilihan/tracker";
const char *mqtt_username = "";
const char *mqtt_password = "";
const int mqtt_port = 1883;
String client_id = "lilygo-MapelPilihan";

unsigned long curMill = 0;
unsigned long prevMill = 0;
const unsigned long interval1 = 1250;
const unsigned long interval2 = 2500;
const unsigned long interval3 = 3500;

// Pin Input
int digitalPin_1 = 32;
int digitalPin_2 = 33;
int analogPin_1 = 34;
int analogPin_2 = 35;

int digital_1, digital_2, analog_1, analog_2;
float lngi, lati, spd, sat;
int tahun, bulan, hari, jam, menit, detik;
String payload, rs485;

bool setPowerBoostKeepOn(int en) {
  I2CPower.beginTransmission(IP5306_ADDR);
  I2CPower.write(IP5306_REG_SYS_CTL0);
  if (en) {
    I2CPower.write(0x37);
  } else {
    I2CPower.write(0x35);
  }
  return I2CPower.endTransmission() == 0;
}

void setup() {
  SerialMon.begin(9600);
  GPSSerial.begin(9600);
  RS485.begin(9600);

  pinMode(digitalPin_1, INPUT);
  pinMode(digitalPin_2, INPUT);
  pinMode(analogPin_1, INPUT);
  pinMode(analogPin_2, INPUT);
  I2CPower.begin(I2C_SDA, I2C_SCL, 400000);

  bool isOk = setPowerBoostKeepOn(1);
  SerialMon.println(String("IP5306 KeepOn ") + (isOk ? "OK" : "FAIL"));

  // Set modem reset, enable, power pins
  pinMode(MODEM_PWKEY, OUTPUT);
  pinMode(MODEM_RST, OUTPUT);
  pinMode(MODEM_POWER_ON, OUTPUT);
  digitalWrite(MODEM_PWKEY, LOW);
  digitalWrite(MODEM_RST, HIGH);
  digitalWrite(MODEM_POWER_ON, HIGH);

  SerialAT.begin(115200, SERIAL_8N1, MODEM_RX, MODEM_TX);
  delay(3000);
  SerialMon.println("Inisialisasi modem...");
  modem.restart();

  if (strlen(simPIN) && modem.getSimStatus() != 3 ) {
    modem.simUnlock(simPIN);
  }
  setupSIM();
  setupMqtt();
}

void loop() {
  while (GPSSerial.available() > 0) {
    curMill = millis();

    if (gps.encode(GPSSerial.read())) {
//      if (gps.location.isValid()) {
        if (curMill - prevMill < interval1) {
          waktuHandler();
          GPSHandler();
//          Serial.println(F("Membaca GPS"));
        }
        else if (curMill - prevMill > interval1 and curMill - prevMill < interval2) {
          bacaInp();
//          Serial.println(F("Membaca Input"));
        }
        else if (curMill - prevMill > interval2 and curMill - prevMill < interval3) {
          RSHandler();
//          Serial.println(F("Membaca RS485"));
        }
        else if (curMill - prevMill > interval3) {
          if (mqtt.connected()) {
            publishData();
            SerialMon.println(F("Publish data"));
          }
          else {
            reconnect();
            publishData();
            SerialMon.println(F("Publish data"));
          }
          if (!modem.isGprsConnected()){
            ESP.restart();
          }
          prevMill = curMill;
        }
//      } else {
//        SerialMon.println(F("Data GPS tidak valid"));
//      }
    }
  }
//  mqtt.subscribe(topic);
}

void setupSIM() {
  SerialMon.print("Menghubungkan ke APN: ");
  SerialMon.print(apn);
  if (!modem.gprsConnect(apn, gprsUser, gprsPass)) {
    SerialMon.println(" Gagal!");
    ESP.restart();
  }
  else {
    SerialMon.println(" Berhasil!");
  }
  if (modem.isGprsConnected()) SerialMon.println("Terhubung ke Internet");
}

void setupMqtt() {
  //  client_id += String(WiFi.macAddress());
  mqtt.setServer(mqtt_broker, mqtt_port);
  mqtt.setCallback(callback);
  while (!client.connected()) {
    Serial.printf("The client %s connects to the public MQTT broker\n", client_id.c_str());
    if (mqtt.connect(client_id.c_str())) {
      Serial.println("Public EMQX MQTT broker connected");
    } else {
      Serial.print("failed with state ");
      Serial.print(mqtt.state());
      delay(2000);
    }
  }
}

void callback(char *topic, byte *payload, unsigned int length) {
  Serial.print("Message arrived in topic: ");
  Serial.println(topic);
  Serial.print("Message:");
  for (int i = 0; i < length; i++) {
    Serial.print((char) payload[i]);
  }
  Serial.println();
  Serial.println("-----------------------");
}

void reconnect() {
  while (!mqtt.connected()) {
    Serial.print("Menghubungkan ulang ke MQTT...");
    if (mqtt.connect(client_id.c_str())) {
      Serial.println("connected");
    } else {
      Serial.print("Gagal, rc=");
      Serial.print(mqtt.state());
      Serial.println(" mencoba kembali dalam 5 detik");
      delay(2500);
    }
  }
}

void waktuHandler() {
  tahun = gps.date.year();
  bulan = gps.date.month();
  hari = gps.date.day();
  jam = gps.time.hour();
  menit = gps.time.minute();
  detik = gps.time.second();

  jam += 7;

  if (jam >= 24) {
    jam -= 24;
    hari++;
  }
  if (hari > 31) {
    hari = 1;
    bulan++;
  }
  if (bulan > 12) {
    bulan = 1;
    tahun++;
  }
}

void GPSHandler() {
  lngi = gps.location.lng();
  lati = gps.location.lat();
  sat = gps.satellites.value();
  spd = gps.speed.kmph();
}

void RSHandler(){
  if (RS485.available() > 0){
    char data = RS485.read();
    rs485 = String(data);
  }
  else{
    rs485 = "no data";
  }
}

void bacaInp() {
  digital_1 = digitalRead(digitalPin_1);
  digital_2 = digitalRead(digitalPin_2);
  analog_1 = analogRead(analogPin_1);
  analog_2 = analogRead(analogPin_2);
}

void publishData() {
  payload = "";
  payload += String(tahun);
  payload += "/";
  if (bulan < 10) payload += "0";
  payload += String(bulan);
  payload += "/";
  if (hari < 10) payload += "0";
  payload += String(hari);
  payload += "/";
  if (jam < 10) payload += "0";
  payload += String(jam);
  payload += ":";
  if (menit < 10) payload += "0";
  payload += String(menit);
  payload += ":";
  if (detik < 10) payload += "0";
  payload += String(detik);
  payload += ",";
  payload += String(lngi, 6);
  payload += ",";
  payload += String(lati, 6);
  payload += ",";
  payload += String(sat, 0);
  payload += ",";
  payload += String(digital_1);
  payload += ",";
  payload += String(digital_2);
  payload += ",";
  payload += String(analog_1);
  payload += ",";
  payload += String(analog_2);
  payload += ",";
  payload += String(spd, 2);
  payload += ",";
  payload += rs485;
  mqtt.publish(topic, String(payload).c_str());
  Serial.print("Data terkirim: ");
  Serial.println(payload);
}

Jika program eror bisa gunakan link Drive

3.      Buatlah laporan praktikum dan dikumpulkan!

 

 

 

 

 

 

 

 

Dokumen Untuk PPL 2025

 PPL UNY 2025 Periode Juli - September 2025 CP dan ATP Mapel Motor Listrik disini https://docs.google.com/document/d/1Nqhubj8UAlmCR1IsdLw_CF...