#include <WiFi.h>
#include <ThingSpeak.h>
#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <DHT.h>
#define DHTPIN 4 // Pin ESP yang tersambung ke pin Data DHT22 (pin 4)
#define DHTTYPE DHT22 // Jenis sensor DHT 22 (AM2302)
DHT dht(DHTPIN, DHTTYPE);
float hum = 0; // Variabel untuk menyimpan nilai kelembaban
float temp = 0; // Variabel untuk menyimpan nilai suhu
float hic = 0; // Heat index dalam celcius
#define SCREEN_WIDTH 128 // Lebar display OLED dalam pixels
#define SCREEN_HEIGHT 64 // Tinggi display OLED dalam pixels
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire);
char ssid[] = "Wokwi-GUEST"; // Wokwi Wifi
char pass[] = ""; // Password kosong
int keyIndex = 0; // Nomor index key jaringan (hanya untuk WEP)
WiFiClient client;
unsigned long myChannelNumber = 3062102;
const char *myWriteAPIKey = "P4ZAJNT3RO7RAG6J";
unsigned long previousMillis = 0;
const long ts_update_interval = 20000; // Update data setiap 20 detik
// 'thermometer' icon, 48x48px - DATA DIPERBAIKI
const unsigned char thermo[] PROGMEM = {
0x00, 0x07, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xf8, 0x00, 0x00, 0x00,
0x00, 0x3f, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xfe, 0x00, 0x00, 0x00,
0x00, 0x7f, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xfe, 0x00, 0x00, 0x00,
0x00, 0x7f, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xfe, 0x00, 0x00, 0x00,
0x00, 0x7f, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xfe, 0x00, 0x00, 0x00,
0x00, 0x7f, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xfe, 0x00, 0x00, 0x00,
0x00, 0x7f, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xfe, 0x00, 0x00, 0x00,
0x00, 0x7f, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xfe, 0x00, 0x00, 0x00,
0x00, 0x7f, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xfe, 0x00, 0x00, 0x00,
0x00, 0x7f, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xfe, 0x00, 0x00, 0x00,
0x00, 0x7f, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xfe, 0x00, 0x00, 0x00,
0x00, 0x7f, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xfe, 0x00, 0x00, 0x00,
0x00, 0x7f, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xfe, 0x00, 0x00, 0x00,
0x00, 0x7f, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xfe, 0x00, 0x00, 0x00,
0x00, 0x7f, 0xfe, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00,
0x01, 0xff, 0xff, 0x80, 0x00, 0x00, 0x03, 0xff, 0xff, 0xc0, 0x00, 0x00,
0x07, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x07, 0xff, 0xff, 0xe0, 0x00, 0x00,
0x0f, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xf0, 0x00, 0x00,
0x0f, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xf0, 0x00, 0x00,
0x0f, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xf0, 0x00, 0x00,
0x07, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x07, 0xff, 0xff, 0xe0, 0x00, 0x00,
0x03, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x01, 0xff, 0xff, 0x80, 0x00, 0x00,
0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xfe, 0x00, 0x00, 0x00,
0x00, 0x3f, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xf8, 0x00, 0x00, 0x00,
0x00, 0x07, 0xe0, 0x00, 0x00, 0x00};
// 'wifi connected', 16x16px - Hex value diperbaiki
const unsigned char wifi_icon[] PROGMEM = {
0x00, 0x00, 0x00, 0x00, 0x07, 0xe0, 0x1f, 0xf8, 0x7c, 0x3e, 0x07, 0xe7,
0xdf, 0xfb, 0x39, 0x1c, 0x37, 0xec, 0x0f, 0xf0, 0x0f, 0xf0, 0x03, 0xc0,
0x03, 0xc0, 0x01, 0x80, 0x00, 0x00, 0x00, 0x00};
// 'wifi disconnected', 16x16px - Format diperbaiki
const unsigned char wifi_dc[] PROGMEM = {
0x00, 0x00, 0x00, 0x04, 0x03, 0xce, 0x1f, 0xdc, 0x7f, 0xba, 0xf8, 0x77,
0x60, 0xe6, 0x05, 0xc0, 0x0b, 0xb0, 0x07, 0x70, 0x0e, 0x20, 0x1c, 0x00,
0x1b, 0xb0, 0x03, 0xc0, 0x01, 0x80, 0x00, 0x00};
const unsigned char Update_OK[] PROGMEM = {
0x01, 0x80, 0x0e, 0x70, 0x10, 0x08, 0x20, 0x04, 0x40, 0x32, 0x40, 0x62,
0x84, 0x63, 0x83, 0xc3, 0x41, 0x82, 0x40, 0x02, 0x40, 0x06, 0x20, 0x04,
0x10, 0x08, 0x0e, 0x70, 0x01, 0x80};
const unsigned char Update_NOK[] PROGMEM = {
0x01, 0x80, 0x0e, 0x70, 0x10, 0x08, 0x20, 0x04, 0x48, 0x32, 0x44, 0x62,
0xc2, 0x81, 0x82, 0x83, 0x82, 0xc6, 0x42, 0x4c, 0x22, 0x48, 0x16, 0x20,
0x10, 0x18, 0x0e, 0xf0, 0x01, 0x80};
void ConnectWIFI()
{
if (WiFi.status() != WL_CONNECTED)
{
Serial.print("Attempting to connect to SSID: ");
Serial.println(ssid);
WiFi.mode(WIFI_STA);
WiFi.begin(ssid, pass); // Untuk Simulasi >> Spesifik channel 6
int i = 0;
int a = 0;
while (WiFi.status() != WL_CONNECTED)
{
Serial.print(".");
display.clearDisplay();
display.setTextSize(1);
if (a == 0)
{
display.drawBitmap(52, 15, wifi_icon, 16, 16, WHITE);
a = 1;
}
else
{
display.drawBitmap(52, 15, wifi_icon, 16, 16, BLACK);
a = 0;
}
display.setCursor(25, 38);
display.print("Connecting ...");
display.display();
delay(1000);
++i;
if (i == 30)
{
i = 0;
Serial.println("\n Failed to Connect.");
break;
}
}
}
if (WiFi.status() == WL_CONNECTED)
{
Serial.println("\n Connected!");
display.clearDisplay();
display.setTextSize(1);
display.drawBitmap(52, 15, wifi_icon, 16, 16, WHITE);
display.setCursor(33, 38);
display.print("Connected!");
display.display();
}
else
{
display.clearDisplay();
display.setTextSize(1);
display.drawBitmap(52, 15, wifi_dc, 16, 16, WHITE);
display.setCursor(20, 38);
display.print("Wifi Connection");
display.setCursor(36, 48);
display.print("Failed!");
display.display();
}
delay(3000);
}
void setup()
{
Serial.begin(9600);
Serial.println(F("Temp & Hum Monitoring System"));
dht.begin();
// SSD1306_SWITCHCAPVCC = generate display voltage from 3.3V internally
if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C))
{
Serial.println(F("SSD1306 allocation failed"));
for (;;)
;
}
// Just intro
display.clearDisplay();
display.setTextColor(WHITE);
display.setTextSize(1);
display.println(F("ThingSpeak"));
display.setCursor(30, 20);
display.println(F("Temp-Hum Monitor"));
display.display(); // Tampilkan data
delay(3000);
WiFi.mode(WIFI_STA);
ThingSpeak.begin(client); // Initialize ThingSpeak
ConnectWIFI();
}
void loop()
{
hum = dht.readHumidity();
temp = dht.readTemperature(); // Membaca suhu dalam Celsius
// Check if any reads failed and exit early (to try again).
if (isnan(hum) || isnan(temp))
{
Serial.println(F("Gagal mendapat data dari sensor DHT!"));
return;
}
// Compute heat index in Celsius (isFahreheit = false)
hic = dht.computeHeatIndex(temp, hum, false);
Serial.print(F("Kelembaban: "));
Serial.print(hum);
Serial.print(F("% "));
Serial.print(F("Suhu: "));
Serial.print(temp);
Serial.print(F("°C "));
Serial.print(F("Heat index: "));
Serial.print(hic);
Serial.println(F("°C "));
display.clearDisplay();
// PERBAIKAN: Menggunakan ukuran bitmap yang baru (48x48)
display.drawBitmap(0, 5, thermo, 48, 48, WHITE);
display.setTextSize(1); // Ukuran teks sudah diatur ke 1 (paling kecil)
// 1. Menampilkan nama di bagian atas
display.setCursor(55, 8);
display.print(F("by fahmi"));
// 2. Menampilkan Suhu
display.setCursor(55, 22);
display.print(temp);
display.print(F(" C"));
// 3. Menampilkan Kelembaban
display.setCursor(55, 36);
display.print(hum);
display.print(F(" %"));
// 4. Menampilkan Heat Index
display.setCursor(55, 50);
display.print(F("HI: "));
display.print(hic);
display.print(F(" C"));
if (WiFi.status() != WL_CONNECTED)
{
display.drawBitmap(110, 0, wifi_dc, 16, 16, WHITE);
}
else
{
display.drawBitmap(110, 0, wifi_icon, 16, 16, WHITE);
}
unsigned long currentMillis = millis();
if (currentMillis - previousMillis >= ts_update_interval)
{
previousMillis = currentMillis;
if (WiFi.status() != WL_CONNECTED)
{
Serial.print("Attempting to connect to SSID: ");
Serial.println(ssid);
WiFi.begin(ssid, pass);
int i = 0;
while (WiFi.status() != WL_CONNECTED)
{
delay(500);
Serial.print(".");
++i;
if (i == 20)
{
i = 0;
Serial.println("\n Failed to Connect.");
break;
}
}
}
ThingSpeak.setField(1, hum); // Field humidity
ThingSpeak.setField(2, temp); // Field temperature
ThingSpeak.setField(3, hic); // Field heat index
// Write to the ThingSpeak channel
int x = ThingSpeak.writeFields(myChannelNumber, myWriteAPIKey);
if (x == 200)
{
Serial.println("Sukses Update Chanel.");
display.drawBitmap(90, 0, Update_OK, 16, 16, WHITE);
}
else
{
Serial.println("Update Chanel Bermasalah. HTTP error code " + String(x));
display.drawBitmap(90, 0, Update_NOK, 16, 16, WHITE);
}
}
display.display();
delay(2000);
}