Balanza electrónica utilizando un sensor de presión resistivo utilizando Arduino


Objetivo: medir el peso en onzas, utilizando una balanza física, circuitería y software de programación (hiperterminal de Arduino).

Este proyecto requiere los siguientes materiales:
  • 1 Arduino UNO
  • 1 sensor de presión
  • 1 LM 258
  • 2 resistencias de 1kOhm
  • 1 resistencia de 100kOhms
  • 2 LED's (rojo y verde)
Para empezar, cabe aclarar que el sensor utilizado para este tipo de proyecto no es el ideal para medir peso. Por lo tanto este diseño se basa en un modelo estadístico para aproximar lo más posible el peso. Pero mejor empecemos hablando del sensor para entender ¿por qué no sirve funciona correctamente para esta implementación?

Empecemos porque ese sensor es resistivo, recordemos el comportamiento de una resistencia variable medida con un multimetro: tratamos de ajustar un valor, pero siempre cambia y no es estable. Así es el comportamiento de este sensor, incluso en el lugar donde se hace presión si se cambia da otros valores, así que hay que tener muy en cuenta este factor.

Según la hoja de datos este es el comportamiento del sensor:


A una mayor fuerza ejercida sobre el sensor, menor será la resistencia. Además de eso, la hoja de datos nos proporciona varios circuitos, el que yo utilicé fue este:


El AmpOp es un LM258, RM es la resistencia fija, la gráfica de la par explica que valores podemos tomar para esa resistencia y obviamente su comportamiento. Cabe resaltar que el comportamiento no es exactamente igual, pero es similar, por ejemplo si usas la resistencia de 100K no te llegara a 4.7v sino que llegaría a unos 3.7 - 4.2v (Es muy importante para tu modelación que pruebes antes este circuito).

A mí no me dejó satisfecho el comportamiento de este circuito, así que decidí hacer el divisor de voltaje que hay entre RM y FSR invertido, el resultado obviamente es inverso, pero me gustó más los resultados muestreados. El circuito que use para todo el proyecto es el siguiente, tiene un led rojo para marcar el límite de operación del sensor (además este led parpadea cuando no hay un sensor conectado al circuito) y uno verde que indica que no sobre pasa el límite. El circuito fue hecho en Fritzing (¿Por qué Fritzing? Porque con este programa podemos hacer shields y conectarlo al Arduino sin necesidad de cables): 


Obteniendo la siguiente gráfica (basada en la medición de algunos objetos con un peso ya definido y tabulándolos):


Así que con los datos medidos, es hora de hacer una regresión (si miran la gráfica tiende a una función logarítmica, por lo tanto realicé una regresión logarítmica) con mi calculadora voyage 200.

Luego de la obtención de la ecuación de regresión se estimó los posibles rangos de medición para cada peso:
Valor medido (oz)
Valor mostrado regresión
Límite inferior
Límite superior
0
#¡NUM!
#¡NUM!
#¡NUM!
0.25
184
179
189
0.5
153
148
158
0.75
135
130
140
1
122
117
127
1.5
104
99
109
2
92
87
97
3
74
69
79
4
61
56
66
5
51
46
56
6
43
38
48
7
36
31
41
8
30
25
35
9
25
20
30
10
20
15
25
11
16
11
21
12
12
7
17
13
8
3
13
14
5
0
10
15
2
-3
7
16
-1
-6
4


Secuencia del programa:
1.       Lee pin analógico
2.       Compara el valor con un valor equivalente a la desconexión del sensor
a.        Si es afirmativo:
                                                               i.      Enciende y apaga el led rojo
                                                              ii.      lee el pin analógico
                                                            iii.      Regresa a paso 2
b.       Si es negativo:
                                                               i.      Continua con programa
3.       Repetir 5 veces
a.        lee pin analógico
b.       Compara en los distintos rangos definidos en la tabla para cada valor
                                                               i.      Si es afirmativo
1.       envía valor de onzas
                                                              ii.      Si es negativo
1.       continua el programa
c.        Retardo 500 milisegundos
d.       Vuelve a paso 3, hasta cumplir condición
4.       Compara el valor del pin analógico
a.        Si el valor no excede el rango de lectura normal
                                                               i.      Led verde = ON
                                                              ii.      Led rojo = OFF
b.       Si el valor excede el rango de lectura normal
                                                               i.      Led verde = OFF
                                                              ii.      Led rojo = ON
5.       Fin de comparación
6.       Reestablece variable
7.       Retardo de 1.5 segundos
8.       Regresa a paso 1

Código del programa con comentarios:
int secuencia = 0;
int Pinanalogo = A0;    // coloco en una variable el pin analogo
int valor = 0;  // variable que almacenará la lectura analóga
 void setup() {
  Serial.begin(9600); //inicia el protocolo de comunicación a PC
  pinMode(2,OUTPUT); //pin digital 2 salida
  pinMode(3,OUTPUT); //pin digital 3 salida
}
 void loop() {
  valor = analogRead(Pinanalogo);
  while (valor > 600)
  {
    digitalWrite(3,LOW); //pin digital 3 en 0 lógico
    delay (150);
    digitalWrite(3,HIGH); //pin digital 2 en 1 lógico
    delay (150);
    valor = analogRead(Pinanalogo);
  }
  digitalWrite(3,LOW); //pin digital 3 en 0 lógico
    for (secuencia=0;secuencia<6;secuencia++)
    {
      valor = analogRead(Pinanalogo); // almacena en "valor" la lectura analoga
      if (valor > 178 && valor< 188) //condicion para 0.25 onza
      {
          Serial.println("0.25 onza");
      }
      if (valor > 148 && valor< 158) //condicion para 0.5 onza
      {
          Serial.println("0.5 onza");
      }
      if (valor > 130 && valor< 140) //condicion para 0.75 onza
      {
          Serial.println("0.75 onza");
      }
      if (valor > 115 && valor< 127) //condicion para 1 onza
      {
          Serial.println("1 onza");
      }
      if (valor > 99 && valor< 109) //condición para 1.5 onzas
      {
          Serial.println("1.5 onzas");
      }
      if (valor > 86 && valor< 96) //condicion para 2 onzas
      {
          Serial.println("2 onzas");
      }
      if (valor > 68 && valor< 78) // condición para 3 onzas
      {
          Serial.println("3 onzas");
      }
      if (valor > 55 && valor< 65) //condición para 4 onzas
      {
          Serial.println("4 onzas");
      }
      if (valor > 45 && valor< 55) //condición para 5 onzas
      {
          Serial.println("5 onzas");
      }
      if (valor > 37 && valor< 47) //condición para 6 onzas
      {
          Serial.println("6 onzas");
      }
      if (valor > 30 && valor< 40) //condición para 7 onzas
      {
          Serial.println("7 onzas");
      }
      if (valor > 24 && valor< 34) //condición para 8 onzas
      {
          Serial.println("8 onzas");
      }
        if (valor > 19 && valor< 29) //condición para 9 onzas
      {
          Serial.println("9 onzas");
      }
        if (valor > 21 && valor< 25) //condición para 10 onzas
      {
          Serial.println("10 onzas");
      }
        if (valor > 17 && valor< 20) //condición para 11 onzas
      {
          Serial.println("11 onzas");
      }
      if (valor > 12 && valor< 16) //condición para 12 onzas
      {
          Serial.println("12 onzas");
      }
      if (valor > 9 && valor< 13) //condición para 13 onzas
      {
          Serial.println("13 onzas");
      }
      if (valor > 6 && valor< 10) //condición para 14 onzas
      {
          Serial.println("14 onzas");
      }
      if (valor > 5 && valor< 7) //condición para 15 onzas
      {
          Serial.println("15 onzas");
      }
      if (valor > 0 && valor< 4) //condición para 16 onzas
      {
          Serial.println("16 onzas");
      }
      delay(500);
    }
  if (valor > 30) //condiciones para leds
  {
    digitalWrite(3,LOW); //pin digital 3 en 0 lógico
    digitalWrite(2,HIGH); //pin digital 2 en 1 lógico
  }
  else
  {
    digitalWrite(2,LOW); //pin digital 2 en 0 lógico
    digitalWrite(3,HIGH); // pin digital 3 en 1 lógico
  }
  secuencia=0;
  delay(1500); // retardo 1.5 segundos
}
Recomendaciones:
  • Utilizar un Amplificador Operacional en modo de seguidor de corriente, es una técnica que se debe aplicar al momento de leer un valor analógico, de esta manera estamos protegiendo al microcontrolador, ya que el Amplificador Operacional en esta configuración se comporta: Ventrada=Vsalida.
  • Utilizar indicadores visuales al momento de alguna falla como lo son LED's, así se podrá tener una noción de lo que está sucediendo.
  • Realizar un buen diseño de balanza para que pueda concentrar en un solo punto la fuerza ejercida al sensor resistivo y así tener una lectura más o menos constante.
  • Utilizar los "shields" para Arduino simplifican la conexión a través de alambres y evita que las soldaduras se puedan quebrar ya que no se usan alambras para conectar al Arduino.
  • Utilizar un sensor de peso en lugar del sensor de presión resistivo, como lo habíamos indicado en los retos encontrados, este sensor no es bueno para medir el peso de objetos, sino más bien para medir el empuje o presión que alguien o algo ejerce al sensor. Recomendamos que se utilice este sensor: http://www.sparkfun.com/products/10245. Claramente se puede observar en sus especificaciones que fue diseñado para medir peso y no fuerza como el sensor resistivo.