Ejercicio 24: Grabadora de ritmos
El zumbador repite con una secuencia de pitidos la secuencia de golpes que damos con la mano sobre la superficie en la que se encuentra el piezoeléctrico actuando como sensor.
| Novedades hardware | Novedades software |
| | |
Requisitos:
- Un LED, una resistencia de 220 ohmios.
- Un pulsador, una resistencia de 1Kohmio.
- Un zumbador piezoeléctrico.
- Una resistencia de varios Mohmios.
Planteamiento: Marca un ritmo con tus manos y podrás oírlo a continuación, tantas veces como quieras
La lectura de las señales del sensor se hace como en el ejercicio anterior sensor de pisadas? y la cuenta se lleva de la misma manera.
Para evitar que la vibración que persiste un tiempo tras cada golpe nos dé lecturas repetidas, usamos un delay(100).
Pero ahora tenemos que llevar la cuenta de los tiempos entre golpes.
Hay dos elementos que requieren un poco de atención:
El primer golpe es distinto, pues no viene precedido de un tiempo determinado.
El último golpe puede corresponder a un nº distinto de golpes cada vez.
Los tiempos que contamos son los que pasan después de cada golpe, excepto en el que consideremos el último.
Esta situación la podríamos haber afrontado usando una variable que nos diferencie el primer caso del resto, para empezar a contar y, del mismo modo, el último tiempo de los anteriores, para descartarlo.
Como queremos que la secuencia de golpes pueda contener un nº distinto de golpes cada vez, descartar el último tiempo presentaba un problema adicional, así que hemos optado por otra aproximación: la de asignar los tiempos a los números de golpes colocando expresamente en una cadena los números de golpes que corresponden a cada tiempo.
El procedimiento guardatiempos( ) se ocupa de hacer esta comprobación.
Para saber cuándo ha terminado la secuencia de golpes, ponemos como criterio que haya pasado un determinado tiempo sin otro golpe, de esto se ocupa el condicional:
if((numgolpes>0)&&(tiempo >=30))
Al reproducir con pitidos la secuencia, el primer pitido se da siempre igual y luego comienzan a recuperarse los tiempos de la cadena donde se habían guardado para ir reproduciendo el resto.
Los tiempos se han ido actualizando de uno en uno en cada ciclo, para que el nº de ciclos se transforme en milisegundos multiplicamos por una constante, en este caso 90, que obtenemos probando repetidamente.
VIDEO DEL EJERCICIO 24
CODIGO FUENTE
Copyright (C) 2006 Juan Carlos Alonso de Mena
This program is free software; you can redistribute it and/or modify it under the terms
of the GNU General Public License as published by the Free Software Foundation;
See the GNU General Public License for more details?
int led=13;
int piezoSensor = 0;
int medida = 0;
int nivel = 80; //valor de la señal analógica que establecemos como límite de la sensibilidad del sensor
int zumb = 10;
int numgolpes = 0; //variable que lleva la cuenta del nº de golpes
int tiempo = 0; //variable que lleva la cuenta del tiempo entre cada par de golpes
int n=0;
int cadenatiempos[] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,}; //cadena en la que se guardarán los tiempos entre golpes
int cadenagolpes[] ={2,3,4,5,6,7,8,9,10,11,12,13,14,15}; //cadena en la que llevamos la cuenta de los golpes
void setup() {
pinMode(led, OUTPUT);
pinMode(zumb, OUTPUT);
beginSerial(9600); //inicia la comunicación con el puerto serie del ordenador y
} //establece la velocidad de transferencia
void guardatiempos(){ //procedimiento que guarda los tiempos entre golpes en una cadena
for (n=0 ;n<14 ;n++){
if (numgolpes ==cadenagolpes[n]){ //compara el valor del contador de golpes con los valores de la cadena
cadenatiempos[n] =tiempo; //para asociar el primer tiempo con 2 golpes, el segundo con 3 golpes y así sucesivamente
} //a través de la posición que ocupan en las cadenas
}
}
void sifinrepro(){ //procedimiento que reproduce, con una se cuencia de pitidos la secuencia de golpes
delay(500); //las tres primeras líneas producen el primer pitido
digitalWrite(zumb, HIGH);
delay(50);
digitalWrite(zumb, LOW);
for(n=0 ;n<(numgolpes-1); n++){ //iteración que produce los pitidos a partir del segundo
delay(cadenatiempos[n]*90); //incorporando los tiempos que se han guardado, el multiplicar por 90 es un ajuste empírico
digitalWrite(zumb, HIGH); //que tiene en cuenta los tiempos que pasan mientras se ejecuta el programa
delay(50);
digitalWrite(zumb, LOW);
} //cuando termina la reproducción:
numgolpes=0; //se reinician las variables para poder comenzar con otra secuencia
tiempo=0;
}
void loop() {
medida = analogRead(piezoSensor); //actualizamos el valor de la señal del sensor
if (medida >= nivel) { //si la señal supera el límite
digitalWrite(led,HIGH); //se enciende el LED
printString("Knock! "); //se envían caracteres por el puerto serie
// printByte(10);
printByte(13);
numgolpes = numgolpes +1; //aumenta en uno el contador de golpes
guardatiempos(); //guardamos el tiempo en su cadena
tiempo = 0; //cada vez que se guarda un tiempo el contador se pone a 0 para empezar a contar el siguiente
delay(100); //espera para no obtener una lectura múltiple de un solo golpe
digitalWrite(led,LOW);
} //si no hay una señal de intensidad suficiente:
delay(100); //espera para no saturar el puerto serie
tiempo = tiempo +1; //aumenta el contador de tiempo
if((numgolpes>0)&&(tiempo >=30)){ //si pasa mucho tiempo después de al menos un golpe:
digitalWrite(led,HIGH); //se considera que se ha terminado y comienza la reproducción
sifinrepro();
digitalWrite(led,LOW);
}
}
Volver?
Copyright (c) 2006 Juan Carlos Alonso de Mena
Permission is granted to copy, distribute and/or modify this document under the terms of
the GNU Free Documentation License, Version 1.2 or any later version published by the
Free Software Foundation; with no Invariant Sections, no Front-Cover Texts, and no
Back-Cover Texts. A copy of the license is included in the section entitled
GNU Free Documentation License?.