#include <Adafruit_GFX.h>
#include <Adafruit_ILI9341.h>
#include <XPT2046_Touchscreen.h>
#include <SPI.h>
// TFT and Touchscreen SPI Pin Configuration
#define TFT_CS 10
#define TFT_DC 8
#define TFT_RST 9
#define TOUCH_CS 7
Adafruit_ILI9341 tft = Adafruit_ILI9341(TFT_CS, TFT_DC, TFT_RST);
XPT2046_Touchscreen ts(TOUCH_CS);
// Relay control and states
int relayPins[4] = {2, 3, 4, 5};
bool relayState[4] = {false, false, false, false};
// Draw touch button
void drawButton(int x, int y, int w, int h, const char* label, bool state) {
tft.fillRect(x, y, w, h, state ? ILI9341_GREEN : ILI9341_RED);
tft.drawRect(x, y, w, h, ILI9341_WHITE);
tft.setCursor(x + 10, y + 20);
tft.setTextColor(ILI9341_WHITE);
tft.setTextSize(2);
tft.print(label);
}
// Touch area check
void checkTouch() {
if (ts.touched()) {
TS_Point p = ts.getPoint();
// Map touch to screen (landscape mode)
int x = map(p.y, 200, 3800, 0, 320); // Wokwi calibrated range
int y = map(p.x, 300, 3700, 0, 240);
// Relay 1
if (x > 20 && x < 140 && y > 20 && y < 70) {
relayState[0] = !relayState[0];
digitalWrite(relayPins[0], relayState[0]);
drawButton(20, 20, 120, 50, "Relay 1", relayState[0]);
}
// Relay 2
else if (x > 170 && x < 290 && y > 20 && y < 70) {
relayState[1] = !relayState[1];
digitalWrite(relayPins[1], relayState[1]);
drawButton(170, 20, 120, 50, "Relay 2", relayState[1]);
}
// Relay 3
else if (x > 20 && x < 140 && y > 100 && y < 150) {
relayState[2] = !relayState[2];
digitalWrite(relayPins[2], relayState[2]);
drawButton(20, 100, 120, 50, "Relay 3", relayState[2]);
}
// Relay 4
else if (x > 170 && x < 290 && y > 100 && y < 150) {
relayState[3] = !relayState[3];
digitalWrite(relayPins[3], relayState[3]);
drawButton(170, 100, 120, 50, "Relay 4", relayState[3]);
}
delay(300); // Simple debounce
}
}
void setup() {
Serial.begin(9600);
// Init display and touchscreen
tft.begin();
ts.begin();
ts.setRotation(1);
tft.setRotation(1); // Landscape
// Init relay pins
for (int i = 0; i < 4; i++) {
pinMode(relayPins[i], OUTPUT);
digitalWrite(relayPins[i], LOW);
}
// Draw interface
drawButton(20, 20, 120, 50, "Relay 1", relayState[0]);
drawButton(170, 20, 120, 50, "Relay 2", relayState[1]);
drawButton(20, 100, 120, 50, "Relay 3", relayState[2]);
drawButton(170, 100, 120, 50, "Relay 4", relayState[3]);
// Status text
tft.setCursor(40, 200);
tft.setTextColor(ILI9341_WHITE);
tft.setTextSize(2);
tft.print("Tap to toggle relays");
}
void loop() {
checkTouch();
}