// TheUnlocker v1.5
// by Myth!
// The code defines a combination lock system using a sequence of button presses.
/// Declaration of constants and pins used
const int dataPinLED = 2;
const int clockPinLED = 3;
const int latchPinLED = 4;
const int dataPinButton = 5;
const int clockPinButton = 7;
const int latchPinButton = 6;
const int RedLed = 8;
const int GreenLed = 9;
const int numButtonsLEDs = 8;
const int combination[] = {1, 2, 3, 4, 5}; // Combination sequence
int enteredSequence[sizeof(combination)] = {0};
unsigned long lastButtonPressTime = 0;
const unsigned long debounceDelay = 200;
void setup() {
// Initialize Serial Monitor for debugging
Serial.begin(9600);
// Set pin mode for LEDs
pinMode(RedLed, OUTPUT);
pinMode(GreenLed, OUTPUT);
pinMode(dataPinLED, OUTPUT);
pinMode(clockPinLED, OUTPUT);
pinMode(latchPinLED, OUTPUT);
// Set pin mode for buttons
pinMode(dataPinButton, INPUT); // We are using an external pull-up resistors
pinMode(clockPinButton, OUTPUT);
pinMode(latchPinButton, OUTPUT);
}
void writeLEDs(int ledIndex, bool state = HIGH) {
// Write to the LEDs using shift register 74hc595
static byte ledStates = 0;
bitWrite(ledStates, ledIndex, state);
digitalWrite(latchPinLED, LOW);
shiftOut(dataPinLED, clockPinLED, MSBFIRST, ledStates);
digitalWrite(latchPinLED, HIGH);
}
byte readButtons() {
// Read the buttons state from the shift register 74hc165
digitalWrite(latchPinButton, LOW);
delayMicroseconds(5); // Small delay for latching
digitalWrite(latchPinButton, HIGH);
return shiftIn(dataPinButton, clockPinButton, MSBFIRST);
}
void loop() {
// Static variable to keep track of current sequence index
static int sequenceIndex = 0;
unsigned long currentTime = millis();
byte buttonState = readButtons();
// Debugging: print the button state
Serial.print("Button state: ");
Serial.println(buttonState, BIN);
// Loop through all buttons
for (int i = 0; i < numButtonsLEDs; i++) {
// Check button pressed and debounce time passed
if (bitRead(buttonState, i) == LOW && (currentTime - lastButtonPressTime) > debounceDelay) {
enteredSequence[sequenceIndex++] = i + 1;
writeLEDs(i);
lastButtonPressTime = currentTime;
// Debugging: print the pressed button
Serial.print("Button ");
Serial.print(i + 1);
Serial.println(" pressed");
}
}
// Check if the entered sequence length matches the combination length
if (sequenceIndex == sizeof(combination) / sizeof(combination[0])) {
bool correctSequence = true;
for (int i = 0; i < sizeof(combination) / sizeof(combination[0]); i++) {
if (enteredSequence[i] != combination[i]) {
correctSequence = false;
break;
}
}
// Turn on the appropriate LED based on sequence correctness
digitalWrite(correctSequence ? GreenLed : RedLed, HIGH);
if (correctSequence) {
delay(1000);
turnOffLEDs();
while (true) { /* UNLOCKED! */ }
}
delay(1000);
digitalWrite(RedLed, LOW);
turnOffLEDs();
// Reset sequence index and entered sequence array
sequenceIndex = 0;
memset(enteredSequence, 0, sizeof(enteredSequence));
}
}
void turnOffLEDs() {
// Turn off all LEDs
for (int i = 0; i < numButtonsLEDs; i++) {
writeLEDs(i, LOW);
delay(100);
}
}