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 hardwareNovedades 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?.