Curso Arduino y robótica: Control Umbral

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.

Documentacion ZaragozaMakerSpace Github

Un comentario sobre “Curso Arduino y robótica: Control Umbral

Deja un comentario

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

1 × cinco =

Este sitio usa Akismet para reducir el spam. Aprende cómo se procesan los datos de tus comentarios.