Introduction: Tap Sensing Box

Use a piezo sensor attached to a motor to unlock a box. The pizeo sensor will act as the lock by controlling the motor.

Supplies

piezo sensor

servo motor

100uF capacitator

red, green, blue LEDs

3 push buttons

3 220Ω resistors

3 10KΩ resistors

1 1MΩ resistor

Step 1: Code + Circuit (user Tuixte's Knock Box W/ Modifications)

/************************************/

/************ KNOCK BOX *************/ /*** A project by Michele Marolla ***/ /************************************/

#include

/* Pins */ const int closedLED_p = 5; const int openLED_p = 6; const int inputLED_p = 7; const int rhythmBTN_p = 8; const int closeBTN_p = 9; const int playBTN_p = 10; const int piezo_p = A0; const int servo_p = 11;

/* Rhythm Management */ const int RHYTHM_SIZE = 10; const int TOLERANCE = 150; const int TRESHOLD = 180; class Rhythm{ private: int rhythm[RHYTHM_SIZE];

public: Rhythm(); void getRhythm(int *rhythm_a); void setRhythm(const int rhythm_a[RHYTHM_SIZE]); int getActualSize() const; int getActualSize(const int rhythm_a[RHYTHM_SIZE]) const; void play() const; void play(const int rhythm_a[RHYTHM_SIZE]) const; int listenForKnock() const; void listenForRhythm(int *rhythm_a); boolean checkRhythm(); };

Rhythm::Rhythm(){ int temp[RHYTHM_SIZE] = {500, 500, 100, -1, -1, -1, -1, -1, -1, -1}; this->setRhythm(temp); }

void Rhythm::getRhythm(int *rhythm_a){ for(int i=0; irhythm[i]; }

void Rhythm::setRhythm(const int rhythm_a[RHYTHM_SIZE]){ for(int i=0; irhythm[i] = rhythm_a[i]; }

int Rhythm::getActualSize() const{ return this->getActualSize(this->rhythm); }

int Rhythm::getActualSize(const int rhythm_a[RHYTHM_SIZE]) const{ int count = 0; for(int i=0; i

void Rhythm::play() const{ this->play(this->rhythm); }

void Rhythm::play(const int rhythm_a[RHYTHM_SIZE]) const{ pinMode(piezo_p, OUTPUT); // First knock tone(piezo_p, 2000); delay(100); noTone(piezo_p); // Other knocks for(int i=0; i getActualSize(rhythm_a); i++){ delay(rhythm_a[i]); tone(piezo_p, 2000); delay(100); noTone(piezo_p); } }

int Rhythm::listenForKnock() const{ Serial.println("LISTEN FOR KNOCK"); pinMode(piezo_p, INPUT); unsigned long time = millis(); unsigned long temp; while(true){ temp = millis() - time; if(temp >= 3000) return -1; if((analogRead(piezo_p) >= TRESHOLD) && (temp >= 100)){ digitalWrite(inputLED_p, HIGH); delay(20); digitalWrite(inputLED_p, LOW); return (int)temp; } delay(50); } }

void Rhythm::listenForRhythm(int *rhythm_a){ int time; this->listenForKnock(); // First knock int i; for(i=0; ilistenForKnock(); if(time == -1) break; rhythm_a[i] = time; } for(; i

boolean Rhythm::checkRhythm(){ Serial.println("CHECK RHYTHM"); int time; // Listen and check int temp = this->listenForKnock(); while(temp == -1) temp = this->listenForKnock(); // First knock for(int i=0; i getActualSize(); i++){ time = this->listenForKnock(); if((time == -1) || (time > 3000)) return false; if((time < this->rhythm[i]-TOLERANCE) || (time > this->rhythm[i]+TOLERANCE)) return false; } return true; }

/* Box Management */ class Box{ private: boolean locked; Servo servo; public: Box(); boolean isLocked() const; void openBox(); void closeBox(); void recordNewRhythm(Rhythm *rhythm); };

Box::Box(){ this->locked = true; this->servo.attach(servo_p); this->servo.write(90); digitalWrite(openLED_p, LOW); digitalWrite(inputLED_p, LOW); digitalWrite(closedLED_p, HIGH); }

boolean Box::isLocked() const{ return this->locked; }

void Box::openBox(){ this->locked = false; this->servo.write(0); digitalWrite(openLED_p, HIGH); digitalWrite(inputLED_p, LOW); digitalWrite(closedLED_p, LOW); }

void Box::closeBox(){ this->locked = true; this->servo.write(90); digitalWrite(openLED_p, LOW); digitalWrite(inputLED_p, LOW); digitalWrite(closedLED_p, HIGH); }

void Box::recordNewRhythm(Rhythm *rhythm){ digitalWrite(openLED_p, HIGH); digitalWrite(closedLED_p, HIGH); int newRhythm[RHYTHM_SIZE]; rhythm->listenForRhythm(&newRhythm[0]); rhythm->play(newRhythm); while(true){ if(digitalRead(closeBTN_p) == HIGH){ digitalWrite(closedLED_p, LOW); delay(100); return; }else if(digitalRead(rhythmBTN_p) == HIGH){ rhythm->setRhythm(newRhythm); this->closeBox(); return; } delay(100); } }

/* Setup */ Box *box; Rhythm *rhythm;

void setup(){ Serial.begin(9600); pinMode(closedLED_p, OUTPUT); pinMode(openLED_p, OUTPUT); pinMode(inputLED_p, OUTPUT); pinMode(rhythmBTN_p, INPUT); pinMode(closeBTN_p, INPUT); pinMode(piezo_p, INPUT); pinMode(playBTN_p, INPUT); box = new Box(); rhythm = new Rhythm(); }

/* Loop */ void loop(){ Serial.print("Box is locked? "); Serial.println(box->isLocked()); if(box->isLocked()){ if(rhythm->checkRhythm()){ box->openBox(); }else{ tone(piezo_p, 500); delay(400); noTone(piezo_p); } }else{ if(digitalRead(closeBTN_p) == HIGH) box->closeBox(); else if(digitalRead(rhythmBTN_p) == HIGH) box->recordNewRhythm(rhythm); else if(digitalRead(playBTN_p) == HIGH) rhythm->play(); } delay(100); }

Step 2: Make Box

Can really be any shape and material but I used plexi so it'd be durable.