sábado, 25 de febrero de 2017

Implementación de un Paso de Peatones con Sensores Inteligentes de Bajo Coste. Parte III

Sistema Software

Software nodo terminal


La calibración de los sensores trata de establecer la relación que existe entre las medidas reales y las medidas tomadas por los sensores, en este caso solo es necesario calibrar el sensor de luz. Consistirá en rellenar la tabla lockup con 4 valores medidos y asignarle 4 valores reales. A partir de estos valores se obtiene el valor máximo y mínimo de la luminosidad. 
Tanto para obtener la luz como la distancia, el algoritmo para la obtención de medidas es el que se muestra a continuación:
 
 Para más info


A continuación, se muestra el código .ino correspondiente a la calibración y obtención de medidas para el dispositivo WeMos D1.

  ///////////////////////////////////////////////////////////////////////////
 //////////////////////VARIABLES OBTENCION LUZ/////////////////////////////
 //////////////////////////////////////////////////////////////////////////
 int medidas_luz[10] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0};  //valores de ejemplo
 int n_medidas_luz=10;
 int real_luz[4] = {0, 323, 626, 934};                  //valores de ejemplo
 int medida_luz[4] = {8, 852, 867, 913};                //valores de ejemplo
 int n_lookup_luz = 4;
 int min_medida_luz = 8;                                //valores de ejemplo
 int max_medida_luz = 913;                              //valores de ejemplo
 int min_real_luz = 0;                                //valores de ejemplo
 int max_real_luz = 934;                              //valores de ejemplo
 int old_index_luz = 0;
 int tolerancia_luz = 2;
 int out_luz=0;
 ///////////////////////////////////////////////////////////////////////////
 ////////////////////VARIABLES OBTENCION DISTANCIA//////////////////////////
 //////////////////////////////////////////////////////////////////////////
 int medidas_distancia[10] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0};  //->valores de ejemplo
 int n_medidas_distancia=10;
 int min_medida_distancia = 3;                                //->valores de ejemplo
 int max_medida_distancia = 13;                              //->valores de ejemplo
 int min_real_distancia = 3;                                //->valores de ejemplo
 int max_real_distancia = 13;                              //->valores de ejemplo
 int old_index_distancia = 0;
 int tolerancia_distancia = 2;
 int out_distancia=0;
//FUNCION QUE MAPEA LA VARIABLE DE ENTRADA CON EL RANGO DE ENTRADA EN EL RANGO DE SALIDA
double mapdouble(double x, double in_min, double in_max, double out_min, double out_max)
{
 return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
}

 //FUNCION QUE RESTRINGE EL RANGO DE UNA VARIABLE
 double constraintdouble(double x, double in_min, double in_max){
  if(x<in_min){
    return in_min;
  }else if(x>in_max){
    return in_max;
  }else{
    return x;
  }
}

//FUNCION QUE OBTIENE LA MEDIDA DE LA LUZ A PARTIR DE LA TABLA LOOK UP

 int look_up_luz(){
    int luz_in = analogRead(LDR);
    int luz_out=0;
    if (luz_in < min_medida_luz) {
      luz_out = real_luz[0];
    } else if (luz_in > max_medida_luz) {
      luz_out = real_luz[n_lookup_luz - 1];
    } else {
      int i = 1;
      while (i < (n_lookup_luz - 1) && medida_luz[i] < luz_in) {
        i++;
      }
      luz_out = map(luz_in, medida_luz[i - 1], medida_luz[i], real_luz[i - 1], real_luz[i]);
    }
    //Serial.print("Luz lookup: ");   Serial.println(luz_out);
    return luz_out;
}

//FUNCION QUE OBTIENE LA MEDIA DE LAS MEDIDAS ALMACENADAS EN EL CASO DE LA LUZint mean_medidas_luz() {
  float sum = 0;

  for (int i = 0; i < n_medidas_luz; i++) {
    sum = sum + medidas_luz[i];
  }
  return round(sum / n_medidas_luz);
}

//FUNCION QUE OBTIENE LA MEDIA DE LAS MEDIDAS ALMACENADAS EN EL CASO DE LA DISTANCIAint mean_medidas_distancia() {
  float sum = 0;
  for (int i = 0; i < n_medidas_distancia; i++) {
    sum = sum + medidas_distancia[i];
  }
  return round(sum / n_medidas_distancia);
}

//FUNCION QUE OBTIENE LA MEDIDA DE LA DISTANCIA

 int distancia() {
  long tiempo;
  digitalWrite(TRIGPIN, LOW); /* Por cuestión de estabilización del sensor*/
  delayMicroseconds(2);
  digitalWrite(TRIGPIN, HIGH); /* envío del pulso ultrasónico*/
  delayMicroseconds(10);
  digitalWrite(TRIGPIN, LOW);
  tiempo = pulseIn(ECHOPIN, HIGH); /* Función para medir la longitud del pulso entrante. Mide el tiempo que transcurrido entre el envío
  del pulso ultrasónico y cuando el sensor recibe el rebote, es decir: desde que el pin 12 empieza a recibir el rebote, HIGH, hasta que
  deja de hacerlo, LOW, la longitud del pulso entrante*/
  int distancia = int(tiempo/58.2); /*fórmula para calcular la distancia obteniendo un valor entero*/
  /*Monitorización en centímetros por el monitor serial*/
  if (distancia < min_medida_distancia) {
    distancia = min_medida_distancia;
  } else if (distancia > max_medida_distancia) {
    distancia = max_medida_distancia;
  }
  return distancia;
}
//FUNCION DE INICIALIZACION PRINCIPAL
void setup() {
  Serial.begin(115200);
 delay(100);
  ///////////////////////////////////////////////////////////////////////////
  ///////////////////////CALIBRACION LUZ (LDR)///////////////////////////////
  //////////////////////////////////////////////////////////////////////////
  pinMode(LDR, INPUT);
  for (int i = 0; i < n_medidas_luz; i++) {
    medidas_luz[i] = 0;
  }
  Serial.println("CALIBRACION DEL SENSOR");
  char continuar = 'n';
  while (continuar == 'n') {
    Serial.println("A continuacion se deberan introducir 4 valores de menor a mayor del sensor de iluminacion");
    int i = 0;
    while (i < n_lookup_luz) {
      Serial.print("Introduzca el valor real actual ");
      Serial.println((i + 1));
      while (!Serial.available()) {}
      real_luz[i] = Serial.parseInt();
      medida_luz[i] = analogRead(LDR);
      i++;
    }
    Serial.println("Tabla Lockup");
    Serial.println("Medida, Real");
    for (int i = 0; i < n_lookup_luz; i++) {
      Serial.print(medida_luz[i]);
      Serial.print(",");
      Serial.println(real_luz[i]);
    }
    do {
      Serial.println("¿Los valores son correctos? (y/n)");
      while (!Serial.available()) {
      }
      continuar = (char)Serial.read();
    } while (continuar != 'y' && continuar != 'n');
  }
  min_medida_luz = medida_luz[0];
  max_medida_luz = medida_luz[n_lookup_luz - 1];
  min_real_luz = real_luz[0];
  max_real_luz = real_luz[n_lookup_luz - 1];
  tolerancia_luz=2; //tolerancia_luz -> obtenido realizando estudio previo
  //Rellena Medidas Lookup_luz
 Serial.println("Tabla Medidas Luz Rellena");
  for (int i = 0; i < n_medidas_luz; i++) {
    medidas_luz[i] = look_up_luz();
    while (medidas_luz[i] < min_real_luz || medidas_luz[i] > max_real_luz) {
      medidas_luz[i] = look_up_luz();
    }
  }
  ///////////////////////////////////////////////////////////////////////////
  //////////////////CALIBRACION DISTANCIA (HC-SR04)/////////////////////////
  //////////////////////////////////////////////////////////////////////////
  //No es necesario calibracion, solo inicializacion
  pinMode(TRIGPIN, OUTPUT); /*activación del pin 9 como salida: para el pulso ultrasónico*/
  pinMode(ECHOPIN, INPUT);
  for (int i = 0; i < n_medidas_distancia; i++) {
    medidas_distancia[i] = 0;
  }
  //Relleno Medidas Distancia
    Serial.println("Tabla Medidas Distancia Rellena");
  for (int i = 0; i < n_medidas_distancia; i++) {
    medidas_distancia[i] = distancia();//obtener distancia del sensor
    while (medidas_distancia[i] < min_real_distancia || medidas_distancia[i] > max_real_distancia) {
      medidas_distancia[i] = distancia();//obtener distancia del sensor);
    }
  }
}

//FUNCION BUCLE PRINCIPAL
 void loop() {   
  //////////////OBTENCION LUZ (0,1)//////////////
  int in_luz = look_up_luz();
  while (in_luz < min_real_luz || in_luz > max_real_luz) {
    in_luz = look_up_luz();
  }
  medidas_luz[old_index_luz] = in_luz;
  old_index_luz = (old_index_luz + 1) % n_medidas_luz;
  int result_mean_luz = mean_medidas_luz();
  if (in_luz > (result_mean_luz - tolerancia_luz) && in_luz < (result_mean_luz+ tolerancia_luz)) {
    out_luz = result_mean_luz;
  }
  //Serial.println(out_luz);
  ///////////OBTENCION DISTANCIA (0,1)///////////
   int in_distancia = distancia();//obtener distancia del sensor
  while (in_distancia < min_real_distancia || in_distancia > max_real_distancia) {
    in_distancia = distancia();//obtener distancia del sensor);
  }
  medidas_distancia[old_index_distancia] = in_distancia;
  old_index_distancia = (old_index_distancia + 1) % n_medidas_distancia;
  int result_mean_distancia = mean_medidas_distancia();
  if (in_distancia > (result_mean_distancia - tolerancia_distancia) && in_distancia < (result_mean_distancia + tolerancia_distancia)) {
    out_distancia = result_mean_distancia;
  }
}


<<Anterior 

No hay comentarios:

Publicar un comentario