Paso 4: Paso 4: código
Código
Este proyecto utiliza el código de Arduino de la directa y la biblioteca estándar de Arduino EEPROM. Copiar y pegar el código siguiente en un nuevo dibujo y subirlo a su baratija.
Copia el código
/ * Código de baratija golpe secreto para correr un secreto llaman bloqueo a la baratija de Adafruit. Versión 13.10.31 construido con Arduino IDE 1.0.5 By Steve Hoefer http://grathio.com licenciado bajo Creative Commons Attribution-Noncommercial-Share Alike 3.0 http://grathio.com (en Resumen: hacer lo que quiera, siempre y cuando me de crédito, no utilizarla lo y no vender o usar en cualquier cosa que vende sin ponerse en contacto con mí)---cableado---Pin 0: botón Registro un nuevo golpe. Pin 1: (utiliza el construido en LED) Pin 2 (análogo 1): un elemento piezo para sonido y sensor de golpes. PIN 3: Se conecta a un transistor que se abre un solenoide de bloqueo cuando HIGH.* / #include const byte eepromValid = 123; Si el primer byte en la eeprom es esto los datos son válidos. / * Perno de definiciones / const int programButton = 0; Nuevo golpe de registro A button.const int ledPin = 1; Construido en LEDconst int knockSensor = 1; (Análogo 1) para usar el piezo como un dispositivo de entrada. (también conocido como knock sensor) const int audioOut = 2; (2 digital) para usar el peizo como un dispositivo de salida. (Lo que pasa bip.) const int espiga = 3; El pin que activa el solenoide de bloqueo. / * Ajuste constantes. Modificación de los valores a continuación cambia el comportamiento del dispositivo/int umbral = 3; Señal mínima de la piezo para registrarse como un golpe. Más alto = menos sensible. Valores típicos 1 - 10const int rejectValue = 25; Si un golpe individual está apagada por este porcentaje de un golpe que no abrimos. Valores típicos 10-30const int averageRejectValue = 15; Si el tiempo promedio de todos los golpes está desactivada en este por ciento no lo abrimos. Valores típicos 5-20const int knockFadeTime = 150; Milisegundos, permitir que un golpe a desvanecerse antes de escuchar por otro. (Debounce temporizador). const int lockOperateTime = 2500; Milisegundos que operamos el solenoide de bloqueo de cierre antes de soltar it.const int maximumKnocks = 20; Número máximo de golpes para escuchar for.const int knockComplete = 1200; Tiempo más largo para esperar un golpe antes de asumir que se acabó. (milisegundos) byte secretCode [maximumKnocks] = {50, 25, 25, 50, 100, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; Configuración inicial: "Afeitado y un corte de pelo, dos pedacitos." int knockReadings [maximumKnocks]; Cuando alguien toca esta matriz llena los retrasos entre knocks.int knockSensorValue = 0; Última medición de la precipitación sensor.boolean programModeActive = false; Es true si estamos tratando de programar un nuevo golpe. void setup() {pinMode (ledPin, salida); pinMode (espiga, salida); readSecretKnock(); / / el golpe secreto de carga (si existe) de EEPROM. doorUnlock(500); / / abre la puerta para un poco cuando enciende. Para la comprobación del sistema y para permitir una manera adentro si se olvida la llave. Delay(500); Este retraso está aquí porque el solenoide cerradura regresa al lugar puede otro tipo gatillo y llamo inadvertida.} void loop() {/ / escuchar cualquier llamada en toda. knockSensorValue = analogRead(knockSensor); if (digitalRead(programButton) == HIGH) {/ / se presiona el botón de programa? Delay(100); Debounce barato. Si (digitalRead(programButton) == HIGH) {si (programModeActive == false) {/ / si no estamos en modo de programación, enciende. programModeActive = true; / / recuerda que estamos en la programación de modo digitalWrite (ledPin, HIGH); / / enciende el rojo luz demasiado así que el usuario Conozca somos programación. chirp (500, 1500); / / y un tono en caso de que el usuario no puede ver el LED. chirrido (500, 1000);} otro {/ / si estamos en modo de programación , lo apaga. programModeActive = false; digitalWrite (ledPin, LOW); chirrido (500, 1000); Apague el LED de programación y tocar una nota triste. chirrido (500, 1500); Delay(500); } mientras (digitalRead(programButton) == HIGH) {delay(10); / / colgar alrededor hasta que se suelta el botón.}} Delay(250); Otro debounce barato. Más largo porque soltar el botón a veces se sintió como un golpe. } Si (knockSensorValue > = umbral) {si (programModeActive == true) {/ / parpadea el LED cuando detectamos un knock. digitalWrite (ledPin, LOW);} else {digitalWrite (ledPin, HIGH);} knockDelay(); si (programModeActive == true) {/ / ONU-blink LED. digitalWrite (ledPin, HIGH);} else {digitalWrite (ledPin, LOW);} listenToSecretKnock(); / / tenemos nuestro primer golpe. Ir a ver lo que están otros golpes en el almacén...} } / / Registra el momento de knocks.void listenToSecretKnock() {int me = 0; / / restablecer primero la matriz escucha. para (me = 0; me < maximumKnocks; i ++) {knockReadings [i] = 0;} int currentKnockNumber = 0; / posición de contador de la matriz. int startTime = millis(); / referencia para cuando este golpe. int ahora = millis(); hacer {/ / escuchar para el golpe siguiente o esperar a knockSensorValue tiempo de espera. = analogRead(knockSensor); si (knockSensorValue > = umbral) {/ aquí es otro golpe. Ahorrar el tiempo entre golpes. Now=Millis(); knockReadings [currentKnockNumber] =-startTime; currentKnockNumber ++; startTime = ahora; Si (programModeActive == true) {/ / parpadea el LED cuando detectamos un knock. digitalWrite (ledPin, LOW);} else {digitalWrite (ledPin, HIGH);} knockDelay(); Si (programModeActive == true) {/ / ONU-blink LED. digitalWrite (ledPin, HIGH);} else {digitalWrite (ledPin, LOW);}} ahora = millis(); Dejar de escuchar si hay demasiados golpes o hay demasiado tiempo entre golpes. } mientras que ((ahora startTime < knockComplete) & & (currentKnockNumber < maximumKnocks)); tiene nuestra golpee registrado, vamos a ver si es válido si (programModeActive == false) {/ / sólo hacer esto si nosotros no estamos grabando una nueva knock. Si (validateKnock() == true) {doorUnlock(lockOperateTime);} otro {/ / knock es válido. Parpadear el LED como una advertencia a los demás. para (i = 0; i < 4; i ++) {digitalWrite (ledPin, HIGH); delay(50); digitalWrite (ledPin, LOW); delay(50);}} } else {/ / si estamos en la programación de modo que aún validar la cerradura porque hace algunos números que necesitamos, simplemente no hacemos nada con la vuelta. validateKnock();}} Abre el doorUnlock de door.void (int delayTime) {digitalWrite (ledPin, HIGH); digitalWrite (espiga, HIGH); delay(delayTime); digitalWrite (espiga, LOW); digitalWrite (ledPin, LOW); delay(500); / este retraso es aquí porque soltar el pestillo puede causar una vibración que se sintió como un golpe.} / / comprueba si nuestra golpee coincide con el secret.// devuelve true si es un buen golpe, falsa si es not.boolean validateKnock() {int i = 0; int currentKnockCount = 0; int secretKnockCount = 0; int maxKnockInterval = 0; / utilizar más adelante para normalizar los tiempos. para (i = 0; i 0) {currentKnockCount ++;} si (secretCode [i] > 0) {secretKnockCount ++;} si (knockReadings [i] > maxKnockInterval) {/ / recopilar datos de normalización mientras estamos bucle. maxKnockInterval = knockReadings [i];}} Si estamos grabando un nuevo golpe, guardar la información y salir de aquí. Si (programModeActive == true) {para (i = 0; i < maximumKnocks; i ++) {/ / normalizar el tiempo entre golpes. (el tiempo más largo = 100) secretCode [i] = mapa (knockReadings [i], 0, maxKnockInterval, 0, 100); } saveSecretKnock(); guardar el resultado en EEPROM programModeActive = false; playbackKnock(maxKnockInterval); devuelven el valor false; } Si (currentKnockCount! = secretKnockCount) {/ / comprobar más fácil primero. Si el número de golpes es incorrecto, no desbloquea. devuelven el valor false; } / * Ahora comparamos los intervalos relativos de nuestros golpes, no el tiempo absoluto entre ellos. (es decir: debe abrir la puerta si haces el mismo patrón lento o rápido.) Esto hace menos exigente, que al tiempo que menos seguros puede también hacerlo menos de un dolor usar si eres tempo es un poco lento o rápido. * / int totaltimeDifferences = 0; timeDiff int = 0; para (i = 0; i < maximumKnocks; i ++) {/ / normalizar los tiempos knockReadings [i] = mapa (knockReadings [i], 0, maxKnockInterval, 0, 100); timeDiff = abs (knockReadings [i] - secretCode[i]); if (timeDiff > rejectValue) {/ / persona valor demasiado lejos fuera de control. No hay acceso para este golpe! devuelven el valor false; } totaltimeDifferences += timeDiff; } / / También puede fallar si todo es demasiado inexacta. Si (totaltimeDifferences / secretKnockCount > averageRejectValue) {vuelta falso;} vuelta verdad;} Lee el golpe secreto de EEPROM. (si los hay.) anular readSecretKnock() {lectura byte; int i; lectura = EEPROM.read(0); si (leyendo == eepromValid) {/ / leer EEPROM si el byte de la firma es correcto. para (int me = 0; me < maximumKnocks; i ++) {secretCode [i] = EEPROM.read(i+1);}}} //saves un nuevo patrón demasiado eepromvoid saveSecretKnock() {EEPROM.write (0, 0); / / borrar la firma. De esa manera sabemos que si no acabamos la grabación con éxito. para (int i = 0; i < maximumKnocks; i ++) {EEPROM.write (i + 1, secretCode[i]);} EEPROM.write (0, eepromValid); todo lo bueno. Escribir la firma vamos a saber que todo es bueno.} Reproduce el patrón de la knock-in parpadea y beepsvoid playbackKnock (int maxKnockInterval) {digitalWrite (ledPin, LOW); delay(1000); digitalWrite (ledPin, HIGH); chirp (200, 1800); para (int i = 0; me < maximumKnocks; i ++) {digitalWrite (ledPin, LOW); / sólo gire si hay un retraso si (secretCode [i] > 0) {retardo (mapa (secretCode [i], 0, 100, 0, maxKnockInterval)); / / expandir el tiempo hacia lo que era. Más o menos. digitalWrite (ledPin, HIGH); chirrido (200, 1800); {}} digitalWrite (ledPin, LOW);} Aborda el golpe demora thingy.void knockDelay() {int itterations = (knockFadeTime 20); / / esperar a que el pico se disipe antes de escuchar otro. para (int i = 0; me < itterations; i ++) {delay(10); analogRead(knockSensor); / / esto se hace en un intento de desactivar el condensador del sensor analógico que dará lecturas falsas en alta impedancia sensores. delay(10);}} / / juega un sonido no musical en el piezoeléctrico. / / recreo = milisegundos para reproducir el tono / / delayTime = tiempo en microsegundos entre garrapatas. (menor = mayor tono tono.) void chirp (playTime int, int delayTime) {loopTime largo = (playTime * 1000L) / delayTime; pinMode(audioOut, OUTPUT); para (int i = 0; me < loopTime; i ++) {digitalWrite (audioOut, HIGH); delayMicroseconds(delayTime); digitalWrite (audioOut, LOW);} pinMode (audioOut, entrada);}
Para los curiosos, aquí está un breve resumen de lo que el código hace: él inicializa todo, configurar la entrada apropiada y pines de salida, y cargas los salvados llamo patrón (si existe) de la EEPROM. Después de todo se inicializa escucha para un punto en el sensor piezoeléctrico.
Cuando su por encima de cierto umbral que cuenta como un "golpe".
Cuando oye un golpe inicia un temporizador y luego escucha los golpes más.
Cuando se golpea otro ahorra el tiempo entre golpes en una matriz.
Cuando hay no más golpes (hay por lo menos 1,2 segundos sin un golpe) comprueba si la secuencia es correcta.
Esto logra por normalizar el tiempo entre golpes, que está haciendo en relación con otro, no las exactas milisegundos entre ellos. Así que el más largo tiempo entre golpes se convierte en 100, medio que tiempo llega a ser 50, etc..
Usar el lenguaje de la música sobre todo son 100 media Notas 50, negras son 25, etc..
Compara estos valores a los golpes almacenados.
Si igualar (o casi igualar) la cerradura se abre por unos segundos y luego vuelve a #2. Si no coincide con el golpe, parpadea una luz de falla y entonces van de nuevo a #2.It hace otras cosas, como leer el botón para ver si se deben programar un nuevo golpe, etc..
El código está comentado liberalmente y pero aquí hay un par de cosas que podría estar interesado en la modificación de:
Copia el código
int umbral = 3; (línea 29)
Si el sensor knock es demasiado sensible puede intentar aumentar este valor. Generalmente los valores por debajo de 10 funcionan mejor, pero valores de hasta 250 se han sabido para trabajar. (Si usted necesita hacer esto por encima de 250 entonces probablemente tienes algo mal con el circuito o los componentes.)
Copia el código
const int rejectValue = 25; const int averageRejectValue = 15; (línea 30-ish)
Estos dos porcentajes indican cómo precisa el golpe tiene que ser para desbloquear. Elevando estas cifras permite un golpe enlodado a trabajar. Bajarles requiere un golpe más estricto.