Knock Sensing Circuit
Zur Navigation springen
Zur Suche springen
KNOCK-KNOCK RECORD AND PLAYBACK CODE
- detects knocks with a piezo element, then triggers a solenoid to knock back the pattern
- detects up to maxNumberOfKnocks
- or stops waiting for a next knock after maxIntervalBetweenKnocks
- plays back the knock pattern once, then goes back to listening
CIRCUIT
CODE
/*
KNOCK-KNOCK RECORD AND PLAYBACK CODE
- detects knocks with a piezo element, then triggers a solenoid to knock back the pattern
- detects up to maxNumberOfKnocks
- or stops waiting for a next knock after maxIntervalBetweenKnocks
- plays back the knock pattern once, then goes back to listening
*/
//VALUES to CHANGE
#define threshold 20 // Schwellenwert, ab dem der Piezo-Sensor als "Klopf" erkannt wird
#define maxNumberOfKnocks 10
#define maxIntervalBetweenKnocks 3000
#define knockDelay 100 //milliseconds for the "HIGH" state of each knock. need to try out which value works well
//VALUES Defined
#define piezoPin A0 // Analog-Pin für den Piezo-Sensor
#define solenoidPin 13
bool listening = true; //listening for knocks
int sensorValue = 0; // Aktuell gemessener Wert
int knockCount = 0;
unsigned long knockTime; // Zählvariable für die Anzahl der Klopfzeichen
// type "long" because the milliseconds will get to be long numbers if the arduino runs for hours/days...
// "+1" because we start couting knocks at 1 and not 0
unsigned long knockTimeStamps[maxNumberOfKnocks + 1];
/////////////////////////////////////////////////////////////////////////////
void setup() {
Serial.begin(9600); // Serielle Übertragung zum PC starten
pinMode(piezoPin, INPUT);
pinMode(solenoidPin, OUTPUT);
digitalWrite(solenoidPin, LOW); //off?
delay(20);
Serial.println("LISTENING...");
listening = true;
}
/////////////////////////////////////////////////////////////////////////////
void loop() {
/////////////
//LISTENING//
/////////////
if (listening == true) {
// LISTENING becomes false if:
// more than maxNumberOfKnocks are registered
// at least one knock is registered AND maxIntervalBetweenKnocks has been exceeded
if (knockCount >= maxNumberOfKnocks) {
listening = false;
delay(maxIntervalBetweenKnocks); //delay so that it does not start knocking right away
}
if (knockCount >= 1 && (millis() - knockTimeStamps[knockCount]) > maxIntervalBetweenKnocks) listening = false;
sensorValue = analogRead(piezoPin); // Eingangswert an A0 lesen
// Liegt der Wert über dem Schwellenwert? Dann Klopfzeichen gezählt
if (sensorValue > threshold) {
knockCount++; // Zähler erhöhen
knockTimeStamps[knockCount] = millis();
Serial.print("KNOCK: #");
Serial.print(knockCount);
Serial.print("\t timestamp: ");
Serial.println(knockTimeStamps[knockCount]);
delay(100); // Eine kleine Verzögerung, um wiederholte schnelle Auslösungen zu vermeiden
}
}
/////////////
///PLAYING///
/////////////
if (listening == false) {
Serial.print("PLAYING ");
Serial.print(knockCount);
Serial.println(" KNOCKS...");
for (int i = 1; i < knockCount + 1; i++) {
int delayBetweenKnocks = knockTimeStamps[i + 1] - knockTimeStamps[i];
Serial.print("KNOCK: #");
Serial.print(i);
digitalWrite(solenoidPin, HIGH);
delay(knockDelay);
digitalWrite(solenoidPin, LOW);
if (i < knockCount) {
Serial.print("\t delay: ");
Serial.print(delayBetweenKnocks);
delay(delayBetweenKnocks);
}
Serial.println();
}
Serial.println("LISTENING...");
knockCount = 0; //only reset when finished playing the recorded knock pattern
listening = true;
}
}
Inspiration
https://www.deutschlandfunknova.de/beitrag/netzbasteln-klopf-klopf-und-die-tuer-geht-auf
https://learn.adafruit.com/secret-knock-activated-drawer-lock/overview