#include <Wire.h>
#include <LiquidCrystal_I2C.h>
/*
Things needed are:
1. Arduino Mega
2. 9 TTP223 capacitive touch sensors (https://hobbycomponents.com/sensors/901-ttp223-capacitive-touch-sensor)
3. 20x4 I2C LCD
4. Some wires/cabling as needed
5. An LED
*/
/*
The board is Arduino Mega
LCD 16x2 located at I2C addr: 0x27
*/
LiquidCrystal_I2C screen(0x27, 20, 4);
// LED connected to 29
int ledPin = 29;
enum keypad_pin {
KEYPAD_NUM0,
KEYPAD_NUM1,
KEYPAD_NUM2,
KEYPAD_NUM3,
KEYPAD_NUM4,
KEYPAD_NUM5,
KEYPAD_NUM6,
KEYPAD_NUM7,
KEYPAD_NUM8,
KEYPAD_NUM9,
KEYPAD_CLEAR,
KEYPAD_CHANGE_PIN,
KEYPAD_COUNT
};
// The button should be TTP223 but it
// doesnt exist on simulator
// Pins where the buttons connected to
static int buttonToDigitalPin[KEYPAD_COUNT] = {
[KEYPAD_NUM0] = 33,
[KEYPAD_NUM1] = 37,
[KEYPAD_NUM2] = 39,
[KEYPAD_NUM3] = 41,
[KEYPAD_NUM4] = 43,
[KEYPAD_NUM5] = 45,
[KEYPAD_NUM6] = 47,
[KEYPAD_NUM7] = 49,
[KEYPAD_NUM8] = 51,
[KEYPAD_NUM9] = 53,
[KEYPAD_CLEAR] = 31,
[KEYPAD_CHANGE_PIN] = 35
};
enum global_state {
GLOBAL_STATE_NOP,
GLOBAL_STATE_ASKING_PIN,
GLOBAL_STATE_CHECK_PIN,
GLOBAL_STATE_WAIT_ANY_KEY
};
enum button_state {
BUTTON_PRESSED,
BUTTON_RELEASED
};
bool buttonStatePrev[KEYPAD_COUNT] = {false};
bool buttonStateCurrent[KEYPAD_COUNT] = {false};
enum button_state buttonState[KEYPAD_COUNT] = {};
enum global_state globalState = GLOBAL_STATE_NOP;
// 6 PIN code
#define PIN_SIZE 6
int currentPIN[PIN_SIZE] = {5,5,7, 7,5,5};
int currentPos = 0;
int pinBuffer[PIN_SIZE] = {};
void lockTheThing() {
// digitalWrite(ledPin, LOW);
}
void unlockTheThing() {
digitalWrite(ledPin, HIGH);
}
void setup() {
for (int i = 0; i < KEYPAD_COUNT; i++)
pinMode(buttonToDigitalPin[i], INPUT);
pinMode(ledPin, OUTPUT);
digitalWrite(ledPin, HIGH);
screen.init();
screen.backlight();
screen.setCursor(0, 0);
screen.print("Hello There UwU");
screen.setCursor(0, 1);
screen.blink();
lockTheThing();
}
void clearLine(int y) {
screen.setCursor(0, y);
screen.print(" ");
screen.setCursor(0, y);
}
void clearScreen() {
screen.clear();
screen.setCursor(0, 3);
screen.print(" By Fox <3");
}
#define EINVAL 1
#define ENODATA 2
// -ENODATA: No button pressed
// -EINVAL: non numeric buttons
int getNumberAndPrint() {
int ret = -ENODATA;
for (int i = 0; i < KEYPAD_COUNT; i++) {
if (buttonState[i] == BUTTON_PRESSED) {
ret = i - KEYPAD_NUM0;
break;
}
}
if (ret > 9)
ret = -EINVAL;
if (ret >= 0)
screen.print(ret);
return ret;
}
void loop() {
for (int i = 0; i < KEYPAD_COUNT; i++)
buttonStateCurrent[i] = digitalRead(buttonToDigitalPin[i]) == HIGH;
for (int i = 0; i < KEYPAD_COUNT; i++) {
if (buttonStatePrev[i] == false && buttonStateCurrent[i] == true)
buttonState[i] = BUTTON_PRESSED;
else
buttonState[i] = BUTTON_RELEASED;
}
// button_manager_poll();
int buttonActive = 0;
for (int i = 0; i < KEYPAD_COUNT; i++)
buttonActive += buttonStateCurrent[i] ? 1 : 0;
// We only care if there one button active
if (buttonActive != 1)
goto dont_care;
screen.noBlink();
switch (globalState) {
case GLOBAL_STATE_WAIT_ANY_KEY:
// No button was recently pressed
if (getNumberAndPrint() == -ENODATA)
break;
globalState = GLOBAL_STATE_NOP;
lockTheThing();
clearScreen();
break;
case GLOBAL_STATE_NOP:
clearScreen();
screen.setCursor(0, 0);
screen.print("Enter PIN UwU:");
screen.setCursor(3, 1);
screen.print("-");
screen.setCursor(0, 1);
currentPos = 0;
globalState = GLOBAL_STATE_ASKING_PIN;
case GLOBAL_STATE_ASKING_PIN:
// Always place the seperator
screen.setCursor(3, 1);
screen.print("-");
screen.setCursor(currentPos + (currentPos / 3), 1);
int num = getNumberAndPrint();
if (num < 0 && buttonState[KEYPAD_CLEAR] == BUTTON_PRESSED) {
clearLine(1);
currentPos = 0;
goto processing_done;
}
if (num >= 0 && num <= 9) {
pinBuffer[currentPos] = num;
currentPos++;
}
if (currentPos == PIN_SIZE)
globalState = GLOBAL_STATE_CHECK_PIN;
else
break;
case GLOBAL_STATE_CHECK_PIN:
clearScreen();
screen.setCursor(0, 0);
currentPos = 0;
// Check pin
if (memcmp(pinBuffer, currentPIN, sizeof(pinBuffer)) != 0) {
screen.print("Incorrect PIN! :(");
goto wrong_pin_wait_for_any_key;
}
screen.print("Correct PIN! :)");
// At here maybe open something
// protected
unlockTheThing();
wrong_pin_wait_for_any_key:
// Wait for any key
screen.setCursor(0, 1);
screen.print("Press any key :3");
globalState = GLOBAL_STATE_WAIT_ANY_KEY;
break;
}
processing_done:
screen.blink();
dont_care:
memcpy(buttonStatePrev, buttonStateCurrent, sizeof(buttonStateCurrent));
delay(10);
}