En mi aplicación, un microcontrolador Cortex M0 actualmente muestrea una señal ADC a 10 kHz y envía el resultado a través de un cable serial USB a una computadora.
Ahora quiero aumentar la frecuencia de muestreo a más de 100 kHz y agregar un segundo canal.
El enlace serie USB está limitado a 1-3 Mbps, por lo que es físicamente imposible transmitir a esta velocidad con un valor ADC de 12 bits y 2 bytes necesarios para transferir cada muestra. Para el muestreo de dos canales ADC a 100 KHz, la tasa de bits requerida es de aproximadamente 4 Mbps:
Soy consciente de que podría colocar 2 muestras de ADC en 3 bytes, pero quiero comprimir un poco los datos de ADC.
¿Cuáles son algunos algoritmos de compresión que son adecuados para ejecutarse en un microcontrolador Cortex M0?
Hay docenas de algoritmos de compresión, pero estoy buscando algo que pueda ejecutarse en una plataforma con recursos limitados.
¿Es esto realmente una aplicación de audio? ¿Podría reemplazar todo con una interfaz de audio dedicada que resolverá todos estos problemas por usted, o necesita el nivel de CC preciso? El estéreo de 96 ksps es bastante alcanzable.
No tiene muchos MIPS con los que trabajar, así que voy a proponer el siguiente esquema de codificación. Es una tasa de bits técnicamente variable, por lo que es mejor que espere que los transitorios sean raros. Funciona para muestras de hasta 15 bits.
La reconstrucción es simple:
Hay algunos pasos "sencillos" que puede seguir para reducir la velocidad de transmisión necesaria:
¿Realmente necesitas una resolución de 12 bits? Si puede sacrificar los 4 bits menos significativos (que podrían ser solo ruido), reduce el ancho de banda requerido en un 33% y ahorra algunas operaciones al mismo tiempo.
en qué cantidad la señal "generalmente" cambia entre 2 muestras sucesivas. Por ejemplo, si el 95% de las veces, la diferencia está solo en los 6 bits menos significativos, puede enviar:
Finalmente, una cosa interesante que dijiste en los comentarios es que necesitas una tasa de muestreo tan alta porque quieres observar transitorios.
Por lo tanto, veo 2 soluciones, un poco más complicadas, pero que podrían reducir significativamente la velocidad en baudios necesaria para su aplicación específica:
Si solo necesita los transitorios: ¿por qué no "disparar" sobre ellos? Almacena todas sus medidas en un búfer rodante (usando DMA si puede). Luego, utiliza algún cálculo de software para definir un transitorio (por ejemplo, una diferencia mayor que X entre la medición N y N-N0). Si detecta uno, envía solo los valores alrededor de la medición N. Si sus transitorios son raros, su tasa de baudios requerida se vuelve realmente baja. NB: en esta versión, SOLO ve los transitorios, no el resto (puede o no satisfacer sus necesidades, si no, vea la solución 4)
Otra solución es no enviar muestreos con intervalos de tiempo regulares: aún muestrea a 100 kHz (almacenado en un búfer interno con DMA), pero solo transmite parte de los datos: cuando los datos cambian rápidamente, envía muchos datos, cuando va cambiando poco a poco, te mandan pocos. Por ejemplo :
Entonces, básicamente, en el lado receptor, recibe el valor en la forma A[0:3].M[0:12], siendo A el número de muestras omitidas (entonces (A+1) sampling_period el tiempo desde la última muestra ) , y M el valor de esa muestra. Si su señal está cambiando lo suficientemente lento y los transitorios son raros, tendrá un promedio de A entre 14 y 15 (seamos conservadores y digamos 14), por lo que tiene una tasa de bits promedio de 2 canales 16 bits * 100000 Hz/15 = 213 kb / s: eso se hace fácilmente en un UART de 1 Mb/s
Si lo hace, tendrá una sobrecarga computacional significativa, debe asegurarse de que puede hacer todo a tiempo. Tendrá que revisar todos los datos varias veces, esto es del orden O(n). Porque obviamente no puede hacerlo sin revisar todos los datos al menos una vez y también necesita hacer algo con ellos. Tal vez pueda ahorrar algo de tiempo en la automatización del procedimiento de envío: puede hacer que un temporizador active las interrupciones regularmente y luego active la transmisión de los datos con DMA. Esto liberará algo de poder computacional. Si lo necesita, tal vez pueda manejarlo de la manera más simple y aún así hacerlo. (ni siquiera publicó MCU y la frecuencia en la que opera, al momento de escribir esto)
Puede tener un diccionario de compresión estático o dinámico (qué sustituye a qué). Si es estático, puede codificarlo en el extremo receptor para descomprimirlo. Si es dinámico, se necesitarán más cálculos en el lado de MCU para generarlo y también deberá transmitirlo como datos al lado receptor (PC), porque necesita decodificarlo.
Primero, haga una estimación de qué tipo de valores devuelve su ADC con más frecuencia. Tal vez quieras comprimir los bits más significativos. Tendrá que buscar algunos algoritmos específicos, pero creo que no hay forma de hacerlo sin renunciar a un poco de ancho de banda, porque lo que envía debe ser distinguible: ¿envía datos sin procesar reales o datos comprimidos o diccionario? Por ejemplo, puede codificar que cada 16 bytes enviará un byte que será un diccionario para los próximos 16 bytes (o más, pero luego su compresión podría empeorar debido a la variedad de datos). Lo que significa que su compresión debe ser lo suficientemente buena para superar esta sobrecarga y aun así aumentar la cantidad total de datos transmitidos.
Pero el paso número 1 siempre es estimar si hay algo en los datos para comprimir. Si espera que todos los valores posibles sean totalmente aleatorios todo el tiempo, no hay mucho que pueda hacer, entonces es posible que desee descartar algunas medidas. Esta es simplemente su limitación de hardware. Solo puedes obtener tanto con eso.
Solo necesita comunicaciones de ancho de banda completo con la PC si planea que el ARM sea solo un ADC USB tonto y todas las cosas inteligentes que suceden en la PC. Si coloca el procesamiento en el ARM, puede enviar cosas a la PC más lentamente.
Dices que estás buscando transitorios. Esencialmente, entonces estamos hablando de diferenciación (buscando una tasa de cambio rápida). Habiendo hecho esto recientemente con el trabajo (diferenciando la posición para dar velocidad y aceleración, y luego ejecutando el control de posición-velocidad-aceleración de circuito cerrado), puedo decirle que el muestreo es ruidoso y necesita niveles significativos de filtrado cuando busca a tasa de cambio. Si no lo hace, entonces los falsos disparadores del ruido van a matar su diseño. (Filtros de paso bajo Bessel FTW, debido a un sobreimpulso mínimo y un retraso de grupo sólido en la banda de paso; y también mire la transformada MZTi para obtener una mejor respuesta a medida que la constante de tiempo del filtro se acerca a Nyquist).
Ahora tenemos algo con más datos útiles para que funcione la PC. Pero también tenemos algo que se puede enviar de regreso a la PC más lentamente, porque si ha filtrado sus datos con un filtro de paso bajo, entonces no necesita enviar esos datos más rápido que el doble de su nuevo ancho de banda.
Ilia
jwsc
mr_js
mr_js
Pato D
Ilia
antonio51
winny
stevesh