dianartanto

esp32c3_mqtt_uas

Sep 23rd, 2026 (edited)
43
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 9.34 KB | Source Code | 0 0
  1. /*
  2.  * ESP32-C3 + DHT11 + OLED I2C + MQTT (JSON Kirim & Terima)
  3.  *
  4.  * - Membaca suhu & kelembaban dari DHT11 (GPIO4)
  5.  * - Menampilkan data lokal di OLED I2C
  6.  * - Mengirim suhu ke topik: sensor1/data1  -> {"value":261}
  7.  * - Mengirim kelembaban ke topik: sensor2/data2 -> {"value":800}
  8.  * - Menerima data JSON {"value":angka} dari topik:
  9.  *     sensor3/data3  dan  sensor4/data4
  10.  * - Mengekstrak nilai angka dan menampilkannya di OLED
  11.  *
  12.  * Broker: broker.emqx.io (port 1883)
  13.  */
  14.  
  15. #include <WiFi.h>
  16. #include <PubSubClient.h>
  17. #include <DHT.h>
  18. #include <Wire.h>
  19. #include <Adafruit_GFX.h>
  20. #include <Adafruit_SSD1306.h>
  21. #include <ArduinoJson.h>    // <-- Library baru untuk parsing JSON
  22.  
  23. // ======================= KONFIGURASI =======================
  24. const char* WIFI_SSID     = "FALCONJR"; //ganti dengan MEKATRONIKA
  25. const char* WIFI_PASSWORD = "08251027"; //ganti dengan robotika
  26.  
  27. const char* MQTT_SERVER   = "broker.emqx.io";
  28. const int   MQTT_PORT     = 1883;
  29. const char* MQTT_CLIENT_ID = "ESP32C3_DHT11_OLED";
  30.  
  31. // Topik MQTT untuk PUBLISH
  32. const char* NIM              = "NIM_Anda";        //ganti NIM_Anda
  33. const char* TOPIC_SUHU       = "NIM_Anda/data1";  //ganti NIM_Anda
  34. const char* TOPIC_KELEMBABAN = "NIM_Anda/data2";  //ganti NIM_Anda
  35.  
  36. // Topik MQTT untuk SUBSCRIBE
  37. const char* TOPIC_PWM1    = "NIM_Anda/data3";  //ganti NIM_Anda
  38. const char* TOPIC_PWM2    = "NIM_Anda/data4";  //ganti NIM_Anda
  39.  
  40. // Pin DHT11
  41. #define DHTPIN  4
  42. #define DHTTYPE DHT11
  43.  
  44. // Konfigurasi OLED
  45. #define SCREEN_WIDTH  128
  46. #define SCREEN_HEIGHT 64
  47. #define OLED_RESET    -1
  48. #define OLED_ADDRESS  0x3C
  49.  
  50. // ======================= OBJEK GLOBAL =======================
  51. DHT dht(DHTPIN, DHTTYPE);
  52. Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
  53. WiFiClient espClient;
  54. PubSubClient mqttClient(espClient);
  55.  
  56. // Variabel data lokal
  57. float suhu = 0.0;
  58. float kelembaban = 0.0;
  59.  
  60. // Variabel data yang diterima dari MQTT (nilai angka saja)
  61. // Gunakan String agar fleksibel menampilkan "-" jika belum ada data
  62. String nilaiData3 = "--";
  63. String nilaiData4 = "--";
  64.  
  65. // Flag apakah sudah pernah menerima data
  66. bool adaData3 = false;
  67. bool adaData4 = false;
  68.  
  69. // Timing
  70. unsigned long lastDHTRead = 0;
  71. unsigned long lastMQTTPublish = 0;
  72. const unsigned long DHT_INTERVAL = 2000;
  73. const unsigned long PUBLISH_INTERVAL = 5000;
  74.  
  75. // ======================= FUNGSI OLED =======================
  76. void updateOLED() {
  77.   display.clearDisplay();
  78.   display.setTextSize(1);
  79.   display.setTextColor(SSD1306_WHITE);
  80.   display.setCursor(0, 0);
  81.   display.println(NIM);
  82.  
  83.   display.setCursor(0, 14);
  84.   display.print("Suhu: ");
  85.   display.print(suhu, 1);
  86.   display.println(" C");
  87.  
  88.   display.setCursor(0, 28);
  89.   display.print("Kelembaban: ");
  90.   display.print(kelembaban, 1);
  91.   display.println(" %");
  92.  
  93.   display.setCursor(0, 42);
  94.   display.print("PWM1: ");
  95.   display.println(adaData3 ? nilaiData3 : "--");
  96.  
  97.   display.setCursor(0, 56);
  98.   display.print("PWM2: ");
  99.   display.println(adaData4 ? nilaiData4 : "--");
  100.   display.display();
  101. }
  102.  
  103. // ======================= FUNGSI PARSING JSON =======================
  104. // Mengembalikan true jika berhasil parsing, dan mengisi outValue
  105. bool parseJsonValue(const String& payload, long& outValue) {
  106.   // Gunakan StaticJsonDocument (lebih efisien untuk JSON kecil)
  107.   // Ukuran 128 byte cukup untuk {"value":123456}
  108.   StaticJsonDocument<128> doc;
  109.  
  110.   DeserializationError err = deserializeJson(doc, payload);
  111.   if (err) {
  112.     Serial.print("Gagal parse JSON: ");
  113.     Serial.println(err.c_str());
  114.     return false;
  115.   }
  116.  
  117.   // Cek apakah field "value" ada
  118.   if (!doc.containsKey("value")) {
  119.     Serial.println("Field 'value' tidak ditemukan!");
  120.     return false;
  121.   }
  122.  
  123.   // Ambil nilai "value". Bisa berupa int, long, atau float.
  124.   // as<long>() akan mengonversi tipe apapun ke long.
  125.   if (doc["value"].is<long>()) {
  126.     outValue = doc["value"].as<long>();
  127.     return true;
  128.   }
  129.   else if (doc["value"].is<float>()) {
  130.     outValue = (long)doc["value"].as<float>();
  131.     return true;
  132.   }
  133.   else if (doc["value"].is<const char*>()) {
  134.     // Jika value dikirim sebagai string, coba konversi
  135.     outValue = atol(doc["value"].as<const char*>());
  136.     return true;
  137.   }
  138.  
  139.   Serial.println("Tipe 'value' tidak dikenali!");
  140.   return false;
  141. }
  142.  
  143. // ======================= FUNGSI MQTT CALLBACK =======================
  144. void mqttCallback(char* topic, byte* payload, unsigned int length) {
  145.   // Konversi payload menjadi String
  146.   String message = "";
  147.   for (unsigned int i = 0; i < length; i++) {
  148.     message += (char)payload[i];
  149.   }
  150.  
  151.   Serial.print("Pesan diterima [");
  152.   Serial.print(topic);
  153.   Serial.print("]: ");
  154.   Serial.println(message);
  155.  
  156.   long extractedValue = 0;
  157.   bool parseOk = parseJsonValue(message, extractedValue);
  158.  
  159.   // Simpan data berdasarkan topik
  160.   if (String(topic) == TOPIC_PWM1) {
  161.     if (parseOk) {
  162.       nilaiData3 = String(extractedValue);
  163.       adaData3 = true;
  164.       Serial.print("  -> Nilai Data3: ");
  165.       Serial.println(extractedValue);
  166.     } else {
  167.       nilaiData3 = "ERR";
  168.       adaData3 = true;
  169.     }
  170.   }
  171.   else if (String(topic) == TOPIC_PWM2) {
  172.     if (parseOk) {
  173.       nilaiData4 = String(extractedValue);
  174.       adaData4 = true;
  175.       Serial.print("  -> Nilai Data4: ");
  176.       Serial.println(extractedValue);
  177.     } else {
  178.       nilaiData4 = "ERR";
  179.       adaData4 = true;
  180.     }
  181.   }
  182.  
  183.   updateOLED();
  184. }
  185.  
  186. // ======================= FUNGSI KONEKSI WIFI =======================
  187. void setupWiFi() {
  188.   Serial.print("Menghubungkan ke WiFi: ");
  189.   Serial.println(WIFI_SSID);
  190.  
  191.   WiFi.mode(WIFI_STA);
  192.   WiFi.begin(WIFI_SSID, WIFI_PASSWORD);
  193.   WiFi.setTxPower(WIFI_POWER_8_5dBm);
  194.   while (WiFi.status() != WL_CONNECTED) {
  195.     delay(500);
  196.     Serial.print(".");
  197.   }
  198.  
  199.   Serial.println();
  200.   Serial.println("WiFi terhubung!");
  201.   Serial.print("IP Address: ");
  202.   Serial.println(WiFi.localIP());
  203. }
  204.  
  205. // ======================= FUNGSI KONEKSI MQTT =======================
  206. void reconnectMQTT() {
  207.   while (!mqttClient.connected()) {
  208.     Serial.print("Menghubungkan ke MQTT Broker...");
  209.    
  210.     if (mqttClient.connect(MQTT_CLIENT_ID)) {
  211.       Serial.println(" terhubung!");
  212.      
  213.       mqttClient.subscribe(TOPIC_PWM1);
  214.       mqttClient.subscribe(TOPIC_PWM2);
  215.      
  216.       Serial.print("Subscribe ke: ");
  217.       Serial.print(TOPIC_PWM1);
  218.       Serial.print(" dan ");
  219.       Serial.println(TOPIC_PWM2);
  220.     } else {
  221.       Serial.print(" gagal, rc=");
  222.       Serial.print(mqttClient.state());
  223.       Serial.println(" - Coba lagi dalam 3 detik");
  224.       delay(3000);
  225.     }
  226.   }
  227. }
  228.  
  229. // ======================= SETUP =======================
  230. void setup() {
  231.   Serial.begin(115200);
  232.   delay(1000);
  233.  
  234.   Serial.println("\n=== ESP32-C3 DHT11 + OLED + MQTT (JSON Kirim & Terima) ===");
  235.  
  236.   dht.begin();
  237.   Serial.println("DHT11 diinisialisasi.");
  238.  
  239.   Wire.begin(5,6);
  240.  
  241.   if (!display.begin(SSD1306_SWITCHCAPVCC, OLED_ADDRESS)) {
  242.     Serial.println("Gagal menginisialisasi OLED SSD1306!");
  243.     while (1) delay(10);
  244.   }
  245.  
  246.   display.clearDisplay();
  247.   display.setTextSize(1);
  248.   display.setTextColor(SSD1306_WHITE);
  249.   display.setCursor(0, 0);
  250.   display.println("Inisialisasi...");
  251.   display.display();
  252.  
  253.   Serial.println("OLED siap.");
  254.  
  255.   setupWiFi();
  256.  
  257.   mqttClient.setServer(MQTT_SERVER, MQTT_PORT);
  258.   mqttClient.setCallback(mqttCallback);
  259.  
  260.   display.clearDisplay();
  261.   display.setCursor(0, 0);
  262.   display.println("WiFi Connected!");
  263.   display.print("IP: ");
  264.   display.println(WiFi.localIP());
  265.   display.display();
  266.   delay(2000);
  267.  
  268.   updateOLED();
  269. }
  270.  
  271. // ======================= LOOP =======================
  272. void loop() {
  273.   if (!mqttClient.connected()) {
  274.     reconnectMQTT();
  275.   }
  276.   mqttClient.loop();
  277.  
  278.   unsigned long now = millis();
  279.  
  280.   // ---- Baca sensor DHT11 secara berkala ----
  281.   if (now - lastDHTRead >= DHT_INTERVAL) {
  282.     lastDHTRead = now;
  283.    
  284.     float newTemp = dht.readTemperature();
  285.     float newHum  = dht.readHumidity();
  286.    
  287.     if (!isnan(newTemp) && !isnan(newHum)) {
  288.       suhu = newTemp;
  289.       kelembaban = newHum;
  290.      
  291.       Serial.print("Suhu: ");
  292.       Serial.print(suhu);
  293.       Serial.print(" C | Kelembaban: ");
  294.       Serial.print(kelembaban);
  295.       Serial.println(" %");
  296.      
  297.       updateOLED();
  298.     } else {
  299.       Serial.println("Gagal membaca DHT11!");
  300.     }
  301.   }
  302.  
  303.   // ---- Kirim data ke MQTT dalam format JSON {"value":angka} ----
  304.   if (now - lastMQTTPublish >= PUBLISH_INTERVAL) {
  305.     lastMQTTPublish = now;
  306.    
  307.     if (mqttClient.connected()) {
  308.       long suhuInt       = lround(suhu * 10.0);
  309.       long kelembabanInt = lround(kelembaban * 10.0);
  310.      
  311.       char tempPayload[32];
  312.       char humPayload[32];
  313.      
  314.       snprintf(tempPayload, sizeof(tempPayload), "{\"value\":%ld}", suhuInt);
  315.       snprintf(humPayload,  sizeof(humPayload),  "{\"value\":%ld}", kelembabanInt);
  316.      
  317.       bool pubTemp = mqttClient.publish(TOPIC_SUHU, tempPayload);
  318.       bool pubHum  = mqttClient.publish(TOPIC_KELEMBABAN, humPayload);
  319.      
  320.       Serial.print("Publish MQTT -> ");
  321.       Serial.print(TOPIC_SUHU);
  322.       Serial.print(": ");
  323.       Serial.print(tempPayload);
  324.       Serial.print("  |  ");
  325.       Serial.print(TOPIC_KELEMBABAN);
  326.       Serial.print(": ");
  327.       Serial.println(humPayload);
  328.      
  329.       if (!pubTemp || !pubHum) {
  330.         Serial.println("Gagal mengirim data MQTT!");
  331.       }
  332.     }
  333.   }
  334. }
Add Comment
Please, Sign In to add comment