Combination Lock

Use a 3 digit combination to unlock your safe.


220 Ohm Resistor


4 Digit Display Module


Rotary Encoder


InventrKits HERO

The HERO is a derivative of “Arduino UNO R3 Reference design” we just changed up a few things to make it our own. If you’re curious about what goes into our HERO board we published the open-source hardware files on our GitHub.





This combines the rotary encoder and the display from day 16. The combination must be entered in the correct order and an LED and a message on the display  indicates which latch you are on. This is a fun project getting to explore bool logic.




Leave a Reply

Your email address will not be published. Required fields are marked *

// Orginal code written by Alexander Eschenauer for the Adventure kit //Modified by Ross O’Connor // Include the library: #include // Rotary Encoder Inputs #define CLK2 2 #define DT2 3 int SW = 4; // Define the connections pins: #define CLK 6 #define DIO 5 //LED from Bool Logic int LED1=13; int LED2 =12; int LED3 =11; bool Latch1; bool Latch2; bool Latch3; bool Latch4; bool Latch5; // Create display object of type TM1637Display: TM1637Display display = TM1637Display(CLK, DIO); // Create array that turns all segments on: const uint8_t data[] = {0xff, 0xff, 0xff, 0xff}; // Create array that turns all segments off: const uint8_t blank[] = {0x00, 0x00, 0x00, 0x00}; // You can set the individual segments per digit to spell words or create other symbols: const uint8_t L1[] = { SEG_F | SEG_E | SEG_D, // L SEG_B | SEG_C, // 1 }; const uint8_t L2[] = { SEG_F | SEG_E | SEG_D, // L SEG_A | SEG_B | SEG_G | SEG_E | SEG_D, // 2 }; const uint8_t L3[] = { SEG_F | SEG_E | SEG_D, // L SEG_A | SEG_B | SEG_G | SEG_C | SEG_D, // 3 }; int counter = 0; int currentStateCLK; int lastStateCLK; String currentDir =””; void updateEncoder(){ // Read the current state of CLK currentStateCLK = digitalRead(CLK2); // If last and current state of CLK are different, then pulse occurred // React to only 1 state change to avoid double count if (currentStateCLK != lastStateCLK && currentStateCLK == 1){ // If the DT state is different than the CLK state then // the encoder is rotating CCW so decrement if (digitalRead(DT2) != currentStateCLK) { counter –; currentDir =”CCW”; } else { // Encoder is rotating CW so increment counter ++; currentDir =”CW”; } Serial.print(” | Counter: “); Serial.println(counter); } // Remember last CLK state lastStateCLK = currentStateCLK; } void setup() { // Set encoder pins as inputs pinMode(CLK2,INPUT); pinMode(DT2,INPUT); pinMode(SW, INPUT); pinMode(LED1,OUTPUT); pinMode(LED2,OUTPUT); pinMode(LED3,OUTPUT); // Setup Serial Monitor Serial.begin(9600); // Read the initial state of CLK lastStateCLK = digitalRead(CLK2); // Clear the display: display.clear(); delay(1000); display.setBrightness(7); // Call updateEncoder() when any high/low changed seen // on interrupt 0 (pin 2), or interrupt 1 (pin 3) attachInterrupt(0, updateEncoder, CHANGE); attachInterrupt(1, updateEncoder, CHANGE); } void loop() //Change counter number to change the lock code { display.showNumberDec(counter); delay(50); int btnState = digitalRead(SW); if(counter == 25 && btnState ==LOW) { display.clear(); display.setSegments(L1,2,0); Latch1 =true; delay(3000); display.clear(); Serial.println(“Latch 1 unlocked”); } if(counter == 5 && btnState ==LOW && Latch1) { display.clear(); display.setSegments(L2,2,0); Latch2 =true; delay(3000); display.clear(); Serial.println(“Latch 2 unlocked”); } if(counter == 16 && btnState ==LOW &&Latch2) { display.clear(); display.setSegments(L3,2,0); Latch3 =true; delay(3000); display.clear(); Serial.println(“Latch 3 unlocked”); } //Changing LED based on bool if (Latch1){digitalWrite(LED1,HIGH); } if (Latch2){digitalWrite(LED2,HIGH); } if (Latch3){digitalWrite(LED3,HIGH); } //Reset branch if(Latch1 && Latch2 && Latch3){ Serial.println(“Unlocked. Good Job”); Latch1 =false; Latch2 =false; Latch3 =false; Latch4=true;} //Reset lock circuit. Turn counter to 0 and press button if(Latch4 && btnState==LOW && counter == 0){ digitalWrite(LED1,LOW); digitalWrite(LED2,LOW); digitalWrite(LED3,LOW); Latch4=false; } if(btnState ==LOW){ Serial.println(“Button has been pressed!”); delay(200); } }
Leave a comment
Ross O'Connor

Modified and built the code

Alexander Eschenauer

Built the encoder program.

Leave a comment
Share on whatsapp
Share on facebook
Share on twitter
Share on linkedin
Share on reddit
Share on pinterest
Share on email


I cascaded four SN74HC595 shift registers to control 32 LEDs on 4 registers using 3 wires. I am adding a I2C 20×4 LCD screen to display the register and led values. I might add a standard 16×2 LCD screen to show up it is done.
A simple light meter. It’s not calibrated to any meaningful scale, but the digital readout shows a higher number the brighter is the light falling on the photoresistor.