Knock-Knock - Baris Kalkan

by bkalk in Circuits > Arduino

124 Views, 0 Favorites, 0 Comments

Knock-Knock - Baris Kalkan

Bildschirm­foto 2023-07-21 um 21.10.41.png

Was ist Knock-Knock?

Knock-Knock ist die Idee, sein Haustürschloss oder auch jedes andere Türschloss nur durch das Klopfen öffnen zu können, um Problemen wie Schlüsselverlust, Diebstahl und überfüllte Schlüsselbunde entgegenwirken zu können.

Dabei soll natürlich nicht jeder in der Lage sein, die Tür öffnen zu können.

Genau deshalb erkennt dich Knock-Knock an einem im Vorhinein gesetztem Klopfmuster, welches so individuell wie man selbst sein kann.

Kurz gefasst: Knock-Knock ist ein Smart Lock, welches sich durch die Eingabe eines individuellen Klopfmusters öffnet und somit einem das Leben erleichtert.

Die Idee für Knock-Knock kam mir beim versehentlichen ausschließen aus dem eigenem Haus:

Warum kann ich jetzt nicht einfach klopfen?

Supplies

155132.jpg
s-l400.jpg
0J11569.600x480.jpg
arduino_uno_smd_rev3_-_overview.jpg

Für die Erstellung von Knock-Knock benötigen wir folgende (oben von Links nach Rechts abgebildete) Komponenten:

  1. Mikrofon Sound Sensor - zum Erkennen von Klopfeingaben.
  2. Einen 12V Schneckengetriebe Motor mit min. 1,5Nm Kraft - Türschlösser müssen laut DIN EN 1303 mit 1,5Nm Drehmoment betätigt werden können. Daher fiel hier die Wahl auf einen Motor mit ausreichend Drehmoment.
  3. Polulu DRV8876 Single Brushed DC Motor Driver Carrier - zur Steuerung des Motors, aber vor allem zur Nutzung der "Current Sensing" Funktion. Diese ermöglicht es uns zu messen, wie viele Ampere der Motor zieht, denn ein DC Motor zieht bei höherer Belastung mehr Ampere. Somit lassen sich die Schlossendpunkte erkennen und der Motor zerstört nicht unser gesamtes Projekt oder sich selbst.
  4. Nützlich: 12V AA Batteriefach für 8 AA Batterien.
  5. Zuletzt benötigen wir auch ein Arduino UNO (oder ähnliche Boards von anderen Herstellern).

Wir benötigen zudem auch weitere kleinere Komponenten wie 1 rote, 1 grüne LED und einen passiven Buzzer für ein Nutzer Interaktion sowie einen Knopf zur einfachen Steuerung der Aufnahme Funktion.

Und wie für wahrscheinlich jedes Projekt benötigen wir natürlich auch Kabel!

Klopfmuster Erkennung

IMG_4186.PNG

Zuerst beschäftigten sich drei meiner Teamkollegen um die Erkennung, Speicherung und den Abgleich von Klopfmustern.

Hierfür wird der Mikrofon Sensor mit + an einen Pin, am besten 12 oder 13, GND an den neben Pin 13 liegenden GND und A0 an den analogen Input A0 am Arduino angeschlossen. Am Ende der Anleitung gibt es dann noch den gesamten Schaltplan zu sehen.

Zur Erkennung von Klopfmustern wird nun der an + angeschlossene Pin auf HIGH gesetzt und mit A0 das Signal des Mikrofonsensors ausgewertet. Hierbei tasten wir mit 115200 Baud ab.

Nun setzten wir einen Threshold als Schwellwert, um Klopfen von anderen möglichen Inputs unterscheiden zu können, dieser muss je nach Material der Klopfoberfläche angepasst werden und lag bei uns zwischen 1.6 und 1.73.

Jetzt müssen wir es ermöglichen, Muster zu erkennen; dafür speichern wir uns mit der Funktion millis() den Zeitstempel des ersten Klopfers ab und nehmen ihn als Nullpunkt. Jeder folgende Klopfer erhält einen Zeitstempel mit der Differenz zu seinem vorherigen Klopfer, sodass wir am Ende eine Liste an Intervallen vom ersten bis zum letzten Klopfer haben. Damit wir bei Stromverlust dieses Muster auch weiterhin behalten können, haben meine Teamkollegen sich dazu entschieden, dieses Muster auf den EEPROM des Arduinos zu speichern.

Zum Abgleich des Musters werden nun die erkannten Intervalle des Sensors mit den Gespeicherten auf dem EEPROM verglichen. Da es aber nahezu unmöglich wäre, auf die Millisekunde genau zu klopfen, haben wir hierfür einen Skalierungsfaktor genutzt um leichte Latenzen in der Eingabe zu ermöglichen.

Anschließen Und Steuern Des Motors

0J11428.600.jpg
Motoranchluss.png

Zur Nutzung des Motors benötigen wir eine 12V Stromquelle, das Arduino kann zwar auch mit einer 12V Stromquelle betrieben werden, wird dabei aber heiß und gibt dann auch nur 250mA über VIN aus, daher eignet sich das DRV8876 perfekt auch zur Schaltung der Stromquelle.

Das Anschließen und Steuern über das DRV8876 wirkt zuerst recht kompliziert, ist jedoch nach genauerer Recherche im Datenblatt von POLULU und Texas Instruments etwas verständlicher als man denken würde.

Man kann das ganze zum Beispiel anschließen, wie auf dem ersten Bild oben zu sehen ist.

Wir haben noch einiges abgeändert, um es auf unsere Bedürfnisse anzupassen, wie man auf dem zweiten Bild sehen kann.

Hierbei ist der SLP Pin ansteuerbar auf Pin 8, dies ermöglicht es den DRV8876 bei fehlenden HIGH-Input in einen Sleep-Modus zu versetzten, in welchem das Board nur minimal Strom verbraucht. PMODE ist für die Kontrollart des Motors zuständig und ist bei uns im PHASE/ENABLE Modus auf Ground gesetzt.

Die 12V Stromquelle geht direkt auf VIN und das drunterliegende Ground, aus dem gegenüber liegendem VM und GND kann nun Strom für das Arduino genutzt werden, womit unser Motor zuerst versorgt wird und nicht nur mit 250mA aus dem Arduino auskommen muss. Die Pins VM und das drunterliegende GND werden mit dem VIN und GND des Arduinos verbunden, womit das gesamte System nur noch eine Stromquelle hat.

OUTPUT 1/2 werden an den Motor angeschlossen und zuletzt schließen wir IN1/EN auf Pin 10 und IN2/PH auf Pin 9.

Um unseren Motor jetzt steuern zu können, muss zuerst Strom auf den SLP Pin gesetzt werden. Anschließend können wir den Motor vorwärts drehen, indem wir Pin 9(PH) auf HIGH setzten und nun auf Pin 10(EN) entweder ein HIGH Signal oder mit PWM sogar eine prozentuale Geschwindigkeit setzten können. Um den Motor rückwärts zu drehen, muss lediglich Pin 9(PH) auf LOW gesetzt werden, der Rest ist analog zu vorwärts.

Current Sensing

111.jpg

Zuletzt kommt das Herzstück vom Türöffnungsmechanismus, das Current Sensing.

Wie zuvor erwähnt müssen wir die Endpunkte des Schlosses erkennen können, damit der Motor nicht versucht weiterzudrehen.

Hierfür nutzen wir das Current Sensing des DRV8876.

Wir verbinden den CS Pin auf dem DRV8876 mit einem analogen Input Pin, in unserem Fall A1. Nun bekommen wir auf diesem je genutzter Ampere des Motors 2.5V Input. Diese Daten können wir nutzen, um zu erkennen, dass der Motor unter Last steht und diesen bei erreichen eines gewissen Punktes stoppen.

Dies hört sich intuitiver an, als es ist, denn DC Motoren haben die Eigenschaft, beim Anfahren, ähnlich wie beim Stalling, hohe Ampere zu ziehen. Das Ganze sieht wie auf dem Bild oben zu sehen ist aus.

Wie man sehen kann, sehen Anfahren und Widerstand erreichen fast gleich aus, mit der Ausnahme, dass nach dem Peak beim Anfahren die Ampere wieder abfallen.

Um das Stoppen des Motors direkt beim Anfahren umgehen zu können haben wir eine Schleife verwendet, welche vor der While-Schleife für den Threshold des Motors 201 mal CS abtastet, während der Motor anläuft und den Mittelwert der Werte berechnet. Sollte dieser über einem sehr hohem Wert von 800 liegen, bricht das Programm ab zu fahren. Falls der Wert aber darunter liegt, fährt der Motor in die jeweilige Richtung, bis ein CS Wert von 200 erreicht wird. Diesen Wert haben wir durch Herantasten mit dem Motor an der Tür herausgefunden. Hierbei war es wichtig, dass die While nicht schon beim Widerstand des Schlosses auslöst, sondern erst am jeweiligen Endpunkt. In Code sieht das Ganze dann so aus:

int openthedoor(int opVal) {  
//initialisieren der Variablen für Current Sensing
int sensorValue = 0;
int sensValAvg = 0;
//Prueft op der Richtige opCode mitgegeben wurde (aktuell fürs testen um perma-loop zu vermeiden)
if(opVal != 1){
exit(0);
}else{
//opCode richtig: beginne Türöffnung Pins 8, 9, 10 auf HIGH = Motor dreht Vorwärts
playSound(2);//spielt öffnungs sound
digitalWrite(slpPin, HIGH);
digitalWrite(enPin, HIGH);
digitalWrite(phPin, HIGH);
analogWrite(ledPin, 60);
//100 Sampledaten von CS output des DRV8876 um Anfahrpeak nicht als Stop zu deuten
for(int i = 0; i < 200; i++){
sensorValue = analogRead(csRead);
sensValAvg += sensorValue;
}
//weiteres Delay um Peak bei Motoranfahrt zu vermeiden
delay(300);
sensorValue = sensValAvg / 100;
if(sensorValue >=800){
return(-1);
}
//while laeuft bis CS ein mA Output von ueber 250 gibt = Ende/ Widerstand erreicht (Schluessel nicht kaputt machen)

while(sensorValue <= 200){
digitalWrite(enPin, HIGH);
digitalWrite(phPin, HIGH);
sensorValue = analogRead(csRead); //updated sensorValue sonst uerde while nie greifen... :p
}//Amp zu Hoch/ Widerstand/Ende erreicht
//bleibe stehen
digitalWrite(enPin, LOW);
digitalWrite(phPin, LOW);
delay(1000);
//drehe Zurueck um Belastung vom Schluessel zu nehmen
digitalWrite(enPin, HIGH);
digitalWrite(phPin, LOW);
delay(1900);
//alle Pins auf LOW und raus
digitalWrite(enPin, LOW);
digitalWrite(phPin, LOW);
digitalWrite(slpPin, LOW);
playSound(2700);
return(0);
}
}

Wie man sehen kann, kommen nach der While noch Motorbefehle. Diese bewirken, dass der Schnapper der Tür eine Sekunde offenbleibt, um dem Nutzer Zeit zu geben, die Tür aufzuschieben. Dann fährt der Motor kurz rückwärts, um den Schnapper wieder rauszufahren und Stress vom Schlüssel zu nehmen.

Mechanik Und Design

Viel an Mechanik gibt es an unserem Smart Lock nicht. Wir haben lediglich einen Metallhaken mit Gewinde zur Verbindung von Motor mit Schlüssel genutzt.

An Design gab es dafür deutlich mehr.

Wir haben ein Gehäuse entworfen, welches genug Platz für alle Komponenten und auf der Rückseite Platz zur Befestigung des Motors haben soll.

Ziel des Gehäuses war es neben praktisch auch möglichst elegant auszusehen, um dem Prototypen wenigstens etwas Eleganz zu geben.

Zudem haben wir einen Deckel zum Verstecken des Motors und ein Batteriefach für 12V AA Batteriepacks entworfen.

Am Ende hatte ich folgende Box in Fusion 360:

Finish & Extras

Zum Abschluss fügen wir dem Projekt noch Feedback/Outputs und Inputs hinzu.

Hierfür nutzen wir eine grüne sowie eine rote LED die an der Seite der Box eingelassen werden. Diese werden zum Steuern mit Pins 5 und 6 verbunden und teilen sich einen gemeinsamen Ground auf dem DRV8876.

Die grüne LED leuchtet bei korrekt erfasstem Klopfmuster sowie im Rhythmus des eingegebenen Klopfmusters nach Einspeicherung eines neuen Musters. Die rote LED leuchtet bei einem falsch eingegeben Klopfmuster.

Zur Erweiterung der Interaktion mit Menschen fügen wir der Smart Lock noch einen passiven Buzzer hinzu. Dieser kann Töne zwischen 2000 - 5000Hz abspielen und wird bei unserem Projekt mehrfach genutzt.

Wir haben eine Melodie beim hochfahren des Systems, Mustereingabe, Öffnung sowie Schließung der Tür und die Funktion des Piepen im Rhythmus des Klopfcodes parallel zur grünen LED. Dies sah in der Umsetzung dann so aus:


void playSound(int songNm){
if(songNm >= 1500){//spiele ton auf gewisser frequenz
tone(buzPin, songNm);
delay(100);
noTone(buzPin);
}else if(songNm == 0){//startup sound
tone(buzPin, 4400);
delay(100);
noTone(buzPin);
delay(50);
tone(buzPin, 2800);
delay(100);
noTone(buzPin);
delay(50);
tone(buzPin, 3800);
delay(100);
noTone(buzPin);
delay(50);
tone(buzPin, 4700);
delay(150);
noTone(buzPin);
}else if(songNm == 1){//pattern recording sound
tone(buzPin, 3300);
delay(100);
noTone(buzPin);
delay(100);
tone(buzPin, 3300);
delay(100);
noTone(buzPin);
delay(100);
tone(buzPin, 3300);
delay(100);
noTone(buzPin);
delay(100);
}else if(songNm == 2){//opening door
tone(buzPin, 2700);
delay(100);
noTone(buzPin);
delay(50);
tone(buzPin, 2200);
delay(100);
noTone(buzPin);
delay(50);
tone(buzPin, 3300);
delay(200);
noTone(buzPin);
}else if(songNm == 3){//close door
tone(buzPin, 3500);
delay(100);
noTone(buzPin);
delay(100);
tone(buzPin, 2400);
delay(100);
noTone(buzPin);
delay(100);
tone(buzPin, 1800);
delay(200);
noTone(buzPin);
}else if(songNm == 4){ //wrong pattern
tone(buzPin, 2400);
delay(200);
noTone(buzPin);
delay(100);
tone(buzPin, 1800);
delay(200);
noTone(buzPin);
}
return;
}


Der Buzzer wird mit dem Mikrofonsensor gemeinsam auf dem GND neben Pin 13 geerdet, da es bei dem GND des DRV8876 zu eventuellen Interferenzen durch den Motor kommen kann. Bei Bedarf kann noch ein Potentiometer zwischen GND und Buzzer geschaltet werden, um die Lautstärke regulieren zu können. + des Buzzers setzen wir nun auf Pin 3 des Arduinos, da wir PWM zur Ton Generierung benötigen.

Zuletzt haben wir noch einen Knopf, welcher über einen 10K Ohm Widerstand ebenfalls auf dem GND des DRV8876 geerdet wird, 5V direkt Strom aus dem 5V Output des Arduinos bekommt und auf Pin 2 des Arduinos verbunden wird.

Dieser Knopf hat die einzige Funktion, die Eingabe eines neuen Klopfmusters zu ermöglichen. Nach Drücken des Knopfes wird die entsprechende Melodie abgespielt, um zu signalisieren, dass man nun ein neues Muster eingeben kann.

Nun sollte der Schaltplan wie unten zu sehen ist aussehen und wir sind fertig!

Abschlussworte

ProjektBild.png
IMG_4211.PNG

Auf dem zweiten Bild kann man noch zu sehen wie das ganze auf dem Breadboard gesteckt aussah.


Und wenn alles richtig läuft, sollte die Tür auch öffnen! :)