Stasiun Cuaca dengan NodeMCU: DHT22, WiFi dan ThingSpeak

Setelah membahas target akhir dari Stasiun Cuaca Mandiri dengan NodeMCU di artikel sebelumnya, tahap awal pembuatan stasiun cuaca dimulai dengan hal yang paling dasar, yaitu membaca data lingkungan dan mengirimkannya ke internet. Untuk tahap awal ini cukup dilakukan dengan sebuah sensor, yaitu DHT22.

Merakit NodeMCU dengan Sensor DHT22

Sebagai sensor lingkungan pertama, dipilih sensor DHT22. Sensor ini memiliki kemampuan untuk membaca suhu dan kelembaban. Sensor DHT22 dijual dalam 2 bentuk: kemasan plastik dengan 4 kaki atau kemasan plastik diatas PCB kecil dengan 3 kaki. Pastikan untuk memilih kemasan di atas PCB kecil dengan 3 kaki sehingga tidak dibutuhkan pull-up resistor terpisah.

Ketiga kaki sensor DHT22 memiliki fungsi sebagai berikut: Vcc, DATA dan GND. Nama dari kaki sensor DHT22 ini sudah cukup mudah dimengerti. Untuk komunikasi dengan NodeMCU, maka kaki dari DHT22 dihubungkan dengan pin NodeMCU sebagai berikut:

  1. DHT22-Vcc –> NodeMCU 3V
  2. DHT22-GND –> NodeMCU GND
  3. DHT22-Data –> NodeMCU D3 (GPIO 0)

Setelah perakitan NodeMCU dan sensor DHT22 selesai, kita masuk kedalam pemrograman. Saya memilih untuk menggunakan Arduino IDE karena banyaknya library untuk berbagai sensor, dan juga contoh yang mudah dicari. Arduino IDE bisa diunduh di tautan ini.

Membaca Sensor DHT22

Untuk membaca sensor DHT22, silahkan gunakan program di bawah ini. Program ini akan membaca suhu, kelembaban, dan menghitung index suhu dari hasil pengukuran. Hasil dari pembacaan dan perhitungan akan ditampilkan melalui port Serial. Dari Arduino IDE, data yang dikirim dari NodeMCU melalui port serial bisa dibaca melalui menu Tools --> Serial Monitor.

Beberapa komentar dalam program dibawah ini akan membantu untuk memahami struktur dari program tersebut.

/**
* Program untuk membaca suhu dan kelembaban dari sensor DHT22
* menggunakan NodeMCU
*
* Hak cipta (c) 2016 x.benny.id. All rights reserved.
* https://x.benny.id
*/
// Konfigurasi DHT22
#include <DHT.h>
#define DHTPIN 0 // PIN D3 (GPIO 0) dari NodeMCU terhubung dengan PIN Data dari DHT22
#define DHTTYPE DHT22 // Kita menggunakan tipe DHT22
DHT dht(DHTPIN, DHTTYPE); // Inisialisasi DHT22
// Mempersiapkan NodeMCU melalui fungsi setup()
// Catatan: Nama fungsi dibawah ini tidak boleh dirubah
void setup() {
// Inisialisasi Serial port untuk debugging
Serial.begin(115600);
Serial.setTimeout(2000);
while(!Serial) { }
Serial.println("NodeMCU Siap Dipakai");
Serial.println("Membaca sensor DHT22");
}
int timeSinceLastRead = 0;
void loop() {
// Report every 2 seconds.
if(timeSinceLastRead > (2000)) {
// Membaca kelembaban
float h = dht.readHumidity();
// Membaca suhu dalam derajat celcius
float t = dht.readTemperature();
// Membaca suhu dalam derajat farenheit
float f = dht.readTemperature(true);
// Memastikan kalau semua pembacaan sukses
if (isnan(h) || isnan(t) || isnan(f)) {
Serial.println("Failed to read from DHT sensor!");
timeSinceLastRead = 0;
return;
}
// Menghitung index suhu dalam farenheit
float hif = dht.computeHeatIndex(f, h);
// Menghitung index suhu dalam farenheit
float hic = dht.computeHeatIndex(t, h, false);
// Menulis hasil pembacaan melalui Serial
Serial.print("\Kelembaban: ");
Serial.print(h);
Serial.print(" %\t");
Serial.print("Suhu: ");
Serial.print(t);
Serial.print(" *C ");
Serial.print(f);
Serial.print(" *F\t");
Serial.print("Persepsi Suhu: ");
Serial.print(hic);
Serial.print(" *C ");
Serial.print(hif);
Serial.println(" *F");
timeSinceLastRead = 0;
}
delay(100); // Menunggu pembacaan selanjutnya
timeSinceLastRead += 100;
}

Setelah di upload ke NodeMCU, hasil pembacaan DHT22 bisa dilihat di Serial Monitor seperti di bawah ini:

Menghubungkan dengan WiFi

Setelah bisa membaca sensor, untuk mengirimkan data ke server IoT dibutuhkan koneksi internet. NodeMCU dilengkapi dengan built-in WiFi untuk bisa terkoneksi dengan internet. Untuk menggunakan koneksi WiFi, kita akan memanfaatkan library WiFi Arduino yang sudah ada, dengan menambahkan kode dibawah ini kedalam kode pembacaan DHT22:

/**
* Program untuk membaca suhu dan kelembaban dari sensor DHT22
* menggunakan NodeMCU
*
* Hak cipta (c) 2016 x.benny.id. All rights reserved.
* https://x.benny.id
*/
// Konfigurasi DHT22
#include <DHT.h>
#define DHTPIN 0 // PIN D3 (GPIO 0) dari NodeMCU terhubung dengan PIN Data dari DHT22
#define DHTTYPE DHT22 // Kita menggunakan tipe DHT22
DHT dht(DHTPIN, DHTTYPE); // Inisialisasi DHT22
// Konfigurasi WiFi
#include <ESP8266WiFi.h>
#define WIFI_SSID "myWiFi" // Ganti dengan SSID WiFi yang digunakan
#define WIFI_PASS "myPassword" // Ganti dengan password WiFi yang benar
// Mempersiapkan NodeMCU melalui fungsi setup()
// Catatan: Nama fungsi dibawah ini tidak boleh dirubah
void setup() {
// Inisialisasi Serial port untuk debugging
Serial.begin(115600);
Serial.setTimeout(2000);
while(!Serial) { }
Serial.println("NodeMCU Siap Dipakai");
// Mengaktifkan koneksi WiFi
Serial.print("Menhubungkan dengan WiFi: ");
Serial.println(WIFI_SSID);
int wifiStatus = startWiFi(WIFI_SSID, WIFI_PASS);
Serial.println("Membaca sensor DHT22");
}
int timeSinceLastRead = 0;
void loop() {
// Report every 2 seconds.
if(timeSinceLastRead > (2000)) {
// Membaca kelembaban
float h = dht.readHumidity();
// Membaca suhu dalam derajat celcius
float t = dht.readTemperature();
// Membaca suhu dalam derajat farenheit
float f = dht.readTemperature(true);
// Memastikan kalau semua pembacaan sukses
if (isnan(h) || isnan(t) || isnan(f)) {
Serial.println("Failed to read from DHT sensor!");
timeSinceLastRead = 0;
return;
}
// Menghitung index suhu dalam farenheit
float hif = dht.computeHeatIndex(f, h);
// Menghitung index suhu dalam farenheit
float hic = dht.computeHeatIndex(t, h, false);
// Menulis hasil pembacaan melalui Serial
Serial.print("\Kelembaban: ");
Serial.print(h);
Serial.print(" %\t");
Serial.print("Suhu: ");
Serial.print(t);
Serial.print(" *C ");
Serial.print(f);
Serial.print(" *F\t");
Serial.print("Persepsi Suhu: ");
Serial.print(hic);
Serial.print(" *C ");
Serial.print(hif);
Serial.println(" *F");
timeSinceLastRead = 0;
}
delay(100); // Menunggu pembacaan selanjutnya
timeSinceLastRead += 100;
}

Ada 2 hal yang harus dilakukan sebelum kode diatas bisa digunakan:

  • SSID dan Password untuk WiFi harus diubah sesuai dengan nama dan password WiFi yang akan digunakan
  • Kode diatas menggunakan fungsi startWiFi, yang didefinisikan dalam tautan file startWiFi.ino. File ini harus diletakkan dalam folder yang sama dengan folder kode utama NodeMCU.

Apabila koneksi ke WiFi berhasil, maka dari serial monitor akan terlihat nama WiFi dan IP address yang didapatkan seperti gambar di bawah ini

Mengirimkan Hasil Pengukuran ke ThingSpeak

Setelah berhasil membaca sensor dan terhubung dengan internet, sekarang waktunya untuk menambahkan baris kode untuk mengirimkan hasil pembacaan ke internet. Data IoT seperti hasil pembacaan suhu dan kelembaban ini dikirimkan ke server IoT untuk diproses lebih lanjut. Untuk saat ini saya mencoba mengirimkan data ke ThingSpeak. Untuk itu, diperlukan account di server ThingSpeak.

Ada 2 hal yang perlu didapatkan dari ThingSpeak setelah membuat account. Yang pertama adalah API Key sebagai penanda bahwa kita adalah pemilik data tersebut, dan Channel ID. Channel ID ini bisa didapatkan dengan membuat Channel, yang berisi kumpulan data yang relevan untuk analisis.

/**
* Program untuk membaca suhu dan kelembaban dari sensor DHT22
* menggunakan NodeMCU
*
* Hak cipta (c) 2016 x.benny.id. All rights reserved.
* https://x.benny.id
*/
// Konfigurasi DHT22
#include <DHT.h>
#define DHTPIN 0 // PIN D3 (GPIO 0) dari NodeMCU terhubung dengan PIN Data dari DHT22
#define DHTTYPE DHT22 // Kita menggunakan tipe DHT22
DHT dht(DHTPIN, DHTTYPE); // Inisialisasi DHT22
// Konfigurasi WiFi
#include <ESP8266WiFi.h>
#define WIFI_SSID "MyWiFit" // Ganti dengan SSID WiFi yang digunakan
#define WIFI_PASS "MyWiFiPassword" // Ganti dengan password WiFi yang benar
// Konfigurasi ThingSpeak
#include <PubSubClient.h>
#define THINGSPEAK_CLIENT_ID "WXStation" // Bisa diganti dengan Client ID Sembarang
#define THINGSPEAK_MQTT_API "SomeMQTTAPIKey" // Ganti dengan User MQTT API Key dari ThingSpeak
#define THINGSPEAK_CHANNEL_API "SomeChannelAPIKey" // Ganti dengan Channel API Key dari ThingSpeak
#define THINGSPEAK_CHANNEL_ID MyChannelID // Ganti dengan Channel ID dari ThingSpeak
// Mempersiapkan NodeMCU melalui fungsi setup()
// Catatan: Nama fungsi dibawah ini tidak boleh dirubah
void setup() {
// Inisialisasi Serial port untuk debugging
Serial.begin(115600);
Serial.setTimeout(2000);
while(!Serial) { }
Serial.println("NodeMCU Siap Dipakai");
// Mengaktifkan koneksi WiFi
Serial.print("Menhubungkan dengan WiFi: ");
Serial.println(WIFI_SSID);
int wifiStatus = startWiFi(WIFI_SSID, WIFI_PASS);
Serial.println("Membaca sensor DHT22");
}
int timeSinceLastRead = 0;
void loop() {
// Report every 10 seconds.
if(timeSinceLastRead > (10000)) {
// Membaca kelembaban
float h = dht.readHumidity();
// Membaca suhu dalam derajat celcius
float t = dht.readTemperature();
// Membaca suhu dalam derajat farenheit
float f = dht.readTemperature(true);
// Memastikan kalau semua pembacaan sukses
if (isnan(h) || isnan(t) || isnan(f)) {
Serial.println("Failed to read from DHT sensor!");
timeSinceLastRead = 0;
return;
}
// Menghitung index suhu dalam farenheit
float hif = dht.computeHeatIndex(f, h);
// Menghitung index suhu dalam farenheit
float hic = dht.computeHeatIndex(t, h, false);
// Menulis hasil pembacaan melalui Serial
Serial.print("\Kelembaban: ");
Serial.print(h);
Serial.print(" %\t");
Serial.print("Suhu: ");
Serial.print(t);
Serial.print(" *C ");
Serial.print(f);
Serial.print(" *F\t");
Serial.print("Persepsi Suhu: ");
Serial.print(hic);
Serial.print(" *C ");
Serial.print(hif);
Serial.println(" *F");
timeSinceLastRead = 0;
int mqttThingSpeakResult = sendThingSpeak(t, h); // Di kita mengirimkan data ke ThingSpeak
}
delay(1000); // Menunggu pembacaan selanjutnya
timeSinceLastRead += 1000;
}

Sebelum baris kode diatas dipasang di NodeMCU, ada beberapa hal yang harus dirubah terlebih dahulu:

  • Sama seperti tahap sebelumnya, baris-baris yang berisi WiFi ID dan passcode harus diupdate
  • Baris-baris konfigurasi untuk ThingSpeak juga perlu disesuaikan dengan akun ThingSpeak masing-masing
  • Kode untuk fungsi sendThingSpeak berada di berkas sendThingSpeak.ino di tautan ini. Berkas ini harus diletakkan di folder yang sama dengan folder kode utama NodeMCU

Hasil pengiriman bisa dilihat di Serial Monitor. Apabila pengiriman data ke ThingSpeak berhasil, maka hasil pengukuran DHT22 juga bisa dilihat di ThingSpeak, seperti dalam tautan stasiun cuaca YD0SPU-13 ini.

Memasuki Mode Deep Sleep

Langkah terakhir dari stasiun cuaca ini adalah memasuki mode deep sleep. Data pada stasiun cuaca biasanya dikirimkan dalam interval tertentu. Dalam FAQ dari Citizen Weather Observation Program (CWOP), rekomendasi pengiriman data cuaca adalah setiap 5 menit atau lebih jarang. Karena akan dipasang dengan sumber daya batere, maka selama interval pengukuran NodeMCU akan berada dalam Mode Deep Sleep, yaitu mode yang memiliki konsumsi daya paling kecil

Kode untuk memasuki Mode Deep Sleep kita tambahkan setelah pengiriman data ke ThingSpeak. Kita juga menambahkan konstanta baru yang akan menentukan seberapa lama NodeMCU akan berada dalam Mode Deep Sleep.

/**
* Program untuk membaca suhu dan kelembaban dari sensor DHT22
* menggunakan NodeMCU
*
* Hak cipta (c) 2016 x.benny.id. All rights reserved.
* https://x.benny.id
*/
// Konfigurasi DHT22
#include <DHT.h>
#define DHTPIN 0 // PIN D3 (GPIO 0) dari NodeMCU terhubung dengan PIN Data dari DHT22
#define DHTTYPE DHT22 // Kita menggunakan tipe DHT22
DHT dht(DHTPIN, DHTTYPE); // Inisialisasi DHT22
// Konfigurasi WiFi
#include <ESP8266WiFi.h>
#define WIFI_SSID "corsica" // Ganti dengan SSID WiFi yang digunakan
#define WIFI_PASS "br0wnispis4ng" // Ganti dengan password WiFi yang benar
// Konfigurasi ThingSpeak
#include <PubSubClient.h>
#define THINGSPEAK_CLIENT_ID "YD0SPU-13" // Bisa diganti dengan Client ID Sembarang
#define THINGSPEAK_MQTT_API "SO9F3X3I52MUX0W7" // Ganti dengan User MQTT API Key dari ThingSpeak
#define THINGSPEAK_CHANNEL_API "TN6NIKBPQEIFKYWF" // Ganti dengan Channel API Key dari ThingSpeak
#define THINGSPEAK_CHANNEL_ID 647364 // Ganti dengan Channel ID dari ThingSpeak
// Konfigurasi Deep Sleep
#define SCAN_INTERVAL 600 // Inteval pembacaan cuaca dalam detik
// Mempersiapkan NodeMCU melalui fungsi setup()
// Catatan: Nama fungsi dibawah ini tidak boleh dirubah
void setup() {
// Inisialisasi Serial port untuk debugging
Serial.begin(115600);
Serial.setTimeout(2000);
while(!Serial) { }
Serial.println("NodeMCU Siap Dipakai");
// Mengaktifkan koneksi WiFi
Serial.print("Menhubungkan dengan WiFi: ");
Serial.println(WIFI_SSID);
int wifiStatus = startWiFi(WIFI_SSID, WIFI_PASS);
Serial.println("Membaca sensor DHT22");
}
int timeSinceLastRead = 0;
void loop() {
// Report every 10 seconds.
if(timeSinceLastRead > (10000)) {
// Membaca kelembaban
float h = dht.readHumidity();
// Membaca suhu dalam derajat celcius
float t = dht.readTemperature();
// Membaca suhu dalam derajat farenheit
float f = dht.readTemperature(true);
// Memastikan kalau semua pembacaan sukses
if (isnan(h) || isnan(t) || isnan(f)) {
Serial.println("Failed to read from DHT sensor!");
timeSinceLastRead = 0;
return;
}
// Menghitung index suhu dalam farenheit
float hif = dht.computeHeatIndex(f, h);
// Menghitung index suhu dalam farenheit
float hic = dht.computeHeatIndex(t, h, false);
// Menulis hasil pembacaan melalui Serial
Serial.print("\Kelembaban: ");
Serial.print(h);
Serial.print(" %\t");
Serial.print("Suhu: ");
Serial.print(t);
Serial.print(" *C ");
Serial.print(f);
Serial.print(" *F\t");
Serial.print("Persepsi Suhu: ");
Serial.print(hic);
Serial.print(" *C ");
Serial.print(hif);
Serial.println(" *F");
timeSinceLastRead = 0;
int mqttThingSpeakResult = sendThingSpeak(t, h); // Di kita mengirimkan data ke ThingSpeak
// Memasuki Mode Deep Sleep
Serial.println("Entering Deep Sleep");
ESP.deepSleep(SCAN_INTERVAL*1000000);
}
delay(1000); // Menunggu pembacaan selanjutnya
timeSinceLastRead += 1000;
}

Hasil perubahan kode dengan menambahkan Mode Deep Sleep bisa dilihat dari Serial Monitor.

Sampai saat ini NodeMCU masih belum terbangun secara otomatis setelah periode Deep Sleep berakhir. untuk itu ada 1 langkah terakhir yang perlu dilakukan.

Saat ini NodeMCU sudah bisa dilepas dari komputer, dan bisa dihubungkan dengan catu data DC 5V melalui micro USB, misalnya dengan charger telepon genggam. Setelah dilepas dari komputer, pin D0 dari NodeMCU harus dihubungkan dengan pin RST. Koneksi antara pin D0 dan pin RST ini yang akan membangunkan NodeMCU ketika interval Deep Sleep telah berakhir.

Dan ketika akan melalukan konfigurasi lagi pada NodeMCU, jangan lupa koneksi pin D0 dan pin RST ini dilepas, sebelum NodeMCU dihubungkan dengan komputer.

Selamat mencoba. Apabila ada pertanyaan atau masukan, silahkan tinggalkan pesan atau komentar di bawah ini.