ARD08 – Calibración automática

Facebooktwittergoogle_pluslinkedinmailFacebooktwittergoogle_pluslinkedinmail

La calibración manual está muy bien, si queremos partir de unos valores base concretos para empezar nuestras mediciones. Pero ¿que ocurre si las condiciones del entorno que queremos medir (luz, temperatura, etc) son tan variables de un momento a otro que no podemos tener un valor base durante toda la ejecución del sketch?

Piénsalo. Suponte un sensor de luz, como pueda ser una resistencia LDR (cuyo valor resistivo varía según la luz que incide sobre ella) funcionando en un entorno donde la iluminación varía constantemente, encendiendo y apagando lámparas, o por reflejos de sol a través de la ventana, etc). Lo que necesitas en este caso, para que Arduino pueda medir la iluminación relativa que incide sobre la LDR de una forma fiable a lo largo de un tiempo de funcionamiento, es una calibración automática, de modo que el valor base no venga establecido por programación, sino que se redefina según los valores máximo y mínimo de iluminación (o el parámetro que estemos midiendo), en cada momento. Veamos en este capítulo como funciona la calibración automática de sensores.

Para esto vamos a usar otra función de gestión de tiempo de ejecución. Ya conocemos la función delay(ms), que “detiene” la ejecución durante los milisegundos especificados y luego continúa. Ahora vamos a usar la función millis(), que devuelve el número de milisegundos transcurridos desde que Arduino empezó a ejecutar el sketch en curso. Este número puede llegar a ser sorprendentemente grande: se pone a cero después de, aproximadamente, cincuenta días seguidos de ejecución.

EL PROYECTO

Lo que vamos a hacer es un circuito que mida la iluminación ambiental. En función de como varíe esta, se encenderán más o menos LED’s de una escala de diez, similar a la de los vúmetros de los aparatos musicales. Estas escalas de LED tienen un aspecto parecido al de los circuitos integrados, como vemos en la figura 8.1.

Figura 8.1. Una pastilla de LEDs.

Figura 8.1. Una pastilla de LEDs.

Estos componentes contienen diez diodos LED. Normalmente son todos del mismo color, aunque también se fabrican con LED’s de diferentes colores en la misma pastilla. Nosotros, para no complicarnos, usaremos una con los diez LED’s de color rojo. Su precio en el mercado oscila entre 1 y 3 euros, según el modelo.

Estas pastillas tienen, por debajo, diez pares de pines. Cada par de pines corresponde al positivo y negativo de un LED, de tal modo que las diez patillas de un lado son los negativos de los diez LED’s, y las diez patillas del otro lado son los positivos. Como no suelen venir marcados (dependiendo del fabricante), lo primero que tenemos que hacer es determinar la polaridad. Para ello vamos a insertar la pastilla en la placa protoboard y conectarle unas resistencias de 330 Ω entre las patillas de un lado y el canal de masa, como vemos en la figura 8.2.

Figura 8.2. Prueba de polaridad de una pastilla de LED's

Figura 8.2. Prueba de polaridad de una pastilla de LED’s

Ahora conectamos la fila superior marcada con el signo – (menos) al pin GND de Arduino y la fila inferior marcada con el signo + (más) al pin 5V de la plaquita Arduino. Por supuesto, debemos conectar Arduino al ordenador por USB, o a una fuente de alimentación de entre 7 y 12 V, mediante el conector negro que hay al lado del USB.

Si la pastilla de LED’s está correctamente orientada, se encenderán todos los LED’s. Si no se enciende ninguno, sacamos la pastilla de la protoboard, la damos la vuelta y la volvemos a insertar en los mismos agujeritos.

Una vez determinados cuales son los pines positivos y negativos de la pastilla, podemos marcar los laterales con un rotulador indeleble, para evitar confusiones en el futuro.

Figura 8.3. Una resistencia LDR.

Figura 8.3. Una resistencia LDR.

Otro componente que vamos a usar en este montaje es una resistencia LDR, cuyo valor resistivo depende de la luz que recibe: a mayor intensisdad luminosa, menos resistencia en ohmios. En la figura 8.3 vemos un ejemplar.

EL CIRCUITO

Este circuito tienen algunos componentes más de los que estamos habituados. Como ya sabemos, el objetivo es que la resistencia LDR mida el nivel de luz que le llega en cada momento y, en función de dicho nivel de luz, se activen más o menos LED’s de la pastilla. El esquema teórico está en la figura 8.4.

Figura 8.4. El esquema teórico de este montaje

Figura 8.4. El esquema teórico de este montaje

Vamos a estudiar un poco el circuito para establecer algunos conceptos importantes de electrónica con Arduino, que nos serán muy útiles más adelante.

En primer lugar fíjate en la parte que hemos dedicado a la entrada de señal luminosa. La resistencia LDR está en serie con una resistecia fija de 10 kΩ. Cuando dos resistencias se conectan en serie (una a continuación de otra), la resistencia total entre los extremos es la suma de ambas. El valor de la LDR es, como sabemos, variable. En oscuridad total puede llegar a infinito (como si el circuito estuviera cortado) mientras que con un nivel lo suficientemente elevado de luz puede ser prácticamente 0 (como si fuera un trocito de cable). Como la serie de ambas resistencias está entre el positivo y la masa, quiere decir que entre ambos puntos siempre habrá, como mínimo, los 10 kΩ de la resistencia fija, con lo que nunca se producirá un cortocircuito que pudiera llegar a dañar la placa Arduino.

La señal que leemos la sacamos del punto de unión entre las resistencias. Esto es lo que se conoce en electrónica como un divisor de tensión. El voltaje en el punto medio con respecto a la masa es proporcional al valor de ambas resistencias. Por ejemplo. Supongamos que tenemos la LDR en oscuridad absoluta. Su valor resistivo es infinito (o prácticamente infinito: en todo caso, sumamente elevado). Eso quiere decir que toda la tensión cae en esa resistencia. Por lo tanto, en el punto medio (donde tomamos la señal) no tendremos tensión. En este caso la resistencia fija de 10 kΩ no es relevante, es como si el punto medio estuviera, directamente, conectado a masa. Ahora aumentemos, siguiendo este este razonamiento, un poco la luz que incide en la LDR. Digamos que la aumentamos hasta que su valor resistivo sea de 10kΩ. En ese caso ambas resistencias tienen el mismo valor. Como la alimentación proporcionada por Arduino es de 5V. en el punto medio estaremos midiendo 2,5V. justo la mitad. Al ser ambas resistencias iguales, en cada una “cae” la mitad de la tensión.

Ahora seguimos aumentando la luz que incide sobre la LDR. Supongamos que su valor es cero. Como decíamos, esto es como un cortocircuito entre el punto medio y la alimentación. Por lo tanto, en el punto medio tendremos los 5V. de Arduino.

Este concepto del divisor de tensión formado por dos resistencias es muy empleado en electrónica y, cuando una de ellas es variable en base a un parámetro ambiental (como, en este caso, la luz), la tensión del punto medio varia en base a dicho parámetro. Como vemos en el esquema, conectamos el punto medio del divisor de tensión a una entrada analógica de Arduino, para poder medir su valor.

Ahora observemos la salida. La pastilla de LED’s es como si fueran diez LED’s independientes, solo que, físicamente, es más cómodo manejarlos así. Observa que están conectados a los pines digitales de 2 al 11 ¿Por qué hemos empezado a conectar los LED’s apartir del pin 2? ¿Por qué no hemos usado el 0 y el 1? Observa tu placa Arduino. Verás que los pines digitales 0 y 1 tienen serigrafiadas las indicaciones RX y TX, respectivamente. Esto nos indica que se usan para recepción y transmisión de datos serie: en realidad, actúan como una copia de los datos serie que se transmiten por el cable USB al ordenador. Cuando no se usa el objeto Serial de la programación de Arduino, estos pines pueden usarse como pines digitales normales. Sin embargo, cuando usamos el objeto Serial, la transmisión de datos interfiere con las señales que queramos enviar o recibir por estos dos pines. Como en este montaje vamos a incluir transmisión de datos serie, descartamos estos dos primeros pines. El montaje final queda con un aspecto como el que ves en la figura 8.5.

Figura 8.5. El montaje físico de este artículo.

Figura 8.5. El montaje físico de este artículo.

La parte hardware ya la tenemos completada, y nos ha enseñado algo de electrónica (el divisor de tensión) y algo más sobre los pines de Arduino. Ahora vamos con el sketch. Agárrate al asiento.

EL SKETCH

El sketch completo, que luego analizaremos paso a paso, es el siguiente:

Como ya es habitual, en el primer bloque de código se definen las variables y constantes que emplearemos en el sketch: pinSensor es el pin donde conectamos el divisor de tensión, para medir el voltaje que cae en la LDR, es decir, el nivel de luz que la resistencia percibe; valorSensor es la variable donde se leerá, en cada momento, la tensión que da la LDR; LED es una variable que se referirá al pin de conexión de cada uno de los LED’s de la pastilla. Como van a ir de 2 a 11, empezamos asignándole un valor inicial de 2; valorMaximo y valorMinimo serán los límites de tensión que entregue la LDR, en base a los límites de luz ambiental en el funcionamiento de nuestro montaje; por último, intensidadLuz será el valor de luz que está midiendo la LDR, con respecto a los límites valorMaximo y valorMinimo, calculada a partir de la tensión que de al pin de entrada.

Dentro de la sección setup realizamos varias operaciones: en primer lugar, establecemos los pines del 2 al 11 como de salida, con un valor digital LOW (0), para que los diez LEDs de la pastilla queden apagados.

A continuación abrimos la conexión serie para poder comunicar la placa Arduino con el ordenador. Recuerda que, como los datos serie, además del cable USB, también están presentes en los pines digitales 0 y 1, esta es la razón por la que los led se conectan a partir del pin 2.

Y ahora entramos en un proceso llamado calibración automática. Se trata de calibrar un sensor analógico (en este ejemplo la LDR) para que luego nos de una medida realista. Lo que hacemos es que, durante un determinado periodo de tiempo, vamos a registrar los valores máximo y mínimo que detecte el sensor, y los vamos a almacenar, de modo que luego se medirán los datos como fluctuaciones entre dichos límites. Para ello, lo primero que debemos hacer es un proceso que se esté ejecutando durante un cierto periodo de de tiempo. La función delay() no nos vale en este caso, porque lo que hace es detener temporalmente la ejecución, pero durante ese tiempo no se mide nada, ni se lleva a cabo ninguna tarea. En su lugar vamos a emplear la función millis() que nos devuelve el tiempo en milisegundos transcurrido desde que se cargó el sketch y se empezó a ejecutar. Observa el siguiente bucle.

Este bucle se inicia comprobando si el tiempo en ejecución es menor que 5000 milisegundos, es decir, cinco segundos. Si es así, se repite, y vuelve a comprobar el tiempo de ejecución devuelto por la función millis(). Cuando alcanza (o supera) el valor indicado (5000 milisegundos), termina de repetirse el bucle, y la ejecución continúa en la siguiente línea de código. Salvo condiciones muy variables, cinco segundos es tiempo más que suficiente para calibrar un sensor.

Pero tenemos el bucle. Aún no mide nada, ni calibra nada, ni hace nada. Dentro del bucle, vamos a introducir el código de calibración, como vemos a continuación:

Veamos lo que hace. Una vez entramos en el bucle, se mide el valor aportado por la LDR que, como ya sabemos, entra por el pin analógico A0 (porque así lo hemos definido y construido; podríamos haber usado otro pin). Si este valor es mayor que el máximo que tenemos en ese momento (que, en la primera iteración es 0, como definimos en el primer bloque de código) el valor medido se almacena como máximo. A continuación se comprueba si es menor que el mínimo. En ese caso, el valor medido se almacena como el mínimo.

En la siguiente iteración se repite el proceso, y así, sucesivamente. Dada la velocidad de trabajo de los circuitos electrónicos de Arduino, en cinco segundos se reitera muchísimas veces, de modo que se actualizan los valores máximo y mínimo.

Al final de los cinco segundos tenemos unos límites que reflejan perfectamente las fluctuaciones de la luz ambiental. Veamos ahora como podemos usar esos límites para nuestro medidor de luz, en la sección loop. Lo primero es medir el valor que nos da la LDR, así:

A continuación lo mapeamos con la ya conocida función map(), de modo que, a partir de los valores mínimo y máximo que obtuvimos durante la calibración, se obtenga un valor entre 0 y 10, así:

Este valor se almacena en la variable intensidadLuz. Y ¿por qué entre 0 y 10? Pues porque contamos una pastilla de diez LED’s y queremos que, según el valor medido, se enciendan más o menos de dichos LED’s. Así podremos hacer coincidir el valor con el número de LED’s que se encenderán. Ahora entramos en un bucle que va a recorrer los diez pines de salida a los que tenemos conectados los LED. En base al valor de intensidadLuz encenderá unos u otros, así:

Fíjate que el bucle se recorre desde un valor inicial 1 a un valor que sea menor o igual que 10, es decir, de 1 a 10. Pero los pines de salida van numerados de 2 a 11, como ya vimos, así que en cada iteración, se refiere al pin que corresponde a la variable de control led más 1 (cuando la variable vale 1, se refiere al pin 2, cuando la variable vale 2, se refiere al pin 3, y así sucesivamente). Al pin indicado, al ser digital, se le puede asignar un valor HIGH (encendido, o true) o LOW (apagado, o false). Quizá no veas clara la operativa de este código, porque lo he optimizado al máximo. Te muestro la versión “extendida”, para que lo entiendas mejor:

Veamos como actúa. Supongamos que, en un momento dado, el valor de intensidadLuz es 3. Iniciamos el recorrido del bucle for:

  • Primera iteración. La variable led vale 1. Como 3 es mayor que 0, en el pin 2 se establece el valor HIGH.
  • Segunda iteración. La variable led vale 2. Como 3 es mayor que 1, en el pin 3 se establece el valor HIGH.
  • Tercera iteración. La variable led vale 3. Como 3 es mayor que 2, en el pin 4 se establece el valor HIGH.
  • Cuarta iteración. La variable led vale 4. Como 3 NO es mayor que 3, en el pin 5 se establece el valor LOW.
  • Quinta y sucesivas iteraciones. Igual que en la cuarta, estableciendo el valor LOW en los demás pines, hasta el 11.

Después de acabar las diez iteraciones, se envían los datos de la medición a la consola serie, para poder verlos en el IDE de Arduino, se demora un tiempo, y se vuelve a empezar el loop.

Todo esto ocurre tan deprisa que, por lo que a nosotros los humanos respecta, la respuesta es inmediata. Prueba el circuito tapando parcialmente la LDR con la mano o un papel. Verás que, según la tapes más o menos, cambia el numero de LED’s que hay encendidos. No la tapes durante los primeros cinco segundos, para que se haga adecuadamente la calibración en base a la luz ambiental.

Podemos desarrollar nuestros códigos en la versión extendida para probarlos y depurarlos, pero es bueno acostumbrarse a optimizarlos lo más posible cuando ya funcionan como queremos.

     

2 comentarios:

  1. Buenas noches, os ha dicho alguien que vuestro blog puede ser adictiva ? estoy preocupada, desde que os recibo no puedo parar de mirar todas vuestras sugerencias y estoy muy feliz cuando recibo uno más, sois lo mejor en español, me encata vuestra presentación y el curre que hay detrás. Un beso y abrazos, MUCHAS GRACIAS POR VUESTRO TRABAJO, nos alegrais la vida.

    Saludos

    • Gracias a ti por tus palabras de aliento. Tratamos de dar lo mejor (aunque no siempre podemos sacar tiempo para colgar nuevos contenidos), y agrademos mucho que os guste.
      Esperamos no decepcionaros y daros todo lo que podamos.

      Un saludo.

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *