#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_ILI9341.h>
#include <Adafruit_FT6206.h>
#include <Keypad.h>
#include <WiFi.h>
#define TFT_CS 5
#define TFT_DC 2
#define TFT_RST 4
#define TFT_MOSI 23
#define TFT_CLK 18
#define TFT_MISO 19
#define SDA_PIN 21
#define SCL_PIN 22
#define TFT_WIDTH 320
#define TFT_HEIGHT 240
const byte ROWS = 4;
const byte COLS = 4;
char keys[ROWS][COLS] = {
{'1', '2', '3', 'A'},
{'4', '5', '6', 'B'},
{'7', '8', '9', 'C'},
{'*', '0', '#', 'D'}
};
byte rowPins[ROWS] = {32, 33, 25, 26};
byte colPins[COLS] = {27, 14, 12, 13};
Keypad keypad = Keypad(makeKeymap(keys), rowPins, colPins, ROWS, COLS);
const int MENU_ROWS = 2;
const int MENU_COLS = 3;
const int BOX_PADDING = 10;
const int BOX_WIDTH = (TFT_WIDTH / MENU_COLS) - BOX_PADDING * 2;
const int BOX_HEIGHT = (TFT_HEIGHT / MENU_ROWS) - BOX_PADDING * 2;
char boxes[] = {'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I'};
int currentMenuStart = 0;
int selectedBoxIndex = -1;
bool isBoxSelected = false;
Adafruit_ILI9341 tft = Adafruit_ILI9341(TFT_CS, TFT_DC, TFT_RST);
Adafruit_FT6206 ts = Adafruit_FT6206();
#define REFRESH_BUTTON_X 10
#define REFRESH_BUTTON_Y 200
#define REFRESH_BUTTON_W 100
#define REFRESH_BUTTON_H 30
bool isCapital = false;
String typedText = "";
void setup() {
Serial.begin(115200);
tft.begin();
tft.setRotation(1);
tft.fillScreen(ILI9341_BLACK);
tft.setTextColor(ILI9341_WHITE);
tft.setTextSize(2);
Wire.begin();
if (!ts.begin(40)) {
Serial.println("Unable to start touchscreen.");
while (1);
}
displayMenu();
}
void loop() {
if (ts.touched()) {
TS_Point p = ts.getPoint();
p.x = map(p.x, 0, 240, 240, 0);
if (!isBoxSelected) {
handleMenuTouch(p.x, p.y);
} else {
handleSelectedBoxTouch(p.x, p.y);
}
delay(200);
}
if (selectedBoxIndex == 1) {
char key = keypad.getKey();
if (key) {
handleKeypadInput(key);
}
}
}
void displayMenu() {
tft.fillScreen(ILI9341_BLACK);
int index = 0;
for (int row = 0; row < MENU_ROWS; row++) {
for (int col = 0; col < MENU_COLS; col++) {
if (currentMenuStart + index < sizeof(boxes)) {
int x = col * (BOX_WIDTH + BOX_PADDING * 2) + BOX_PADDING;
int y = row * (BOX_HEIGHT + BOX_PADDING * 2) + BOX_PADDING;
tft.fillRect(x, y, BOX_WIDTH, BOX_HEIGHT, ILI9341_BLUE);
tft.setCursor(x + BOX_WIDTH / 2 - 10, y + BOX_HEIGHT / 2 - 10);
tft.setTextColor(ILI9341_WHITE);
tft.setTextSize(3);
tft.print(boxes[currentMenuStart + index]);
index++;
}
}
}
}
void handleMenuTouch(int x, int y) {
int col = y / (BOX_WIDTH + BOX_PADDING);
int row = x / (BOX_HEIGHT + BOX_PADDING);
int index = currentMenuStart + (row * MENU_COLS + col);
if (index >= 0 && index < sizeof(boxes) && currentMenuStart + index < sizeof(boxes)) {
selectedBoxIndex = index;
selectBox();
}
}
void handleSelectedBoxTouch(int x, int y) {
if (isWithinButton(x, y)) {
scanAndIdentifyI2CDevices();
} else {
backToMenu();
}
}
bool isWithinButton(int x, int y) {
return (x >= REFRESH_BUTTON_X && x <= REFRESH_BUTTON_X + REFRESH_BUTTON_W &&
y >= REFRESH_BUTTON_Y && y <= REFRESH_BUTTON_Y + REFRESH_BUTTON_H);
}
void drawRefreshButton() {
tft.fillRect(REFRESH_BUTTON_X, REFRESH_BUTTON_Y, REFRESH_BUTTON_W, REFRESH_BUTTON_H, ILI9341_BLUE);
tft.setCursor(REFRESH_BUTTON_X + 10, REFRESH_BUTTON_Y + 7);
tft.setTextColor(ILI9341_WHITE);
tft.setTextSize(2);
tft.print("Refresh");
}
void selectBox() {
if (selectedBoxIndex == 0) {
scanAndIdentifyI2CDevices();
}
if(selectedBoxIndex == 1) {
displayKeypadInterface();
}
if (selectedBoxIndex >= 1 && selectedBoxIndex < sizeof(boxes) && selectedBoxIndex != 1) {
int selectedIndex = currentMenuStart + selectedBoxIndex;
tft.fillScreen(ILI9341_BLACK);
tft.setCursor(110, 60);
tft.setTextColor(ILI9341_WHITE);
tft.setTextSize(15);
tft.print(boxes[selectedIndex]);
isBoxSelected = true;
}
}
void backToMenu() {
if (isBoxSelected) {
isBoxSelected = false;
displayMenu();
}
}
void displayKeypadInterface() {
tft.fillScreen(ILI9341_BLACK);
tft.setCursor(10, 10);
tft.setTextSize(2);
tft.print("Wi-Fi Networks:");
int n = WiFi.scanNetworks();
if (n == 0) {
tft.setCursor(10, 50);
tft.print("No networks found");
} else {
for (int i = 0; i < n; ++i) {
tft.setCursor(10, 50 + i * 20);
tft.print(WiFi.SSID(i));
delay(10);
}
}
tft.drawRect(10, 140, 300, 50, ILI9341_WHITE);
tft.setCursor(15, 155);
tft.setTextColor(ILI9341_WHITE);
tft.setTextSize(2);
tft.print(typedText);
isBoxSelected = true;
}
void handleKeypadInput(char key) {
if (key == '*') {
if (typedText.length() > 0) {
typedText.remove(typedText.length() - 1);
}
} else if (key == '#') {
typedText = "";
} else if (key == '0') {
typedText += " ";
} else if (key == '1') {
isCapital = !isCapital;
} else {
char charToAdd = getCharForKey(key);
if (charToAdd != '\0') {
typedText += charToAdd;
}
}
tft.fillRect(15, 155, 300, 30, ILI9341_BLACK);
tft.setCursor(15, 155);
tft.setTextColor(ILI9341_WHITE);
tft.setTextSize(2);
tft.print(typedText);
}
char getCharForKey(char key) {
static unsigned long lastKeyPressTime = 0;
static char lastKeyPressed = '\0';
static int charIndex = 0;
unsigned long currentTime = millis();
char charToReturn = '\0';
if (key != lastKeyPressed || currentTime - lastKeyPressTime > 1000) {
lastKeyPressed = key;
charIndex = 0;
} else {
charIndex = (charIndex + 1) % 4;
}
lastKeyPressTime = currentTime;
switch (key) {
case '2':
charToReturn = isCapital ? "ABC2"[charIndex] : "abc2"[charIndex];
break;
case '3':
charToReturn = isCapital ? "DEF3"[charIndex] : "def3"[charIndex];
break;
case '4':
charToReturn = isCapital ? "GHI4"[charIndex] : "ghi4"[charIndex];
break;
case '5':
charToReturn = isCapital ? "JKL5"[charIndex] : "jkl5"[charIndex];
break;
case '6':
charToReturn = isCapital ? "MNO6"[charIndex] : "mno6"[charIndex];
break;
case '7':
charToReturn = isCapital ? "PQRS7"[charIndex] : "pqrs7"[charIndex];
break;
case '8':
charToReturn = isCapital ? "TUV8"[charIndex] : "tuv8"[charIndex];
break;
case '9':
charToReturn = isCapital ? "WXYZ9"[charIndex] : "wxyz9"[charIndex];
break;
default:
charToReturn = key;
break;
}
return charToReturn;
}
void scanAndIdentifyI2CDevices() {
byte error, address;
int deviceCount = 0;
tft.fillScreen(ILI9341_BLACK);
tft.setCursor(10, 10);
tft.setTextSize(3);
tft.print("Scanning I2C bus...");
delay(1000); // Delay for visibility
tft.fillScreen(ILI9341_BLACK);
struct Device {
uint8_t address;
const char *name;
};
Device devices[] = {
{0x3C, "OLED Display"}, // OLED display
{0x27, "LCD Display"}, // LCD display with PCF8574 I/O expander
{0x50, "EEPROM (AT24C32)"}, // EEPROM memory
{0x68, "RTC Module"}, // RTC module
{0x76, "Barometric Sensor"}, // Barometric pressure sensor
{0x40, "Temperature Sensor"}, // Temperature sensor
{0x41, "Digital Potentiometer"},// Digital potentiometer
{0x48, "ADC (ADS1115)"}, // ADC (Analog-to-Digital Converter)
{0x60, "Accelerometer"}, // Accelerometer
{0x61, "Gyroscope"}, // Gyroscope
{0x68, "IMU (MPU6050)"}, // Inertial Measurement Unit
{0x70, "EEPROM (24AA02)"}, // EEPROM memory
{0x71, "IO Expander (MCP23017)"},// I/O Expander
{0x72, "IO Expander (MCP23008)"},// I/O Expander
{0x76, "Pressure Sensor (MS5611)"},// Pressure sensor
{0x77, "Pressure Sensor (BMP180)"},// Pressure sensor
{0x38, "TFT Display"},
{0x08, "Accelerometer (ADXL345)"}, // Accelerometer
{0x0C, "Gyroscope (L3GD20)"}, // Gyroscope
{0x18, "Temperature/Humidity Sensor (HTU21D)"}, // Temperature and Humidity Sensor
{0x1E, "Compass (HMC5883L)"}, // Magnetometer/Compass
{0x21, "Color Sensor (TCS34725)"}, // Color sensor
{0x23, "Lux Meter (TSL2561)"}, // Light sensor (Lux meter)
{0x29, "Ambient Light Sensor (LTR-559)"}, // Ambient light sensor
{0x39, "Ambient Light Sensor (VEML7700)"},// Ambient light sensor
{0x48, "ADC (ADS1115)"}, // Analog-to-Digital Converter
{0x50, "EEPROM (AT24C32)"}, // EEPROM memory
{0x57, "Proximity Sensor (VL6180X)"}, // Proximity sensor
{0x60, "Pressure Sensor (MS5611)"}, // Barometric pressure sensor
{0x68, "RTC Module (DS3231)"}, // Real-Time Clock module
{0x76, "Barometric Sensor (BMP280)"}, // Barometric pressure sensor
{0x77, "Pressure Sensor (BMP180)"}, // Pressure sensor
{0x78, "EEPROM (24AA02)"}, // EEPROM memory
{0x7A, "Temperature Sensor (TMP102)"}, // Temperature sensor
{0x7F, "IO Expander (PCF8574)"}, // I/O Expander
};
for (address = 1; address < 127; address++) {
Wire.beginTransmission(address);
error = Wire.endTransmission();
if (error == 0) {
tft.setCursor(10, 10);
tft.setTextSize(3);
tft.print("Device Found");
tft.setCursor(10, 50 + deviceCount * 20);
tft.setTextSize(2);
tft.setTextColor(ILI9341_CYAN);
tft.print("0x");
if (address < 16) {
tft.print("0");
}
tft.print(address, HEX);
bool identified = false;
for (int i = 0; i < sizeof(devices) / sizeof(devices[0]); i++) {
if (address == devices[i].address) {
tft.print(" - ");
tft.print(devices[i].name);
identified = true;
break;
}
}
if (!identified) {
tft.print(" - Unknown Device");
}
deviceCount++;
delay(500);
}
}
if (deviceCount == 0) {
tft.setCursor(10, 50);
tft.setTextSize(2);
tft.setTextColor(ILI9341_WHITE);
tft.print("No I2C devices found.");
}
drawRefreshButton();
}