Alberto E. Villalobos Chaves
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.
Mínima Medición = 5000 mV = 4.9 mV Ecuación 1
1024
Este valor es insuficiente si se quieren hacer mediciones precisas en ámbitos de valores amplios con señales de entrada pequeñas que es el caso que nos ocupa en este blog pues lo que se ha querido medir es el espectro luminoso producido por un espectrofotómetro de emisión atómica como el mostrado en la Figura 1 en el que se ve que hay señales muy intensas acompañadas de otras muy pequeñas lo que ocasiona que al querer examinar las señales pequeñas para su estudio estarán muy afectadas por el ruido electrónico ya que están en el límite de la mínima señal medida por el Arduino.
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:
Figura 1: Espectro de emisión atómica de una disolución de cloruro de hierro
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:
Número de capturas = 4^n Ecuación 2
donde n es
el número de bits adicionales en los que se quiere aumentar la resolución.
Siendo el datoi el valor i-ésimo de voltaje medido en el tiempo i-ésimo.
De esta forma si se quiere aumentar virtualmente la resolución del Arduino de 10 a 11, el valor de n es igual a 1 y el número de muestras a tomar debe ser 4, si el incremento deseado de resolución es a 12 el número de muestras será de 16 y así para otros valores de incremento de resolución de acuerdo a lo indicado en ElectricRCAircraftGuy.com (Cuadro1).
Cuadro 1: Monto en que se debe variar la cantidad de muestra capturada para incrementar la resolución utilizando sobremuestreo
Para programar al Arduino con este algoritmo se utilizó una librería adicional a la IDE de Arduino creada por Gabriel Staples llamada “AnalogReadXXbit” modificándose uno de los ejemplos que la acompañaban para adaptarlo a las necesidades de este proyecto.
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 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.
Figura 2: Efecto de aplicar la librería de sobremuestreo AnalogReadXXbit a la captura de la información espectral generada por un espectrofotómetro de emisión atómica aplicando un incremento de 0, 1, 2 y 3 al valor original del Arduino
Figura 3: Detalle del efecto de incremento en la resolución por sobremuestreo para el valor inicial sin uso del algoritmo AnalogReadXXbit y utilizándolo con un valor de incremento de resolución de 2 que se consideró óptimo
Como se desprende del análisis de las Figuras 2 y 3 anteriores, la mejora en la calidad de la señal fue sustancial y sin necesidad de utilizar amplificación electrónica de la señal sino simplemente por medios matemáticos.
Para la captura de la información se conectó el Arduino al espectrofotómetro utilizando una salida analógica prevista en dicho instrumento (Figura 4).
Figura 5: Salida analógica del espectrofotómetro de emisión atómica utilizada para conectarse al Arduino
Como software de captura se diseñó una aplicación en Processing llamada DatArduino que permite la captura en tiempo real, su manipulación y posterior salvado de la información en formato ".txt", ".dat" o ".csv".
Los datos capturados fueron analizados utilizando una aplicación específica para el análisis de información espectral astronómica llamado Rspec.
ACLARACIÓN AL CONCEPTO DE SOBREMUESTREO EN RELACIÓN A CONSULTAS RECIBIDAS:
Descarga de código (Dropbox):
1. AumentarResolucion por sobremuestreo adaptado del código original de Gabriel Staples (V1.0 alpha).
2. AumentarResolucion para Version 2.1 por sobremuestreo adaptado del código original de Gabriel Staples (V2.1 alpha).
3. DatArduino 1.02
ACLARACIÓN AL CONCEPTO DE SOBREMUESTREO EN RELACIÓN A CONSULTAS RECIBIDAS:
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.
Descarga de código (Dropbox):
1. AumentarResolucion por sobremuestreo adaptado del código original de Gabriel Staples (V1.0 alpha).
2. AumentarResolucion para Version 2.1 por sobremuestreo adaptado del código original de Gabriel Staples (V2.1 alpha).
3. DatArduino 1.02
Referencias
- http://es.wikipedia.org/wiki/Arduino
- http://en.wikipedia.org/wiki/Oversampling
- http://www.electricrcaircraftguy.com
Adendum
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:
Antigua Librería (AnalogReadXXbit V1.0 alpha)
int bits_of_precision = X; con X------>10,11,12,13 y 14
int num_samples = X; con X------>1,4,16,64 y 256
Nueva Librería (AnalogReadXXbit V2.1 alpha)
byte bitsOfResolution = X; con X------>10,11,12,13 y 14
unsigned long numSamplesToAvg = X; con X------>1,4,16,64 y 256
ADC_prescaler_t ADCSpeed = ADC_FAST;
A fin de responder a una consulta en el sentido de cual sería el desempeño de la librería de sobremuestreo (versión AnalogReadXXbit V1.0 alpha) contra utilizar el módulo ADS1115 de Adafruit, que tiene una resolución de 16 bits, se muestra en la Figura 8 el resultado de este experimento.
Antigua Librería (AnalogReadXXbit V1.0 alpha)
int bits_of_precision = X; con X------>10,11,12,13 y 14
int num_samples = X; con X------>1,4,16,64 y 256
Nueva Librería (AnalogReadXXbit V2.1 alpha)
byte bitsOfResolution = X; con X------>10,11,12,13 y 14
unsigned long numSamplesToAvg = X; con X------>1,4,16,64 y 256
ADC_prescaler_t ADCSpeed = ADC_FAST;
A fin de responder a una consulta en el sentido de cual sería el desempeño de la librería de sobremuestreo (versión AnalogReadXXbit V1.0 alpha) contra utilizar el módulo ADS1115 de Adafruit, que tiene una resolución de 16 bits, se muestra en la Figura 8 el resultado de este experimento.
Figura 6: Detalle del efecto de incremento en la resolución por sobremuestreo utilizando la anterior biblioteca AnalogReadXXbit V1.0 alpha utilizada originalmente en este post


Figura 7: Detalle del efecto de incremento en la resolución por sobremuestreo utilizando la nueva biblioteca AnalogReadXXbit V2.1 alpha
Figura 8: Detalle del efecto de incremento en la resolución por sobremuestreo utilizando la biblioteca AnalogReadXXbit V1.0 alpha, en comparación con usar el módulo ADS1115 de Adafruit conectado al Arduino
Figura 8: Detalle del efecto de incremento en la resolución por sobremuestreo utilizando la biblioteca AnalogReadXXbit V1.0 alpha, en comparación con usar el módulo ADS1115 de Adafruit conectado al Arduino