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); }
Attachments
Step 2: Make Box
Can really be any shape and material but I used plexi so it'd be durable.