-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathlock.ino
148 lines (119 loc) · 3.49 KB
/
lock.ino
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
#include <Servo.h>
Servo myservo;
const int knockSensor = 0;
const int programSwitch = 2;
const int lockMotor = 3;
const int threshold = 50;
const int rejectValue = 25;
const int averageRejectValue = 15;
const int knockFadeTime = 150;
const int maximumKnocks = 20;
const int knockComplete = 1200;
int secretCode[maximumKnocks] = {50, 25, 25, 50, 100, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; // Initial setup "Shave and a Hair Cut, two bits."
int knockReadings[maximumKnocks];
int knockSensorValue = 0;
int programButtonPressed = false;
void setup() {
myservo.attach(lockMotor);
pinMode(lockMotor, OUTPUT);
pinMode(programSwitch, INPUT);
Serial.begin(9600);
Serial.println("Program start.");
}
void loop() {
knockSensorValue = analogRead(knockSensor);
if (digitalRead(programSwitch) == HIGH) {
programButtonPressed = true;
} else {
programButtonPressed = false;
}
if (knockSensorValue >= threshold) {
listenToSecretKnock();
}
}
void listenToSecretKnock() {
Serial.println("knock starting");
int i = 0;
for (i = 0; i < maximumKnocks; i++) {
knockReadings[i] = 0;
}
int currentKnockNumber = 0;
int startTime = millis();
int now;
delay(knockFadeTime);
do {
knockSensorValue = analogRead(knockSensor);
if (knockSensorValue >= threshold) {
Serial.println("knock.");
now = millis();
knockReadings[currentKnockNumber] = now - startTime;
currentKnockNumber ++;
startTime = now;
delay(knockFadeTime);
}
now = millis();
} while ((now - startTime < knockComplete) && (currentKnockNumber < maximumKnocks));
if (programButtonPressed == false) {
if (validateKnock() == true) {
triggerDoorUnlock();
} else {
Serial.println("Secret knock failed.");
}
} else {
validateKnock();
Serial.println("New lock stored.");
}
}
void triggerDoorUnlock() {
Serial.println("Door unlocked!");
myservo.write(0);
delay(200);
myservo.detach();
delay(5000);
myservo.attach(lockMotor);
myservo.write(90);
}
boolean validateKnock() {
int i = 0;
int currentKnockCount = 0;
int secretKnockCount = 0;
int maxKnockInterval = 0;
for (i = 0; i < maximumKnocks; i++) {
if (knockReadings[i] > 0) {
currentKnockCount++;
}
if (secretCode[i] > 0) {
secretKnockCount++;
}
if (knockReadings[i] > maxKnockInterval) {
maxKnockInterval = knockReadings[i];
}
}
if (programButtonPressed == true) {
for (i = 0; i < maximumKnocks; i++) {
secretCode[i] = map(knockReadings[i], 0, maxKnockInterval, 0, 100);
}
delay(50);
for (i = 0; i < maximumKnocks ; i++) {
if (secretCode[i] > 0) {
delay( map(secretCode[i], 0, 100, 0, maxKnockInterval));
}
delay(50);
}
return false;
}
int totaltimeDifferences = 0;
int timeDiff = 0;
for (i = 0; i < maximumKnocks; i++) {
knockReadings[i] = map(knockReadings[i], 0, maxKnockInterval, 0, 100);
timeDiff = abs(knockReadings[i] - secretCode[i]);
if (timeDiff > rejectValue) {
return false;
}
totaltimeDifferences += timeDiff;
}
if (totaltimeDifferences / secretKnockCount > averageRejectValue) {
return false;
}
return true;
}