Proyecto 5 2017 I

Titulo

Control de Ingreso y Salida de Personas

Participantes

Cristián Estiven Hernández
Julián David Sierra Herrera
Luis Eduardo Romero Jimenez

Abstract

Counting people is an important activity, because allows in different scenarios, to make changes in real time, making life more comfortable. But it is not an easy task, because has many problems such as occlusion, overlapping, merge-split, and shadow effect. Every place without an access control system should use a counting system so they can use it to know the number of people in the place, and have good control, surveillance and for emergencies too. For this reason, we propose a system with an hc-sr04 sensor array, an Arduino UNO and an Ethernet Shield.

Problema

El sistema de conteo y verificacion de ingreso y salida de personas en ambientes empresariales, eventos publicos, servicios publicos y ambientes educativos tiene como objetivo tener un conteo efectivo para conocer exactamente el numero de personas que se encuentran en el lugar y poder actuar eficientemente en casos de emergencia.

Diseño (Arquitectura HW)

imagen%202.png

Desarrollo

Funcionamiento

El diseño y la planeacion del sistema se basa principal en llevar un conteo de la cantidad de personas que ingresan y salen de lugares donde se presenta bastante circulacion de poblacion para tener en una base de datos la cifra exacta de la poblacion que se encuentra dentro del lugar y las personas que ya no se encuentra en el lugar, para que el sistema tenga indices de error baja se tiene que buscar la poscion mas adecuada de los sensores para la toma de estos datos, para ello se tendra en cuenta una altura promedio del piso a la cintura de una persona para ubicar el sensor en ese promedio y lograr que los valores captados sean los mas presisos, ademas se tendra un arreglo de sensores para que tomen varias muestra estas sean comparadas y entregen un resultado mas preciso.

El sensor se caracterizo bajo el parametro de distancia siendo este la caracteristica mas importante ya que si a la distancia programada al sensor la persona pasa toma los datos pertinentes, si no pasa bajo la distancia de este sensor otro de ellos tomara el dato del paso de la persona y entra en funcio el arreglo de sensores, estos sensores seran controlados por medio de una arduino uno y una arduino shield Ethernet donde llegan el valor de un voltaje arrojado por el sensor, la tarjeta caracteriza el dato y realiza el conteo de la persona, el sensor envia el dato al computador, que, a partir de un script de python actua como gateway para el sensor y envia el dato al BUCKET (repositorio) a partir de comando POST HTTP para que sea registrado y luego sea almacenado en un ordenador y sea posible por el controlador del sistema ingresar al repositorio y observar los datos tomados en el dia.

Caracterización del sensor

El sensor Ultrasonido HC-SR04 de arduino, el cual tiene un rango de alcanza de 2 cm a 400 cm y tiene un rango variable de efectividad en la toma de datos de 3 mm, cada modulo HC-SR04 esta comprendido por un transmisor y un receptor.

Los principios de trabajo del sensor son los siguientes:

1. Usando el trigger por al menos 10 us para niveles de señal altas.
2. El modulo automatico envia 8 40kHz y detecta si hay un pulso de señal de vuelta.
3. Si la señal regresa, mediante altos niveles, el tiempo de salida es el tiempo de salida de la señal por el transmisor y regreso de la misma por el receptor.

sensor.png

Para calibrar la distancia a la que es necesaria la medida a registrar por el sensor se toma la siguiente ecuacion

Test distance = (high level time×velocity of sound (340M/S) / 2

tablasen%281%29.png

Descripcion de los pines del HC-SR04:

  • VCC
  • Trig (Disparo del ultrasonido)
  • Echo (Recepción del ultrasonido)
  • GND

Diagrama de sincronizacion: El diagrama de sincronizacion de distribución es mostrado debajo. sólo tiene que suministrar un corto 10uS el pulso a la entrada de Trigger para comenzar la medición de la distancia, y luego el módulo enviará una 8 explosión de ciclo de ultrasonido en 40 kHz y levantará su eco. El Eco es un objeto de distancia que es la anchura de pulso y la gama en la proporción . puede calcular la gama por el intervalo de tiempo entre el enviar a la señal de Trigger y el encubrimiento de la señal de eco. Fórmula: uS / 58 = centímetros o uS / 148 =inch; o : la gama = tiempo nivel alto * velocidad (340M/S) / 2; sugerimos para usar sobre 60ms el ciclo de medida, para prevenir la señal de gatillo a la señal de eco.

diagrasen%281%29.png

Esquemático del montaje

m1.jpeg
m3.jpeg

Posibles aplicaciones

Como se ha mencionado la funcion del sistema del conteo de personas cuando entran y cuando salen de algun lugar es posible la implementacion de este sistema en los siguientes ambientes:

1. Zonas empresariales, como edificios, oficinas y puntos de atencion al publico
2. Zonas de eventos publicos, como conciertos, eventos deportivos, eventos artisticos entre otros.
3. Zonas educativas, como Universidades, Colegios, Academias entre otros.
4. Sector de movilidad, como Buses, Transporte publico, Aviones y otros medios de transporte.

Dificultad encontrada

Establecer conexion entre el sensor y la tarjeta Beaglebone por lo cual se busco aplicar el sistema en una tarjeta arduino.

Con la Arduino se presento que En la nube no se relflejan los cambios cuando se realiza un POST.

Arduino no trabaja con HTTPS.

Se realizó la prueba al bucket con la misma configuracion, la prueba falló.

Se realizó la misma prueba con la red de la universidad, ni siquiera entró a Ubidots.

Se provee conexion a la red utilizando el computador como router, no funcionó.

Se realizaron pruebas con dos codigos de post con la misma configuracion, no sirve:
1) El primer codigo utiliza la direccion IP, falló.
2) El segundo codigo utiliza la direccion URL
No se evidencia error, pero tampoco avanza a la siguiente etapa.

Configuración - paso a paso

Se realiza el montaje del sensor.

arduino_con_ultrasonico_hc_sr04.png

Para realizar la puesta en marcha del sensor sin necesidad de instalar librerias se implementa el siguiente codigo. Se definen variables de una vez y la funcion para hacer el analisis de los datos y determinar su manejo para obtener la distancia en unidades metricas.

1. El siguiente codigo pone en funcionamiento de un sensor:

long tiempo;
int disparador = 2;   // triger
int entrada = 5;      // echo
float distancia;

void setup()
{
  pinMode(disparador, OUTPUT);
  pinMode(entrada, INPUT);

  Serial.begin(9600);
}

void loop()
{
  // lanzamos un pequeño pulso para activar el sensor
  digitalWrite(disparador, HIGH);
  delayMicroseconds(10);
  digitalWrite(disparador, LOW);

  // medimos el pulso de respuesta
  tiempo = (pulseIn(entrada, HIGH)/2); // dividido por 2 por que es el 
                                       // tiempo que el sonido tarda
                                       // en ir y en volver
  // ahora calcularemos la distancia en cm
  // sabiendo que el espacio es igual a la velocidad por el tiempo
  // y que la velocidad del sonido es de 343m/s y que el tiempo lo 
  // tenemos en millonesimas de segundo
  distancia = float(tiempo * 0.0343);

  // y lo mostramos por el puerto serie una vez por segundo
  Serial.println(distancia);
  delay(1000);
}

Los resultados son mostrados en la pantalla de comandos de la arduino.

pantalla.jpg

Se implementa la shield ethernet de arduino con la tarjeta.

EtherShield.jpg

Se realiza la prueba con los comandos HTTP "post" y "get". Es necesario deshabilitar el proxy de la red y conectar directamente la tarjeta al punto de acceso. El DHCP del AP esta activado.

WhatsApp%20Image%202017-06-08%20at%205.27.37%20PM.jpeg

2. El siguiente codigo presenta el funcionamiento de dos a mas sensores usando la libreria NEWPING:

#include <NewPing.h>

#define SONAR_NUM     2 // Number or sensors.
#define MAX_DISTANCE 400 // Maximum distance (in cm) to ping.
#define PING_INTERVAL 33 // Milliseconds between sensor pings (29ms is about the min to avoid cross-sensor echo).

unsigned long pingTimer[SONAR_NUM]; // Holds the times when the next ping should happen for each sensor.
unsigned int cm[SONAR_NUM];         // Where the ping distances are stored.
uint8_t currentSensor = 0;          // Keeps track of which sensor is active.

NewPing sonar[SONAR_NUM] = {     // Sensor object array.
  NewPing(5, 2, MAX_DISTANCE), // Each sensor's trigger pin, echo pin, and max distance to ping.
  NewPing(7, 8, MAX_DISTANCE),
};

void setup() {
  Serial.begin(9600);
  pingTimer[0] = millis() + 75;           // First ping starts at 75ms, gives time for the Arduino to chill before starting.
  for (uint8_t i = 1; i < SONAR_NUM; i++) // Set the starting time for each sensor.
    pingTimer[i] = pingTimer[i - 1] + PING_INTERVAL;
}

void loop() {
  for (uint8_t i = 0; i < SONAR_NUM; i++) { // Loop through all the sensors.
    if (millis() >= pingTimer[i]) {         // Is it this sensor's time to ping?
      pingTimer[i] += PING_INTERVAL * SONAR_NUM;  // Set next time this sensor will be pinged.
      if (i == 0 && currentSensor == SONAR_NUM - 1) oneSensorCycle(); // Sensor ping cycle complete, do something with the results.
      sonar[currentSensor].timer_stop();          // Make sure previous timer is canceled before starting a new ping (insurance).
      currentSensor = i;                          // Sensor being accessed.
      cm[currentSensor] = 0;                      // Make distance zero in case there's no ping echo for this sensor.
      sonar[currentSensor].ping_timer(echoCheck); // Do the ping (processing continues, interrupt will call echoCheck to look for echo).
    }
  }
  // The rest of your code would go here.
}

void echoCheck() { // If ping received, set the sensor distance to array.
  if (sonar[currentSensor].check_timer())
    cm[currentSensor] = sonar[currentSensor].ping_result / US_ROUNDTRIP_CM;
}

void oneSensorCycle() { // Sensor ping cycle complete, do something with the results.
  for (uint8_t i = 0; i < SONAR_NUM; i++) {

    Serial.print(cm[i]);

  }
  Serial.println();
}

Ahora se puede ver en pantalla los dos resultados de los sensores:

dos%20sensores.jpg

Con el siguiente codigo se realiza la subida de datos al repositorio:

#include <SPI.h>
#include <Ethernet.h>
#include <Time.h>
long tiempo, tiempo1;
int disparador = 5;   // triger
int entrada = 2;      // echo
int entrada1 = 8;
float distancia;
float distancia1;
boolean e=false;
boolean y=false;
String var,IO;
time_t T0;

EthernetClient client;

String idvariable_1 = "58ff93867be12b532d5053f9";
String token = "4oceb92f1sc6p66cf0svrgsoro";

void setup()
{
  pinMode(disparador, OUTPUT);
  pinMode(entrada, INPUT);
  pinMode(entrada1, INPUT);
  Serial.begin(9600);

}

void loop()
{

//  T0 = SetFecha(2016, 6, 9, 2, 0, 0);  // 6 nov 2014  20:17
//  printFecha(T0);
  // lanzamos un pequeño pulso para activar el sensor
  digitalWrite(disparador, HIGH);
  delayMicroseconds(10);
  digitalWrite(disparador, LOW);
  client.flush();                        // Se descartan bytes que no han sido leidos por el cliente. 
  client.stop();                         // Se desconecta del cliente para permitir envio frecuente de datos. 
  delay(2000);
  // medimos el pulso de respuesta
  tiempo = (pulseIn(entrada, HIGH)/2); // dividido por 2 por que es el 
  tiempo1 = (pulseIn(entrada1, HIGH)/2); // tiempo que el sonido tarda
                                       // en ir y en volver
  // ahora calcularemos la distancia en cm
  // sabiendo que el espacio es igual a la velocidad por el tiempo
  // y que la velocidad del sonido es de 343m/s y que el tiempo lo 
  // tenemos en millonesimas de segundo
  distancia = float(tiempo * 0.0343);
  distancia1 = float(tiempo1 * 0.0343);
  // y lo mostramos por el puerto serie una vez por segundo
  Serial.println(distancia);
  Serial.println(distancia1);
  delay(1000);

  if(distancia <= 50.0)
  {
    e=true;
    if(y=true)
    {
    //la persona esta saliendo
    IO="out";
    y=false;
    e=false;  
    }
  }

  if(distancia1 <=50.0)
  {
    y=true;  
    if(e=true)
    {
    //la persona esta entrando 
    IO="in";
    y=false;
    e=false; 
    }
  }

  save_value(String(IO));
}

void save_value(String IO)
   {
     // if you get a connection, report back via serial:
     int num_1= 0;
     if (IO=="out"){

     var = "\"SalidaPersonas\"";
     num_1 = var.length();
     IO="";
     }
     else if (IO=="in"){
     var = "\"IngresoPersonas\"";
     num_1 = var.length(); 
     IO="";
     }

/*
if (client.connect("things.ubidots.com", 80))
     {
       Serial.println("connected");
       //Linea de código original. 
       client.println("POST /api/v1.6/variables/" + idvariable_1 + "/values HTTP/1.1\nContent-Type: application/json\nContent-Length: " + String(num_1) + "\nX-Auth-Token: " + token + "\nHost: things.ubidots.com\n");
       Serial.println("POST /api/v1.6/variables/" + idvariable_1 + "/values HTTP/1.1\nContent-Type: application/json\nContent-Length: " + String(num_1) + "\nX-Auth-Token: " + token + "\nHost: things.ubidots.com\n");
       // En el codigo original fala agregar el valor de la variable. 
       client.print(var + "\n");
       Serial.print(var + "\n");

       client.flush();
     }*/

    if(client.connect("oblivion.usantotomas.edu.co", 8080))
    {
    Serial.println("connected");
    client.println("POST https://bucket.usantotomas.edu.co:8443/api/sensors/58ff93867be12b532d5053f9/captures?userToken=4oceb92f1sc6p66cf0svrgsoro  HTTP/1.1");
    client.println("Content-Type: appplication/json");
    String var1= "{\"sensorId\":\"58ff93867be12b532d5053f9\", \"captureTypeName\":" + String (var) +"\", \"value\": \"1\", \"captureDate\":\"2017-03-05 5:05:30\"}";
    client.println("Content-Length: "+String(var1.length()));
    client.println("X-Auth-Token: "+token);
    client.println("Host: https://bucket.usantotomas.edu.co\n");
    client.println(var1);
    Serial.println(var1);
    }
     else
     {
       // if you didn't get a connection to the server:
       Serial.println("connection failed");
     }
     if (!client.connected())
     {
       Serial.println();
       Serial.println("disconnecting.");
       client.stop();
       // do nothing forevermore:

                   // for (;;);                         
     }

     if (client.available())
     {
       char c = client.read();
       Serial.print(c);
     }
}

de esta manera se visualiza el post en la ventada de salida:

bucket.jpg

Finalmente se obtiene el siguiente codigo:

#include <SPI.h>
#include <Ethernet.h>

#include <NewPing.h>

#define SONAR_NUM     2 // Number or sensors.
#define MAX_DISTANCE 400 // Maximum distance (in cm) to ping.
#define PING_INTERVAL 33 // Milliseconds between sensor pings (29ms is about the min to avoid cross-sensor echo).

unsigned long pingTimer[SONAR_NUM]; // Holds the times when the next ping should happen for each sensor.
unsigned int cm[SONAR_NUM];         // Where the ping distances are stored.
uint8_t currentSensor = 0;  
float distancia =1000;
float distancia1=1000;
boolean e=false;
boolean y=false;
String var,IO;

EthernetClient client;

String idvariable_1 = "58ff93867be12b532d5053f9";
String token = "4oceb92f1sc6p66cf0svrgsoro";

NewPing sonar[SONAR_NUM] = {     // Sensor object array.
  NewPing(5, 2, MAX_DISTANCE), // Each sensor's trigger pin, echo pin, and max distance to ping.
  NewPing(7, 8, MAX_DISTANCE),
};

void setup()
{
Serial.begin(9600);
  pingTimer[0] = millis() + 75;           // First ping starts at 75ms, gives time for the Arduino to chill before starting.
  for (uint8_t i = 1; i < SONAR_NUM; i++) // Set the starting time for each sensor.
    pingTimer[i] = pingTimer[i - 1] + PING_INTERVAL;  

}

void loop()
{
for (uint8_t i = 0; i < SONAR_NUM; i++) { // Loop through all the sensors.
    if (millis() >= pingTimer[i]) {         // Is it this sensor's time to ping?
      pingTimer[i] += PING_INTERVAL * SONAR_NUM;  // Set next time this sensor will be pinged.
      if (i == 0 && currentSensor == SONAR_NUM - 1) oneSensorCycle(); // Sensor ping cycle complete, do something with the results.
      sonar[currentSensor].timer_stop();          // Make sure previous timer is canceled before starting a new ping (insurance).
      currentSensor = i;                          // Sensor being accessed.
      cm[currentSensor] = 0;                      // Make distance zero in case there's no ping echo for this sensor.
      sonar[currentSensor].ping_timer(echoCheck); // Do the ping (processing continues, interrupt will call echoCheck to look for echo).
    }
  }

  delay(1000);

}

void echoCheck() { // If ping received, set the sensor distance to array.
  if (sonar[currentSensor].check_timer())
    cm[currentSensor] = sonar[currentSensor].ping_result / US_ROUNDTRIP_CM;
}

void oneSensorCycle() { // Sensor ping cycle complete, do something with the results.
  for (uint8_t i = 0; i < SONAR_NUM; i++) {
    Serial.print(i);
    Serial.print("=");

    if(i==0) {
      distancia= cm[i];
      Serial.print(distancia);
      }  
    if (i==1){
      distancia1= cm[i];
      Serial.print(distancia1);
      }

    }
  Serial.println();
  ingreso_salida(distancia,distancia1);
}

void ingreso_salida(float distancia, float distancia1){
if(distancia <= 50.0)
  {
    e=true;
    if(y=true)
    {
    //la persona esta saliendo
    IO="out";
    y=false;
    e=false;  
    }
  }

  if(distancia1 <=50.0)
  {
    y=true;  
    if(e=true)
    {
    //la persona esta entrando 
    IO="in";
    y=false;
    e=false; 
    }
  }

  save_value(String(IO));
}

void save_value(String IO)
   {
     // if you get a connection, report back via serial:
     int num_1= 0;
     if (IO=="out"){

     var = "\"SalidaPersonas\"";
     num_1 = var.length();
     IO="";
     }
     else if (IO=="in"){
     var = "\"IngresoPersonas\"";
     num_1 = var.length(); 
     IO="";
     }

/*
if (client.connect("things.ubidots.com", 80))
     {
       Serial.println("connected");
       //Linea de código original. 
       client.println("POST /api/v1.6/variables/" + idvariable_1 + "/values HTTP/1.1\nContent-Type: application/json\nContent-Length: " + String(num_1) + "\nX-Auth-Token: " + token + "\nHost: things.ubidots.com\n");
       Serial.println("POST /api/v1.6/variables/" + idvariable_1 + "/values HTTP/1.1\nContent-Type: application/json\nContent-Length: " + String(num_1) + "\nX-Auth-Token: " + token + "\nHost: things.ubidots.com\n");
       // En el codigo original fala agregar el valor de la variable. 
       client.print(var + "\n");
       Serial.print(var + "\n");

       client.flush();
     }*/

    if(client.connect("oblivion.usantotomas.edu.co", 8080))
    {
    Serial.println("connected");
    client.println("POST https://bucket.usantotomas.edu.co:8443/api/sensors/58ff93867be12b532d5053f9/captures?userToken=4oceb92f1sc6p66cf0svrgsoro  HTTP/1.1");
    client.println("Content-Type: appplication/json");
    String var1= "{\"sensorId\":\"58ff93867be12b532d5053f9\", \"captureTypeName\":" + String (var) +"\", \"value\": \"1\", \"captureDate\":\"2017-03-05 5:05:30\"}";
    client.println("Content-Length: "+String(var1.length()));
    client.println("X-Auth-Token: "+token);
    client.println("Host: https://bucket.usantotomas.edu.co\n");
    client.println(var1);
    Serial.println(var1);
    }
     else
     {
       // if you didn't get a connection to the server:
       Serial.println("connection failed");
     }
     if (!client.connected())
     {
       Serial.println();
       Serial.println("disconnecting.");
       client.stop();
       // do nothing forevermore:

                   // for (;;);                         
     }

     if (client.available())
     {
       char c = client.read();
       Serial.print(c);
     }
}

+Solución

Finalmente se soluciona el problema de conectividad a partir del computador, usando su conexión a wi-fi y a partir de un codigo en python que permite tomar el valor dado por la Arduino en el puerto serial y conformando el comando POST en el código. Para esto también se cambia la caracterización del codigo. Los dos codigos se muestran a continuación y el funcionamiento en la imagen.

script
HC-SR04
Python
Varios
Post
Prueba

Unless otherwise stated, the content of this page is licensed under Creative Commons Attribution-ShareAlike 3.0 License