Tuliskan kode program berikut pada sketch baru tersebut pada Arduino IDE:
1. Kode Program Node Aktuator dan Sensor, simpan kode ini dengan nama LoRa_MQTT
/*
Node Aktuator dan Sensor
*/
#include <SPI.h>
#include <LoRa.h>
#include <DHT.h>
#define CS_PIN 5
#define RST_PIN 14
#define DIO0_PIN 25
#define DHTPIN 4
#define DHTTYPE DHT11
DHT dht(DHTPIN, DHTTYPE);
#define RELAY1_PIN 27
#define RELAY2_PIN 26
#define RELAY_ON LOW
#define RELAY_OFF HIGH
unsigned long waktuKirimSebelumnya = 0;
const long intervalKirim = 5000;
void setup() {
Serial.begin(115200);
while (!Serial);
dht.begin();
pinMode(RELAY1_PIN, OUTPUT);
pinMode(RELAY2_PIN, OUTPUT);
digitalWrite(RELAY1_PIN, RELAY_OFF);
digitalWrite(RELAY2_PIN, RELAY_OFF);
LoRa.setPins(CS_PIN, RST_PIN, DIO0_PIN);
if (!LoRa.begin(433E6)) {
Serial.println("Gagal memulai LoRa!");
while (true);
}
Serial.println("LoRa Node 1 (Aktor & Sensor) Siap.");
Serial.println("Mengirim Suhu/Lembab tiap 5 detik dan siap menerima perintah...");
}
void kirimDataSensor() {
unsigned long waktuSekarang = millis();
if (waktuSekarang - waktuKirimSebelumnya >= intervalKirim) {
waktuKirimSebelumnya = waktuSekarang;
float kelembapan = dht.readHumidity();
float suhu = dht.readTemperature();
if (isnan(kelembapan) || isnan(suhu)) {
Serial.println("Gagal membaca dari sensor DHT11!");
return;
}
String pesan = "ID:A|Suhu:" + String(suhu, 1) + "|Lembab:" + String(kelembapan, 1);
LoRa.beginPacket();
LoRa.print(pesan);
LoRa.endPacket();
Serial.println("--- Mengirim Data Sensor: " + pesan);
}
}
void cekPerintahMasuk() {
int packetSize = LoRa.parsePacket();
if (packetSize) {
String pesanPerintah = "";
while (LoRa.available()) {
pesanPerintah += (char)LoRa.read();
}
Serial.println("=================================");
Serial.println("PERINTAH DITERIMA: " + pesanPerintah);
if (pesanPerintah == "R1_ON") {
digitalWrite(RELAY1_PIN, RELAY_ON);
Serial.println("Aksi: Relay 1 ON");
} else if (pesanPerintah == "R1_OFF") {
digitalWrite(RELAY1_PIN, RELAY_OFF);
Serial.println("Aksi: Relay 1 OFF");
} else if (pesanPerintah == "R2_ON") {
digitalWrite(RELAY2_PIN, RELAY_ON);
Serial.println("Aksi: Relay 2 ON");
} else if (pesanPerintah == "R2_OFF") {
digitalWrite(RELAY2_PIN, RELAY_OFF);
Serial.println("Aksi: Relay 2 OFF");
}
Serial.println("=================================");
}
}
void loop() {
kirimDataSensor();
cekPerintahMasuk();
}
2. Kode Program Gateway, simpan kode ini dengan nama Gateway_LoRa_MQTT
/*
Node Gateway
*/
#include <SPI.h>
#include <LoRa.h>
#include <WiFi.h>
#include <PubSubClient.h>
#define BLYNK_TEMPLATE_ID "TMPL6Wq4DeBaP"
#define BLYNK_TEMPLATE_NAME "Lora MQTT Blynk"
#define BLYNK_AUTH_TOKEN "zaZnDoH5jOqWfub1LfhULpaodky5PG4C"
#include <BlynkSimpleEsp32.h>
// Pin LoRa
#define CS_PIN 5
#define RST_PIN 14
#define DIO0_PIN 25
unsigned long waktuTerima = 0;
// Konfigurasi WiFi
const char* ssid = "Kos Putra Lindisanti";
const char* password = "poltekubsahabatan";
// Konfigurasi MQTT
const char* mqtt_broker = "broker.emqx.io";
const int mqtt_port = 1883;
const char *mqtt_username = "IoTelkom";
const char *mqtt_password = "esp32";
const char* mqtt_topic_data_raw = "lora/data/raw";
const char* mqtt_topic_suhu = "lora/dht/suhu";
const char* mqtt_topic_kelembapan = "lora/dht/kelembapan";
const char* mqtt_topic_r1 = "lora/kontrol/relay1";
const char* mqtt_topic_r2 = "lora/kontrol/relay2";
const char* mqtt_topic_rssi = "lora/gateway/rssi";
const char* mqtt_topic_snr = "lora/gateway/snr";
// Konfigurasi Virtual Pin Blynk
#define BLYNK_VPIN_MESSAGE V0
#define BLYNK_VPIN_RSSI V1
#define BLYNK_VPIN_SNR V2
#define BLYNK_VPIN_RELAY1 V3
#define BLYNK_VPIN_RELAY2 V4
#define BLYNK_VPIN_SUHU V5
#define BLYNK_VPIN_LEMBAB V6
WiFiClient espClient;
PubSubClient client(espClient);
void mqttCallback(char* topic, byte* payload, unsigned int length);
void setup_wifi();
void kirimPerintahLoRa(String perintah);
// --- Fungsi Setup WiFi ---
void setup_wifi() {
delay(10);
Serial.println();
Serial.print("Menghubungkan ke ");
Serial.println(ssid);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("");
Serial.println("WiFi Terhubung");
Serial.println("Alamat IP: ");
Serial.println(WiFi.localIP());
}
void kirimPerintahLoRa(String perintah) {
Serial.println("GATEWAY: Mengirim Perintah LoRa: " + perintah);
LoRa.beginPacket();
LoRa.print(perintah);
LoRa.endPacket();
// Selesai transmit, kembali ke mode receive (otomatis oleh library jika tidak di-set idle)
}
BLYNK_WRITE(BLYNK_VPIN_RELAY1) {
if (param.asInt() == 1) {
kirimPerintahLoRa("R1_ON");
} else {
kirimPerintahLoRa("R1_OFF");
}
}
BLYNK_WRITE(BLYNK_VPIN_RELAY2) {
if (param.asInt() == 1) {
kirimPerintahLoRa("R2_ON");
} else {
kirimPerintahLoRa("R2_OFF");
}
}
void mqttCallback(char* topic, byte* payload, unsigned int length) {
String pesanMasuk = "";
for (int i = 0; i < length; i++) {
pesanMasuk += (char)payload[i];
}
pesanMasuk.toUpperCase();
Serial.printf("GATEWAY: Perintah MQTT diterima di [%s]: %s\n", topic, pesanMasuk.c_str());
if (String(topic) == mqtt_topic_r1) {
if (pesanMasuk == "ON") {
kirimPerintahLoRa("R1_ON");
} else if (pesanMasuk == "OFF") {
kirimPerintahLoRa("R1_OFF");
}
} else if (String(topic) == mqtt_topic_r2) {
if (pesanMasuk == "ON") {
kirimPerintahLoRa("R2_ON");
} else if (pesanMasuk == "OFF") {
kirimPerintahLoRa("R2_OFF");
}
}
}
void reconnect_mqtt() {
while (!client.connected() && WiFi.status() == WL_CONNECTED) {
Serial.print("Mencoba koneksi MQTT...");
String clientId = "ESP32-LoRa-Gateway-";
clientId += String((uint32_t)ESP.getEfuseMac(), HEX);
Serial.printf("Menghubungkan sebagai %s...\n", clientId.c_str());
if (client.connect(clientId.c_str(), mqtt_username, mqtt_password)) {
Serial.println("terhubung!");
client.subscribe(mqtt_topic_r1);
client.subscribe(mqtt_topic_r2);
Serial.println("Telah subscribe ke topik kontrol MQTT (Relay 1 & 2)");
} else {
Serial.print("gagal, rc=");
Serial.print(client.state());
Serial.println(" coba lagi dalam 5 detik");
delay(5000);
}
}
}
void parseDanKirimData(String pesan, int rssi, float snr) {
// 1. Ekstrak Suhu
int suhuStartIndex = pesan.indexOf("Suhu:") + 5;
int suhuEndIndex = pesan.indexOf("|", suhuStartIndex);
String strSuhu = pesan.substring(suhuStartIndex, suhuEndIndex);
float suhu = strSuhu.toFloat();
// 2. Ekstrak Kelembapan
int lembabStartIndex = pesan.indexOf("Lembab:") + 7;
String strLembab = pesan.substring(lembabStartIndex);
float kelembapan = strLembab.toFloat();
// Tampilkan hasil parsing di Serial Monitor
Serial.println("--- Hasil Parsing ---");
Serial.println("Suhu: " + strSuhu);
Serial.println("Kelembapan: " + strLembab);
if (WiFi.status() == WL_CONNECTED) {
client.publish(mqtt_topic_data_raw, pesan.c_str(), true);
client.publish(mqtt_topic_suhu, strSuhu.c_str(), true);
client.publish(mqtt_topic_kelembapan, strLembab.c_str(), true);
client.publish(mqtt_topic_rssi, String(rssi).c_str(), true);
client.publish(mqtt_topic_snr, String(snr, 2).c_str(), true);
Serial.println("Pesan (Parsed) dipublikasikan ke MQTT");
// 4. Kirim ke Blynk (VPin Terpisah)
Blynk.virtualWrite(BLYNK_VPIN_MESSAGE, pesan);
Blynk.virtualWrite(BLYNK_VPIN_RSSI, rssi);
Blynk.virtualWrite(BLYNK_VPIN_SNR, snr);
Blynk.virtualWrite(BLYNK_VPIN_SUHU, suhu);
Blynk.virtualWrite(BLYNK_VPIN_LEMBAB, kelembapan);
Serial.println("Pesan (Parsed) dikirim ke Blynk");
Serial.println();
}
}
void setup() {
Serial.begin(115200);
while (!Serial);
// Inisialisasi LoRa
LoRa.setPins(CS_PIN, RST_PIN, DIO0_PIN);
if (!LoRa.begin(433E6)) {
Serial.println("Gagal memulai LoRa!");
while (true);
}
Serial.println("LoRa P2P Receiver Siap.");
// Setup WiFi
setup_wifi();
// Setup MQTT
client.setServer(mqtt_broker, mqtt_port);
client.setCallback(mqttCallback);
// Setup Blynk
Blynk.config(BLYNK_AUTH_TOKEN); // Sekarang ini sudah benar
Serial.println("Menunggu data LoRa...");
}
void loop() {
// Cek jika WiFi terputus
if (WiFi.status() != WL_CONNECTED) {
Serial.println("Koneksi WiFi terputus. Mencoba menghubungkan kembali...");
setup_wifi();
}
// Jika WiFi terhubung, jalankan layanan cloud
if (WiFi.status() == WL_CONNECTED) {
// Jalankan MQTT
if (!client.connected()) {
reconnect_mqtt();
}
client.loop();
Blynk.run();
}
// Cek paket LoRa
int packetSize = LoRa.parsePacket();
if (packetSize) {
// Terima data LoRa
String pesan = "";
while (LoRa.available()) {
pesan += (char)LoRa.read();
}
if (pesan.startsWith("ID:")) {
waktuTerima = millis();
int rssi = LoRa.packetRssi();
float snr = LoRa.packetSnr();
Serial.println("=================================");
Serial.println("DATA SENSOR DITERIMA");
Serial.println("Pesan : " + pesan);
Serial.print("RSSI : "); Serial.print(rssi); Serial.println(" dBm");
Serial.print("SNR : "); Serial.print(snr, 2); Serial.println(" dB");
parseDanKirimData(pesan, rssi, snr);
}
}
}