El título suena algo provocativo, porque se sabe que el refrán tiene un doble sentido. Pero aquí no se pretende expresamente eso. Queremos presentarle cómo puede obtener tonos de su microcontrolador (AVR). La idea del blog surgió porque aprendí, después de muchos años de trabajo con Raspberrry Pis y los microcontroladores, que hay zumbadores activos y pasivos (buzzers). Hasta ahora, la única vez que aparentemente he acertado en algo ha sido por accidente, cuando mis alumnos han programado y probado pequeños programas, por ejemplo, un juego de reacción, hasta el umbral de dolor de mis oídos.
Hardware utilizado
Alguna |
Micro controlador compatible Arduino (AVR) |
1 |
|
1 |
|
alternativamente |
En este juego de reacción para dos jugadores, el objetivo es pulsar el botón lo más rápido posible cuando el zumbador comienza a sonar después de un tiempo elegido al azar. Ahora lo sé: para esto se necesita un zumbador activo, como los que se encuentran instalados en nuestra lavadora o secadora. El zumbador activo tiene un circuito electrónico resonante incorporado (oscilador), que genera un tono de zumbido cuando se aplica el voltaje de 3,3V o 5V. Debido al diseño hay que prestar atención a la polaridad del zumbador. En el momento de la entrega, estos zumbadores generalmente tienen una pequeña pegatina con el signo más y "Quitar el sello después del lavado". También hay un + en el propio componente. Para reconocer la pierna más larga, tiene que mirar dos veces. O bien, toma una pequeña tabla de conexión como la del kit de sensores de 35 en 1; aquí están los contactos marcados con S (= señal) y - (menos). La tercera conexión (central) no está conectada. Puede probar el zumbador con un simple sketch como Blink, donde (casi) cualquier pin se conmuta en ALTO durante un segundo y en BAJO durante un segundo a la vez con digitalWrite ().
El zumbador pasivo no tiene un oscilador incorporado; por lo tanto, el microcontrolador debe realizar esta función. Si prueba el sketch anterior en un zumbador pasivo, escuchará un suave clic en cada segundo, nada más. Sin embargo, si se acorta extremadamente el tiempo de pausa (delay (1) o delay (2)), puede escuchar un tono cuya frecuencia podemos calcular fácilmente: un milisegundo en cada caso significa ALTO o BAJO (descuidando el tiempo de ejecución de los otros comandos) alrededor de 500 Ciclos de encendido / apagado por segundo, es decir, 500Hz.
Con el siguiente pequeño fragmento de código puede generar un breve tono de advertencia corto en el PIN (previamente definido) para el zumbador:
int var = 0;
while (var < 100) {
// do something repetitive 100 times
digitalWrite(Buzzer, HIGH);
delay(1);
digitalWrite(Buzzer, LOW);
delay(1);
var++;
}
Mejor aun, la producción de tonos funciona con la función tone(), que, sin embargo, sólo puede generar una señal de tono (una frecuencia) en un pin. Las siguientes explicaciones se aplican al zumbador pasivo o también a un pequeño altavoz, que está conectado al PIN correspondiente a través de una resistencia de 100 Ohm.
La sintaxis es:
Tono (Pin, Frecuencia) o
Tono (Pin, Frecuencia, Duración)
Los parámetros utilizados son:
pin: El pin de Arduino en el que se genera el tono.
frecuencia: La frecuencia del tono en Hertz. Tipos de datos permitidos: int sin asignar.
duración: La duración del tono en milisegundos (opcional). Tipos de datos permitidos: long sin asignar.
A menos que se especifique un tercer parámetro para la duración, la frecuencia se emite en el zumbador pasivo (o alternativamente en un pequeño altavoz) hasta que se realice una nueva asignación de frecuencia o se llame a la función noTone (PIN).
Sin embargo, especificar el parámetro de duración, no implica (!) que uno pueda tocar una escala de esta manera. Los siguientes tonos "bajan", sa menos que se añada una pausa adicional con delay () en el sketch. Pero entonces puede omitir la duración cuando toque una melodía. Por lo tanto: utilice duración sólo si se desea reproducir un solo tono (de advertencia) durante un corto periodo de tiempo.
Con respecto a las frecuencias, no nos ahorramos un viaje a la música o física. Las pocas cosas que recuerdo, son el tono de concierto A = 440Hz y la reducción a la mitad o al doble de la la frecuencia por octava. Se recomienda utilizar la notación americana para los nombres de las variables, es decir, A4 = 440Hz, A3 = 220Hz, A5 = 880Hz. Con los números se nombran las respectivas octavas, por ejemplo, en el piano. Desafortunadamente, no siempre hay las frecuencias enteras (como recordatorio: Tipo de datos requerido = INT sin asignar); por lo tanto, la cacofonía es inevitable debido al sistema, pero como sólo se toca una frecuencia a la vez, sigue siendo soportable y la melodía sigue siendo reconocible.
Lo mejor es definir las notas al comienzo del sketch, por ejemplo, para la cuarta octava con el tono de concierto A:
O puede tomar el archivo pitches.h del archivo de la muestra toneKeyBoard, en el que se definen todas las notas desde 31 Hz hasta 4,978 kHz.
Los archivos para el ejemplo están en la carpeta del programa para el Arduino-IDE en los "Ejemplos" de subdirectorio:
Copie este archivo y guárdelo en su carpeta de sketch; luego inclúyalo en el sketch con #include "Pitches.h".
En Internet, había visto un sketch con "todos mis patitos ...", que sonaba fatal porque no se hacían pausas entre las distintas notas; esto en particular es molesto cuando se repite una nota. Así que si quiere escuchar tonos individuales de una melodía como en un piano, debe detener la salida de tono con noTone () y otra pausa después del primer delay (). Ambas pausas juntas determinan la duración de una nota; por lo tanto, uno debe establecer estos valores con una variable, por ejemplo, para el número de milisegundos de una negra.
En el siguiente sketch, he empeorado "todos mis patitos ..." estableciendo la duración del tono audible con int DELAY= 400; y de la pausa con int PAUSE = 100;.Así, la duración de una negra es de 500 ms. Como se ha descrito anteriormente, puse el archivo pitches.h en la carpeta de sketchs.
/* Alle meine Entchen ... einmal abgespielt
* Die Datei pitches.h muss sich im gleichen Dateiordner befinden
*/
int DELAY = 400;
int PAUSE = 100;
void setup() {
tone(7, NOTE_C5);
delay(DELAY);
noTone(7);
delay(PAUSE);
tone(7, NOTE_D5);
delay(DELAY);
noTone(7);
delay(PAUSE);
tone(7, NOTE_E5);
delay(DELAY);
noTone(7);
delay(PAUSE);
tone(7, NOTE_F5);
delay(DELAY);
noTone(7);
delay(PAUSE);
tone(7, NOTE_G5);
delay(2*DELAY);
noTone(7);
delay(2*PAUSE);
tone(7, NOTE_G5);
delay(2*DELAY);
noTone(7);
delay(2*PAUSE);
tone(7, NOTE_A5);
delay(DELAY);
noTone(7);
delay(PAUSE);
tone(7, NOTE_A5);
delay(DELAY);
noTone(7);
delay(PAUSE);
tone(7, NOTE_A5);
delay(DELAY);
noTone(7);
delay(PAUSE);
tone(7, NOTE_A5);
delay(DELAY);
noTone(7);
delay(PAUSE);
tone(7, NOTE_G5);
delay(2*DELAY);
noTone(7);
delay(2*PAUSE);
tone(7, NOTE_A5);
delay(DELAY);
noTone(7);
delay(PAUSE);
tone(7, NOTE_A5);
delay(DELAY);
noTone(7);
delay(PAUSE);
tone(7, NOTE_A5);
delay(DELAY);
noTone(7);
delay(PAUSE);
tone(7, NOTE_A5);
delay(DELAY);
noTone(7);
delay(PAUSE);
tone(7, NOTE_G5);
delay(2*DELAY);
noTone(7);
delay(2*PAUSE);
tone(7, NOTE_F5);
delay(DELAY);
noTone(7);
delay(PAUSE);
tone(7, NOTE_F5);
delay(DELAY);
noTone(7);
delay(PAUSE);
tone(7, NOTE_F5);
delay(DELAY);
noTone(7);
delay(PAUSE);
tone(7, NOTE_F5);
delay(DELAY);
noTone(7);
delay(PAUSE);
tone(7, NOTE_E5);
delay(2*DELAY);
noTone(7);
delay(2*PAUSE);
tone(7, NOTE_E5);
delay(2*DELAY);
noTone(7);
delay(2*PAUSE);
tone(7, NOTE_G5);
delay(DELAY);
noTone(7);
delay(PAUSE);
tone(7, NOTE_G5);
delay(DELAY);
noTone(7);
delay(PAUSE);
tone(7, NOTE_G5);
delay(DELAY);
noTone(7);
delay(PAUSE);
tone(7, NOTE_G5);
delay(DELAY);
noTone(7);
delay(PAUSE);
tone(7, NOTE_C5);
delay(2*DELAY);
noTone(7);
}
void loop() {
//keine zu wiederholende Aktion
}
Como puede ver, no es una obra maestra del arte de la programación. Pero ciertamente es bueno utilizarlo si desea similar una sirena de dos tonos como en un vehículo de emergencia.
Para melodías más largas, el enfoque de dos matrices es más adecuado, como se describe en nuestro libro electrónico. Aquí hay un enlace a la melodía publicada en Internet que está vinculada a los Piratas del Caribe:
https://github.com/xitangg/-Pirates-of-the-Caribbean-Theme-Song
En la primera matriz int notes [] se enumeran las notas, en el segundo int durations [] la duración del tono respectivo. Al igual que con otros ejemplos, la melodía se reproduce solo una vez, por lo que el código del programa para la ejecución está en el void setup (); el void loop () se deja vacío.
Aquí están las explicaciones del boceto:
Para repetir el bucle para todas las notas, el primero paso es obtener el número de notas totalNotes con la función sizeof(). Dado que esta función devuelve el número de bytes de la matriz, todavía hay que dividirlo por el número de bytes entero, es decir, para 2.
Los valores respectivos de las matrices se almacenan temporalmente en las variables currentNote y wait. En las pausas, marcadas con 0, en la matriz, se llama a la función noTone().
Aquí sólo la sección void setup() del sketch:
void setup()
{
const int totalNotes = sizeof(notes) / sizeof(int);
// Loop through each note
for (int i = 0; i < totalNotes; i++)
{
const int currentNote = notes[i];
float wait = durations[i] / songSpeed;
// Play tone if currentNote is not 0 frequency, otherwise pause (noTone)
if (currentNote != 0)
{
tone(buzzer, notes[i], wait); // tone(pin, frequency, duration)
}
else
{
noTone(buzzer);
}
// delay is used to wait for tone to finish playing before moving to next loop
delay(wait);
}
}
Existen otras librerías de programas para las placas de microcontroladores ATMEGA328P / ATMEGA16U2 (AVR) para emitir tonos, por ejemplo, para emitir dos tonos al mismo tiempo en pines diferentes. Pero estos son a veces muy complejos y, tan aleccionadores como resultado de la simple salida de tonos con tone(). Nuestro versátil microcontrolador es adecuado para muchas aplicaciones, pero ciertamente no para un sintetizador.
Juego de reacción GPIO Zero para Raspberry Pi
Aquí, lo vinculo a un pequeño juego para la Raspberry Pi, para la cual, utiliza pulsadores y LEDs (junto con resistencias), además del zumbador. Puede encontrar más descripción en el código fuente.
Descargar gpiozero_reactiongame_nochenating.py
Conclusión
Si quiere emitir un tono de aviso corto, debe usar un zumbador activo, que esté encendido y apagado como un LED (o en paralelo). Se debe prestar atención a la polaridad.
Si desea programar una sirena de dos tonos (que se escucha más claramente) o una melodía corta de reconocimiento (jingle), debe utilizar el zumbador pasivo o un pequeño altavoz.