Tabla de contenido:

Procesamiento de señal digital y audio Bluetooth: un marco Arduino: 10 pasos
Procesamiento de señal digital y audio Bluetooth: un marco Arduino: 10 pasos

Video: Procesamiento de señal digital y audio Bluetooth: un marco Arduino: 10 pasos

Video: Procesamiento de señal digital y audio Bluetooth: un marco Arduino: 10 pasos
Video: PR#20 Arduino - Recibir datos Bluetooth en móvil 2024, Noviembre
Anonim
Image
Image
Procesamiento de señal digital y audio Bluetooth: un marco Arduino
Procesamiento de señal digital y audio Bluetooth: un marco Arduino

Resumen

Cuando pienso en Bluetooth, pienso en música, pero lamentablemente la mayoría de los microcontroladores no pueden reproducir música a través de Bluetooth. La Raspberry Pi puede pero eso es una computadora. Quiero desarrollar un marco basado en Arduino para que los microcontroladores reproduzcan audio a través de Bluetooth. Para flexionar completamente los músculos de mi microcontrolador, voy a agregar procesamiento de señal digital (DSP) en tiempo real al audio (filtrado de paso alto, filtrado de paso bajo y compresión de rango dinámico). Para la cereza en la parte superior, agregaré un servidor web que se puede usar para configurar el DSP de forma inalámbrica. El video integrado muestra los conceptos básicos del audio Bluetooth en acción. También me muestra usando el servidor web para realizar un filtrado de paso alto, filtrado de paso bajo y compresión de rango dinámico. El primer uso de la compresión de rango dinámico provoca distorsión a propósito como un ejemplo de mala elección de parámetros. El segundo ejemplo elimina esta distorsión.

Para este proyecto, el ESP32 es el microcontrolador de elección. Cuesta menos de £ 10 y está repleto de funciones con ADC, DAC, Wifi, Bluetooth Low Energy, Bluetooth Classic y un procesador de doble núcleo de 240 MHz. El DAC integrado técnicamente puede reproducir audio, pero no sonará muy bien. En su lugar, usaré el decodificador estéreo Adafruit I2S para producir una señal de salida de línea. Esta señal se puede enviar fácilmente a cualquier sistema de alta fidelidad para agregar instantáneamente audio inalámbrico a su sistema de alta fidelidad existente.

Suministros

Con suerte, la mayoría de los fabricantes tendrán placas de prueba, puentes, cables USB, soldadores de fuente de alimentación y solo tendrán que gastar £ 15 en el ESP32 y el decodificador estéreo. De lo contrario, todas las piezas necesarias se enumeran a continuación.

  • Un ESP32 - probado en ESP32-PICO-KIT y TinyPico - £ 9.50 / £ 24
  • Decodificador estéreo Adafruit I2S - £ 5.51
  • Placa de pruebas - £ 3- £ 5 cada una
  • Cables de puente - £ 3
  • Auriculares con cable / sistema Hi-Fi - £££
  • Encabezados de empuje o soldador - £ 2.10 / £ 30
  • Cable micro USB - £ 2,10 / £ 3
  • Conector de 3,5 mm a RCA / conector de 3,5 mm a conector (o lo que necesite su altavoz) - £ 2,40 / £ 1,50
  • Fuente de alimentación USB - £ 5

Paso 1: Construcción: la placa de pruebas

Construcción - la placa de pruebas
Construcción - la placa de pruebas

Si compró el ESP32-PICO-KIT, no tendrá que soldar ninguna clavija, ya que viene pre-soldada. Simplemente colóquelo en la placa de pruebas.

Paso 2: Construcción - Encabezados de empuje / soldadura

Construcción - Encabezados de empuje / soldadura
Construcción - Encabezados de empuje / soldadura
Construcción - Encabezados de empuje / soldadura
Construcción - Encabezados de empuje / soldadura

Si tiene un soldador, suelde los pines al decodificador estéreo de acuerdo con las instrucciones en el sitio web de Adafruit. En el momento de escribir este artículo, mi soldador estaba funcionando y estaba bloqueado. No quería pagar por un soldador temporal, así que corté algunos cabezales de empuje de pimoroni. Los corté para que encajaran en el decodificador estéreo. Esta no es la mejor solución (y no es la forma en que se pretendía utilizar los cabezales), pero es la alternativa más barata a un soldador. Coloque el cabezal cortado en la placa de pruebas. Solo debería necesitar 1 línea de 6 pines para el decodificador. Puede agregar otros seis al otro lado para mayor estabilidad, pero esto no es necesario para este sistema prototipo. Los pines para colocar los encabezados son vin, 3vo, gnd, wsel, din y bclk.

Paso 3: Construcción: cablee los pines de alimentación

Construcción: cablee los pines de alimentación
Construcción: cablee los pines de alimentación

Coloque el decodificador estéreo en los encabezados de empuje (pines vin, 3vo, gnd, wsel, din y bclk) y júntelos firmemente. Nuevamente, esto idealmente debería hacerse con un soldador, pero tuve que improvisar. Notarás que todos los cables en este instructable son azules. Eso es porque no tenía cables de puente, así que corté 1 cable largo en trozos más pequeños. Además, soy daltónico y realmente no me importa el color del cable. Los pines de alimentación se adjuntan de la siguiente manera:

3v3 (ESP32) -> a vin en decodificador estéreo

gnd (ESP32) -> a gnd en decodificador estéreo

Paso 4: Construcción - Cableado I2S

Construcción: cableado I2S
Construcción: cableado I2S

Para enviar el audio Bluetooth desde el ESP32 al decodificador estéreo vamos a utilizar un método de comunicación digital llamado I2S. El decodificador estéreo tomará esta señal digital y la convertirá en una señal analógica que se puede conectar a un altavoz o HiFi. I2S solo requiere 3 cables y es bastante sencillo de entender. La línea del reloj de bits (bclk) se vuelve alta y baja para indicar que se transmite un nuevo bit. La línea de salida de datos (dout) se vuelve alta o baja para indicar si ese bit tiene un valor de 0 o 1 y la línea de selección de palabra (wsel) se vuelve alta o baja para indicar si se está transmitiendo el canal izquierdo o derecho. No todos los microcontroladores admiten I2S, pero el ESP32 tiene 2 líneas I2S. Esto lo convierte en una opción obvia para este proyecto.

El cableado es el siguiente:

27 (ESP32) -> wsel (decodificador estéreo)

25 (ESP32) -> din (decodificador estéreo)

26 (ESP32) -> bclk (decodificador estéreo)

Paso 5: Instalación de la biblioteca BtAudio

Instalación de la biblioteca BtAudio
Instalación de la biblioteca BtAudio
Instalación de la biblioteca BtAudio
Instalación de la biblioteca BtAudio

Si aún no los tiene instalados, instale el IDE de Arduino y el núcleo de Arduino para ESP32. Una vez que los haya instalado, visite mi página de Github y descargue el repositorio. Dentro del IDE de Arduino en Sketch >> Incluir biblioteca >> seleccione "Agregar biblioteca. ZIP". Luego seleccione el archivo zip descargado. Esto debería agregar mi biblioteca btAudio a sus bibliotecas Arduino. Para usar la biblioteca, deberá incluir el encabezado correspondiente en el boceto de Arduino. Verá esto en el siguiente paso.

Paso 6: uso de la biblioteca BtAudio

Usando la biblioteca BtAudio
Usando la biblioteca BtAudio
Usando la biblioteca BtAudio
Usando la biblioteca BtAudio

Una vez instalado, conecte su ESP32 a su computadora a través de micro USB y luego conecte su decodificador estéreo a su altavoz con su cable de 3.5 mm. Antes de cargar el boceto, deberá cambiar algunas cosas en el editor de Arduino. Una vez que haya seleccionado su placa, deberá editar el esquema de partición en Herramientas >> Esquema de partición y seleccionar "Sin OTA (aplicación grande)" o "SPIFFS mínimo (APLICACIONES grandes con OTA)". Esto es necesario porque este proyecto utiliza tanto WiFi como Bluetooth, que son bibliotecas con mucha memoria. Una vez que haya hecho esto, cargue el siguiente boceto en el ESP32.

#incluir

// Establece el nombre del dispositivo de audio btAudio audio = btAudio ("ESP_Speaker"); void setup () {// transmite datos de audio al ESP32 audio.begin (); // envía los datos recibidos a un I2S DAC int bck = 26; int ws = 27; int dout = 25; audio. I2S (bck, dout, ws); } bucle vacío () {}

El boceto se puede dividir en tres pasos:

  1. Cree un objeto btAudio global que establezca el "nombre de Bluetooth" de su ESP32
  2. Configure el ESP32 para recibir audio con el método btAudio:: begin
  3. Configure los pines I2S con el método btAudio:: I2S.

¡Eso es todo en el lado del software! Ahora todo lo que necesita hacer es iniciar la conexión Bluetooth a su ESP32. Simplemente busque nuevos dispositivos en su teléfono / computadora portátil / reproductor MP3 y aparecerá "ESP_Speaker". Una vez que esté contento de que todo está funcionando (se reproduce música), puede desconectar el ESP32 de su computadora. Enciéndalo con la fuente de alimentación USB y recordará el último código que cargó en él. De esta manera, puede dejar su ESP32 escondido detrás de su sistema de alta fidelidad para siempre.

Paso 7: DSP - Filtrado

Ampliación del receptor con procesamiento de señal digital

Si siguió todos los pasos (y no dejé nada) ahora tiene un receptor Bluetooth en pleno funcionamiento para su sistema de alta fidelidad. Si bien esto es genial, realmente no lleva al microcontrolador al límite. El ESP32 tiene dos núcleos que funcionan a 240MHz. Eso significa que este proyecto es mucho más que un simple receptor. Tiene la capacidad de ser un receptor Bluetooth con un Procesador de Señal Digital (DSP). Los DSP esencialmente realizan operaciones matemáticas en la señal en tiempo real. Una operación útil se llama filtrado digital. Este proceso atenúa las frecuencias en una señal por debajo o por encima de una cierta frecuencia de corte, dependiendo de si está utilizando un filtro de paso alto o de paso bajo.

Filtros de paso alto

Los filtros de paso alto atenúan las frecuencias por debajo de una determinada banda. He creado una biblioteca de filtros para sistemas Arduino basada en el código de earlevel.com. La principal diferencia es que cambié la estructura de clases para permitir la construcción de filtros de orden superior más fácilmente. Los filtros de orden superior suprimen las frecuencias más allá de su corte de manera más efectiva, pero requieren mucho más cálculo. Sin embargo, con la implementación actual, ¡incluso puede usar filtros de sexto orden para audio en tiempo real!

El boceto es el mismo que el encontrado en el paso anterior excepto que hemos cambiado el bucle principal. Para habilitar los filtros usamos el método btAudio:: createFilter. Este método acepta 3 argumentos. El primero es el número de cascadas de filtros. El número de cascadas de filtros es la mitad del orden del filtro. Para un filtro de sexto orden, el primer argumento debería ser 3. Para un filtro de octavo orden, sería 4. El segundo argumento es el corte del filtro. Lo configuré en 1000Hz para tener un efecto realmente dramático en los datos. Finalmente, especificamos el tipo de archivador con el tercer argumento. Debe ser de paso alto para un filtro de paso alto y de paso bajo para un filtro de paso bajo. El siguiente script cambia el corte de esta frecuencia entre 1000Hz y 2Hz. Debería escuchar un efecto dramático en los datos.

#incluir

btAudio audio = btAudio ("ESP_Speaker"); configuración vacía () {audio.begin (); int bck = 26; int ws = 27; int dout = 25; audio. I2S (bck, dout, ws); } bucle vacío () {retraso (5000); audio.createFilter (3, 1000, paso alto); retraso (5000); audio.createFilter (3, 2, paso alto); }

Filtros de paso bajo

Los filtros de paso bajo hacen lo contrario de los filtros de paso alto y suprimen las frecuencias por encima de cierta frecuencia. Se pueden implementar de la misma manera que los filtros de paso alto, excepto que requieren cambiar el tercer argumento a paso bajo. Para el boceto a continuación, alterno el corte de paso bajo entre 2000Hz y 20000Hz. Con suerte, escucharás la diferencia. Debería sonar bastante amortiguado cuando el filtro de paso bajo está a 2000Hz.

#incluir

btAudio audio = btAudio ("ESP_Speaker"); configuración vacía () {audio.begin (); int bck = 26; int ws = 27; int dout = 25; audio. I2S (bck, dout, ws); } bucle vacío () {retraso (5000); audio.createFilter (3, 2000, paso bajo); retraso (5000); audio.createFilter (3, 20000, paso bajo); }

Paso 8: DSP - Compresión de rango dinámico

Fondo

La compresión de rango dinámico es un método de procesamiento de señales que intenta igualar el volumen del audio. Comprime los sonidos fuertes, que se elevan por encima de un cierto umbral, al nivel de los silenciosos y luego, opcionalmente, amplifica ambos. El resultado es una experiencia auditiva mucho más uniforme. Esto resultó muy útil mientras estaba viendo un programa con música de fondo muy alta y voces muy tranquilas. En este caso, simplemente aumentar el volumen no ayudó, ya que esto solo amplificó la música de fondo. Con la compresión de rango dinámico, pude reducir la música de fondo alta al nivel de las voces y volver a escuchar todo correctamente.

El código

La compresión de rango dinámico no solo implica bajar el volumen o ajustar el umbral de la señal. Es un poco más inteligente que eso. Si baja el volumen, los sonidos bajos se reducirán al igual que los fuertes. Una forma de evitar esto es establecer el umbral de la señal, pero esto da como resultado una distorsión severa. La compresión de rango dinámico implica una combinación de umbral suave y filtrado para minimizar la distorsión que se obtendría si tuviera que limitar / recortar la señal. El resultado es una señal en la que los sonidos fuertes se "recortan" sin distorsión y los silenciosos se dejan como están. El siguiente código cambia entre tres niveles diferentes de compresión.

  1. Compresión con distorsión
  2. Compresión sin distorsión
  3. Sin compresión

#incluir

btAudio audio = btAudio ("ESP_Speaker"); configuración vacía () {audio.begin (); int bck = 26; int ws = 27; int dout = 25; audio. I2S (bck, dout, ws); } bucle vacío () {retraso (5000); audio.compress (30, 0.0001, 0.0001, 10, 10, 0); retraso (5000); audio.compress (30, 0.0001, 0.1, 10, 10, 0); retraso (5000); audio.decompress (); }

La compresión de rango dinámico es complicada y los métodos btAudio:: compress tienen muchos parámetros. Intentaré explicarlos (en orden) aquí:

  1. Umbral: el nivel al que se reduce el audio (medido en decibelios)
  2. Attack time (Tiempo de ataque): el tiempo que tarda el compresor en comenzar a funcionar una vez que se ha superado el umbral.
  3. Tiempo de liberación: el tiempo que tarda el compresor en dejar de funcionar.
  4. Relación de reducción: el factor por el cual se comprime el audio.
  5. Ancho de rodilla: el ancho (en decibelios) alrededor del umbral en el que el compresor funciona parcialmente (sonido más natural).
  6. La ganancia (decibelios) añadida a la señal después de la compresión (aumentar / disminuir el volumen)

La distorsión muy audible en el primer uso de la compresión se debe a que el umbral es muy bajo y tanto el tiempo de ataque como el tiempo de liberación son muy cortos, lo que da como resultado un comportamiento de umbral difícil. Esto se resuelve claramente en el segundo caso aumentando el tiempo de liberación. Esto esencialmente hace que el compresor actúe de una manera mucho más suave. Aquí, solo he mostrado cómo cambiar 1 parámetro puede tener un efecto dramático en el audio. Ahora es tu turno de experimentar con diferentes parámetros.

La implementación (las matemáticas mágicas - opcional)

Descubrí que implementar ingenuamente la compresión de rango dinámico es un desafío. El algoritmo requiere convertir un número entero de 16 bits en decibelios y luego volver a transformarlo en un número entero de 16 bits una vez que haya procesado la señal. Noté que una línea de código tardaba 10 microsegundos en procesar datos estéreo. Como el audio estéreo muestreado a 44.1 KHz deja solo 11.3 microsegundos para el DSP, esto es inaceptablemente lento … Sin embargo, al combinar una pequeña tabla de búsqueda (400 bytes) y un procedimiento de interpolación basado en las diferencias divididas de Netwon, podemos obtener una precisión de casi 17 bits en 0.2 microsegundos. Adjunto un documento pdf con todas las matemáticas para los realmente interesados. ¡Es complicado, has sido advertido!

Paso 9: la interfaz wifi

La interfaz wifi
La interfaz wifi
La interfaz wifi
La interfaz wifi

Ahora tiene un receptor Bluetooth capaz de ejecutar DSP en tiempo real. Lamentablemente, si desea cambiar alguno de los parámetros de DSP, deberá desconectarse de su equipo de alta fidelidad, cargar un nuevo boceto y luego volver a conectarse. Esto es torpe. Para solucionar esto, desarrollé un servidor web que puede usar para editar todos los parámetros de DSP sin volver a conectarse a su computadora. El esquema para usar el servidor web se encuentra a continuación.

#incluir

#include btAudio audio = btAudio ("ESP_Speaker"); webDSP web; configuración vacía () {Serial.begin (115200); audio.begin (); int bck = 26; int ws = 27; int dout = 25; audio. I2S (bck, dout, ws); // reemplace con su ID de WiFi y contraseña const char * ssid = "SSID"; const char * contraseña = "CONTRASEÑA"; web.begin (ssid, contraseña y audio); } bucle vacío () {web._server.handleClient (); }

El código asigna una dirección IP a su ESP32 que puede usar para acceder a la página web. La primera vez que ejecute este código, debe tenerlo adjunto a su computadora. De esa manera, puede ver la dirección IP asignada a su ESP32 en su monitor de serie. Si desea acceder a esta página web, simplemente ingrese esta dirección IP en cualquier navegador web (probado en Chrome).

A estas alturas deberíamos estar familiarizados con el método para habilitar Bluetooth e I2S. La diferencia clave es el uso de un objeto webDSP. Este objeto toma su SSID Wifi y contraseña como argumentos, así como un puntero al objeto btAudio. En el bucle principal, obtenemos continuamente que el objeto webDSP escuche los datos entrantes de la página web y luego actualizamos los parámetros de DSP. Como punto de cierre, cabe señalar que tanto Bluetooth como Wifi utilizan la misma radio en el ESP32. Esto significa que es posible que deba esperar hasta 10 segundos desde que ingresa los parámetros en la página web hasta que la información llega realmente al ESP32.

Paso 10: planes futuros

Con suerte, ha disfrutado de este instructivo y ahora ha agregado audio Bluetooth y DSP a su equipo de alta fidelidad. Sin embargo, creo que hay mucho espacio para el crecimiento en este proyecto y solo quería señalar algunas direcciones futuras que podría tomar.

  • Habilite la transmisión wifi de audio (para obtener la mejor calidad de audio)
  • Utilice un micrófono I2S para habilitar los comandos de voz
  • desarrollar un ecualizador controlado por WiFi
  • Hágalo bonito (la placa de pruebas no grita un gran diseño de producto)

Cuando logre implementar estas ideas, haré más instructables. O tal vez alguien más consiga implementar estas funciones. ¡Esa es la alegría de hacer que todo sea de código abierto!

Recomendado: