/*
Kódos ajtónyitó rendszer
Szerző: Morvai Ferenc
Verzió: v1.0
Dátum: 2025-08-26
Hardver: Arduino Pro Mini, 4x3 mátrix billentyűzet, relé, NeoPixel LED-ek
Leírás:
- 4 jegyű kód alapján vezérli a relét
- Programozó módban új kód menthető EEPROM-ba
- LED-ek és buzzer adnak visszajelzést
- D13 LED világít programozó módban, normál módban sötét
*/
#include <EEPROM.h>
#include <Adafruit_NeoPixel.h>
#define LED_PIN 11 // A neopixel LED adatvezeték csatlakozója az Arduino-n
#define LED_COUNT 4 // A használt LED-ek száma
Adafruit_NeoPixel leds(LED_COUNT, LED_PIN, NEO_GRB + NEO_KHZ800);
int ledState = 0;
unsigned char key, mem[4], num[4], ir = 0;
bool pMode = false;
void setup() {
pinMode(7, OUTPUT); // relé
pinMode(8, OUTPUT); // COL1
pinMode(9, OUTPUT); // COL2
pinMode(10, OUTPUT); // COL3
pinMode(13, OUTPUT); // programozó LED
pinMode(12, OUTPUT); // buzzer
pinMode(2, INPUT_PULLUP); // ROW4
pinMode(3, INPUT_PULLUP); // ROW3
pinMode(4, INPUT_PULLUP); // ROW2
pinMode(5, INPUT_PULLUP); // ROW1
pinMode(6, INPUT_PULLUP); // nyomógomb pMode
leds.begin();
digitalWrite(7, LOW);
digitalWrite(8, LOW);
digitalWrite(9, LOW);
digitalWrite(10, LOW);
// EEPROM-ból beolvassuk a tárolt kódot
for (unsigned char i = 0; i < 4; ++i) {
num[i] = EEPROM.read(i);
}
digitalWrite(13, LOW); // alapból nem világít (nem programozó módban)
}
void loop() {
// Programozó mód kapcsoló
if (!digitalRead(6)) {
pMode = true;
digitalWrite(13, HIGH); // programozó LED bekapcsol
}
// Ha bármelyik gomb lenyomva
if (!digitalRead(5) || !digitalRead(4) || !digitalRead(3) || !digitalRead(2)) {
int pressed = get_key();
if (pressed != -1) {
tone(12, 1000, 50);
mem[ir] = pressed;
// LED visszajelzés kék
if (ir < LED_COUNT) {
leds.setPixelColor(ledState, 0, 0, 255);
leds.show();
ledState++;
}
// Ha megvan a 4 szám
if (ir == 3 && pMode == false) {
if (mem[0] == num[0] && mem[1] == num[1] && mem[2] == num[2] && mem[3] == num[3]) {
// Helyes kód
digitalWrite(7, HIGH);
for (int i = 0; i < 4; i++) {
leds.setPixelColor(i, 0, 255, 0); // zöld
}
leds.show();
tone(12, 1000, 150);
delay(150);
tone(12, 1500, 150);
delay(2500); // relé ennyi ideig húz be
digitalWrite(7, LOW);
ledsclear();
} else {
// Hibás kód
for (int i = 0; i < 4; i++) {
leds.setPixelColor(i, 255, 0, 0); // piros
}
leds.show();
tone(12, 1000, 150); delay(200);
tone(12, 1500, 150); delay(200);
tone(12, 2000, 150); delay(200);
tone(12, 1500, 150); delay(200);
tone(12, 1000, 150); delay(300);
ledsclear();
}
}
// Programozó mód: új kód mentése EEPROM-ba
if (ir == 3 && pMode == true) {
for (unsigned char j = 0; j < 4; j++) {
EEPROM.write(j, mem[j]);
num[j] = mem[j];
}
ledsclear();
pMode = false;
digitalWrite(13, LOW); // kilépés programozó módból
}
ir++;
if (ir == 4) {
ir = 0;
}
// várunk, amíg felengedik a gombot
while (!digitalRead(5) || !digitalRead(4) || !digitalRead(3) || !digitalRead(2)) {}
delay(100);
}
}
}
int get_key() {
int detectedKey = -1;
int lastKey = -1;
unsigned long startTime = millis();
// max 50 ms-ig figyelünk, stabil érték kell
while (millis() - startTime < 50) {
int currentKey = -1;
// Oszlop 1
digitalWrite(8, LOW);
digitalWrite(9, HIGH);
digitalWrite(10, HIGH);
if (!digitalRead(5)) currentKey = 1;
if (!digitalRead(4)) currentKey = 4;
if (!digitalRead(3)) currentKey = 7;
// Oszlop 2
digitalWrite(9, LOW);
digitalWrite(8, HIGH);
digitalWrite(10, HIGH);
if (!digitalRead(5)) currentKey = 2;
if (!digitalRead(4)) currentKey = 5;
if (!digitalRead(3)) currentKey = 8;
if (!digitalRead(2)) currentKey = 0;
// Oszlop 3
digitalWrite(10, LOW);
digitalWrite(9, HIGH);
digitalWrite(8, HIGH);
if (!digitalRead(5)) currentKey = 3;
if (!digitalRead(4)) currentKey = 6;
if (!digitalRead(3)) currentKey = 9;
// Ha kétszer egymás után ugyanaz jött -> stabil
if (currentKey == lastKey && currentKey != -1) {
detectedKey = currentKey;
break;
}
lastKey = currentKey;
delay(5);
}
// reseteljük az oszlopokat
digitalWrite(8, LOW);
digitalWrite(9, LOW);
digitalWrite(10, LOW);
if (detectedKey != -1) {
key = detectedKey;
}
return detectedKey;
}
void ledsclear() {
leds.clear();
leds.show();
ledState = 0;
}