Étape 4: Étape 4: Code
Code
Ce projet utilise directe Arduino code et la bibliothèque standard de Arduino EEPROM. Copiez et collez le code ci-dessous dans une nouvelle esquisse et transférez-le sur votre bijou.
Copier le Code
/ * Code de bijou secret Knock pour faire fonctionner un secret knock serrure sur le bijou Adafruit. Version 13.10.31 Built with Arduino IDE 1.0.5 By Steve Hoefer http://grathio.com Licensed sous Creative Commons Attribution-Noncommercial-Share Alike 3.0 http://grathio.com (en bref : faites ce que vous voulez, aussi longtemps que vous me créditer, ne pas changer la licence vers elle et ne vendez pas elle ou l’utilisation dans tout ce que vous vendez sans contacter me.)---câblage---Pin 0: bouton Record A nouveau Knock. Broche 1: (utilise l’intégré LED) broche 2 (Analog 1): un élément piézo-électrique pour biper et détection des chocs. Broche 3: Se connecte à un transistor que s’ouvre un solénoïde se bloquer lorsque HIGH.* / #include const byte eepromValid = 123 ; Si le premier octet en eeprom est la suivante, puis les données sont valides. / * Pin définitions * / const int programButton = 0 ; Enregistrement A nouveau Knock button.const int ledPin = 1 ; Construit en LEDconst int knockSensor = 1 ; (Analogique 1) pour utiliser le piezo comme périphérique d’entrée. (aka knock sensor) const int audioOut = 2 ; (2 digial) pour utiliser le piézo comme un périphérique de sortie. (Chose qui va de bip). const int épine = 3 ; La goupille qui active le verrou à solénoïde. / * Réglage des constantes. Changer les valeurs ci-dessous modifie le comportement du seuil appareil. * / int = 3 ; Minimale du signal de la piezo s’inscrire comme un coup. Plus haut = moins sensible. Valeurs typiques 1 - 10const int rejectValue = 25 ; Si un cognement individuel est désactivée par ce pourcentage d’un coup que nous ne débloquer. Valeurs typiques 10-30const int averageRejectValue = 15 ; Si la date moyenne de tous les coups est désactivée par ce pourcentage que nous ne débloquer. Valeurs typiques 5-20const int knockFadeTime = 150 ; Millisecondes nous permettre un coup se fanent avant que nous écoutons pour un autre. (Minuterie debounce.) const int lockOperateTime = 2500 ; Verrou de millisecondes que nous opérons le solénoïde de verrouillage avant de libérer it.const int maximumKnocks = 20 ; Nombre maximum de coups d’écouter for.const int knockComplete = 1200 ; Plus longtemps à attendre un coup avant que nous partons du principe que c’est fini. (en millisecondes) octets secretCode [maximumKnocks] = {50, 25, 25, 50, 100, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} ; Configuration initiale: « Rasage et une coupe de cheveux, deux bits. » int knockReadings [maximumKnocks] ; Quand quelqu'un frappe ce tableau se remplit avec les retards entre knocks.int knockSensorValue = 0 ; Dernière lecture de la frapper sensor.boolean programModeActive = false ; Cette propriété a la valeur true si nous essayons de programmer un nouveau coup. void setup() {pinMode (ledPin, sortie); pinMode (épine, OUTPUT); readSecretKnock(); / / charge le secret knock (le cas échéant) de EEPROM. doorUnlock(500); / / déverrouiller la porte pour un peu quand on allume. Pour la vérification du système et de permettre une façon if la clé est oubliée. Delay(500) ; Ce retard est ici parce que le retour de verrou de solénoïde pour placer peut autrement détente et knock involontaire.} void loop() {/ / Ecoute pour toute frappe à All. knockSensorValue = analogRead(knockSensor) ; if (digitalRead(programButton) == HIGH) {/ / que l'on appuie sur le bouton de programme? Delay(100) ; Debounce bon marché. Si (digitalRead(programButton) == HIGH) {si (programModeActive == false) {/ / si nous ne sommes pas dans le mode programmation, allumez-le. programModeActive = true; / / n’oubliez pas que nous sommes dans la programmation mode. digitalWrite (ledPin, HIGH); / / allumer le voyant rouge voyant aussi alors l’utilisateur sait nous sommes programmation. chirp (500, 1500); / / et jouer un ton dans le cas où l’utilisateur ne peut pas voir le chirp LED. (500, 1000);} else {/ / si nous sommes en mode de programmation , mettez-le hors tension. programModeActive = false ; digitalWrite (ledPin, basse) ; chirp (500, 1000) ; Éteindre la LED programmation et jouez une note triste. chirp (500, 1500) ; Delay(500) ; {tout en (digitalRead(programButton) == HIGH) {delay(10); / / traîner jusqu'à ce que le bouton est relâché.}} Delay(250) ; Un autre bon marché debounce. Plus longtemps car la touche parfois pour être perçue comme un coup. } Si (knockSensorValue > = seuil) {si (programModeActive == true) {/ / clignoter la LED lorsque nous percevons un cognement. digitalWrite (ledPin, LOW);} else {digitalWrite (ledPin, HIGH);} knockDelay() ; if (programModeActive == true) {/ / ONU-clignotement du LED. digitalWrite (ledPin, HIGH);} else {digitalWrite (ledPin, LOW);} listenToSecretKnock(); / / nous avons notre premier coup. Aller et de voir quelles sont les autres chocs en magasin...} } / / Enregistre le moment de knocks.void listenToSecretKnock() {int j’ai = 0; / / d’abord réinitialiser le tableau écoute. pour (j’ai = 0; j’ai < maximumKnocks; i ++) {knockReadings [i] = 0;} int currentKnockNumber = 0; / / Position compteur pour le tableau. int startTime = millis(); / / au démarrage de ce coup de référence pour. int maintenant = millis() ; faire {/ / écouter le prochain coup ou attendez qu’il à knockSensorValue timeout. = analogRead(knockSensor) ; if (knockSensorValue > = seuil) {/ / Voici un autre coup. Économiser le temps entre les coups. Now=Millis() ; knockReadings [currentKnockNumber] = maintenant - startTime ; currentKnockNumber ++ ; startTime = maintenant ; Si (programModeActive == true) {/ / clignoter la LED lorsque nous percevons un cognement. digitalWrite (ledPin, LOW);} else {digitalWrite (ledPin, HIGH);} knockDelay() ; Si (programModeActive == true) {/ / ONU-clignotement du LED. digitalWrite (ledPin, HIGH);} else {digitalWrite (ledPin, LOW);}} maintenant = millis() ; Arrêter l’écoute si il y a trop de coups ou il y a beaucoup trop de temps entre les coups. } tandis que ((maintenant-startTime < knockComplete) & & (currentKnockNumber < maximumKnocks)) ; Nous avons notre coup enregistré, permet de voir si elle est valide si (programModeActive == false) {/ / seulement le faire si nous ne sommes pas enregistrez un nouveau knock. si (validateKnock() == true) {doorUnlock(lockOperateTime);} else {/ / knock est non valide. Clignoter la LED comme un avertissement aux autres. pour (i = 0; j’ai 4 <; i ++) {digitalWrite (ledPin, HIGH); digitalWrite (ledPin, basse), delay(50) ; delay(50);}} } else {/ / si nous sommes en mode nous toujours valider la serrure car elle rend certains numéros, nous avons besoin de programmation, nous avons tout simplement pas faire n’importe quoi avec le retour. validateKnock();}} Déverrouille le doorUnlock de door.void (int delayTime) {digitalWrite (ledPin, HIGH); digitalWrite (épine, HIGH); digitalWrite (épine, LOW); delay(delayTime) ; delay(500) ; digitalWrite (ledPin, basse) / / ce retard est ici parce que libérer le verrou peut provoquer une vibration qui sera sentie comme un cognement.} / / vérifie si notre coup correspond à la secret.// retourne true si c’est un bon coup, faux si c’est not.boolean validateKnock() {int j’ai = 0; int currentKnockCount = 0; int secretKnockCount = 0; int maxKnockInterval = 0; / / nous l’utiliser plus tard pour normaliser le times. pour (i = 0; i 0) {currentKnockCount ++;} si (secretCode [i] > 0) {secretKnockCount ++;} si (knockReadings [i] > maxKnockInterval) {/ / collecter des données de normalisation alors que nous sommes en boucle. maxKnockInterval = knockReadings [i];}} Si nous sommes en train d’enregistrer un nouveau frapper, enregistrer les infos et de sortir d’ici. Si (programModeActive == true) {pour (i = 0; j’ai < maximumKnocks; i ++) {/ / normaliser le temps entre les coups. (le plus long temps = 100) secretCode [i] = carte (knockReadings [i], maxKnockInterval, 0, 0, 100) ; } saveSecretKnock() ; enregistrer le résultat dans l’EEPROM programModeActive = false ; playbackKnock(maxKnockInterval) ; retourne la valeur false ; } Si (currentKnockCount! = secretKnockCount) {/ / vérifier d’abord plus facile. Si le nombre de coups est mauvais, ne déverrouiller. retourne la valeur false ; } / * Maintenant nous comparons les intervalles relatives de nos coups, pas l’heure absolue entre eux. (c’est à dire: Si vous faites le même schéma, lent ou rapide il devrait encore ouvrir la porte.) Cela rend moins pointilleux, qui, tout en la rendant moins sûre, peut aussi faire moins d’une douleur à utiliser si vous êtes tempo est un peu lent ou rapide. * / int totaltimeDifferences = 0 ; timeDiff int = 0 ; pour (i = 0; j’ai < maximumKnocks; i ++) {/ / normaliser les temps knockReadings [i] = carte (knockReadings [i], 0, maxKnockInterval, 0, 100); timeDiff = abs (knockReadings [i] - secretCode[i]) ; if (timeDiff > rejectValue) {/ / individu valeur trop loin détraqué. Pas d’accès pour ce coup! retourne la valeur false ; } totaltimeDifferences += timeDiff ; } / / On peut également échouer si tout cela est trop imprécise. Si (totaltimeDifferences / secretKnockCount > averageRejectValue) {return false;} return true;} lit le coup secret d’EEPROM. (le cas échéant.) void readSecretKnock() {lecture octet ; int i; lecture = EEPROM.read(0) ; if (lecture == eepromValid) {/ / uniquement en lecture EEPROM si l’octet de la signature est correcte. pour (int j’ai = 0; j’ai < maximumKnocks; i ++) {secretCode [i] = EEPROM.read(i+1);}}} //saves un nouveau motif trop eepromvoid saveSecretKnock() {EEPROM.write (0, 0); / / effacer la signature. De cette façon, nous savons si nous n’a pas fini de l’écrire avec succès. pour (int i = 0; i < maximumKnocks; i ++) {EEPROM.write (i + 1, secretCode[i]);} EEPROM.write (0, eepromValid) ; tout est bon. Écrivez la signature donc nous saurons que c’est tout bon.} Relit le patron de la frapper en clignote et beepsvoid playbackKnock (int maxKnockInterval) {digitalWrite (ledPin, LOW); delay(1000) ; digitalWrite (ledPin, HIGH); chirp (200, 1800); pour (int j’ai = 0; j’ai < maximumKnocks; i ++) {digitalWrite (ledPin, basse); / / seulement allumez-le s’il y a un retard si (secretCode [i] > 0) {retard (carte (secretCode [i], 0, 100, 0, maxKnockInterval)); / / étendre le temps régulariser ce qu’elle était. À peu près. digitalWrite (ledPin, HIGH) ; chirp (200, 1800) ; {}} digitalWrite (ledPin, LOW);} Traite le knock retard thingy.void knockDelay() {int itterations = (knockFadeTime / 20); / / attendre que le pic de se dissiper avant d’écouter un prochain. pour (int j’ai = 0; j’ai < itterations; i ++) {delay(10) ; analogRead(knockSensor); / / Ceci est fait pour tenter de désamorcer le condensateur du capteur analogique qui va donner des lectures erronées sur haute impédance capteurs. delay(10);}} / / joue un ton non musicaux sur le piezo. / / playTime = millisecondes pour jouer le diapason / / /Delay = temps en microsecondes entre les graduations. (plus petit = plu ton pitch.) Sub chirp (playTime int, int delayTime) {loopTime long = (playTime * 1000L) / /Delay ; pinMode(audioOut, OUTPUT) ; pour (int j’ai = 0; j’ai < loopTime; i ++) {digitalWrite (audioOut, HIGH); delayMicroseconds(delayTime) ; digitalWrite (audioOut, LOW);} pinMode (audioOut, INPUT);}
Pour les curieux, voici un bref résumé de ce que le code est:-ce ça initialise tout, régler l’entrée appropriée et les broches de sortie et charges les sauvés frappent le motif (le cas échéant) dans l’EEPROM. Après que tout est initialisé il écoute un épi sur le capteur piezo.
Lorsque son dépassant un certain seuil, il est considéré comme un « coup ».
Lorsqu’il entend un coup elle démarre une minuterie et ensuite à l’écoute des coups plus.
Lorsqu’il reçoit un autre coup il sauve le temps entre les coups dans un tableau.
Lorsqu’il n’y a pas plus de coups (il y a au moins 1,2 secondes sans frapper), il vérifie pour voir si la séquence est correcte.
Il fait ceci en normalisant le temps entre les coups, ce qui les rend par rapport à l’autre, pas l’exacts millisecondes entre eux. Donc le plus long temps entre les coups devient 100, moitié ce temps devient 50, etc..
Pour reprendre les termes de la musique ensemble notes sont 100, demi-notes sont 50, noires sont 25, etc..
Il compare ces valeurs à la frapper stockée.
Si ils correspondent (ou presque correspond à) la serrure s’ouvre pendant quelques secondes et puis remonte au #2. Si ne correspond pas à la frapper, il clignote une lumière de l’échec et puis remonte à #2.It n’autres choses aussi, comme lire le bouton pour voir si il doit programmer un nouveau knock, etc..
Le code est abondamment commenté et mais voici quelques choses qui peuvent vous intéresser dans la modification de:
Copier le Code
seuil d’int = 3 ; (ligne 29)
Si le capteur de cognement est trop sensible vous pouvez essayer d’augmenter cette valeur. Généralement les valeurs inférieures à 10 fonctionnent le mieux, mais les valeurs jusqu'à 250 ont été connus pour travailler. (Si vous avez besoin de porter ce supérieures à 250 alors vous avez probablement quelque chose de mal avec votre circuit ou des composants.)
Copier le Code
const int rejectValue = 25 ; const int averageRejectValue = 15 ; (ligne 30-ish)
Ces deux pourcentages indiquent comment précis que l'on frappe doit être débloquer. Augmenter ces chiffres permet un coup sloppier de travailler. Abaisser les nécessite un coup plus strict.