#include <Keypad.h>
#include <WiFi.h>
#include <PubSubClient.h>
//asd
#define ROW_NUM 4
#define COLUMN_NUM 4
#define MAX_KEY_LIST 20
const char* ssid = "Wokwi-GUEST";
const char* password = "";
const char* mqttServer = "broker.emqx.io";
int port = 1883;
String stMac;
char mac[50];
char clientId[50];
unsigned long lastCheckStatusLED ;
unsigned long statusLEDShowDuration = 2000;
bool isShowingStatusLED = false;
char keys[ROW_NUM][COLUMN_NUM] = {
{'1', '2', '3', 'A'},
{'4', '5', '6', 'B'},
{'7', '8', '9', 'C'},
{'*', '0', '#', 'D'}
};
byte pin_rows[ROW_NUM] = {13, 12, 14, 27};
byte pin_column[COLUMN_NUM] = {26, 25, 33, 32};
int ledPins[6] = {15,2,4,5,18,19};
int statusPins[2] = {22,23};
int keyCursor = 0;
char keyStore[6];
String keyList[MAX_KEY_LIST];
Keypad keypad = Keypad(makeKeymap(keys), pin_rows, pin_column, ROW_NUM, COLUMN_NUM);
void handleKeyPress(char key);
bool checkIsNumber(char key);
void resetKeyStore();
void ledControl();
void showStatusPin(bool pass);
void updateStatusPin();
void addKeyToList(String key);
void checkKeyInList(String key);
void restructureKeyList();
int spaceLeftIntKeyList();
void checkIfKeyIsInList(String key);
void sendMqtt(String topic , String message);
void callback(char* topic, byte* message, unsigned int length);
void mqttReconnect();
WiFiClient espClient;
PubSubClient client(espClient);
void setup() {
Serial.begin(115200);
randomSeed(analogRead(0));
Serial.print("Connecting to WiFi");
WiFi.begin(ssid, password, 6);
while (WiFi.status() != WL_CONNECTED) {
delay(100);
Serial.print(".");
}
Serial.println(" Connected!");
client.setServer(mqttServer, port);
client.setCallback(callback);
for(int i = 0;i < (sizeof(ledPins) / sizeof(ledPins[0])); i++){
pinMode(ledPins[i] , OUTPUT);
}
for(int i = 0;i < (sizeof(statusPins)/ sizeof(statusPins[0])); i++){
pinMode(statusPins[i] , OUTPUT);
}
}
void loop() {
if (!client.connected()) {
mqttReconnect();
}
client.loop();
char key = keypad.getKey();
if (key) {
handleKeyPress(key);
}
updateStatusPin();
delay(10);
}
void updateStatusPin(){
if(millis() - lastCheckStatusLED > statusLEDShowDuration && isShowingStatusLED){
digitalWrite(statusPins[1] , LOW);
digitalWrite(statusPins[0] , LOW);
isShowingStatusLED = false;
}
}
void showStatusPin(bool pass){
if(pass){
digitalWrite(statusPins[1] , HIGH);
digitalWrite(statusPins[0] , LOW);
}else{
digitalWrite(statusPins[1] , LOW);
digitalWrite(statusPins[0] , HIGH);
}
lastCheckStatusLED = millis();
isShowingStatusLED = true;
}
void sendMqtt(String topic , String message){
client.publish(topic.c_str() , message.c_str());
}
void mqttReconnect() {
while (!client.connected()) {
Serial.print("Attempting MQTT connection...");
long r = random(1000);
sprintf(clientId, "clientId-%ld", r);
if (client.connect(clientId)) {
Serial.print(clientId);
Serial.println(" connected");
client.subscribe("gate_1/otp");
} else {
Serial.print("failed, rc=");
Serial.print(client.state());
Serial.println(" try again in 5 seconds");
delay(5000);
}
}
}
void restructureKeyList(){
String newKeyList[MAX_KEY_LIST];
int cursor = 0;
for(int i = 0 ; i < MAX_KEY_LIST;i++){
if(keyList[i] != ""){
newKeyList[cursor] = keyList[i];
cursor++;
}
}
memcpy(keyList,newKeyList,sizeof(newKeyList));
}
int spaceLeftIntKeyList(){
int ans = MAX_KEY_LIST;
for(int i = 0 ; i < MAX_KEY_LIST;i++){
if(keyList[i] != ""){
ans--;
}
}
return ans;
}
void addKeyToList(String key){
restructureKeyList();
if(spaceLeftIntKeyList() == 0){
keyList[0] = "";
restructureKeyList();
}
keyList[MAX_KEY_LIST - spaceLeftIntKeyList()] = key;
}
void callback(char* topic, byte* message, unsigned int length) {
Serial.print("Message arrived on topic: ");
Serial.println(topic);
if (String(topic) == "gate_1/otp") {
char key[6];
for (int i = 0; i < length; i++) {
key[i] = (char)message[i];
}
Serial.print("Recieve key: ");
Serial.println(key);
addKeyToList(String(key));
}
}
bool checkIsNumber(char key){
if(key == '0' || key == '1' || key == '2' || key == '3' || key == '4' || key == '5' || key == '6' || key == '7' || key == '8' || key == '9'){
return true;
}else{
return false;
}
}
void ledControl(){
for(int i = 0;i < sizeof(ledPins)/ sizeof(ledPins[0]); i++){
digitalWrite(ledPins[i] , LOW);
}
for(int i = 0;i < keyCursor; i++){
digitalWrite(ledPins[i] , HIGH);
}
}
void resetKeyStore(){
memset(keyStore , 0 , sizeof(keyStore));
keyCursor = 0;
}
void checkIfKeyIsInList(String key){
bool haveCorrent = false;
for(int i = 0; i < MAX_KEY_LIST; i++){
if(strncmp(key.c_str() ,keyList[i].c_str() , 6) == 0){
keyList[i] = "";
showStatusPin(true);
haveCorrent = true;
sendMqtt("gate1_enter" , "correct");
break;
}
}
if(!haveCorrent){
showStatusPin(false);
sendMqtt("gate1_enter" , "wrong");
}
}
void handleKeyPress(char key){
if(key == 'C'){
resetKeyStore();
}else if(checkIsNumber(key)){
keyStore[keyCursor] = key;
keyCursor++;
if(keyCursor == 6){
Serial.print("Key entered: ");
Serial.println(keyStore);
checkIfKeyIsInList(String(keyStore));
resetKeyStore();
}
}
ledControl();
}