#include <ESP32Servo.h>
// Habilitacion de debug para la impresion por el puerto serial ...
//----------------------------------------------
#define SERIAL_DEBUG_ENABLED 1
#if SERIAL_DEBUG_ENABLED
#define DebugPrint(str)\
{\
Serial.println(str);\
}
#else
#define DebugPrint(str)
#endif
#define DebugPrintEstado(estado,evento)\
{\
String est = estado;\
String evt = evento;\
String str;\
str = "-----------------------------------------------------";\
DebugPrint(str);\
str = "EST-> [" + est + "]: " + "EVT-> [" + evt + "].";\
DebugPrint(str);\
str = "-----------------------------------------------------";\
DebugPrint(str);\
}
//----------------------------------------------
//----------------------------------------------
// Estado de un sensor ...
#define ESTADO_SENSOR_OK 108
#define ESTADO_SENSOR_ERROR 666
//----------------------------------------------
//----------------------------------------------
// Estado de un mensaje ...
#define MENSAJE_ENVIADO_OK 10
#define MENSAJE_ENVIADO_ERROR 666
//----------------------------------------------
// Otras constantes ....
//----------------------------------------------
#define UMBRAL_ESPERA_TIMER 5000 //msegundos
#define UMBRAL_LUZ 400
#define UMBRAL_DISTANCIA 10
#define MAX_CANT_SENSORES 3
#define PIN_SENSOR_LUZ 35
#define PIN_SENSOR_PULSADOR 22
#define PIN_TRIGGER 5
#define PIN_ECHO 4
#define PIN_LED 15
#define PIN_SERVO 2
#define UMBRAL_DIFERENCIA_TIMEOUT 500
#define SENSOR_DISTANCIA 1
#define SENSOR_LUZ 2
#define SENSOR_PULSADOR 3
//defino la velocidad del sonido
#define VELOCIDAD_SONIDO 0.034
//Instanciamos nuestro servo
Servo servo;
int pos_servo=0;
long duration;
float distanceCm;
//----------------------------------------------
//----------------------------------------------
struct stSensor
{
int pin;
int estado;
long valor_actual;
long valor_previo;
};
stSensor sensores[MAX_CANT_SENSORES];
//----------------------------------------------
void none();
void activate_timer();
void free_space();
void busy_space();
void light_on();
void light_off();
void error();
//----------------------------------------------
enum states { ST_IDLE, ST_WAIT_TIMER , ST_FREE_SPACE , ST_BUSY_SPACE, ST_ERROR } current_state;
String states_s [] = {"ST_ILDE", "ST_WAIT_TIMER" , "ST_FREE_SPACE" , "ST_BUSY_SPACE", "ST_ERROR" };
enum events { EV_CONT, EV_PUSH_BUTTON , EV_TIMEOUT , EV_LIGHT , EV_NOT_LIGHT , EV_DETECT_CAR ,EV_NOT_DETECT_CAR , EV_UNKNOW } new_event;
String events_s [] = {"EV_CONT", "EV_PUSH_BUTTON" , "EV_TIMEOUT" , "EV_LIGHT", "EV_NOT_LIGHT" , "EV_DETECT_CAR" ,"EV_NOT_DETECT_CAR", "EV_UNKNOW" };
#define MAX_STATES 5
#define MAX_EVENTS 8
typedef void (*transition)();
transition state_table[MAX_STATES][MAX_EVENTS] =
{
{none , activate_timer , none , none , none , none , none } , // state ST_IDLE
{none , none , free_space , none , none , none , none } , // state ST_WAITING_RESPONSE
{none , activate_timer , error , light_on , light_off , busy_space , none } , // state ST_FREE_SPACE
{none , none , none , light_on , light_off , none , free_space } , // state ST_BUSY_SPACE
{error , error , error , error , error , error , error } // state ST_ERROR
//EV_CONT , EV_PUSH_BUTTON , EV_TIMEOUT , EV_LIGHT , EV_NOT_LIGHT , EV_DETECT_CAR, EV_NOT_DETECT_CAR
};
bool timeout;
long lct;
bool luz;
//----------------------------------------------
void do_init()
{
Serial.begin(9600);
pinMode(PIN_LED, OUTPUT);
pinMode(PIN_SERVO , OUTPUT);
pinMode(PIN_TRIGGER,OUTPUT);
pinMode(PIN_SENSOR_PULSADOR,INPUT_PULLDOWN);
pinMode(PIN_SENSOR_LUZ,INPUT);
pinMode(PIN_ECHO,INPUT);
sensores[SENSOR_LUZ].pin = PIN_SENSOR_LUZ;
sensores[SENSOR_LUZ].estado = ESTADO_SENSOR_OK;
sensores[SENSOR_DISTANCIA].pin = PIN_ECHO;
sensores[SENSOR_DISTANCIA].estado = ESTADO_SENSOR_OK;
sensores[SENSOR_PULSADOR].pin = PIN_SENSOR_PULSADOR;
sensores[SENSOR_PULSADOR].estado = ESTADO_SENSOR_OK;
//Inicializamos la posicion del servo
servo.attach(PIN_SERVO, 500, 2500);
// Inicializo el evento inicial
current_state = ST_IDLE;
timeout = false;
lct = millis();
}
//----------------------------------------------
//----------------------------------------------
long leerSensorLuz( )
{
return analogRead(PIN_SENSOR_LUZ);
}
long leerSensorDistancia()
{
//Desactivo el trigger
digitalWrite(PIN_TRIGGER, LOW);
delayMicroseconds(2);
//Activo el Trigger por 10 microsegundos
digitalWrite(PIN_TRIGGER, HIGH);
delayMicroseconds(10);
//Desactivo el trigger
digitalWrite(PIN_TRIGGER, LOW);
//Leo el pin de Echo, y retorno el tiempo en
//microsegundos en donde se encuentra el objeto
return pulseIn(PIN_ECHO, HIGH);
}
//----------------------------------------------
long leerSensorPulsador()
{
return digitalRead(PIN_SENSOR_PULSADOR);
}
//----------------------------------------------
void apagar_leds( )
{
digitalWrite(PIN_LED, false);
}
//----------------------------------------------
//----------------------------------------------
void encender_led( )
{
digitalWrite(PIN_LED , true );
}
void abrir_servo()
{
servo.write(90);
}
void cerrar_servo()
{
servo.write(0);
}
//----------------------------------------------
//----------------------------------------------
//----------------------------------------------
// ---------------------------------------------
bool verificarEstadoSensorLuz( )
{
sensores[SENSOR_LUZ].valor_actual = leerSensorLuz( );
int valor_actual = sensores[SENSOR_LUZ].valor_actual;
int valor_previo = sensores[SENSOR_LUZ].valor_previo;
if( valor_actual != valor_previo )
{
sensores[SENSOR_LUZ].valor_previo = valor_actual;
if( valor_actual < UMBRAL_LUZ )
{
new_event = EV_NOT_LIGHT;
}
if( valor_actual >= UMBRAL_LUZ )
{
new_event = EV_LIGHT;
}
return true;
}
return false;
}
//----------------------------------------------
//----------------------------------------------
bool verificarEstadoSensorDistancia( )
{
long tiempo=leerSensorDistancia( );
sensores[SENSOR_DISTANCIA].valor_actual = tiempo*VELOCIDAD_SONIDO/2;
int valor_actual = sensores[SENSOR_DISTANCIA].valor_actual;
int valor_previo = sensores[SENSOR_DISTANCIA].valor_previo;
if( valor_actual != valor_previo )
{
sensores[SENSOR_DISTANCIA].valor_previo = valor_actual;
if( valor_actual < UMBRAL_DISTANCIA )
{
new_event = EV_DETECT_CAR;
}
if( valor_actual >= UMBRAL_DISTANCIA )
{
new_event = EV_NOT_DETECT_CAR;
}
return true;
}
return false;
}
//----------------------------------------------
bool verificarEstadoSensorPulsador( )
{
sensores[SENSOR_PULSADOR].valor_actual = leerSensorPulsador();
int valor_actual = sensores[SENSOR_PULSADOR].valor_actual;
int valor_previo = sensores[SENSOR_PULSADOR].valor_previo;
if( valor_actual != valor_previo )
{
sensores[SENSOR_PULSADOR].valor_previo = valor_actual;
if( valor_actual == HIGH )
{
new_event = EV_PUSH_BUTTON;
return true;
}
Serial.println("no presiona");
}
return false;
}
//----------------------------------------------
//----------------------------------------------
bool verificarOtroSensor2()
{
// Emulacion Sensor 2 ...
return false;
}
//----------------------------------------------
//----------------------------------------------
bool enviar_mensaje()
{
}
//----------------------------------------------
//----------------------------------------------
bool verificarSiHayRespuestaServidor()
{
}
//----------------------------------------------
//----------------------------------------------
void get_new_event( )
{
long ct = millis();
int diferencia = (ct - lct);
timeout = (diferencia > UMBRAL_DIFERENCIA_TIMEOUT)? (true):(false);
if( timeout )
{
// Doy acuse de la recepcion del timeout
timeout = false;
lct = ct;
if( (verificarEstadoSensorLuz() == true) || (verificarEstadoSensorDistancia() == true) || (verificarEstadoSensorPulsador() == true) ||
(verificarSiHayRespuestaServidor() == true) )
{
return;
}
}
// Genero evento dummy ....
new_event = EV_CONT;
}
//----------------------------------------------
void init_()
{
DebugPrintEstado(states_s[current_state], events_s[new_event]);
apagar_leds();
current_state = ST_IDLE;
}
void error()
{
}
void none()
{
}
void activate_timer()
{
abrir_servo();
current_state=ST_FREE_SPACE;
delay(5000);
//hack
free_space();
}
void free_space()
{
cerrar_servo();
Serial.println("estacionamiento libre");
current_state=ST_FREE_SPACE;
}
void busy_space()
{
Serial.println("estacionamiento ocupado");
current_state=ST_BUSY_SPACE;
}
void light_on()
{
encender_led();
}
void light_off()
{
apagar_leds();
}
//----------------------------------------------
void maquina_estados_climatizador_ambiente( )
{
get_new_event();
if( (new_event >= 0) && (new_event < MAX_EVENTS) && (current_state >= 0) && (current_state < MAX_STATES) )
{
if( new_event != EV_CONT )
{
DebugPrintEstado(states_s[current_state], events_s[new_event]);
}
state_table[current_state][new_event]();
}
else
{
DebugPrintEstado(states_s[ST_ERROR], events_s[EV_UNKNOW]);
}
// Consumo el evento...
new_event = EV_CONT;
}
//----------------------------------------------
// Funciones de arduino !.
//----------------------------------------------
void setup()
{
do_init();
}
//----------------------------------------------
//----------------------------------------------
void loop()
{
maquina_estados_climatizador_ambiente();
}
//----------------------------------------------