#include #include #include #include #include #include #include #define PN532_SCK (13) #define PN532_MISO (12) #define PN532_MOSI (14) #define PN532_SS (33) #define TFT_CS 5 #define TFT_RST 16 #define TFT_RS 17 #define TFT_SDI 23 #define TFT_CLK 18 #define TFT_LED 4 #define WIFI_SSID "KOSAN KAMAR DEPAN" #define WIFI_PASSWORD "ngoooook" #define MQTT_SERVER "192.168.100.77" #define MQTT_PORT 1883 #define MQTT_TOPIC_PZEMOUT1 "pzemout1/voltage" #define MQTT_TOPIC_PZEMOUT2 "pzemout2/current" #define MQTT_TOPIC_PZEMOUT3 "pzemout3/power" #define MQTT_TOPIC_PZEMOUT4 "pzemout4/energy" #define MQTT_TOPIC_BIAYA "home/biaya" #define MQTT_TOPIC_SISA_SALDO "home/Sisa_saldo_str" #define MQTT_TOPIC_SALDO_FIX "home/Sisa_saldo_strin" TFT_22_ILI9225 tft = TFT_22_ILI9225(TFT_RST, TFT_RS, TFT_CS, TFT_SDI, TFT_CLK, TFT_LED); Adafruit_PN532 nfc(PN532_SCK, PN532_MISO, PN532_MOSI, PN532_SS); String idcard, voltage, current, power, energy, biayaStr, saldoStr, Sisa_saldo_strin; float biaya, saldo, Sisa_saldo; const byte ROWS = 4; const byte COLS = 4; char keys[ROWS][COLS] = { { 'D', '#', '0', '*' }, { 'C', '9', '8', '7' }, { 'B', '6', '5', '4' }, { 'A', '3', '2', '1' } }; byte rowPins[ROWS] = { 0, 1, 2, 3 }; byte colPins[COLS] = { 4, 5, 6, 7 }; Keypad_I2C kpd(makeKeymap(keys), rowPins, colPins, ROWS, COLS, 0x20, PCF8574); WiFiClient wifiClient; PubSubClient client(wifiClient); long time_1 = 0; int interval = 1000; char display = '0'; void callback(char* topic, byte* payload, unsigned int length) { String message = ""; for (int i = 0; i < length; i++) { message += (char)payload[i]; } Serial.println(message); Serial.print("Message arrived ["); Serial.print(topic); Serial.print("] "); if (strcmp(topic, MQTT_TOPIC_PZEMOUT1) == 0) { voltage = message; } if (strcmp(topic, MQTT_TOPIC_PZEMOUT2) == 0) { current = message; } if (strcmp(topic, MQTT_TOPIC_PZEMOUT3) == 0) { power = message; } if (strcmp(topic, MQTT_TOPIC_PZEMOUT4) == 0) { energy = message; } if (strcmp(topic, MQTT_TOPIC_BIAYA) == 0) { biayaStr = message; biaya = biayaStr.toFloat(); } if (strcmp(topic, MQTT_TOPIC_SALDO_FIX) == 0) { Sisa_saldo_strin = message; } } void setup() { tft.begin(); tft.setOrientation(1); tft.setFont(Terminal12x16); tft.setBackgroundColor(COLOR_BLACK); tft.clear(); nfc.begin(); uint32_t versiondata = nfc.getFirmwareVersion(); if (!versiondata) { Serial.print("Didn't find PN53x board"); while (1) ; } nfc.SAMConfig(); Serial.println("Waiting for an NFC card..."); Wire.begin(); kpd.begin(makeKeymap(keys)); Serial.begin(115200); Serial.println("start"); WiFi.begin(WIFI_SSID, WIFI_PASSWORD); while (WiFi.status() != WL_CONNECTED) { delay(1000); Serial.println("Connecting to WiFi..."); } Serial.println("Connected to WiFi"); client.setServer(MQTT_SERVER, MQTT_PORT); client.setCallback(callback); reconnect(); } void loop() { char key = kpd.getKey(); if (key != NO_KEY) { display = key; Serial.println(key); tft.clear(); } switch (display) { case '1': pilihKamar(); break; case '2': printText(10, 10, "Silahkan Tap "); printText(10, 30, "Kartu"); readMessageFromCard(2, 1); break; case 'A': dashboard(); break; case 'B': dashboard(); break; case '0': displayMenu(); break; default: break; } if (!client.connected()) { reconnect(); } client.loop(); kirimSaldo(); } void reconnect() { while (!client.connected()) { printText(10, 10, "MQTT CONNECTING..."); if (client.connect("ESP322_Client")) { printText(10, 30, "connected"); tft.clear(); client.subscribe(MQTT_TOPIC_PZEMOUT1); client.subscribe(MQTT_TOPIC_PZEMOUT2); client.subscribe(MQTT_TOPIC_PZEMOUT3); client.subscribe(MQTT_TOPIC_PZEMOUT4); client.subscribe(MQTT_TOPIC_BIAYA); client.subscribe(MQTT_TOPIC_SALDO_FIX); saldo = saldoStr.toFloat(); Sisa_saldo = saldo - biaya; break; } else { Serial.print("failed, rc="); Serial.print(client.state()); Serial.println(" try again in 5 seconds"); delay(5000); } } } void printText(int x, int y, String text) { int lineHeight = 16; int charWidth = 12; int cursorX = x; int cursorY = y; for (int i = 0; i < text.length(); i++) { char character = text[i]; if (character == '\n') { cursorY += lineHeight; cursorX = x; } else { tft.drawChar(cursorX, cursorY, character); cursorX += charWidth; } } } void readMessageFromCard(uint8_t block, uint8_t sector) { uint8_t success; uint8_t uid[] = { 0, 0, 0, 0, 0, 0, 0 }; uint8_t uidLength; success = nfc.readPassiveTargetID(PN532_MIFARE_ISO14443A, uid, &uidLength); if (success) { idcard = ""; for (byte i = 0; i < uidLength; i++) { idcard += (uid[i] < 0x10 ? "0" : "") + String(uid[i], HEX); } uint8_t keyData[] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; if (nfc.mifareclassic_AuthenticateBlock(uid, uidLength, sector, 0xFF, keyData)) { Serial.println("Authentication successful."); uint8_t readBlock[16]; if (nfc.mifareclassic_ReadDataBlock(block, readBlock)) { Serial.print("Read Data from Block "); Serial.print(block); Serial.print(": "); for (byte i = 0; i < 16; i++) { Serial.print(readBlock[i], HEX); Serial.print(" "); saldoStr += (char)readBlock[i]; } Serial.println(); saldo = saldoStr.toFloat(); printText(10, 10, "Saldo Terdeteksi "); printText(10, 30, "Saldo : " + saldoStr); printText(10, 50, "Tunggu 4 Detik"); printText(10, 70, "Untuk Kembali"); delay(4000); tft.clear(); display = '0'; } else { Serial.println("Failed to read data from the card."); } } else { Serial.println("Authentication failed."); } } } void dashboard() { if (millis() >= time_1 + interval) { time_1 = millis(); printText(10, 10, "Voltage : " + voltage + "V"); printText(10, 30, "Current : " + current + "A"); printText(10, 50, "Power : " + power + "W"); printText(10, 70, "Energy :" + energy + "Kwh"); printText(10, 90, "Biaya : Rp." + biayaStr); printText(10, 110, "Saldo : Rp." + Sisa_saldo_strin); } } void kirimSaldo() { Sisa_saldo = saldo - biaya; String Sisa_saldo_str = String(Sisa_saldo, 2); client.publish(MQTT_TOPIC_SISA_SALDO, Sisa_saldo_str.c_str()); } void displayMenu() { printText(10, 10, "MENU"); printText(10, 30, "1. DASHBOARD"); printText(10, 50, "2. TOP UP SALDO"); } void pilihKamar() { printText(10, 10, "A. Kamar 1"); printText(10, 30, "B. Kamar 2"); }