Funcionamiento del subsistema
Funcionamiento del subsistema
Como en nuestro caso vamos a utilizar doble sensor LDR no necesitamos implementar ningún sistema de lógica difusa para detectar si un coche ha entrado o salido del parking haciendo que nuestro sistema sea más simple de implementar y mantener.
A continuación, se va a mostrar el código completo del funcionamiento del subsistema de entrada/salida al parking en la placa ESP8266.
En el funcionamiento principal, lo primero que hacemos es crear un bucle for para leer los datos de ambos sensores. Como no se pueden leer ambos a la vez, los dos sensores están deshabilitados procediendo a habilitar el sensor en cuestión que se va a leer. Lo siguiente es restringir el valor obtenido a los valores de máximo y mínimo que se obtuvieron en el calibrado. Por último, hacemos un ajuste escalando los valores a una horquilla entre 0 y 255.
De esta forma controlamos en cada momento los vehículos que entran o salen y el número de ellos que se encuentran dentro del parking ocupando plazas.

A continuación, se va a mostrar el código completo del funcionamiento del subsistema de entrada/salida al parking en la placa ESP8266.
Código de funcionamiento de entrada/salida de vehículos
#include <string.h>
#include <ResponsiveAnalogRead.h>
#include <ESP8266WiFi.h>
#include <PubSubClient.h>
//Wifi Setup
const char* ssid = "SergioMi5S";
const char* password = "49056136b";
//Broker
const char* mqtt_server = "broker.hivemq.com"; /// MQTT Broker
int mqtt_port = 1883;
WiFiClient espClient;
PubSubClient client(espClient);
long lastMsg = 0;
char msg[50];
int value = 0;
//Sensors
const int NUM_SENSORES = 2; // Número de Sensores
const int settime = 5000; // Tiempo dedicado al ajuste desde el inicio del programa
int limitCoche[] = {0,0}; // Offset pasa coche
int PLAZAS_LIBRES = 0; // Número de plazas libres
int ValorLDR[] = {0,0}; // Valor lectura LDR
int MinLDR[] = {1023, 1023}; // Valor mÃnimo de la LDR
int MaxLDR[] = {0,0}; // Valor máximo de la LDR
int enable[] = { D5, D6 }; // Pines habilitado sensores
ResponsiveAnalogRead luz(A0, true);
//Estados
enum Estados { inicio, parking_lleno, entrando1, encima, entrando2, entra_coche,
saliendo1, encima2, saliendo2, sale_coche };
Estados estado = inicio;
void setup() {
Serial.begin(9600);
for(int i=0; i<NUM_SENSORES; i++) {
pinMode(enable[i], OUTPUT);
}
Serial.println((String)"Calibrando durante "+settime+" ms...");
//Iniciamos la calibración
for(int j=0; j<(settime)/100; j++) {
for(int i=0; i<NUM_SENSORES; i++) {
// habilita el ldr
digitalWrite(enable[i], HIGH);
// update the ResponsiveAnalogRead object every loop
luz.update();
ValorLDR[i] = luz.getValue(); // Leemos el valor del sensor 1
// deshabilita el ldr
digitalWrite(enable[i], LOW);
// Grabamos el valor máximo si es mayor que el guardado
if (ValorLDR[i] > MaxLDR[i]) {
MaxLDR[i] = ValorLDR[i];
}
// Grabamos el valor mÃnimo si es menor que el guardado
if (ValorLDR[i] < MinLDR[i]) {
MinLDR[i] = ValorLDR[i];
limitCoche[i] = MinLDR[i]+40;
}
}
delay(100);
}
Serial.println("Fin calibrado");
setup_wifi();
client.setServer(mqtt_server, mqtt_port);
client.setCallback(callback);
client.subscribe("PARKING_IOT_MONITOR");
Serial.println("Connected");
Serial.print("MQTT Server ");
Serial.print(mqtt_server);
Serial.print(":");
Serial.println(String(mqtt_port));
Serial.print("ESP8266 IP ");
Serial.println(WiFi.localIP());
}
void loop() {
for(int i=0; i<NUM_SENSORES; i++) {
// habilita el ldr
digitalWrite(enable[i], HIGH);
// update the ResponsiveAnalogRead object every loop
luz.update();
ValorLDR[i] = luz.getValue(); // Leemos el valor del sensor 1
// deshabilita el ldr
digitalWrite(enable[i], LOW);
//Restringimos los valores a los obtenidos durante el calibrado
ValorLDR[i] = constrain(ValorLDR[i], MinLDR[i], MaxLDR[i]);
// Escalamos los valores en la horquilla obtenida en calibracion
ValorLDR[i] = map(ValorLDR[i], MinLDR[i], MaxLDR[i], 0, 255);
}
switch(estado) {
case inicio:
if(ValorLDR[0] < limitCoche[0] && PLAZAS_LIBRES > 0) {
estado = entrando1;
} else if(ValorLDR[1] < limitCoche[1]) {
estado = saliendo1;
}
break;
case entrando1:
Serial.println("Estado: Pasando 1");
if(ValorLDR[0] < limitCoche[0] && ValorLDR[1] < limitCoche[1]) {
estado = encima;
}
break;
case encima:
Serial.println("Estado: Encima ENTRADA");
if(ValorLDR[0] >= limitCoche[0]) {
estado = entrando2;
}
break;
case entrando2:
Serial.println("Estado: Pasando 2");
if(ValorLDR[1] >= limitCoche[1]) {
estado = entra_coche;
}
break;
case entra_coche:
client.publish("PARKING_IOT", "ENTRA"); /// send char
Serial.println("Estado: Entra coche");
estado = inicio;
break;
case saliendo1:
Serial.println("Estado: Saliendo 1");
if(ValorLDR[0] < limitCoche[0] && ValorLDR[1] < limitCoche[1]) {
estado = encima2;
}
break;
case encima2:
Serial.println("Estado: Encima SALIDA");
if(ValorLDR[1] >= limitCoche[1]) {
estado = saliendo2;
}
break;
case saliendo2:
Serial.println("Estado: Saliendo 2");
if(ValorLDR[0] >= limitCoche[0]) {
estado = sale_coche;
}
break;
case sale_coche:
client.publish("PARKING_IOT", "SALE"); /// send char
Serial.println("Estado: Sale coche");
estado = inicio;
break;
default:
estado = inicio;
break;
}
if (!client.connected()) {
reconnect();
}
client.loop();
delay(100);
}
void callback(char* topic, byte* payload, unsigned int length) {
String s = String((char*)payload);
PLAZAS_LIBRES = s.toFloat();
Serial.print("PLAZAS LIBRES => ");
Serial.println(PLAZAS_LIBRES);
}
void reconnect() {
// Loop until we're reconnected
while (!client.connected()) {
Serial.print("Attempting MQTT connection...");
// Attempt to connect
if (client.connect("ESP8266Client")) {
Serial.println("connected");
client.subscribe("PARKING_IOT_MONITOR");
} else {
Serial.print("failed, rc=");
Serial.print(client.state());
Serial.println(" try again in 5 seconds");
// Wait 5 seconds before retrying
delay(5000);
}
}
}
void setup_wifi() {
delay(10);
// We start by connecting to a WiFi network
Serial.println();
Serial.print("Connecting to ");
Serial.println(ssid);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("");
Serial.println("WiFi connected");
Serial.println("IP address: ");
Serial.println(WiFi.localIP());
}
|
En el funcionamiento principal, lo primero que hacemos es crear un bucle for para leer los datos de ambos sensores. Como no se pueden leer ambos a la vez, los dos sensores están deshabilitados procediendo a habilitar el sensor en cuestión que se va a leer. Lo siguiente es restringir el valor obtenido a los valores de máximo y mínimo que se obtuvieron en el calibrado. Por último, hacemos un ajuste escalando los valores a una horquilla entre 0 y 255.
Máquinas de estado
A continuación, nos encontramos la máquina de estados que gobierna el subsistema. Consta de nueve estados, un estado inicial que es el que evalúa si hay presencia de un vehículo que quiere salir o entrar y ocho estados posteriores que podemos dividir en dos grupos:- Entrada de Vehículo
- Salida de Vehículo
- Entrada de Vehículo:
- Primer Estado:
- Segundo Estado:
- Tercer Estado:
- Cuarto Estado:
- Salida de Vehículo:
- Primer Estado:
- Segundo Estado:
- Tercer Estado:
- Cuarto Estado:
De esta forma controlamos en cada momento los vehículos que entran o salen y el número de ellos que se encuentran dentro del parking ocupando plazas.
Comentarios
Publicar un comentario