Knock Sensing Circuit

Aus hyperdramatik
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

Knock-sensing-circuit.jpg


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