Linealizacion de sensores por el metodo de minimos cuadrados

Chico3001

Moderador
Supongamos que queremos medir con un microcontrolador la salida de un sensor de temperatura X, pero descubrimos que la salida es una curva leve, asi que surge la duda.... como convertimos el voltaje del sensor a su equivalente en temperatura para poder hacer el desplegado en un display?

Uno de los metodos mas simples y rapidos es hacer una tabla de busqueda, programamos en un area de memoria diversos valores y despues por medio de comparaciones podemos obtener un valor aproximado, sin embargo este metodo aunque es el mas rapido para ejecutar es el mas inexacto por que solo nos retornara los valores que hayamos programado, si hacemos una busqueda de algun valor intermedio tendremos que ajustarnos al valor mas proximo (hacia arriba o hacia abajo)

Asi que aplicando un poco las matematicas podemos hacer la aproximacion de una curva por medio de una recta como se muestra en la figura a continuacion:

minimos%20cuadrados.png


La ecuacion de esta recta se puede programar para que la procese cualquier microcontrolador, de manera que podemos tener una salida aproximada en un tiempo razonable y con un error pequeño , incluso se puede extender el metodo para meter una serie de aproximaciones con multiples rectas que nos permitan reducir aun mas el error de calculo

Asi que sin mas pasemos al ejemplo practico:

Primer Paso:

Necesitamos obtener la tabla de valores de entrada y salida del sensor, en nuestro ejemplo usaremos un sensor de temperatura cualquiera pero el metodo se puede aplicar a cualquier tipo de sensor:

Código:
Temp Medida (°C)	Voltaje Medido (mV)
47	749
45.2	774
44.1	799
43.1	823
42.2	852
41.2	877
40.4	906
39.3	935
38.4	970
37.4	999
36.4	1033
35.3	1068
34.5	1101
33.5	1136
32.5	1174
31.6	1209
30.6	1248
29.7	1287
28.5	1331
27.6	1370
26.9	1413
25.6	1458
24.9	1502
23.7	1547
22.7	1595
21.8	1642
20.8	1692
20	1740
18.9	1793
18	1847
17.1	1901
16.1	1956
15.1	2008
14.3	2066
13.4	2120
12.3	2174
11.3	2239
10.5	2297
9.2	2354
8.6	2385
6.8	2507
5.8	2566
5	2629

Segundo Paso:

Como obligatoriamente necesitamos usar un convertidor Analogico digital para poder digitalizar la señal necesitamos obtener el resultado de la conversion para cada uno de los valores anteriores

Primero procedemos a obtener la resolucion del convertidor, si consideramos que el voltaje de referencia es de 5V y nuestro convertidor es de 12 bits su resolucion sera la siguiente:

Resolución = Voltaje Referencia / (2^12)
Resolución = 5 / 4096
Resolucion = 1.2207 mV

Sabiendo que el valor digital es igual al voltaje medido entre la resolucion podemos anexar una nueva tabla donde podamos ver el valor esperado de conversion (los valores estan redondeados)

Código:
Temp Medida (°C)	Voltaje Medido (mV)	Resultado CAD
47.00	749.00	614
45.20	774.00	634
44.10	799.00	655
43.10	823.00	674
42.20	852.00	698
41.20	877.00	718
40.40	906.00	742
39.30	935.00	766
38.40	970.00	795
37.40	999.00	818
36.40	1033.00	846
35.30	1068.00	875
34.50	1101.00	902
33.50	1136.00	931
32.50	1174.00	962
31.60	1209.00	990
30.60	1248.00	1022
29.70	1287.00	1054
28.50	1331.00	1090
27.60	1370.00	1122
26.90	1413.00	1158
25.60	1458.00	1194
24.90	1502.00	1230
23.70	1547.00	1267
22.70	1595.00	1307
21.80	1642.00	1345
20.80	1692.00	1386
20.00	1740.00	1425
18.90	1793.00	1469
18.00	1847.00	1513
17.10	1901.00	1557
16.10	1956.00	1602
15.10	2008.00	1645
14.30	2066.00	1692
13.40	2120.00	1737
12.30	2174.00	1781
11.30	2239.00	1834
10.50	2297.00	1882
9.20	2354.00	1928
8.60	2385.00	1954
6.80	2507.00	2054
5.80	2566.00	2102
5.00	2629.00	2154

Tercer Paso:

Ya que tenemos los preparativos listos es momento de aplicar el metodo de minimos cuadrados que nos generara la ecuacion de una recta que mejor aproxime nuestra tabla de valores... para todos aquellos que no esten familiarizados con el metodo pueden leer de que se trata en estas webs:

http://es.wikipedia.org/wiki/Mínimos_cuadrados
http://www.cte.edu.uy/cteI/mincuad.pdf
http://www.slideshare.net/jcoronelf/minimos-cuadrados-presentacion-final

La aplicacion es facil... solo tenemos que sustituir los valores de la tabla en el sistema de ecuaciones para obtener los valores m y b que pondremos en nuestra ecuacion mx+b (la resolucion completa se encuentra en el archivo de excell)

pendiente.png

ordenada.png


Para nuestro ejemplo tomamos el resultado del convertidor como X y la temperatura como Y por que el resultado final que necesitamos obtener es la temperatura

Los valores de salida fueron:

pendiente (m)= -0.02632091
ordenada (b)= 58.88122820

Cuarto Paso:

Existe un metodo simple que me gusta aplicar para saltarme el calculo con flotantes y funciona bastante bien, solo consiste en multiplicar todos los valores x10, x100, x1000, o asi hasta encontrar el multiplicador maximo que podamos implementar en nuestras variables, despues solo encendemos el punto decimal donde lo necesitemos y eso equivaldria a dividir todo el resultado al final

Por ejemplo, si quisieramos hacer calculos enteros con signo en 16 bits, tenemos que revisar que el valor que tomen las variables no exceda de -32768 a 32767, si multiplicamos m x 1000 tendriamos m=26 y b=58881, tendriamos que poner b en una variable de tipo signed long o nos daria un error de calculo, de otra manera tendriamos que multiplicar x 100 y vivir con el error extra generado por la perdida de decimales

Entre mayor la precision es mejor el resultado, pero el microcontrolador tendra que pasar mas tiempo haciendo los calculos, en mi caso opte multiplicar todo por 10,000 y usar variables con signo de 32 bits... asi que la subrutina quedaria de la siguiente manera:

Código:
// ---------------------------------------------------------------------
//	ajstemp.- Aplica mx+b para convertir el dato del convertidor
//		  a su equivalente en temperatura
// ---------------------------------------------------------------------

signed int ajstemp(signed int dato) {

	long signed int y;
	signed int temperatura=0;

	y=(long int)dato*-2632;				// Multiplica por M
	y=y+5888122;							// Divide entre 100
	temperatura=y;						// Trunca el resultado de long a int
	return (temperatura);
}

Por simplicidad el ejemplo mostrado se aplico usando una sola recta, pero es mucho mejor dividir la curva en varias partes y aproximar cada una por una recta individual, asi se puede reducir mucho el error generado por el calculo
 

Adjuntos

  • minimos_cuadrados_117.xls
    41 KB · Visitas: 417
Última edición:
COmo estan en el caso de humedades q actuan con porcentajes por ejemplo de 0 a 100% cual es la rutina q deberia implementar, ademas si toy usando asembler en vez de C como seria el subprgrama.
Espero q puedan guiarme en esto =) xcias
 
Esta misma formula la he aplicado yo recientemente a una libreria glcd para hacer rectas, mire las librerias que habia pero se complicaban demasiado, con unos pocos calculos consegui poder hacer rectas con distintas pendientes y/o offsets.

Tambien me fue util en sensores lineales de presion.

Sinceramente me costo entenderla, porque la pendiente no habia ningun problema, era simple, pero la ordenada me costo mucho entenderla despues de ver muchas paginas de calculos.

Como tu hiciste yo tambien hice, evitar los flotantes, unicamente *1000 y al final /1000 y no hay mas problemas :LOL:

COmo estan en el caso de humedades q actuan con porcentajes por ejemplo de 0 a 100% cual es la rutina q deberia implementar, ademas si toy usando asembler en vez de C como seria el subprgrama.
Espero q puedan guiarme en esto =) xcias

Una simple regla de tres.

Si estas usando ADC y el sensor da 5V al 100% de humedad seria:

1024-------100%
ADC---------X%

Cambias el valor de ADC por el que te de el modulo adc.

Sobre en asm pues debes ver como multiplicar y dividir. Seria: x=adc*100/1024
 
Última edición:
Atrás
Arriba