Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /*
- * ESP32-C3 + DHT11 + OLED I2C + MQTT (JSON Kirim & Terima)
- *
- * - Membaca suhu & kelembaban dari DHT11 (GPIO4)
- * - Menampilkan data lokal di OLED I2C
- * - Mengirim suhu ke topik: sensor1/data1 -> {"value":261}
- * - Mengirim kelembaban ke topik: sensor2/data2 -> {"value":800}
- * - Menerima data JSON {"value":angka} dari topik:
- * sensor3/data3 dan sensor4/data4
- * - Mengekstrak nilai angka dan menampilkannya di OLED
- *
- * Broker: broker.emqx.io (port 1883)
- */
- #include <WiFi.h>
- #include <PubSubClient.h>
- #include <DHT.h>
- #include <Wire.h>
- #include <Adafruit_GFX.h>
- #include <Adafruit_SSD1306.h>
- #include <ArduinoJson.h> // <-- Library baru untuk parsing JSON
- // ======================= KONFIGURASI =======================
- const char* WIFI_SSID = "FALCONJR"; //ganti dengan MEKATRONIKA
- const char* WIFI_PASSWORD = "08251027"; //ganti dengan robotika
- const char* MQTT_SERVER = "broker.emqx.io";
- const int MQTT_PORT = 1883;
- const char* MQTT_CLIENT_ID = "ESP32C3_DHT11_OLED";
- // Topik MQTT untuk PUBLISH
- const char* NIM = "NIM_Anda"; //ganti NIM_Anda
- const char* TOPIC_SUHU = "NIM_Anda/data1"; //ganti NIM_Anda
- const char* TOPIC_KELEMBABAN = "NIM_Anda/data2"; //ganti NIM_Anda
- // Topik MQTT untuk SUBSCRIBE
- const char* TOPIC_PWM1 = "NIM_Anda/data3"; //ganti NIM_Anda
- const char* TOPIC_PWM2 = "NIM_Anda/data4"; //ganti NIM_Anda
- // Pin DHT11
- #define DHTPIN 4
- #define DHTTYPE DHT11
- // Konfigurasi OLED
- #define SCREEN_WIDTH 128
- #define SCREEN_HEIGHT 64
- #define OLED_RESET -1
- #define OLED_ADDRESS 0x3C
- // ======================= OBJEK GLOBAL =======================
- DHT dht(DHTPIN, DHTTYPE);
- Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
- WiFiClient espClient;
- PubSubClient mqttClient(espClient);
- // Variabel data lokal
- float suhu = 0.0;
- float kelembaban = 0.0;
- // Variabel data yang diterima dari MQTT (nilai angka saja)
- // Gunakan String agar fleksibel menampilkan "-" jika belum ada data
- String nilaiData3 = "--";
- String nilaiData4 = "--";
- // Flag apakah sudah pernah menerima data
- bool adaData3 = false;
- bool adaData4 = false;
- // Timing
- unsigned long lastDHTRead = 0;
- unsigned long lastMQTTPublish = 0;
- const unsigned long DHT_INTERVAL = 2000;
- const unsigned long PUBLISH_INTERVAL = 5000;
- // ======================= FUNGSI OLED =======================
- void updateOLED() {
- display.clearDisplay();
- display.setTextSize(1);
- display.setTextColor(SSD1306_WHITE);
- display.setCursor(0, 0);
- display.println(NIM);
- display.setCursor(0, 14);
- display.print("Suhu: ");
- display.print(suhu, 1);
- display.println(" C");
- display.setCursor(0, 28);
- display.print("Kelembaban: ");
- display.print(kelembaban, 1);
- display.println(" %");
- display.setCursor(0, 42);
- display.print("PWM1: ");
- display.println(adaData3 ? nilaiData3 : "--");
- display.setCursor(0, 56);
- display.print("PWM2: ");
- display.println(adaData4 ? nilaiData4 : "--");
- display.display();
- }
- // ======================= FUNGSI PARSING JSON =======================
- // Mengembalikan true jika berhasil parsing, dan mengisi outValue
- bool parseJsonValue(const String& payload, long& outValue) {
- // Gunakan StaticJsonDocument (lebih efisien untuk JSON kecil)
- // Ukuran 128 byte cukup untuk {"value":123456}
- StaticJsonDocument<128> doc;
- DeserializationError err = deserializeJson(doc, payload);
- if (err) {
- Serial.print("Gagal parse JSON: ");
- Serial.println(err.c_str());
- return false;
- }
- // Cek apakah field "value" ada
- if (!doc.containsKey("value")) {
- Serial.println("Field 'value' tidak ditemukan!");
- return false;
- }
- // Ambil nilai "value". Bisa berupa int, long, atau float.
- // as<long>() akan mengonversi tipe apapun ke long.
- if (doc["value"].is<long>()) {
- outValue = doc["value"].as<long>();
- return true;
- }
- else if (doc["value"].is<float>()) {
- outValue = (long)doc["value"].as<float>();
- return true;
- }
- else if (doc["value"].is<const char*>()) {
- // Jika value dikirim sebagai string, coba konversi
- outValue = atol(doc["value"].as<const char*>());
- return true;
- }
- Serial.println("Tipe 'value' tidak dikenali!");
- return false;
- }
- // ======================= FUNGSI MQTT CALLBACK =======================
- void mqttCallback(char* topic, byte* payload, unsigned int length) {
- // Konversi payload menjadi String
- String message = "";
- for (unsigned int i = 0; i < length; i++) {
- message += (char)payload[i];
- }
- Serial.print("Pesan diterima [");
- Serial.print(topic);
- Serial.print("]: ");
- Serial.println(message);
- long extractedValue = 0;
- bool parseOk = parseJsonValue(message, extractedValue);
- // Simpan data berdasarkan topik
- if (String(topic) == TOPIC_PWM1) {
- if (parseOk) {
- nilaiData3 = String(extractedValue);
- adaData3 = true;
- Serial.print(" -> Nilai Data3: ");
- Serial.println(extractedValue);
- } else {
- nilaiData3 = "ERR";
- adaData3 = true;
- }
- }
- else if (String(topic) == TOPIC_PWM2) {
- if (parseOk) {
- nilaiData4 = String(extractedValue);
- adaData4 = true;
- Serial.print(" -> Nilai Data4: ");
- Serial.println(extractedValue);
- } else {
- nilaiData4 = "ERR";
- adaData4 = true;
- }
- }
- updateOLED();
- }
- // ======================= FUNGSI KONEKSI WIFI =======================
- void setupWiFi() {
- Serial.print("Menghubungkan ke WiFi: ");
- Serial.println(WIFI_SSID);
- WiFi.mode(WIFI_STA);
- WiFi.begin(WIFI_SSID, WIFI_PASSWORD);
- WiFi.setTxPower(WIFI_POWER_8_5dBm);
- while (WiFi.status() != WL_CONNECTED) {
- delay(500);
- Serial.print(".");
- }
- Serial.println();
- Serial.println("WiFi terhubung!");
- Serial.print("IP Address: ");
- Serial.println(WiFi.localIP());
- }
- // ======================= FUNGSI KONEKSI MQTT =======================
- void reconnectMQTT() {
- while (!mqttClient.connected()) {
- Serial.print("Menghubungkan ke MQTT Broker...");
- if (mqttClient.connect(MQTT_CLIENT_ID)) {
- Serial.println(" terhubung!");
- mqttClient.subscribe(TOPIC_PWM1);
- mqttClient.subscribe(TOPIC_PWM2);
- Serial.print("Subscribe ke: ");
- Serial.print(TOPIC_PWM1);
- Serial.print(" dan ");
- Serial.println(TOPIC_PWM2);
- } else {
- Serial.print(" gagal, rc=");
- Serial.print(mqttClient.state());
- Serial.println(" - Coba lagi dalam 3 detik");
- delay(3000);
- }
- }
- }
- // ======================= SETUP =======================
- void setup() {
- Serial.begin(115200);
- delay(1000);
- Serial.println("\n=== ESP32-C3 DHT11 + OLED + MQTT (JSON Kirim & Terima) ===");
- dht.begin();
- Serial.println("DHT11 diinisialisasi.");
- Wire.begin(5,6);
- if (!display.begin(SSD1306_SWITCHCAPVCC, OLED_ADDRESS)) {
- Serial.println("Gagal menginisialisasi OLED SSD1306!");
- while (1) delay(10);
- }
- display.clearDisplay();
- display.setTextSize(1);
- display.setTextColor(SSD1306_WHITE);
- display.setCursor(0, 0);
- display.println("Inisialisasi...");
- display.display();
- Serial.println("OLED siap.");
- setupWiFi();
- mqttClient.setServer(MQTT_SERVER, MQTT_PORT);
- mqttClient.setCallback(mqttCallback);
- display.clearDisplay();
- display.setCursor(0, 0);
- display.println("WiFi Connected!");
- display.print("IP: ");
- display.println(WiFi.localIP());
- display.display();
- delay(2000);
- updateOLED();
- }
- // ======================= LOOP =======================
- void loop() {
- if (!mqttClient.connected()) {
- reconnectMQTT();
- }
- mqttClient.loop();
- unsigned long now = millis();
- // ---- Baca sensor DHT11 secara berkala ----
- if (now - lastDHTRead >= DHT_INTERVAL) {
- lastDHTRead = now;
- float newTemp = dht.readTemperature();
- float newHum = dht.readHumidity();
- if (!isnan(newTemp) && !isnan(newHum)) {
- suhu = newTemp;
- kelembaban = newHum;
- Serial.print("Suhu: ");
- Serial.print(suhu);
- Serial.print(" C | Kelembaban: ");
- Serial.print(kelembaban);
- Serial.println(" %");
- updateOLED();
- } else {
- Serial.println("Gagal membaca DHT11!");
- }
- }
- // ---- Kirim data ke MQTT dalam format JSON {"value":angka} ----
- if (now - lastMQTTPublish >= PUBLISH_INTERVAL) {
- lastMQTTPublish = now;
- if (mqttClient.connected()) {
- long suhuInt = lround(suhu * 10.0);
- long kelembabanInt = lround(kelembaban * 10.0);
- char tempPayload[32];
- char humPayload[32];
- snprintf(tempPayload, sizeof(tempPayload), "{\"value\":%ld}", suhuInt);
- snprintf(humPayload, sizeof(humPayload), "{\"value\":%ld}", kelembabanInt);
- bool pubTemp = mqttClient.publish(TOPIC_SUHU, tempPayload);
- bool pubHum = mqttClient.publish(TOPIC_KELEMBABAN, humPayload);
- Serial.print("Publish MQTT -> ");
- Serial.print(TOPIC_SUHU);
- Serial.print(": ");
- Serial.print(tempPayload);
- Serial.print(" | ");
- Serial.print(TOPIC_KELEMBABAN);
- Serial.print(": ");
- Serial.println(humPayload);
- if (!pubTemp || !pubHum) {
- Serial.println("Gagal mengirim data MQTT!");
- }
- }
- }
- }
Add Comment
Please, Sign In to add comment