Devices & Components
Arduino Mega 2560 Rev3
Rotary potentiometer (generic)
Analog joystick (Generic)
Servo Module (Generic)
Alphanumeric LCD, 20 x 4
Hardware & Tools
3D Printer (generic)
Software & Tools
Arduino IDE
TinkerCAD
Project description
Code
Running framework for your code and functional sub for combo lock
arduino
This is the minimum required code to implement a three character PO Box combination lock - add to your own code
1// 2// Code excerpt from larger working sketch 3// Copyright 2022 - Mark M. Lambert - Free Use with attribution 4// 5// Simulate a PO box lock. 6// Turn pot to dial setting 7// Click Joystick to enter # 8// 9// Presumes 20x4 LCD 10// 11const int LCD_COLS = 20; 12const int LCD_ROWS = 4; 13// 14// Define strings for PO Box Combo Lock simulator 15// 20 lock postitions 16// 17// Combination dial is pot on A15 18// 19const int Wiper = A15; //Wiper from 5k pot 20// 21// Servo needs a PWM output. Powered by Aux +5 22// 23const int PWM1 = 9; // Big servo 24// 25// Servo angles for locking mechanism - see CAD drawing 26// 27const int LockAngle = 15; 28const int UnLockAngle = LockAngle + 79; //Desired rotation angle to open door from CAD 29const int MidAngle = (LockAngle + UnLockAngle) /2; 30// 31// Joystick switch 32// 33const int Zaxis = 44; // Joystick Z (push sw) 34// 35// Key codes 36// 37char *LockTable[] = { 38 "A", 39 "A-B", 40 "B", 41 "B-C", 42 "C", 43 "C-D", 44 "D", 45 "D-E", 46 "E", 47 "E-F", 48 "F", 49 "F-G", 50 "G", 51 "G-H", 52 "H", 53 "H-I", 54 "I", 55 "I-J", 56 "J", 57 "J-A" 58 }; 59// 60const String LockCombo = "ECB"; // Min combo is three chars 61String LockEntryA; // These could be combined but are separated for 62String LockEntryB; // easy test 63String LockEntryC; 64String LockEntry; // Combined string 65// 66// Code snippet begins with minimum needed includes 67// 68#include <Wire.h> //I2C Driver 69#include <LiquidCrystal_I2C.h> //I2C LCD display driver for all LCD's 70#include <Servo.h> //PWM Servo motorServo DoorServo; // create servo object to control large servo 71// 72// 0x27 is default address for I2C 20x4 LCD displays - adjust accordingly 73// 74LiquidCrystal_I2C lcd(0x27, LCD_COLS, LCD_ROWS); // set the LCD object address to 0x27 and for a 20 chars and 4 line display 75// 76Servo DoorServo; // create servo object to control large servo 77// 78void setup() 79 { 80 Serial.begin(9600); //Warm up comm port 81 // 82 pinMode(Zaxis, INPUT_PULLUP); // Push sw on joystick 83 lcd.init(); //initialize the lcd 84 } 85// 86// you will have your own code here to call this routine 87// 88void loop() 89 { 90 // Your code goes here 91 } 92// ======================= 93// 94// Door lock sub 95// 96void comboLock() 97 { 98 lcd.clear(); 99 lcd.backlight(); 100 // 101 lcd.print("PO Box Sim"); 102 lcd.setCursor(0, 1); 103 lcd.print("First Code &"); 104 lcd.setCursor(0, 2); 105 lcd.print("Press Joystick Btn:"); 106 lcd.setCursor(0, 3); 107 lcd.print("Code: "); 108 // 109 while (digitalRead(Zaxis) != 0) 110 { 111 // 112 // show live reading - 3 chars 113 // 114 lcd.setCursor(6, 3); 115 lcd.print(" "); 116 lcd.setCursor(6, 3); 117 // 118 // We wanna map 0-1023 to 0-19 & display 119 // letters 120 // 121 lcd.print(LockTable[ map( analogRead(Wiper), 0, 1023, 0, 19) ] ); 122 // 123 delay(20); //Reduce display flicker 124 } 125 loop; 126 // 127 // Wait fast for button release 128 // 129 while (digitalRead(Zaxis) == 0) 130 { 131 } 132 loop; 133 // 134 // Button released, use last reading 135 // 136 LockEntryA = LockTable[map( analogRead(Wiper), 0, 1023, 0, 19)]; 137 // 138 lcd.clear(); 139 lcd.print("PO Box Sim"); 140 lcd.setCursor(0, 1); 141 lcd.print("Second Code &"); 142 lcd.setCursor(0, 2); 143 lcd.print("Press Joystick Btn:"); 144 lcd.setCursor(0, 3); 145 lcd.print("Code: "); 146 // 147 while (digitalRead(Zaxis) != 0) 148 { 149 // 150 // show live reading - 3 chars 151 // 152 lcd.setCursor(6, 3); 153 lcd.print(" "); 154 lcd.setCursor(6, 3); 155 // 156 // We wanna map 0-1023 to 0-19 & display 157 // letters 158 // 159 lcd.print(LockTable[ map( analogRead(Wiper), 0, 1023, 0, 19) ] ); 160 // 161 delay(20); //Reduce display flicker 162 } 163 loop; 164 // 165 // Wait fast for button release 166 // 167 while (digitalRead(Zaxis) == 0) 168 { 169 } 170 loop; 171 // 172 // Button released, use last reading 173 // 174 LockEntryB = LockTable[ map( analogRead(Wiper), 0, 1023, 0, 19)] ; 175 // 176 lcd.clear(); 177 lcd.print("PO Box Sim"); 178 lcd.setCursor(0, 1); 179 lcd.print("Final Code &"); 180 lcd.setCursor(0, 2); 181 lcd.print("Press Joystick Btn:"); 182 lcd.setCursor(0, 3); 183 lcd.print("Code: "); 184 // 185 while (digitalRead(Zaxis) != 0) 186 { 187 // 188 // show live reading - 3 chars 189 // 190 lcd.setCursor(6, 3); 191 lcd.print(" "); 192 lcd.setCursor(6, 3); 193 // 194 // We wanna map 0-1023 to 0-19 & display 195 // letters 196 // 197 lcd.print(LockTable[ map( analogRead(Wiper), 0, 1023, 0, 19) ] ); 198 // 199 delay(20); //Reduce display flicker 200 } 201 loop; 202 // 203 // Wait fast for button release 204 // 205 while (digitalRead(Zaxis) == 0) 206 { 207 } 208 loop; 209 // 210 // Button released, use last reading 211 // 212 LockEntryC = LockTable[map( analogRead(Wiper), 0, 1023, 0, 19) ]; 213 // 214 lcd.clear(); 215 lcd.print("PO Box Sim"); 216 lcd.setCursor(0, 1); 217 lcd.print("Code: "); 218 lcd.print(LockEntryA); 219 lcd.print(" "); 220 lcd.print(LockEntryB); 221 lcd.print(" "); 222 lcd.print(LockEntryC); 223 lcd.setCursor(1, 2); 224 // 225 LockEntry = LockEntryA; 226 LockEntry += LockEntryB; 227 LockEntry += LockEntryC; 228 Serial.print(" Entered: "); 229 Serial.println(LockEntry); 230 Serial.print("Required: "); 231 Serial.println(LockCombo); 232 // 233 if (LockEntry == LockCombo) 234 { 235 lcd.print("Access GRANTED."); 236 DoorServo.write(UnLockAngle); 237 delay(3000); 238 DoorServo.write(LockAngle); 239 } 240 else 241 { 242 lcd.print("ACCESS DENIED!"); 243 delay(3000); 244 } 245 // 246 lcd.clear(); 247 // 248 } 249// ======================== 250// FIN 251// ======================== 252
Running framework for your code and functional sub for combo lock
arduino
This is the minimum required code to implement a three character PO Box combination lock - add to your own code
1// 2// Code excerpt from larger working sketch 3// Copyright 2022 - Mark M. Lambert - Free Use with attribution 4// 5// Simulate a PO box lock. 6// Turn pot to dial setting 7// Click Joystick to enter # 8// 9// Presumes 20x4 LCD 10// 11const int LCD_COLS = 20; 12const int LCD_ROWS = 4; 13// 14// Define strings for PO Box Combo Lock simulator 15// 20 lock postitions 16// 17// Combination dial is pot on A15 18// 19const int Wiper = A15; //Wiper from 5k pot 20// 21// Servo needs a PWM output. Powered by Aux +5 22// 23const int PWM1 = 9; // Big servo 24// 25// Servo angles for locking mechanism - see CAD drawing 26// 27const int LockAngle = 15; 28const int UnLockAngle = LockAngle + 79; //Desired rotation angle to open door from CAD 29const int MidAngle = (LockAngle + UnLockAngle) /2; 30// 31// Joystick switch 32// 33const int Zaxis = 44; // Joystick Z (push sw) 34// 35// Key codes 36// 37char *LockTable[] = { 38 "A", 39 "A-B", 40 "B", 41 "B-C", 42 "C", 43 "C-D", 44 "D", 45 "D-E", 46 "E", 47 "E-F", 48 "F", 49 "F-G", 50 "G", 51 "G-H", 52 "H", 53 "H-I", 54 "I", 55 "I-J", 56 "J", 57 "J-A" 58 }; 59// 60const String LockCombo = "ECB"; // Min combo is three chars 61String LockEntryA; // These could be combined but are separated for 62String LockEntryB; // easy test 63String LockEntryC; 64String LockEntry; // Combined string 65// 66// Code snippet begins with minimum needed includes 67// 68#include <Wire.h> //I2C Driver 69#include <LiquidCrystal_I2C.h> //I2C LCD display driver for all LCD's 70#include <Servo.h> //PWM Servo motorServo DoorServo; // create servo object to control large servo 71// 72// 0x27 is default address for I2C 20x4 LCD displays - adjust accordingly 73// 74LiquidCrystal_I2C lcd(0x27, LCD_COLS, LCD_ROWS); // set the LCD object address to 0x27 and for a 20 chars and 4 line display 75// 76Servo DoorServo; // create servo object to control large servo 77// 78void setup() 79 { 80 Serial.begin(9600); //Warm up comm port 81 // 82 pinMode(Zaxis, INPUT_PULLUP); // Push sw on joystick 83 lcd.init(); //initialize the lcd 84 } 85// 86// you will have your own code here to call this routine 87// 88void loop() 89 { 90 // Your code goes here 91 } 92// ======================= 93// 94// Door lock sub 95// 96void comboLock() 97 { 98 lcd.clear(); 99 lcd.backlight(); 100 // 101 lcd.print("PO Box Sim"); 102 lcd.setCursor(0, 1); 103 lcd.print("First Code &"); 104 lcd.setCursor(0, 2); 105 lcd.print("Press Joystick Btn:"); 106 lcd.setCursor(0, 3); 107 lcd.print("Code: "); 108 // 109 while (digitalRead(Zaxis) != 0) 110 { 111 // 112 // show live reading - 3 chars 113 // 114 lcd.setCursor(6, 3); 115 lcd.print(" "); 116 lcd.setCursor(6, 3); 117 // 118 // We wanna map 0-1023 to 0-19 & display 119 // letters 120 // 121 lcd.print(LockTable[ map( analogRead(Wiper), 0, 1023, 0, 19) ] ); 122 // 123 delay(20); //Reduce display flicker 124 } 125 loop; 126 // 127 // Wait fast for button release 128 // 129 while (digitalRead(Zaxis) == 0) 130 { 131 } 132 loop; 133 // 134 // Button released, use last reading 135 // 136 LockEntryA = LockTable[map( analogRead(Wiper), 0, 1023, 0, 19)]; 137 // 138 lcd.clear(); 139 lcd.print("PO Box Sim"); 140 lcd.setCursor(0, 1); 141 lcd.print("Second Code &"); 142 lcd.setCursor(0, 2); 143 lcd.print("Press Joystick Btn:"); 144 lcd.setCursor(0, 3); 145 lcd.print("Code: "); 146 // 147 while (digitalRead(Zaxis) != 0) 148 { 149 // 150 // show live reading - 3 chars 151 // 152 lcd.setCursor(6, 3); 153 lcd.print(" "); 154 lcd.setCursor(6, 3); 155 // 156 // We wanna map 0-1023 to 0-19 & display 157 // letters 158 // 159 lcd.print(LockTable[ map( analogRead(Wiper), 0, 1023, 0, 19) ] ); 160 // 161 delay(20); //Reduce display flicker 162 } 163 loop; 164 // 165 // Wait fast for button release 166 // 167 while (digitalRead(Zaxis) == 0) 168 { 169 } 170 loop; 171 // 172 // Button released, use last reading 173 // 174 LockEntryB = LockTable[ map( analogRead(Wiper), 0, 1023, 0, 19)] ; 175 // 176 lcd.clear(); 177 lcd.print("PO Box Sim"); 178 lcd.setCursor(0, 1); 179 lcd.print("Final Code &"); 180 lcd.setCursor(0, 2); 181 lcd.print("Press Joystick Btn:"); 182 lcd.setCursor(0, 3); 183 lcd.print("Code: "); 184 // 185 while (digitalRead(Zaxis) != 0) 186 { 187 // 188 // show live reading - 3 chars 189 // 190 lcd.setCursor(6, 3); 191 lcd.print(" "); 192 lcd.setCursor(6, 3); 193 // 194 // We wanna map 0-1023 to 0-19 & display 195 // letters 196 // 197 lcd.print(LockTable[ map( analogRead(Wiper), 0, 1023, 0, 19) ] ); 198 // 199 delay(20); //Reduce display flicker 200 } 201 loop; 202 // 203 // Wait fast for button release 204 // 205 while (digitalRead(Zaxis) == 0) 206 { 207 } 208 loop; 209 // 210 // Button released, use last reading 211 // 212 LockEntryC = LockTable[map( analogRead(Wiper), 0, 1023, 0, 19) ]; 213 // 214 lcd.clear(); 215 lcd.print("PO Box Sim"); 216 lcd.setCursor(0, 1); 217 lcd.print("Code: "); 218 lcd.print(LockEntryA); 219 lcd.print(" "); 220 lcd.print(LockEntryB); 221 lcd.print(" "); 222 lcd.print(LockEntryC); 223 lcd.setCursor(1, 2); 224 // 225 LockEntry = LockEntryA; 226 LockEntry += LockEntryB; 227 LockEntry += LockEntryC; 228 Serial.print(" Entered: "); 229 Serial.println(LockEntry); 230 Serial.print("Required: "); 231 Serial.println(LockCombo); 232 // 233 if (LockEntry == LockCombo) 234 { 235 lcd.print("Access GRANTED."); 236 DoorServo.write(UnLockAngle); 237 delay(3000); 238 DoorServo.write(LockAngle); 239 } 240 else 241 { 242 lcd.print("ACCESS DENIED!"); 243 delay(3000); 244 } 245 // 246 lcd.clear(); 247 // 248 } 249// ======================== 250// FIN 251// ======================== 252
Downloadable files
Gadget block diagram - DOESN'T MATCH PINS IN CODE
Basic schematic with available components on TinkerCad. Match Z-axis DI wired to value in code.
Gadget block diagram - DOESN'T MATCH PINS IN CODE

KY-023 Joystick
KY-023 Joystick
KY-023 Joystick

LCD2004 I2C Address Jumpers
I2C addressing jumpering
LCD2004 I2C Address Jumpers

Door Linkage
How servo rotation angles were determined
Door Linkage

KY-023 Joystick
KY-023 Joystick
KY-023 Joystick

LCD2004 I2C Address Jumpers
I2C addressing jumpering
LCD2004 I2C Address Jumpers

Door Linkage
How servo rotation angles were determined
Door Linkage

Gadget block diagram - DOESN'T MATCH PINS IN CODE
Basic schematic with available components on TinkerCad. Match Z-axis DI wired to value in code.
Gadget block diagram - DOESN'T MATCH PINS IN CODE

Documentation
Large Servo Mount 3D .STL print file
This mounts a large (3/4" x 1-9/16") servo. It has cable exit holes on both sides so the servo can be mounted in either direction. the base had f #6 thru holes for mounting. The servo attaches with four 6-32 x 1/2 screws. You should tap the four holes 6-32 before use.
Large Servo Mount 3D .STL print file
5/16" shaft mini potentiometer 8-way mount - 3D .STL print file
Mounts any standard 5/16" shaft mini potentiometer commonly found in Arduino starter kits. Has four anti-rotation holes sized to fit the tab on the pot. Allows mounting in any of four positions from either side for universal 8-way mounting.
5/16" shaft mini potentiometer 8-way mount - 3D .STL print file
20 x 4 LCD front side panel mount - 3D .STL print file
Use this to mount 2004A type LCD displays
20 x 4 LCD front side panel mount - 3D .STL print file
DuPont 5 station slip on connector shroud 3D .STL print file
Slips over cable to change five loose DuPont connections into a single, unified, connector.
DuPont 5 station slip on connector shroud 3D .STL print file
Door pivot for far end of servo 3D .STL print file
Servo arm has 1/16" dia holes for connecting rod. This little piece has a matching 1/16" hole and two #6 thru holes for mounting on the door.
Door pivot for far end of servo 3D .STL print file
Arduino Uno/Mega 2560 wide mount for screw shield clearance - 3D .STL print file
Mounts Uno/Mega
Arduino Uno/Mega 2560 wide mount for screw shield clearance - 3D .STL print file
20 x 4 LCD front side panel mount - 3D .STL print file
Use this to mount 2004A type LCD displays
20 x 4 LCD front side panel mount - 3D .STL print file
Arduino Uno/Mega 2560 wide mount for screw shield clearance - 3D .STL print file
Mounts Uno/Mega
Arduino Uno/Mega 2560 wide mount for screw shield clearance - 3D .STL print file
DuPont 5 station slip on connector shroud 3D .STL print file
Slips over cable to change five loose DuPont connections into a single, unified, connector.
DuPont 5 station slip on connector shroud 3D .STL print file
Large Servo Mount 3D .STL print file
This mounts a large (3/4" x 1-9/16") servo. It has cable exit holes on both sides so the servo can be mounted in either direction. the base had f #6 thru holes for mounting. The servo attaches with four 6-32 x 1/2 screws. You should tap the four holes 6-32 before use.
Large Servo Mount 3D .STL print file
5/16" shaft mini potentiometer 8-way mount - 3D .STL print file
Mounts any standard 5/16" shaft mini potentiometer commonly found in Arduino starter kits. Has four anti-rotation holes sized to fit the tab on the pot. Allows mounting in any of four positions from either side for universal 8-way mounting.
5/16" shaft mini potentiometer 8-way mount - 3D .STL print file
Door pivot for far end of servo 3D .STL print file
Servo arm has 1/16" dia holes for connecting rod. This little piece has a matching 1/16" hole and two #6 thru holes for mounting on the door.
Door pivot for far end of servo 3D .STL print file
KY-023 Joystick Case 3D .STL print file
This mounts a standard Arduino starter kit KY-023 joystick. Four holes are to be tapped 4-40 for mounting the joystick. The top cover mounts with four 6-32 screws and ca be used without tapping, do not over torque! A cable outlet is provided large enough to a five wire DUPONT5 connector shroud.
KY-023 Joystick Case 3D .STL print file
Comments
Only logged in users can leave comments