Post

Homework 12: Knock Lock

Homework 12 project

The Circuit

Circuit

Parts List

NameQuantityComponent
U11Arduino Uno R3
R1, R2, R33220 Ω Resistor
D11Red LED
D21Green LED
D31Yellow LED
PIEZO11Piezo
S11Pushbutton
R4110 kΩ Resistor
SERVO11Positional Micro Servo
C111 uF, 16 V Polarized Capacitor
R511 MΩ Resistor

Parts List CSV

Schematics

Schematics Schematics pdf

Building the Circuit

Building the circuit went by quickly and I don’t really have much more to say about it. I assembled it, loaded the sketch, and it worked fully. One thing I did change in the example sketch was that I added another small delay after the yellow LED went off as more user feedback for accepting a valid knock. It also gave the Piezo time to settle since without the delay, it would register reverberations from the same lock twice, so it could be unlocked with just 1 knock.

Knock Lock project demo

Programming

After confirming that the circuit was working, I then unloaded the example sketch and began programming the arduino. The code this time was a bit more complex and I started getting a feel for how more and more complexity stacks with more components, and it was cool to see the piezo having its uses reversed.

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
#include <Servo.h>
Servo myServo;

const int piezo = A0;
const int switchPin = 2;
const int yellowLed = 3;
const int greenLed = 4;
const int redLed = 5;

int knockVal;
int switchVal;

// variables for the high and low limits of the knock value
const int quietKnock = 10;
const int loudKnock = 100;

// variable to indicate if locked or not
bool locked = false;
int numberOfKnocks = 0;

void setup() {
  myServo.attach(9);

  // make the LED pins outputs
  pinMode(yellowLed, OUTPUT);
  pinMode(redLed, OUTPUT);
  pinMode(greenLed, OUTPUT);

  // set the switch pin as an input
  pinMode(switchPin, INPUT);

  // start serial communication for debugging
  Serial.begin(9600);

  // start with 'door' open
  digitalWrite(greenLed, HIGH);
  myServo.write(0);
  Serial.println("the box is unlocked!");
}

void loop() {
  if (!locked) {
    switchVal = digitalRead(switchPin);

    if (switchVal == HIGH) {
      locked = true;

      // change the status LEDs
      digitalWrite(greenLed, LOW);
      digitalWrite(redLed, HIGH);

      // move the servo to the locked position
      myServo.write(90);
      Serial.println("the box is locked!");
      delay(1000); // wait for servo to move
    }
  }

  if (locked) {
    knockVal = analogRead(piezo);

    // if there are not enough valid knocks
    if (numberOfKnocks < 3 && knockVal > 0) {
      if (checkForKnock(knockVal)) numberOfKnocks++;

      // print status of knocks
      Serial.print(3 - numberOfKnocks);
      Serial.println(" more knocks to go");
    }

    // if there are three knocks
    if (numberOfKnocks >= 3) {
      // unlock the box
      locked = false;
      // move the servo to the unlocked position
      myServo.write(0);
      delay(20);

      // change status LEDs
      digitalWrite(greenLed, HIGH);
      digitalWrite(redLed, LOW);
      Serial.println("the box is unlocked!");

      numberOfKnocks = 0;
    }
  }
}

// checks if detected knock is within range
bool checkForKnock(int value) {
  if (value > quietKnock && value < loudKnock) {
    // turn the status LED on
    digitalWrite(yellowLed, HIGH);
    delay(50);
    digitalWrite(yellowLed, LOW);
    delay(50);

    Serial.print("Valid knock of value ");
    Serial.println(value);
    return true;
  }
  else {
    // print status
    Serial.print("Bad knock value ");
    Serial.println(value);
    return false;
  }
}
This post is licensed under CC BY 4.0 by the author.