Cómo amplificar la señal de un sensor (mps20n0040d) para medirlo con un microcontrolador

Amplificar señales eléctricas utilizando OpAmp

Introducción
Existen sensores de presión diseñados para distintos rangos de presión. El sensor mps20n0040d-s es un sensor con la capacidad de medir de 0 a 5.8 psi (0 a 40kPa). Este sensor es de baja gama y su uso se limita a percibir diferencias de presión.

Esto sensores de presión internamente utilizan una configuración resistiva llamada Wheatstone Bridge el cual se muestra en la siguiente figura:

Wheatstone Bridge

El Wheatstone Bridge se utiliza para medir una resistencia desconocida (Rx) utilizando una resistencia variable (R2) y dos resistencias conocidas (R1 y R3).

Para determinar RX debemos resolver el circuito:

Es claro que la corriente que circula debe cumplir:

I_{AD} = I_{DC} = I = \frac{E}{R_1+R_2}
I_{AB} = I_{BC} = I_X = \frac{E}{R_3+R_x}

Por lo tanto la diferencia de potencial que mide el galvanómetro V_DB es:

V_{DB} = R_2\cdot I - R_X \cdot I_X

Luego:

V_{DB} = E\left(\frac{R_2}{R_1+R_2} - \frac{R_X}{R_3+R_x}\right) = E\cdot R\left(R_1, R_2, R_3, R_X\right)

Lamentablemente, el datasheet de estos sensores es de mala calidad, por lo que no especifica claramente el valor de las resistencias internas y cómo cambian con la presión. Realizando mediciones, las resistencias parecen ser de 4k. Según el datasheet, la variación de potencial debería ser de 50mV a 100mV al alimentarlo con 5V.

Cómo calcular circuitos con OpAmps
Un OpAmp es un amplificador, a continuación un diagrama de un OpAmp:

Modelo de un OpAmp

Un opamp ideal cumple lo siguiente:

G = +\infty
R_{in} = +\infty\Omega
R_{out} = 0 \Omega
V_{S+} = +\infty V
V_{S-} = -\infty V

Un OpAmp ideal normalmente es usado con retroalimentación negativa. En palabras simples un opamp está en configurado con retroalimentación negativa cuando (esto no es 100% correcto): La salida del OpAmp (v_oul) está conectada de alguna manera con su entrada no inversora (v-). Y cuando esto sucede, la salida va a tomar un valor tal que v-=v+. Es decir, un OpAmp ideal con retroalimentación negativa cumple (además de lo anterior):

v_- = v_+

Esto es suficiente para calcular circuitos con un OpAmp.

Cómo amplificar una señal eléctrica (ejemplo con mps20n0040d)
El MPS20N0040D utiliza un circuito similar al Wheatstone Bridge y tiene una impedancia de salida altísima. Por lo tanto, para hacer este sensor apto para ser medido, es ideal un seguidor de voltaje en sus dos terminales de salida. En la siguiente figura se muestra OpAmp en configuración amplificador:

seguidor de voltaje

El voltaje de salida de este OpAmp se calcula de la siguiente forma:

V_1 = V_{in} \quad \text{ (retroalimentaci\'on negativa)}

Luego la corriente I_F va a estar dada por:

I_F = V_{in}/R_2 \quad \text{ (recordar el OpAmp ideal cumple) } R_{in}=\infty\Omega

Luego Vout:

V_{out} = V_{in} + I_F\cdot R_F = V_{in} + V_{in}\cdot R_F/R_2

Si queremos un seguidor de voltaje podemos utilizar:

R_F = 0

Y para consumir menos corriente, podemos hacer:
R_2 = \infty \Omega \text{ (circuito abierto o desconectado)}

Cabe mencionar que sería mucho mejor utilizar un integrado diseñado para ser un seguidor de voltaje (también llamado buffer o driver) y no un OpAmp en esta configuración. Dejando eso de lado el circuito con el esquemático del mps20n0040d con los seguidores es:

mps20n0040d con opamp como seguidor de voltaje
Recién ahora se puede tomar la diferencia de ambas señales para leerlas con otro circuito, para leer la diferencia se utilizará un OpAmp en configuración de restador el cual se muestra en la siguiente figura:

OpAmp en configuración de restador

Utilizando el hecho de que este OpAmp está en configuración restador, se llega a la conclusión de que el voltaje de salida está dado por:

V_{OUT} = -V_1 \frac{R_3}{R_1} + V_2 \left(\frac{R_4}{R_2+R_4}\right)\left(1+\frac{R_3}{R_1}\right)

Idealmente, se desea que la señal de salida (o más bien el rango de salidas) de nuestro circuito restador esté centrada en 2.5V (VDD/2), sin embargo, sin saber cómo varian la salidas, este requerimiento dificil de lograr. Lo único que se sabe es que las salidas deberían ser alrededor de 2.5V y que la diferencia varía alrededor de los 50mV.

El circuito que queremos calcular es el siguiente:

OpAmp en configuración de restador
Si es que se tiene acceso al integrado, lo más correcto sería medir la salida del circuito para poder mapear la salida de 0 a 5V. Ejemplo: Se tiene que a 0kPa se tiene que las salidas son: 2.31V y 2.31V y que a 40kPa las salidas son 2.27V y 2.34V (estos son valores reales). Luego queremos escojer las resistencias tal que nuestro circuito mapee estas salidas a 1 y a 4V respectivamente (dejamos un margen para el error). Esto se puede hacer resolviendo un sistema de ecuaciones no lineal, sin embargo, es preferible hacerlo resolviendo un problema de optimización ya que en realidad hay 4 variables y solo 2 igualdades. Para este ejemplo utilizamos una librería de python para resolver problemas de optimización no lineales llamado scipy:

#!/usr/bin/env python
#  Copyright (C) 2019 Tomas Arturo Herrera Castro 
#
#  This program is free software: you can redistribute it and/or modify
#  it under the terms of the GNU General Public License as published by
#  the Free Software Foundation, either version 3 of the License, or
#  (at your option) any later version.
#
#  This program is distributed in the hope that it will be useful,
#  but WITHOUT ANY WARRANTY; without even the implied warranty of
#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#  GNU General Public License for more details.
#
#  You should have received a copy of the GNU General Public License
#  along with this program.  If not, see .
# 
#  This was code was writen by Chilean Software and Hardware developer 
#  company Southern Lake Technologies as part of its blog.
# 
#  http://www.sltech.cl
#

from scipy.optimize import minimize

# O = output
# m = minus
# p = plus

def get_restrictions():
	Vpp = 4
	Vss = 1
	Om_0kPa = 2.31
	Op_0kPa = 2.31
	Om_40kPa = 2.27
	Op_40kPa = 2.34

	eq1 = lambda R: Vss - Vout(R[0],R[1],R[2],R[3],	Om_0kPa, 	Op_0kPa)
	eq2 = lambda R: Vpp - Vout(R[0],R[1],R[2],R[3],	Om_40kPa, 	Op_40kPa)
	restriction = [	{"type":"eq", 	"fun":eq1	}, 
					{"type":"eq",	"fun":eq2	}]
	return restriction

def get_bounds(rmin = 100, rmax=1e5):
	return (	(rmin, rmax),
				(rmin, rmax),
				(rmin, rmax),
				(rmin, rmax))

# maximizar el valor de las resistencias (impedancia de entrada alta)
def fun_objetivo(R):
	return -(sum(R)) 

# digamos que V1 es el Output - y V2 es Output +
def Vout(R1, R2, R3, R4, V1, V2):
	return V2*R4/(R2+R4)*(1+R3/R1) - V1*R3/R1


if __name__ == "__main__":
	r0 = (1e2,1e2,1e4,1e4)
	b = get_bounds()
	res = minimize(fun_objetivo, r0, bounds = b, constraints=get_restrictions())
	print res
	# Esto es solo verificacion
	print "Solo para verificar:"
	R = res.x
	Om = 2.31
	Op = 2.31
	print "Cuando Om = {}V y Op = {}V, Vout={}V".format(Om, Op, Vout(R[0],R[1],R[2],R[3],	Om, 	Op))
	Om = 2.27
	Op = 2.34
	print "Cuando Om = {}V y Op = {}V, Vout={}V".format(Om, Op, Vout(R[0],R[1],R[2],R[3],	Om, 	Op))
Para correr este script, se requiere instalar python2 y scipy, puedes descargar el archivo aquí. El resultado es el siguiente:

resultado de scipy minimize

Nota: V1 = Output- y V2 = Output+

Podemos ver claramente que para este caso en particular las resistencias valen (cuidado, estos valores de salida son para nuestro sensor en específico, debes reemplazar tus valores para obtener el valor de las resistencias que tu necesitas):

R_1 = 2343\Omega
R_2 = 1315\Omega
R_3 = 100k\Omega
R_4 = 100k\Omega
Con esos valores vas a obtener un buen rango dinámico en tus mediciones. Simulando el circuito con
LtSpice se puede ver que funciona:

simulación opamp diferencial

simulación opamp diferencial

Puedes descargar el archivo de simulación aquí.

O puedes utilizar esta calculadora que corre el script anterior para determinar las resistencias !

VPP = VSS =

Om_0kPa = Op_0kPa =

Om_40kPa = Op_40kPa =

RMAX = RMIN =

Dar valores iniciales a la optimización:
R1_0 = R2_0 = R3_0 = R4_0 =



Nota: Para usar la calculadora debes medir las salidas con respecto a tierra a distintas presiones:

"Output", "+", "0kPa" = Op_0kPa
"Output", "-", "40kPa" = Om_40kPa

Esperamos que les sirva, cualquier duda/consulta/sugerencia pueden enviar un correo a taherrera@uc.cl

UPDATE (30/07/2019)

Gracias a Francisco por seguir este tutorial y darnos un buen feedback !! protoboard con amplificador mps20n0040d