contenidos adicionales del libro taller de arduino
TRANSCRIPT
CONTENIDOS ADICIONALES DEL LIBRO
TALLER DE ARDUINO EXPERIMENTANDO CON ARDUINO MKR 1010
2.a edición
Germán Tojeiro Calaza J. Gerardo Reino
Contenido adicional del libro: Taller de Arduino
Segunda edición, 2021
© 2021 Germán Tojeiro Calaza y Gerardo Reino Bértoa
© 2021 MARCOMBO, S. L. www.marcombo.com
«Cualquier forma de reproducción, distribución, comunicación publica o transformación de esta obra solo puede ser realizada con la autorización de sus titulares, salvo excepción prevista por la ley. Diríjase a CEDRO (Centro Español de Derechos Reprográficos, www.cedro.org) si necesita fotocopiar o escanear algún fragmento de esta obra».
ISBN: 978-84-267-2616-2 D.L.: B 19469-2020
Índice
13. Arduino MKR ZERO .................................................................................................................... 4
13.1 Características de Arduino MKR ZERO ................................................................................ 5
13.2 Comenzar a programar ....................................................................................................... 9
13.3 Registrar datos en una tarjeta micro-SD con RTC ............................................................ 11
Práctica 13.1 Registro de datos de un sensor DHT de humedad y temperatura ........... 13
13.4 Conceptos básicos del sonido ........................................................................................... 17
13.5 Reproducir sonido con MKR ZERO .................................................................................... 18
Práctica 13.2 Reproducir un tono con un altavoz .......................................................... 20
13.6 Reproducir melodías con MKR ZERO ................................................................................ 20
Práctica 13.3 Reproducir la “Marcha Imperial” de Star Wars ........................................ 21
13.7 Reproducir archivos de audio con MKR ZERO .................................................................. 23
Práctica 13.4 Reproductor simple de audio ................................................................... 25
13.8 Reproducir audios con el protocolo I2S ....................................................................... 26
Práctica 13.5 Reproductor de audio I2S con control de volumen .................................. 28
4
CAPÍTULO 13
Arduino MKR ZERO
Figura 13.1
MKR ZERO es una placa que permite implementar la función de audio en sus proyectos (figura 13.1).
Es una placa MKR sin conectividad incorporada, la más pequeña de las placas de la familia MKR, pero
dispone de un conector SD integrado con interfaces SPI dedicadas (SPI1) que permite guardar
información en ella, capturas de información de los sensores, registros de información e, incluso,
archivos de audio. Es decir, archivos de cualquier formato. Pero lo fantástico de esta placa es la
posibilidad de reproducir audio, en formato específico por ahora, pero posible. Imagínese un proyecto
que responda con sonidos complejos, mensajes de advertencia o con cualquier otra información
audible, y sin necesidad de hardware extra, aunque sí necesitará un altavoz.
Para el uso de los audios en esta placa se han creado dos librerías disponibles desde el mismo Arduino
IDE:
Biblioteca Arduino Sound: una forma sencilla de reproducir y analizar datos de audio con Arduino en
placas basadas en SAM D21.
Biblioteca I2S: para utilizar el protocolo I2S en placas basadas en SAMD21. Para aquellos que no saben,
I2S (Inter-IC Sound) es un estándar de interfaz de bus serie eléctrico para conectar dispositivos de
audio digital.
A continuación, se enumeran sus características principales.
Taller de Arduino
5
13.1 Características de Arduino MKR ZERO
La placa funciona con la MCU SAMD21 de Atmel, que cuenta con un núcleo ARM Cortex® M0 + de 32
bits. También funciona a 3.3 V. Así, el voltaje máximo que los pines de entrada/salida pueden tolerar
es 3.3 V. Y el uso de voltajes superiores podría dañar la placa. Contiene todo lo necesario para soportar
el microcontrolador; simplemente debe conectarlo a un ordenador con un cable micro-USB o
encenderlo con una batería Li-Po. El voltaje de la batería también se puede controlar, ya que existe
una conexión entre la batería y el convertidor analógico de la placa (figura 13.2).
Figura 13.2
Características técnicas de Arduino MKR ZERO (figura 13.3):
Microcontrolador: SAMD21 Cortex-M0+ ARM MCU de 32 bits
Alimentación de la placa (USB/Vin) 5 V
Batería soportada: Li-Po, 3.7 V, 700 mAh mínimo
DC para el pin 3.3 V: 600 mA
DC para el pin 5 V: 600 mA
Voltaje interno: 3.3 V
Pines digitales entrada/salida: 22
Pines PWM: 12 (0, 1, 2, 3, 4, 5, 6, 7, 8, 10, A3 – o 18 -, A4 -o 19)
UART: 1
SPI: 1
I2C: 1
Pines de entrada analógica: 7 (ADC 8/10/12 bit)
Pines de salida analógica: 1 (DAC 10 bit)
Interrupciones externas: 8 (0, 1, 4, 5, 6, 7, 8, A1 -o 16-, A2 – o 17)
DC para los pines de entrada/salida: 7 mA
Memoria flash: 256 KB
Memoria flash del bootloader: 8 KB
SRAM 32 KB
EEPROM: no
Reloj: 32.768 kHz (RTC), 48 MHz
LED_BUILTIN: 32
Dispositivo USB Device y host integrado
Arduino MKR ZERO
6
Figura 13.3
SD integrada
Entre las características de esta placa cabe destacar su SD, integrada en placa. Este conector permite
utilizar micro-SD con archivos, crear y utilizar archivos de diferentes formatos según la naturaleza del
proyecto o previamente cargarlos, sin agregar ningún hardware adicional a la placa.
Además, la tarjeta SD es impulsada por una interfaz SPI dedicada (SPI1) y, por lo tanto, cualquiera de
los pines del encabezado está ocupado durante el uso de SD.
Conexión de una batería externa
El MKR ZERO posee un conector tipo JST macho de 2 pines para la conexión de una batería externa. Si
desea conectarla asegúrese de buscar una con conector hembra tipo JST PHR2 de 2 pines. Polaridad:
al mirar las clavijas del conector de la placa, la polaridad es izquierda = positiva, derecha = GND.
Capacidad de la batería
Las baterías Li-Po se cargan hasta 4.2 V con una corriente que generalmente es la mitad de la capacidad
nominal (C/2). Arduino MKR ZERO utiliza un chip especializado que tiene una corriente de carga
preestablecida de 350 mAh. Esto significa que la capacidad mínima de la batería Li-Po debe ser, por lo
menos, de 700 mAh. Las baterías más pequeñas se dañarán por esta corriente y podrían
sobrecalentarse, desarrollar gases internos y explotar, incendiando los alrededores. Así que
recomiendo encarecidamente que seleccione una batería de Li-Po de al menos 700 mAh de capacidad.
Una batería más grande tardará más en cargarse, pero no se dañará ni se sobrecalentará. El chip se
programa con 4 horas de tiempo de carga, luego pasa al modo de reposo automático. Esto limitará la
cantidad de carga a un máximo de 1400 mAh por ronda de carga.
Puerto I2C adicional
El MKR ZERO tiene un conector adicional destinado como una extensión del bus I2C. Es un pequeño
conector de 5 pines que incluye SDA y SCL y, además, los de alimentación GND y +5 V y un pin digital
que puede ser útil para diseñar una expansión.
Taller de Arduino
7
El pinout se muestra en la figura 13.4.
Figura 13.4
El conector sugerido en la imagen para este puerto I2C adicional es el SHR-05V-S-B.
Vin
Este pin se puede usar para alimentar la placa con una fuente regulada de 5 V. Si la alimentación se
alimenta a través de este pin, la fuente de alimentación USB se desconecta. Esta es la única forma en
que puede suministrar 5 V (el rango es de 5 V a un máximo de 6 V) a la placa que no usa USB. Este pin
es una entrada.
5 V
Este pin emite 5 V desde la placa cuando se alimenta desde el conector USB o desde el pin Vin de la
placa. No está regulado y el voltaje se toma directamente de las entradas. Como salida, no debe usarse
como un pin de entrada para alimentar la placa.
VCC
Este pin emite 3.3 V a través del regulador de voltaje incorporado. Este voltaje es el mismo
independientemente de la fuente de alimentación utilizada (USB, Vin y batería).
Led de encendido
Este led está conectado a la entrada de 5 V desde USB o Vin. No está conectado a la batería. Esto
significa que se enciende cuando la alimentación proviene de USB o Vin, pero permanece apagada
Arduino MKR ZERO
8
cuando la placa funciona con batería. Esto maximiza el uso de la energía almacenada en la batería. Por
lo tanto, es normal que la placa funcione correctamente con la batería sin que se encienda el led.
Led de carga
El led de carga en la placa es controlado por un chip integrado que monitoriza la corriente consumida
por la batería Li-Po mientras se carga. Por lo general, se iluminará cuando la placa reciba 5 V de Vin o
USB y el chip comience a cargar la batería Li-Po conectada al conector JST. Hay varias ocasiones en las
que este led comenzará a parpadear a una frecuencia de aproximadamente 2 Hz. Este parpadeo se
debe a las siguientes condiciones mantenidas durante mucho tiempo (de 20 a 70 minutos):
- No hay batería conectada al conector JST.
- La batería descargada/dañada está conectada. No se puede recargar.
- Una batería completamente cargada pasa por otro ciclo de carga innecesario. Esto se hace
desconectando y volviendo a conectar Vin o la batería mientras Vin está conectado.
Led integrado
En MKR ZERO, el led integrado está conectado a un pin dedicado (32) y no a 13 como en otras placas.
Se sugiere utilizar la definición LED_BUILTIN.
Nota: No conecte al conector JST macho presente en la placa una batería que no sea Li-Po, cuyas
características han de cumplir las indicadas anteriormente. No alimente Vin con más de 5 V.
Taller de Arduino
9
13.2 Comenzar a programar
Antes de comenzar a programar su placa con el ya conocido Arduino IDE va a necesitar instalar los
drivers correspondientes desde el gestor de tarjetas. Si ya ha trabajado con el MKR 1010 en las
prácticas anteriores, seguro que ya los tiene instalado. De lo contrario, tan solo debe buscar e instalar
el paquete “Arduino SAMD Boards (32-bits ARM Cortex-M0+) by Arduino”. Este no solo tiene los
drivers correspondientes al MKR ZERO, sino también el del resto de la familia MKR.
Tenga en cuenta también que necesitará ir al gestor de librerías para instalar otro driver
complementario que permitirá utilizar los archivos instalados en la SD para luego hacer varias tareas
como la reproducción de archivos de audio, por ejemplo.
Así que buscará la librería Audio by Arduino para utilizar la SD (figura 13.5).
Figura 13.5
Y la librería RTCZero by Arduino que permite utilizar las funciones RTC para programar acciones
relacionadas con la fecha y la hora (figura 13.6).
Arduino MKR ZERO
10
Figura 13.6
Una vez instaladas las librerías, ya puede seleccionar la placa dentro del listado de placas disponibles
del software de programación y seleccionar el puerto de conexión (figura 13.7).
Figura 13.7
Ahora que ha configurado su placa MKR ZERO, puede iniciar su primera práctica. Para ello, se van a
aprovechar los componentes más destacables de la placa.
Taller de Arduino
11
13.3 Registrar datos en una tarjeta micro-SD con RTC
RTC es un acrónimo de real time clock. Es un reloj en tiempo real incluido en un circuito integrado que
mantiene la hora, y está presente en la mayoría de los aparatos electrónicos que necesitan guardar el
tiempo exacto.
El RTC integrado con el que cuenta su placa junto con el conector SD son su primer reto. Para ello va a
realizar una lectura periódica de un sensor de temperatura y humedad DHT11 y guardar toda esa
información dentro de una micro-SD.
El sensor DHT11 permite realizar la medición simultánea de temperatura y humedad. Dispone de un
procesador interno que lleva a cabo el proceso de medición, proporcionando dicha medición a través
de una señal digital, por lo que resulta muy sencillo obtener la medición desde un microprocesador
como un Arduino. Es un sensor muy limitado, que puede usar con fines de formación, pruebas o en
proyectos que realmente no requieran una medición precisa. Sus características son escasas,
especialmente en los rangos de medición y precisión:
Medición de temperatura entre 0o a 50o, con una precisión de 2 oC
Medición de humedad entre 20 a 80 %, con una precisión del 5 %
Frecuencia de muestreo de 1 muestra por segundo (1 Hz)
Es el modelo inferior de otro más preciso llamado DHT22, pero como contraprestación es realmente
barato; puede encontrarlo por menos de 1 € en webs muy conocidas. Su encapsulado y esquema de
montaje se detalla en la figura 13.8.
Figura 13.8
El sensor DHT11 puede recibir una alimentación de 3.3 V a 6 V y conectarlo es sencillo; simplemente,
alimente desde Arduino al sensor a través de los pines GND y VCC del mismo. Por otro lado, conecte
la salida de datos a una entrada digital de Arduino MKR. No es su caso, pero normalmente el
encapsulado no está tan completo y necesitaría una resistencia de 10 K entre VCC y el pin de datos.
Por lo demás, debe saber que este sensor dispone de una librería propia para facilitar su control y
programación desde Arduino IDE. Esta siempre ha sido una de las librerías más difíciles de instalar, ya
Arduino MKR ZERO
12
que si no utiliza la original de Adafruit, podría estar horas probando diversas librerías disponibles en
Internet y nunca encontrar la adecuada.
Yo aconsejo instalar la DHT sensor library by Adafruit (figura 13.9).
Figura 13.9
Y también la librería EduIntro by Arduino LLC (figura 13.10).
Figura 13.10
Taller de Arduino
13
A partir de aquí, ya dispone de la información necesaria y tiene claro qué quiere hacer. Así que
programará su lectura en los intervalos que precise gracias al RTC, y estos datos se recopilarán en un
archivo de texto y guardados dentro de la tarjeta micro-SD.
La conexión del DHT11 con su placa se hará mediante el pin de transmisión de datos, por ejemplo, al
pin 7, como se muestra en la figura 13.11. Y le proporcionará, además, alimentación mediante los pines
VCC (alimentación 3.3 V) y GND (conexión a tierra).
Figura 13.11
Una vez todo en regla comenzará con la programación del código.
Práctica 13.1 Registro de datos de un sensor DHT de humedad y temperatura
/*
Registro en SD de un sensor de temperatura y humedad,
y tiempo usando el RTC interno de un MKR ZERO.
Piezas requeridas:
1 sensor de temperatura y humedad DHT11
1 placa MKR ZERO
1 tarjeta micro-SD
*/
#include <SD.h>
#include <RTCZero.h>
#include <DHT.h>
Arduino MKR ZERO
14
#define DHTPIN 7
#define DHTTYPE DHT11
DHT dht(DHTPIN, DHTTYPE);
const int chipSelect = SS1;
unsigned long previousTime;
int loadDataCheck; //Comprueba si los datos necesitan ser cargados
RTCZero rtc;
/* Cambiar estos valores para establecer la hora actual */
const byte seconds = 00;
const byte minutes = 00;
const byte hours = 00;
/* Cambiar estos valores para establecer la fecha actual */
const byte day = 29;
const byte month = 08;
const byte year = 20;
void setup()
//Inicializa el pin digital LED_BUILTIN como salida
pinMode(LED_BUILTIN, OUTPUT);
// comprueba si la tarjeta está presente y puede ser inicializada:
if (!SD.begin(chipSelect))
// no hacer nada más:
return;
//Cuando se suministra energía al sensor, se espera un tiempo
//y pasa a estado inestable
delay(1000);
dht.begin();
rtc.begin();
rtc.setTime(hours, minutes, seconds);
rtc.setDate(day, month, year);
rtc.setAlarmTime(0, 0, 0);
rtc.enableAlarm(rtc.MATCH_SS); //alarma añadida cada minuto
rtc.attachInterrupt(dataCheck);
loadDataCheck=0;
Taller de Arduino
15
previousTime=millis();
void loop()
unsigned long currentTime=millis();
if ((currentTime-previousTime)>5000)
digitalWrite(LED_BUILTIN, HIGH); //led que nos muestra cuándo
delay(100); //se almacenan datos en la SD
digitalWrite(LED_BUILTIN, LOW);
previousTime=millis();
if (loadDataCheck) logData();
void dataCheck()
loadDataCheck=1;
void logData(void)
float humidity = dht.readHumidity();
float temperature = dht.readTemperature();
String dataString = "";
dataString += "Temperatura: " + String(temperature) + "
C" + "\t" + "Humedad: " + String(humidity) + "%\t" + "Hora: " + getTime();
// abre el archivo, pero solo uno a la vez,
// por eso debe cerrar este antes de abrir otro.
File dataFile = SD.open("registro.txt", FILE_WRITE);
// si el archivo está disponible se guardan los datos
if (dataFile)
dataFile.println(dataString);
dataFile.close();
loadDataCheck=0;
String getTime(void)
String returnString = "";
if (rtc.getHours() < 10)
returnString += "0" + String(rtc.getHours());
else
returnString += String(rtc.getHours());
returnString += ":";
Arduino MKR ZERO
16
if (rtc.getMinutes() < 10)
returnString += "0" + String(rtc.getMinutes());
else
returnString += String(rtc.getMinutes());
returnString += ":";
if (rtc.getSeconds() < 10)
returnString += "0" + String(rtc.getSeconds());
else
returnString += String(rtc.getSeconds());
return returnString;
En cuanto al código del sketch, es preferible comenzar por el RTC. El reloj en tiempo real es un reloj
que realiza un seguimiento de la hora actual y que se puede utilizar para programar acciones en un
momento determinado, pero cada vez que se enciende la placa el RTC se reinicia y comienza desde
una fecha estándar. Para mantener el tiempo y el RTC en funcionamiento es necesario mantener la
placa encendida y, por ello, es aconsejable el uso de una batería Li-Po para evitar el apagado accidental.
Después de haber definido la variable rtc al inicio, se ha iniciado su funcionamiento con la orden
“rtc.begin()”. Y en el código se debe, por lo tanto, configurar esa hora y fecha estándar desde la que se
iniciará la cuenta en tiempo real.
RTCZero rtc;
const byte seconds = 00;
const byte minutes = 00;
const byte hours = 00;
const byte day = 29;
const byte month = 08;
const byte year = 20;
Para leer la temperatura y la humedad se inicia el sensor con la orden “dht.begin()” y, a continuación,
las funciones dht.readHumidity() y dht.readTemperature() son las que obtienen el valor de cada una
de ellas. Si no cambia ningún parámetro le dará la temperatura en grados centígrados y no en grados
Fahrenheit.
Y, por último, dispone de la SD. Está conectada a una interfaz SPI dedicada y la biblioteca SD se ocupa
de ella, por lo que no es necesario especificar ningún pin de conexión. Usaremos “SD.begin()” y,
automáticamente, será accesible. En nuestra programación se comprobará si la tarjeta está presente
o no, y permitirá más adelante escribir en ella con “SD.open("registro.txt", FILE_WRITE)” el archivo y
los datos que ha definido.
Taller de Arduino
17
Los datos que en ella se guardan dependerán del “void dataCheck” y del “void logData(void)” que
comprobarán si los datos recogidos necesitan ser cargados, si el archivo de registro existe o hay que
crearlo y abrirlo para su edición. Aquí se establecen los datos que desea capturar y escribir en el archivo
TXT. En su caso, se ha configurado que guarde temperatura, humedad y hora cada minuto que avanza
el reloj, por lo que el resultado de su programación será el siguiente:
Figura 13.12
Como se muestra en la figura 13.12, el archivo generado a partir de su código ha empezado a tomar
valores cada minuto. Así, su primer intento de toma de datos con una alimentación Li-Po de 3.7 V y
1800 mAh ha estado tomando datos durante, aproximadamente, 70 horas. Un tiempo que dependerá
siempre del consumo de su placa y de la autonomía de la batería.
13.4 Conceptos básicos del sonido
El sonido se crea por vibraciones en el aire. Cuando esas vibraciones se vuelven lo suficientemente
rápidas, aproximadamente más de 20 veces por segundo, las escucha como un tono. El número de
vibraciones por segundo se llama frecuencia y la frecuencia se mide en hercios (Hz). Entonces, 20 veces
por segundo equivale a 20 Hz. Los humanos pueden escuchar tonos de aproximadamente 20 Hz a
aproximadamente 20 000 Hz, o 20 kilohercios (kHz).
¿De qué vibraciones estamos hablando? Un altavoz puede vibrar. El cono de papel del altavoz se
mueve hacia delante, luego hacia atrás, y luego hacia su lugar de descanso muchas veces por segundo.
El tiempo que lleva moverse de su lugar de descanso a un extremo, luego al otro, y luego a su lugar de
descanso nuevamente se llama la longitud de onda de la vibración. A veces también se llama periodo.
Por ejemplo, si un altavoz está vibrando a 20 Hz, entonces se mueve hacia delante, hacia atrás y hacia
atrás para descansar en 1/20 de segundo, o 0.05 segundos. 0.05 segundos es el periodo, o la longitud
de onda, del sonido que está escuchando. En la figura 13.13 se muestra el altavoz que vibra y un gráfico
del movimiento del altavoz. Este gráfico es una onda sinusoidal.
Arduino MKR ZERO
18
Figura 13.13
Cuando un altavoz vibra en el aire, se mueve hacia delante y hacia atrás en un patrón de onda
sinusoidal. El tiempo que lleva moverse del reposo a su posición de avance a su posición de retroceso
y de regreso al reposo se denomina longitud de onda o periodo de la onda.
Por ejemplo, un ordenador personal emite sonido enviando pulsos de energía eléctrica a través de un
cable conectado al cono de papel de un altavoz. Ese cable está envuelto en una bobina y montado
dentro de un imán. La energía eléctrica genera un campo magnético, y ese campo es atraído por el
imán o repelido por él, dependiendo de en qué dirección fluya la energía eléctrica. La energía
magnética mueve la bobina y, dado que la bobina está unida al cono, el altavoz se mueve.
Así, los ordenadores producen sonido usando señales eléctricas. El procesador central de un
ordenador tiene pines de entrada y salida que pueden generar nuestros cambios de lectura en el
voltaje eléctrico. Para aprender sobre esto, es útil usar un ordenador simple donde pueda conectar los
cables al procesador directamente. Ahí es donde entran los módulos Arduino.
Los módulos Arduino son ordenadores simples llamados microcontroladores. Tienen pines de entrada
y salida, y se puede usar uno de esos pines para hacer vibrar un altavoz. Para comenzar a hacer eso se
enumera a continuación una serie de ejemplos diferentes que espero que sean de su interés.
13.5 Reproducir sonido con MKR ZERO
Como se ha dicho al principio, el MKR ZERO es una placa pensada para implementar audio en sus
proyectos. Pero la música se puede implementar en cualquier modelo de Arduino, desde el más básico.
Por supuesto no hablamos de formatos complejos, sino de sonidos sueltos.
Crear música es relativamente fácil y suele ser una actividad muy interesante para quienes están
empezando a familiarizarse con la programación.
Con cualquier Arduino se pueden crear sonidos gracias a la función tone, cuya sintaxis es:
tone (pinsalida, frecuencia);
Esta función intercambia valores HIGH/LOW a la frecuencia elegida en el pin que ha seleccionado,
hasta que la vuelve a llamar con otra frecuencia o le ordena que pare.
Taller de Arduino
19
noTone(pinsalida)
Tan simple como esto. Así que a continuación se describe cómo hacer sonido con MKR ZERO.
En principio tan solo va a necesitar un zumbador piezoeléctrico como el que ha visto en el capítulo 3.
Este consigue generar un sonido al vibrar en la frecuencia de la señal eléctrica que recibe. El valor en
frecuencia de la señal determinará el tono en el que suene y será un sonido de muy poca calidad, pero
se va a poder generar notas y, con ello, música.
Pero, aunque es lo más lógico e ideal, voy a utilizar en la siguiente práctica el pequeño altavoz reciclado
de una radio. Así verá la ventaja de poder reutilizar componentes en desuso y darles una segunda vida.
Mi altavoz es de 4 Ω, por lo que voy a protegerlo con una resistencia 100 Ω (figura 13.14).
Figura 13.14
Y como ya sabe, puede alimentar la placa por USB, con una batería Li-Po o a través del pin VCC.
Nota: También puede usar auriculares, si lo desea. Para ello, conecte una resistencia de 10 K en el pin
5 que va a las entrada izquierda o derecha de su conector de audio (jack, minijack, etc.), generalmente
es uno de los extremos. Y el conector del medio de jack de audio, al bus de tierra.
Pero primero se detallará el código.
Como se ha explicado antes, la función tone es la única que interviene en este ejercicio. Ninguna
librería es necesaria, pues en este ejemplo no intervienen.
Arduino MKR ZERO
20
Práctica 13.2 Reproducir un tono con un altavoz
void setup()
pinMode(5, OUTPUT); // pin 5 como pin de salida
void loop()
tone(5, 440); // se elige la frecuencia de 440 Hz
delay(500);
noTone(5); // se apaga el altavoz
delay(500);
Como ve, tan solo se ha elegido el pin 5 como pin de comunicación con el altavoz, configurado como
salida y reproduciendo a intervalos de medio segundo (500 ms) una señal de 440 Hz.
Ya ve que es sencillo. Ahora solo debe invertir tiempo e imaginación y podrá reproducir melodías.
13.6 Reproducir melodías con MKR ZERO
Una vez que se comprenden cómo funciona y cómo se generan los sonidos con tone, se pueden realizar
proyectos más complejos. Por supuesto necesitará un mayor grado de conocimiento musical, distinguir
las notas o saber cuáles son las frecuencias de cada una.
Por suerte, Internet está lleno de ejemplos y he podido encontrar melodías configuradas para seguir
con la práctica.
Así que he elegido reproducir la melodía más famosa de Star Wars. No es muy larga, pero al entrar en
bucle se hace eterna y es perfecta para disfrutar del resultado.
Utilizando la función tone he definido:
void tono(int frecuencia, int duración)
para definir la ejecución de cada tono.
Lo difícil aquí es saber las notas musicales, su frecuencia y duración, pero seguro podrá encontrar miles
de canciones con esta información.
Taller de Arduino
21
Práctica 13.3 Reproducir la “Marcha Imperial” de Star Wars
int contador = 0;
void setup()
pinMode(5, OUTPUT); // Pin digital 5 como salida
void loop()
tono(440.00, 500);
tono(440.00, 500);
tono(440.00, 500);
tono(349.23, 350);
tono(523.25, 150);
tono(440.00, 500);
tono(349.23, 350);
tono(523.25, 150);
tono(440.00, 650);
delay(500);
tono(659.26, 500);
tono(659.26, 500);
tono(659.26, 500);
tono(698.46, 350);
tono(523.25, 150);
tono(415.30, 500);
tono(349.23, 350);
tono(523.25, 150);
tono(440.00, 650);
delay(500);
tono(880.00, 500);
tono(440.00, 300);
tono(440.00, 150);
tono(880.00, 500);
tono(830.61, 325);
tono(783.99, 175);
tono(739.99, 125);
tono(698.46, 125);
tono(739.99, 250);
delay(325);
Arduino MKR ZERO
22
tono(440.00, 250);
tono(622.25, 500);
tono(587.33, 325);
tono(554.37, 175);
tono(523.25, 125);
tono(466.16, 125);
tono(523.25, 250);
delay(350);
// Variante 1
tono(349.23, 250);
tono(415.30, 500);
tono(349.23, 350);
tono(440.00, 125);
tono(523.25, 500);
tono(440.00, 375);
tono(523.25, 125);
tono(659.26, 650);
delay(500);
tono(880.00, 500);
tono(440.00, 300);
tono(440.00, 150);
tono(880.00, 500);
tono(830.61, 325);
tono(783.99, 175);
tono(739.99, 125);
tono(698.46, 125);
tono(739.99, 250);
delay(325);
tono(440.00, 250);
tono(622.25, 500);
tono(587.33, 325);
tono(554.37, 175);
tono(523.25, 125);
tono(466.16, 125);
tono(523.25, 250);
delay(350);
tono(349.23, 250);
tono(415.30, 500);
tono(349.23, 375);
tono(523.25, 125);
Taller de Arduino
23
tono(440.00, 500);
tono(349.23, 375);
tono(523.25, 125);
tono(440.00, 650);
delay(650);
void tono(int frecuencia, int duracion) // Función que ejecuta cada tono
tone(5, frecuencia, duracion); // Suena el tono en el altavoz
if(contador % 2 == 0)
delay(duracion);
else
delay(duracion);
delay(50); // Para de sonar el tono en el altavoz
contador++; // Se incrementa el contador
El resultado es un código que podrá usar con cualquier placa Arduino, sin necesidad de librerías,
utilizando además un buzzer o un altavoz
13.7 Reproducir archivos de audio con MKR ZERO
Y, por supuesto, quedaba comprobar la reproducción de un archivo de audio.
Así, en esta práctica, el objetivo es reproducir un archivo WAV almacenado en la tarjeta micro-SD y,
para ello, necesitará tener instalada la nueva librería Audio by Arduino que ya ha visto al inicio de este
capítulo y usará también el convertidor digital analógico del pin DAC de 10 bits.
La prueba simple sería conectar un par de auriculares directamente a tierra y DAC0, respetando la
polaridad. Voy a mostrarles cómo construir un amplificador de audio externo para un altavoz de 8
ohmios.
Componentes para construir un amplificador de audio externo:
LM386 (amplificador de audio de baja potencia)
Potenciómetro de 10 kΩ
Resistencia de 10 Ω
2 condensadores de 10 µF
Condensador de 0.05 µF (o también 0.01 µF)
Condensador de 250 µF
Arduino MKR ZERO
24
Para conectar el altavoz a la placa se debe agregar un circuito de amplificación conectado entre el pin
DAC y el altavoz. El circuito de amplificación aumentará el volumen del altavoz. Hay muchos
amplificadores de audio disponibles, y uno de los más comunes es el LM36.
El siguiente esquema (figura 13.15) muestra cómo construir el circuito usando el LM386 y un montón
de componentes. Se le puede suministrar alimentación al LM386 a través del pin Vs desde diferentes
fuentes de voltaje, como los +5 V que proporciona el pin 5 V del MKR ZERO, o una batería externa de
9 V. La ganancia del amplificador viene dada por el condensador conectado a los pines 1 y 8 del LM386.
Con el condensador de 10 µF la ganancia se establece en 200. Sin el condensador la ganancia sería solo
de 50. Y con el potenciómetro se puede controlar el volumen del amplificador.
Figura 13.15
A partir de él se podrá llegar al siguiente esquema de Fritzing (figura 13.16).
Figura 13.16
Taller de Arduino
25
Ahora solo queda almacenar un archivo de audio en la tarjeta micro-SD en formato .wav con 88 200
Hz, calidad mono de 8-bit. Este tipo de audios pueden obtenerse fácilmente con software de audio con
Audacity.
Práctica 13.4 Reproductor simple de audio
#include <SD.h>
#include <SPI.h>
#include <AudioZero.h>
void setup()
Serial.begin(115200);
Serial.print("Iniciando SD card...");
if (!SD.begin(4))
Serial.println(" error!");
while(true);
Serial.println(" hecho.");
// 44100kHz stereo => 88200 sample rate
AudioZero.begin(2*44100);
void loop()
int count = 0;
// abriendo el archivo de audio desde la micro-SD
File myFile = SD.open("test.wav");
if (!myFile)
// si no se abre el archivo de audio, aparecerá mensaje de error
Serial.println("error abriendo test.wav");
while (true);
Serial.print("Reproduciendo");
// hasta que el audio no finalice
AudioZero.play(myFile);
Serial.println("Final del audio. Gracias por escucharlo!");
while (true);
Arduino MKR ZERO
26
13.8 Reproducir audios con el protocolo I2S
I2S, conocido también como Inter-IC Sound, es un protocolo de reproducción de archivos de sonido
digital que se usa para transmitir audio digital desde un dispositivo a otro. Transfiere datos de audio
modulados por código de pulso (CPM), el estándar para audio digital, desde un circuito integrado (IC)
a otro. Es un estándar desarrollado por Philips en las décadas de 1980 y 1990.
I2S se puede utilizar para enviar archivos de audio pregrabados desde un microcontrolador a un
amplificador o convertidor digital analógico (DAC). También se puede usar para digitalizar audio desde
un micrófono. Como no existe un protocolo de compresión en I2S, no se pueden reproducir archivos
MP3, OGG u otros formatos que comprimen el audio, pero pueden reproducir archivos WAV.
Así, el MKR ZERO y los otros módulos Arduino de la familia MKR pueden comunicarse mediante I2S. En
el siguiente ejemplo se verá cómo usar un amplificador I2S para reproducir archivos WAV desde una
tarjeta micro-SD.
Pero antes hay que tener en cuenta ciertas consideraciones:
Deberá usar la librería ArduinoSound (figura 13.17), por lo que el archivo WAV deberá tener el
formato estéreo, de 16-bit y 44 100 Hz. Una vez más, el software Audacity es un buen recurso para
ello, es gratuito y existe un buen tutorial en la web de Arduino.
La tarjeta micro-SD debe formatearse con FAT32 o FAT16. Si usa MacOS debe formatear como MD-
DOS (FAT).
Figura 13.17
Para realizar las conexiones debe tener en cuenta que I2S es un protocolo de bus síncrono, lo que
significa que puede conectar varios dispositivos en los mismos cables comunes. Las conexiones para
un bus I2S son:
Taller de Arduino
27
Reloj en serie (SCK) o bit clock (BCLK): la línea que transporta la señal del reloj.
Frame select (FS), también llamado word select (WS), o left-right clock (LRC): determina los
canales izquierdo y derecho.
Datos, también llamados salida digital (DOUT) o entrada digital (DIN) según la aplicación: la señal
de datos en sí.
El dispositivo de control envía la señal de reloj, al igual que en otros protocolos seriales síncronos
como I2C y SPI.
Entonces, a partir de estos datos, va a realizar una práctica en la que utilizará el amplificador de audio
MAX98357 I2S. Conectará un altavoz a este amplificador y, a partir de un archivo de la tarjeta SD, se
generará una señal de audio por la salida I2S del microcontrolador (figura 13.18).
Figura 13.18
Este amplificador o placa de conexión de audio SparkFun I2S (figura 13.18) utiliza el convertidor digital
a analógico (DAC) MAX98357A, que convierte el audio I2S en una señal analógica para controlar los
altavoces. El I2S Audio Breakout convierte las señales de audio digital usando el estándar I2S en una
señal analógica y amplifica la señal utilizando un amplificador de clase D que puede entregar hasta 3.2
W de potencia en una carga de 4 Ω. La placa se puede configurar para emitir solo el audio del canal
izquierdo, el canal derecho o ambos.
La placa de conexión de audio SparkFun I2S es bastante simple, requiere solo unas pocas conexiones
de clavija para que funcione. De forma predeterminada, la placa está configurada en funcionamiento
mono, lo que significa que las señales izquierda y derecha se combinan para impulsar un solo altavoz.
Si desea un altavoz separado para los canales de audio izquierdo y derecho, deberá cortar el puente
mono. Además de poder seleccionar la salida del canal de audio, la ganancia también se puede
configurar de varias maneras. La ganancia del amplificador se puede configurar desde tan bajo como
+ 3 dB a tan alto como + 15 dB. Si bien la selección de canales se puede configurar a bordo, la ganancia
se controla externamente utilizando el pin de ganancia. Por defecto, la placa está configurada para +
9 dB, pero se puede cambiar fácilmente.
En la figura 13.19 se muestra el amplificador de audio MAX98357 I2S conectado a un MKR ZERO. Los
pines del amplificador son: LCR conectado al pin 3 de la placa; BCLK conectado al pin 2; DIN
conectado al pin A6; SD conectado al VCC de 3.3 V; GND conectado a tierra y el último pin, que
también estará conectado al bus de 3.3 V. El potenciómetro irá conectado al pin A0, GND y 3.3 V.
Arduino MKR ZERO
28
Figura 13.19
Práctica 13.5 Reproductor de audio I2S con control de volumen
#include <SD.h>
#include <ArduinoSound.h>
const char filename[] = "archivo.wav";
// variable que representa al archivo WAV
SDWaveFile waveFile;
void setup()
Serial.begin(9600);
Serial.print("Iniciando tarjeta SD...");
if (!SD.begin())
Serial.println("Ha fallado la tarjeta SD!");
return;
Serial.println("Tarjeta SD funcionando.");
// se crea el archivo WAV en la SD
waveFile = SDWaveFile(filename);
// comprueba si el archivo WAV es correcto
if (!waveFile)
Taller de Arduino
29
Serial.println("el archivo WAV no es correcto!");
while (1); // do nothing
// imprime la duración del archivo de audio:
long duration = waveFile.duration();
Serial.print("Duracion = ");
Serial.print(duration);
Serial.println(" segundos");
// comprueba si la salida I2S puede reproducir el audio
if (!AudioOutI2S.canPlay(waveFile))
Serial.println("imposible reproducir archivo con I2S!");
while (1); // no hace nada
// comienza la reproducción
Serial.println("reproduciendo indefinidamente");
AudioOutI2S.loop(waveFile);
void loop()
// lee la entrada analógica
int sensorReading = analogRead(A0);
// cambia la medición a un rango de 0 a 100:
int volumen = map(sensorReading, 0, 1023, 0, 100);
// establece el volumen:
AudioOutI2S.volume(volumen);
Serial.print("Volumen: ");
Serial.println(volumen);
Como se puede ver, se ha descartado dos de las librerías anteriores. Ahora solo necesita la SD.h y la
nueva ArduinoSound.”. Comience definiendo el nombre de la canción que va a reproducir. Esta debe
tener entre 3 y 8 caracteres, y por supuesto respetar el formato de audio que se ha comentado antes.
Además, va a apoyarse en el monitor serie para ver y controlar el funcionamiento de su reproductor,
por lo que se ha iniciado el monitor serie, junto a la SD. Durante el “void setup” se comprobará el
formato del archivo y su duración. Si algo falla se informará en pantalla. Si todo va bien, comenzará a
reproducción repitiéndose indefinidamente.
Y el “void loop” solo tiene la configuración del control de volumen cuyo componente es un
potenciómetro. Esta parte del código comienza creando una variable llamada sensorReading para
guardar el valor del potenciómetro que está conectado al pin A0 y que leerá ese valor usando
analogRead(). Luego, usará el comando “map()” para asignar el rango del potenciómetro (0 a 1023) a
un rango menor (0 a 100) que también se almacenará en una variable llamada volumen. Todo ello será
además visible en el monitor serie, donde podrá ver el volumen de su reproductor.