#include <Adafruit_GFX.h>
#include <Adafruit_ILI9341.h>
#include <SPI.h>
#include <Wire.h>
#include "RTClib.h"
#include <DHT.h>
// TFT setup
#define TFT_CS 15
#define TFT_DC 2
#define TFT_RST 4
Adafruit_ILI9341 tft = Adafruit_ILI9341(TFT_CS, TFT_DC, TFT_RST);
// DHT setup
#define DHTPIN 13
#define DHTTYPE DHT22
DHT dht(DHTPIN, DHTTYPE);
// RTC
RTC_DS1307 rtc;
// UI Layout
#define COLOR_BG ILI9341_BLUE
#define COLOR_BOX ILI9341_NAVY
#define COLOR_TEXT ILI9341_LIGHTGREY
#define COLOR_LABEL ILI9341_BLACK
#define COLOR_BTN ILI9341_NAVY
#define COLOR_TITLE ILI9341_WHITE
#define COLOR_HEADER ILI9341_CYAN
int boxW = 96, boxH = 70;
int boxSpacingX = 10, boxSpacingY = 10;
int startX = 8, startY = 50;
void drawBox(int x, int y, int w, int h, const char* label, const char* value) {
tft.fillRect(x, y, w, h, COLOR_BOX);
tft.drawRect(x, y, w, h, COLOR_TEXT);
tft.fillRect(x, y, w, 16, COLOR_HEADER);
tft.setTextColor(COLOR_LABEL);
tft.setTextSize(1);
tft.setCursor(x + 6, y + 3);
tft.print(label);
tft.setTextColor(COLOR_TEXT);
tft.setTextSize(2);
tft.setCursor(x + 8, y + h / 2);
tft.print(value);
}
void drawButton(int x, int y, int w, int h, const char* label) {
tft.fillRect(x, y, w, h, COLOR_BTN);
tft.drawRect(x, y, w, h, COLOR_TEXT);
tft.setTextColor(COLOR_TEXT);
tft.setTextSize(1);
tft.setCursor(x + 10, y + 10);
tft.print(label);
}
void drawTimeDisplay(DateTime now) {
char buffer[32];
sprintf(buffer, "%04d/%02d/%02d %02d:%02d:%02d",
now.year(), now.month(), now.day(),
now.hour(), now.minute(), now.second());
tft.fillRect(100, 30, 300, 16, COLOR_BG);
tft.setTextColor(COLOR_TITLE);
tft.setTextSize(1);
tft.setCursor(100, 30);
tft.print(buffer);
}
void drawTemperature(float temp) {
char tempBuf[16];
snprintf(tempBuf, sizeof(tempBuf), " %.1fC", temp);
drawBox(startX, startY + boxH + boxSpacingY, boxW, boxH, "Temperature", tempBuf);
}
void drawHumidity(float hum) {
char humBuf[16];
snprintf(humBuf, sizeof(humBuf), " %.1f%%", hum);
drawBox(startX + boxW + boxSpacingX, startY + boxH + boxSpacingY, boxW, boxH, "Humidity", humBuf);
}
void setup() {
Serial.begin(115200);
tft.begin();
tft.setRotation(1);
tft.fillScreen(COLOR_BG);
dht.begin();
if (!rtc.begin()) {
Serial.println("RTC gagal!");
while (1);
}
if (!rtc.isrunning()) rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
tft.setTextColor(COLOR_TITLE);
tft.setTextSize(2);
tft.setCursor(50, 5);
tft.print("SMART ENERGY METER");
drawBox(startX, startY, boxW, boxH, "Voltage", " 220V");
drawBox(startX + boxW + boxSpacingX, startY, boxW, boxH, "Current", " 0.00A");
drawBox(startX + 2 * (boxW + boxSpacingX), startY, boxW, boxH, "Power", " 0.0W");
drawBox(startX + 2 * (boxW + boxSpacingX), startY + boxH + boxSpacingY, boxW, boxH, "Network", " OK");
drawButton(0, 210, 80, 30, "Reset");
drawButton(80, 210, 80, 30, "BT Mode");
drawButton(160, 210, 80, 30, "Interval -");
drawButton(240, 210, 80, 30, "Interval +");
}
void loop() {
DateTime now = rtc.now();
drawTimeDisplay(now);
float temp = dht.readTemperature();
float hum = dht.readHumidity();
if (!isnan(temp) && !isnan(hum)) {
drawTemperature(temp);
drawHumidity(hum);
}
delay(1000);
}