En esta sesión vamos a definir la utilidad del concepto umbral.
Hemos de tener en cuenta que las señales eléctricas no siempre son estables, que los materiales de nuestros sensores pueden no ser lo mejores y que los golpes en un robot en movimiento pueden afectar a la transmisión correcta de los eventos a detectar por nuestros programas.
Para ello definiremos el modelo de control por umbral o Threshold.
Material para realizar los ejercicios
- 2x Leds
- Potenciómetro – o un LDR – Sensor de luz
Control Umbral
int LED; int pot; int threshold; int val; void setup() { Serial.begin(9600); pinMode(pot, INPUT); pinMode(LED, OUTPUT); LED = (int)(3); pot = (int)(0); threshold = (int)(450); } void loop() { val = (analogRead(pot)); Serial.println(val); if (val > threshold) { digitalWrite(LED, HIGH); } else { digitalWrite(LED, LOW); } }
Este sistema de control se representa en las figuras de abajo. De forma simple se define un valor umbral para el potenciometro, de manera que; en el momento que se sobrepasa ese valor se activa el LED y si vamos disminuyendo su valor ocurre lo contrario y se apaga.

Control Relay
Aunque parezca muy evidente, éste no es el mejor controlador para según qué sistema.
Sobre todo si estamos cerca del valor umbral. El error del potenciómetro; o ruido; puede ofrecernos alternativamente un valor menor que el valor umbral en un instante y un valor mayor en otro instante, haciendo que el LED se apague y se encienda muchas veces.
Supongamos que con este valor manipulamos la temperatura de nuestra habitación. Cada vez que el sistema aumenta o disminuye un grado se pone en marcha una serie de elementos que consumen mucha energía.
Para evitar un consumo continuo, lo lógico es establecer una serie de rangos de temperatura para la que nuestro sistema se activa hasta alcanzar la temperatura deseada y que se mantenga con el mínimo gasto energético posible.
En la siguiente figura se expone el comportamiento de este sistema.
De forma concreta, establecemos un rango entre 450º y 800º que podría ser el calor que hace en el infierno, dependiendo de lo malo que hayamos sido en vida.
Siguiendo la linea verde, el sistema de ventilación se activará en el momento que hayamos superado los 800º, y empezaríamos a sudar un poco. En el momento que el sistema se ha activado; la linea que se sigue en la gráfica es la linea roja y en lugar de desconectarse cuando alcanzamos valores menores de 800º, se desconectará cuando disminuye de los 450º.
De esta manera, el sistema de ventilación solo trabaja en ese rango determinado y evitamos el efecto de errores o ruido sobre la señal de entrada, además de refrescarnos para que nuestra estancia en el inframundo sea más llevadera.
El código a realizar para este controlador es el siguiente.
int LED; int pot; int threshold_L; int threshold_H; boolean state; int val; void setup() { Serial.begin(9600); pinMode(pot, INPUT); pinMode(LED, OUTPUT); LED = (int)(3); pot = (int)(0); threshold_L = (int)(450); threshold_H = (int)(800); state = (boolean)(false); if ((analogRead(pot)) > threshold_L) { state = true; } else if ((analogRead(pot)) < threshold_H) { state = false; } } void loop() { val = (analogRead(pot)); Serial.println(val); if (state == false && val > threshold_H) { state = true; digitalWrite(LED, HIGH); } else if (state == true && val < threshold_L) { state = false; digitalWrite(LED, LOW); } }
Control Lineal con saturación
Otro sistema de control viene representado por la siguiente figura en la que tenemos una relación lineal entre los valores de entrada y los valores de salida y además de ello hay un efecto de saturación por encima de un umbral.
Para realizar este ejemplo vamos a variar el efecto del delay de nuestro programa con el valor del potenciómetro y lo mapeamos entre dos valores con la función map.
La función map establece una regla de 3 entre dos pares de valores, de tal manera que creamos una relación lineal entre los valores extremos, que en este ejemplo son el valor (0 , 800) del potenciómetro, con los valores (100, 3000) [ms] que es la duración del delay.
int LED = 3; void setup() { Serial.begin(9600); pinMode(LED,OUTPUT); } void loop() { int val ; // declaración de una variable local dentro del loop val = analogRead(0); time=map(val, 0, 800, 100, 3000)); if (val > 800){ time = 3000; } digitalWrite(LED,HIGH); delay(time); digitalWrite(LED,LOW); delay(time); }
Control personalizado en rangos
Para finalizar, vamos a probar a hacer un control en el que tengamos encendido el LED en un valor del potenciómetro entre 0 y 450, se apague entre 450 y 800 y se vuelva a encender para el resto de valores. De esta manera ejercitamos nuestras sentencias condicionales.
int LED = 3; int umbral1 = 450; int umbral2 = 800; int umbral3 = 1100; void setup() { Serial.begin(9600); pinMode(LED,OUTPUT); } void loop() { int val ; // declaración de una variable local dentro del loop val = analogRead(0); Serial.println(analogRead(0)); if (val > umbral1){ digitalWrite(LED,HIGH); }else if ((val > umbral1) && (val < umbral2)){ digitalWrite(LED,LOW); }else { digitalWrite(LED,HIGH); } }
Una vez completado este tutorial, puedes acceder al siguiente nivel.
Los ejercicios de código, proyectos y recursos que desarrollaremos durante el curso se pueden consultar a través de nuestro Github.
Un comentario sobre “Curso Arduino y robótica: Control Umbral”