Source: https://hombrosdegigantes.blogspot.com/2015/03/aumento-virtual-de-la-resolucion-de-un.html
Timestamp: 2020-04-05 00:07:37+00:00

Document:
Hombros de Gigantes: AUMENTO VIRTUAL DE LA RESOLUCIÓN DE UN ARDUINO UTILIZANDO SOBREMUESTREO
Una de las limitantes de los microprocesadores Arduino, que tiene efecto sobre la calidad de la señal leída por sus puertos analógicos y que afecta la relación señal/ruido, es su baja resolución, que en el Arduino UNO y Arduino 2560 es de apenas 10 bit. Esto significa que solo hay 1024 campos de memoria (2^10) para almacenar valores diferentes del voltaje medido, o sea que si utilizamos el voltaje referencia de 5 voltios, que es el que se asigna por defecto el Arduino, el mínimo voltaje al que sería sensible dicho microprocesador sería el indicado por la Ecuación 1.
Para solventar esta limitante, se ha propuesto utilizar una técnica de filtrado matemático de señales conocida como sobremuestreo o oversampling que permite incrementar de forma virtual la resolución y por tanto aumentar la relación señal/ruido y que es consiste en capturar un número mayor de datos de los que son necesarios para recrear la señal medida (límite de Nyquist) y promediar estos datos utilizando la media escalada en lugar de la media aritmética como se muestra en las Ecuaciónes 2 y 3:
donde n es el número de bits adicionales en los que se quiere aumentar la resolución.
El efecto que tiene aplicar esta librería se ejemplifica en las Figuras 2 y 3 en la que se puede ver como hay un incremento tanto en el tamaño del pico como en la forma del mismo (aumento relación señal/ruido) cuando se pasa de la resolución de 10 bits, original del Arduino, a un valor de 12 bits, desmejorándose la forma al pasar a 13 bits razón por la cual se seleccionó 12 bits y 16 muestras por segundo como valor a utilizar.
El método expuesto no aumenta el tamaño de la señal. Para eso se requeriría amplificación electrónica.
En realidad todas las gráficas en la Figura 2 y 3 deberían tener el mismo tamaño pues el rango de votaje es el mismo y todas las mediciones son realizadas bajo las mismas condiciones
10-bit res., --> 5V
11-bit res., --> 5V
12-bit res., --> 5V
13-bit res., --> 5V
La diferencia de tamaño observada se debe a que no se utiliza la media aritmética para obtener el "promedio" de la mediciones, esto es sumar "x" votajes de un punto y dividir entre "x".
En vez de eso se suman los 4^n voltajes de un punto y se dividen entre 2^n (media escalada), donde n está determinado por el incremento virtual de resolución que se quiere obtener sobre los 10 bits originales del Arduino.
10-bit originales del Arduino, --> n=0
11-bit Arduino + 1, --> n=1
12-bit Arduino + 2, --> n=2
13-bit Arduino + 3, --> n=3
El efecto de este "truco matemático" es que al incrementar el valor de n se aumenta el valor de la media escalada y por tanto pareciera que se amplifica el voltaje. En realidad el voltaje no se amplifica pero si se reduce el ruido que es lo que se quiere al final. Para que este procedimiento de sobremuestreo funcione correctamente se debe tener exceso de mediciones de forma tal que se supere el límite de Nyquist (http://en.wikipedia.org/wiki/Oversampling).
Estos conceptos son mas del campo de procesamiento de señales de audio y se refieren a que si tiene una señal cualquiera, por ejemplo una onda sinosoidal perfecta y se captura pocos datos cuando se quiere reconstruir la onda con los datos capturados esta se mostrará distorcionada. Mientras mas datos se capture se verá cada vez mejor la reconstrucción de la onda, hasta que se llega a un punto (el límite de Nyquist) por arriba del cual, por mas datos que se capture ya no mejorará la forma (calidad) de la señal.
El sobremuestreo, que es esa forma especial de promediar, funciona cuando se está por encima del límite de Nyquist. Lo que hice en este proyecto fue aplicar algo que se utiliza en análisis de audio a datos espectroscópicos, y aparentemente ha funcionado pues la forma de los picos mejoró sensiblemente además de que se obtuvo una amplificación matemática de los mismos.
La librería de sobremuestreo utilizada en este trabajo fue la AnalogReadXXbit V1.0 alpha. Una nueva versión ha sido puesta a disposición, llamada AnalogReadXXbit V2.1 alpha que elimina algunas pulgas en el programa y permite realizar la captura de datos de una forma mas rápida.
A efectos de comparar ambas librerías se muestran mediciones realizadas con ambas versiones a diferentes valores de resolución y muestreo de datos (Figuras 6 y 7) utilizando los siguientes parámetros:
Publicado por Alberto Villalobos en 21:52
Etiquetas: Absorción atómica, Arduino, Aumentar resolución, Sobremuestreo
Gabriel Staples dijo...
!Me alegro ver que está utilizando mi librería en su collección de datos! ?Puede usted por favor compartir su código para el Arduino? Y además, me pregunto en que lugar se está aplicando este proceso---?es para su trabajo, en un laboratorio profesional, o está en su hogar, como scientífico aficionado?
28 de marzo de 2015, 9:09
Además, me pregunto por qué los datos conseguidos a mayor bit-resolución son amplificados también? No tiene sentido...y al pensarlo, pienso que deberá ser por motivo de que usted no está presentando el voltaje en el y-axis, sino el valor crudo, es verdad?
Ex (por sobremuestreo):
10-bit res., valor de 512 --> 2.5V
11-bit res., valor de 1023 --> 2.5V
12-bit res., valor de 2046 --> 2.5V
13-bit res., valor de 4092 --> 2.5V
...pero usted hizo los gráficos no con los voltajes sino con los valores, no?
28 de marzo de 2015, 9:30
Alberto Villalobos dijo...
Hola Gabriel, he adicionado un link directo al código Arduino para sobremuestreo (AumentarResolucion) que se basa en el ejemplo de su librería (analogReadXXbit_basic).
Este proceso de sobremuestreo lo estoy utilizando en mi trabajo para eliminar ruido electrónico y aumentar la intensidad de señales generadas por un espectrofotómetro de emisión atómica.
Usted está en lo correcto, los valores graficados son los datos crudos. En realidad los voltajes de las cuatro gráficas deberían ser todos iguales pues no se utilizado amplificación electrónica.
Para ejemplificar el efecto del cambio de resolución era mejor hacerlo así pues se podía ver las diferencias de tamaño.
10-bit res., valor de 512 --> Voltaje verdadero
11-bit res., valor de 1023 --> Valor crudo
12-bit res., valor de 2046 --> Valor crudo
13-bit res., valor de 4092 --> Valor crudo
Alberto, mirando Figura 2, la razon por la cual usted no podía utilizar una resolución de 13 bits era porque no se podían capturar los datos suficientemente rápido con esa resolución. Sin embargo, lo he resuelto. Ahora con mi nuevo librería (Version 2.1 alpha), yo creo que sí se puede. Le recomiendo bajar la version 2.1 alpha (resaltado en amarillo ahora, en mi página), y analizar el nuevo ejemplo. Usted puede aumentar la rapidez de captura al llamar la función: adc.setADCSpeed(ADC_FAST);
O...si bien prefiere continuar con 12-bits, tomando los datos más rápido, con mi nuevo librería, le puede ayudar a capturar mejor la forma verdadera de la señal también, al tomar más muestras por segundo.
14 de abril de 2015, 11:52
Gabriel me interesa mucho lo que me cuenta sobre su nueva librerìa (Version 2.1 alpha) voy a probarla a ver si se mejora la forma de los picos y después le cuento.
Por cierto comenté la técnica de sobremuestreo en un foro de científicos aficionados por si lo quiere revisar:
http://www.cientificosaficionados.com/foros/viewtopic.php?f=7&t=18138
Está bien. Unas cositas más: tenga a bien darse cuenta de que "int num_samples = 16;" (con "int bits_of_precision = 12;" también) en su código (mi ejemplo modificado por usted) no quiere decir, "toma 16 muestras a 10-bits para adquirir una muestra de 12-bits," sino que quiere decir: "toma 16 muestras a 12-bits, para devolver el promedio de estos." El variable num_samples es para "smooth" (lisar? tranquilar?) la señal mientras bits_of_precision es para aumentar la resolución de medición. Quizás ya lo sabe usted, pero solo quiero ceciorarme.
...y la otra cosa: Usted necesita utilizar una manera mejor para capturar datos con un intervalo fijo. Utilizar delay() no es una buena idea. Es mejor hacerlo sin utilizar delay, al utilizar time-stamps (sello/captura de tiempo???). Véase "blink without delay" para un buen ejemplo. También lo puede hacer con las librerías Timer et Timer1. Timer1 es mas preciso pero ocupa el Timer1 del microcontrolador.
14 de abril de 2015, 20:25
Gracias por la explicación del uso de las instrucciones "int num_samples = 16;" y "int bits_of_precision = 12;" pues ahora estoy seguro de que las si las estaba entendiendo de la manera correcta :)
Voy a intentar hacer la captura de datos sin utilizar el delay() y voy a explorar las otras opciones que me menciona.
Quería decirle que yo también use el chip de 16Bit I2C de Adafruit sin sobremuestreo y el resultado no fue mejor que con sobremuestreo, por lo que parece que por lo menos en mi caso el sobremuestreo fue mejor.
Alberto, estoy utilizando su gráfica aquí, para distribuir mi librería: https://gumroad.com/l/eRCaGuy_NewAnalogRead. Está bien con usted? Por favor envíeme un email para decirme sí o no. (rcflyyer [arroba] gmail...). Gracias!
26 de julio de 2015, 13:23
heiken dijo...
He encontrado muy interesante el tema del sobremuestreo. Me preguntaba, si podrias hacer las mediciones (sin sobremuestreo), conectando un modulo ADS1115 al Arduino. La ventaja es que este modulo tiene una precision de 16 bits y solo cuesta 9 dolares. La libreria del AD1115 para el Arduino la encuentras aqui:
https://github.com/adafruit/Adafruit_ADS1X15.
Seria genial que hicieras la prueba y compartieras los resultados.
8 de marzo de 2016, 12:26
Estoy de acuerdo. Me gustaría ver la comparación.
8 de marzo de 2016, 15:49
Hola Heiken,
Gracias por tu comentario. De hecho yo también me había preguntado lo mismo en relación con el módulo ADS1115 y cuando hice las mediciones iniciales con la librería de Gabriel también probé con el ADS1115.
Los resultados con la librería de sobremuestreo fueron superiores por lo que ni siquiera lo mencioné en el blog pero guardé los datos y puesto que te interesa y a Gabriel también los he publicado en este mismo blog en la Figura 8.
Curiosamente la gráfica del ADS1115 de 16 bits se ubica a la altura de la gráfica de sobremuestreo de 12 bits y 16 muestras, siendo sin embargo sumamente ruidosa lo que se puede deber a que en el proceso de sobremuestreo se da un promediado de los datos y pareciera que con el ADS1115 no.
En fin ahí están las gráficas y tal vez ustedes las puedan analizar y sacar alguna conclusión adicional.
8 de marzo de 2016, 19:47
AUMENTO VIRTUAL DE LA RESOLUCIÓN DE UN ARDUINO UTI...
USO DEL PROGRAMA PROCESSING PARA GRAFICAR DATOS CA...

References: RESOLUCIÓN 
 resolución 
 resolución 
 resolución 
 resolución 
 resolución 
 resolución 
 resolución 
 RESOLUCIÓN