#include <Adafruit_GFX.h>
#include <Adafruit_ILI9341.h>
#include <Keypad.h>
// Defaults for TFT display.
#define TFT_CS 15
#define TFT_DC 2
#define TFT_RST 4
#define FONT_SIZE 2.3
Adafruit_ILI9341 tft = Adafruit_ILI9341(TFT_CS, TFT_DC, TFT_RST);
// PIN code settings.
const char* validPin = "0123"; // PIN code to check against.
char pinInput[5] = ""; // To store input from keypad.
int pinIndex = 0; // Current index for input in pinInput.
// Keypad setup.
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] = {25, 26, 27, 14};
byte colPins[COLS] = {12, 13, 32, 33};
Keypad keypad = Keypad(makeKeymap(keys), rowPins, colPins, ROWS, COLS);
const byte SCREEN_PIN = 0;
const byte SCREEN_MENU_MAIN = 1;
byte currentScreen = SCREEN_PIN;
bool incorrectPin = false;
bool isRedraw = true;
void setup() {
tft.begin();
tft.setRotation(0);
}
void ScreenPin() {
char key = keypad.getKey();
if (key) {
if (key == '*' && pinIndex > 0) { // Delete one character.
pinInput[--pinIndex] = '\0';
} else if (key == '#') { // Check PIN.
if (strcmp(pinInput, validPin) == 0) {
currentScreen = SCREEN_MENU_MAIN;
return;
} else {
incorrectPin = true;
pinIndex = 0;
memset(pinInput, 0, sizeof(pinInput));
}
} else if (isdigit(key) && pinIndex < 4) { // Add digit to PIN.
pinInput[pinIndex++] = key;
pinInput[pinIndex] = '\0';
}
isRedraw = true;
}
if (isRedraw) {
isRedraw = false;
tft.fillScreen(ILI9341_BLACK);
tft.setTextSize(3); // Larger text size for the brand name.
tft.setTextColor(ILI9341_WHITE, ILI9341_BLACK);
// Center "BoolScope" horizontally and set it to the top vertically.
int16_t x1, y1;
uint16_t w, h;
const char* title = "BoolScope";
tft.getTextBounds(title, 0, 0, &x1, &y1, &w, &h);
tft.setCursor((tft.width() - w) / 2, 30);
tft.println(title);
// Draw the underline.
tft.drawFastHLine((tft.width() - 140) / 2, 110, 140, ILI9341_WHITE); // Centered underline.
if (incorrectPin) {
tft.setTextSize(1); // Smaller text size for error message.
tft.setTextColor(ILI9341_RED, ILI9341_BLACK);
tft.getTextBounds("Incorrect PIN", 0, 0, &x1, &y1, &w, &h);
tft.setCursor((tft.width() - w) / 2, 120);
tft.println("Incorrect PIN");
}
// Display PIN input as stars.
tft.setTextSize(2); // Reset to normal text size.
tft.setTextColor(ILI9341_WHITE, ILI9341_BLACK);
char stars[5] = "****";
stars[pinIndex] = '\0'; // Only show the number of stars for the input length.
tft.getTextBounds(stars, 0, 0, &x1, &y1, &w, &h);
tft.setCursor((tft.width() - w) / 2, 90); // Centered stars above the line.
tft.println(stars);
tft.setTextSize(1); // Smaller text size for hints.
tft.setTextColor(ILI9341_LIGHTGREY, ILI9341_BLACK);
const char* hint = "# - ok, * - del";
tft.getTextBounds(hint, 0, 0, &x1, &y1, &w, &h);
tft.setCursor((tft.width() - w) / 2, tft.height() - 30);
tft.println(hint);
}
}
void ScreeMenuMain() {
tft.fillScreen(ILI9341_BLACK);
tft.setTextColor(ILI9341_WHITE, ILI9341_BLACK);
tft.setTextSize(3);
tft.setCursor(0, 100);
tft.println("Hello World!");
}
void loop() {
switch (currentScreen) {
case SCREEN_PIN:
ScreenPin();
break;
case SCREEN_MENU_MAIN:
ScreeMenuMain();
break;
}
delay(200); // Debounce delay.
}