Sistema Basico Parquedero 2puestos

by johancass95 in Circuits > Arduino

58 Views, 0 Favorites, 0 Comments

Sistema Basico Parquedero 2puestos

imagen_2023-12-13_152741996.png

Este código integra sensores ultrasónicos, LEDs, un servo motor y un LCD para simular un sistema de estacionamiento que detecta la presencia de vehículos y muestra el estado de los espacios disponibles.

Supplies

dejare la lista en un archivo Csv. pero tabien puedes verla des lasimulacion directa en tinkercad.

Downloads

Descripción General Del Funcionamiento



Inicialización:

  • El código comienza definiendo los pines para el LCD, los pines para los sensores ultrasónicos, los pines para los LEDs, y los valores iniciales para el servo y las variables de distancia y estado de los espacios de estacionamiento.

Configuración inicial:

  • Se configuran los pines del Arduino para el funcionamiento de los sensores ultrasónicos (pines de salida y entrada).
  • Se inicializan los LEDs y el servo motor.
  • Se inicia la comunicación con el LCD.

Bucle principal (loop()):

  • En cada iteración del bucle principal, se realiza la medición de la distancia con los tres sensores ultrasónicos, se actualiza el estado de los espacios de estacionamiento y se controla la apertura de la puerta si hay un vehículo detectado y espacios disponibles.

Medición de distancia:

  • Se utilizan los sensores ultrasónicos para medir la distancia a objetos cercanos.
  • Se envían pulsos ultrasónicos y se mide el tiempo de eco para calcular la distancia.

Actualización de estados:

  • Los LEDs indican el estado de cada espacio de estacionamiento (verde si está disponible, rojo si está ocupado).
  • Se actualiza la cantidad de espacios disponibles.
  • Se muestra un mensaje en el LCD indicando la disponibilidad de espacios.

Control de la puerta:

  • Si se detecta un vehículo y hay espacios disponibles, se muestra un mensaje en el LCD y se abre la puerta durante un tiempo determinado.

Detalles de las funciones y líneas clave del código:

  • Función LCD():
  • Esta función imprime un mensaje en el LCD en una posición específica.
  • Utiliza el método setCursor() para establecer la posición del cursor en la pantalla y print() para mostrar el mensaje.
  • Configuración de pines y objetos:
  • Se definen los pines para los sensores ultrasónicos, LEDs y el servo motor.
  • Se inicializan los objetos de los sensores y el LCD.
  • Loop principal:
  • Se realizan mediciones de distancia con cada sensor ultrasónico.
  • Se actualiza el estado de los espacios de estacionamiento según la distancia medida.
  • Se controla la apertura de la puerta si se cumplen ciertas condiciones.
  • Función abrirPuerta():
  • Abre la puerta (mueve el servo) durante un tiempo determinado.
  • Control de LEDs:
  • Se encienden o apagan los LEDs para indicar el estado de los espacios de estacionamiento (verde para disponible, rojo para ocupado).
  • Actualización de estado de los espacios:
  • Si se detecta un vehículo cerca de un espacio, se actualiza el estado del espacio correspondiente.
  • Mensajes en el LCD:
  • Se muestran mensajes en el LCD indicando la disponibilidad de espacios y mensajes de bienvenida o de no disponibilidad.


Simulacion En Tinkercad

codigo:

#include <Servo.h>
#include <LiquidCrystal.h>
//definicion de piens del lcd
#define rs 13
#define en 12
#define d4 11
#define d5 10
#define d6 9
#define d7 8


LiquidCrystal lcd(rs, en, d4, d5, d6, d7);


void LCD(String(msg), int(col) = 0, int(row) = 0) {
  lcd.setCursor(col, row);
  lcd.print(msg);
}


const int pingPin1 = 7;  // Trigger Pin of Ultrasonic Sensor
const int echoPin1 = 5;  // Echo Pin of Ultrasonic Sensor


const int pingPin2 = 4;  // Trigger Pin of Ultrasonic Sensor
const int echoPin2 = 3;  // Echo Pin of Ultrasonic Sensor


const int pingPin3 = A0;  // Trigger Pin of Ultrasonic Sensor
const int echoPin3 = A1;  // Echo Pin of Ultrasonic Sensor
                          ///////////////////ledSalidas
const int ledDiponibleVerde = A3;
const int ledDiponibleRojo = A2;
const int ledPaq1 = A4;
const int ledPaq2 = A5;


Servo puertaServo;  // Declarar un objeto de servo en la libreria


int servoAbierto = 90;  // Ángulo mínimo del servo (ajusta según tus necesidades apertura)
int servoCerrado = 0;   // Ángulo máximo del servo (ajusta según tus necesidades cerrado)


float minDistance = 40;   // Distancia mínima en centímetros 
float maxDistance = 150;  // Distancia máxima en centímetros


int Numparq = 2;       //variable almacenael nuemro de parqueaderos cojones o espacios
int NumparqOcupados = 0; //variable acomula el nuero de parquederos ocupados
boolean Paq1 = 0, Paq2 = 0; //estado de cada cajon
boolean Paq1Ant = 0, Paq2Ant = 0; //almacena el estado anteriro para comparra la variable actual
void setup() {
  puertaServo.attach(6);  // Asignar el servo al pin 6
  Serial.begin(9600);


//declaracion de salida pines de led 
  pinMode(ledDiponibleVerde, OUTPUT);
  pinMode(ledDiponibleRojo, OUTPUT);
  pinMode(ledPaq1, OUTPUT);
  pinMode(ledPaq2, OUTPUT);
  //inicializan apagados
  digitalWrite(ledDiponibleVerde, LOW);
  digitalWrite(ledDiponibleRojo, LOW);
  digitalWrite(ledPaq1, LOW);
  digitalWrite(ledPaq2, LOW);
//declaracion de modo de los pines de cada sensor  ultrazonido
  pinMode(pingPin1, OUTPUT);
  pinMode(echoPin1, INPUT);


  pinMode(pingPin2, OUTPUT);
  pinMode(echoPin2, INPUT);


  pinMode(pingPin3, OUTPUT);
  pinMode(echoPin3, INPUT);


  puertaServo.write(servoCerrado);
  lcd.begin(16, 2);
  LCD("UTL");
  LCD("TEST CODE", 0, 1);
  delay(200);
  lcd.clear();
  LCD("Bienvenido");
}


void loop() {
// Variables para calcular y almacenar la distancia en centímetros de cada sensor
long duration, cm1, cm2, cm3;


// Sensor ultrasónico 1
pinMode(pingPin1, OUTPUT);
digitalWrite(pingPin1, LOW);
delayMicroseconds(2);
digitalWrite(pingPin1, HIGH);
delayMicroseconds(10);
digitalWrite(pingPin1, LOW);


pinMode(echoPin1, INPUT);
duration = pulseIn(echoPin1, HIGH);
cm1 = (duration * 0.034 / 2);//esta es la medida el ultrzonico de entrada


// Sensor ultrasónico 2
pinMode(pingPin2, OUTPUT);
digitalWrite(pingPin2, LOW);
delayMicroseconds(2);
digitalWrite(pingPin2, HIGH);
delayMicroseconds(10);
digitalWrite(pingPin2, LOW);


pinMode(echoPin2, INPUT);
duration = pulseIn(echoPin2, HIGH);
cm2 = (duration * 0.034 / 2);


// Si la distancia medida por el sensor 2 es menor que la distancia mínima
if (cm2 < minDistance) {
  Paq1 = 1; // Espacio de estacionamiento 2 ocupado
  digitalWrite(ledPaq1, 0); // LED indicador del espacio 2 apagado
} else {
  Paq1 = 0; // Espacio de estacionamiento 2 disponible
  digitalWrite(ledPaq1, 1); // LED indicador del espacio 2 encendido
}


// Sensor ultrasónico 3
pinMode(pingPin3, OUTPUT);
digitalWrite(pingPin3, LOW);
delayMicroseconds(2);
digitalWrite(pingPin3, HIGH);
delayMicroseconds(10);
digitalWrite(pingPin3, LOW);


pinMode(echoPin3, INPUT);
duration = pulseIn(echoPin3, HIGH);
cm3 = (duration * 0.034 / 2);


// Si la distancia medida por el sensor 3 es menor que la distancia mínima
if (cm3 < minDistance) {
  Paq2 = 1; // Espacio de estacionamiento 3 ocupado
  digitalWrite(ledPaq2, 0); // LED indicador del espacio 3 apagado
} else {
  Paq2 = 0; // Espacio de estacionamiento 3 disponible
  digitalWrite(ledPaq2, 1); // LED indicador del espacio 3 encendido
}
if (cm1 < minDistance) {
  // Si un vehículo está detectado cerca del primer sensor ultrasónico
  lcd.clear(); // Borra la pantalla LCD
  LCD("Bienvenido"); // Muestra el mensaje de bienvenida en el LCD
  if (Numparq - NumparqOcupados > 0) {
    // Si hay espacios disponibles en el estacionamiento
    delay(200);
    LCD("ADELANTE", 0, 1); // Muestra "ADELANTE" en el LCD
    abrirPuerta(1800); // Abre la puerta por 800 milisegundos
    delay(200);
    lcd.clear(); // Borra la pantalla LCD
  } else {
    // Si no hay espacios disponibles en el estacionamiento
    delay(200);
    lcd.clear(); // Borra la pantalla LCD
    LCD("Lo sentimos"); // Muestra "Lo sentimos" en el LCD
    LCD("NO HAY ESPACIO ", 0, 1); // Muestra "NO HAY ESPACIO" en el LCD
    delay(800);
    lcd.clear(); // Borra la pantalla LCD después de 800 milisegundos
  }
} else {
  // Si no se detecta un vehículo cerca del primer sensor ultrasónico
  LCD("Parqueaderos disponibles:", 0, 0); // Muestra "Parqueaderos disponibles:" en el LCD
  LCD(String(Numparq - NumparqOcupados), 0, 1); // Muestra el número de espacios disponibles en el LCD
  if (Numparq - NumparqOcupados > 0) {
    // Si hay espacios disponibles en el estacionamiento
    digitalWrite(ledDiponibleVerde, 1); // Enciende el LED verde indicando espacios disponibles
    digitalWrite(ledDiponibleRojo, 0); // Apaga el LED rojo indicando que no hay espacios
  } else {
    // Si no hay espacios disponibles en el estacionamiento
    digitalWrite(ledDiponibleVerde, 0); // Apaga el LED verde
    digitalWrite(ledDiponibleRojo, 1); // Enciende el LED rojo indicando que no hay espacios
  }
}
  // Enviar datos por el puerto serial
  Serial.println("Distancia_Sen1: ");
  Serial.print(cm1);
  Serial.print("Distancia_Sen2: ");
  Serial.print(cm2);
  Serial.print("Distancia_Sen3: ");
  Serial.print(cm3);


// Verificar cambios en el estado de los espacios de estacionamiento 1 y 2
if (Paq1 != Paq1Ant) {
  // Si hay un cambio en el estado del espacio 1
  if (Paq1 == 1) {
    NumparqOcupados++; // Incrementar el número de espacios ocupados
  } else {
    NumparqOcupados--; // Decrementar el número de espacios ocupados
  }
  Paq1Ant = Paq1; // Actualizar el estado anterior del espacio 1
}


// Verificar cambios en el estado de los espacios de estacionamiento 2 y 3
if (Paq2 != Paq2Ant) {
  // Si hay un cambio en el estado del espacio 2
  if (Paq2 == 1) {
    NumparqOcupados++; // Incrementar el número de espacios ocupados
  } else {
    NumparqOcupados--; // Decrementar el número de espacios ocupados
  }
  Paq2Ant = Paq2; // Actualizar el estado anterior del espacio 2
}
}
void abrirPuerta(int mS) {
  puertaServo.write(servoAbierto);  // Mueve el servo a la posición de puerta abierta
  delay(mS);  // Espera un tiempo resibido en el parametro
  puertaServo.write(servoCerrado);  // Mueve el servo a la posición de puerta cerrada
}

en el loop: detallan las acciones que se realizan para cada sensor ultrasónico, incluyendo el envío de pulsos, la medición de la duración del eco, el cálculo de la distancia en centímetros y la actualización del estado de los espacios de estacionamiento (ocupados o disponibles) junto con el control de los LEDs indicadores para cada espacio.

// Variables para calcular y almacenar la distancia en centímetros de cada sensor
long duration, cm1, cm2, cm3;


// Sensor ultrasónico 1
pinMode(pingPin1, OUTPUT);
digitalWrite(pingPin1, LOW);
delayMicroseconds(2);
digitalWrite(pingPin1, HIGH);
delayMicroseconds(10);
digitalWrite(pingPin1, LOW);


pinMode(echoPin1, INPUT);
duration = pulseIn(echoPin1, HIGH);
cm1 = (duration * 0.034 / 2);

// Sensor ultrasónico 2
pinMode(pingPin2, OUTPUT);
digitalWrite(pingPin2, LOW);
delayMicroseconds(2);
digitalWrite(pingPin2, HIGH);
delayMicroseconds(10);
digitalWrite(pingPin2, LOW);


pinMode(echoPin2, INPUT);
duration = pulseIn(echoPin2, HIGH);
cm2 = (duration * 0.034 / 2);


// Si la distancia medida por el sensor 2 es menor que la distancia mínima
if (cm2 < minDistance) {
  Paq1 = 1; // Espacio de estacionamiento 2 ocupado
  digitalWrite(ledPaq1, 0); // LED indicador del espacio 2 apagado
} else {
  Paq1 = 0; // Espacio de estacionamiento 2 disponible
  digitalWrite(ledPaq1, 1); // LED indicador del espacio 2 encendido
}


// Sensor ultrasónico 3
pinMode(pingPin3, OUTPUT);
digitalWrite(pingPin3, LOW);
delayMicroseconds(2);
digitalWrite(pingPin3, HIGH);
delayMicroseconds(10);
digitalWrite(pingPin3, LOW);


pinMode(echoPin3, INPUT);
duration = pulseIn(echoPin3, HIGH);
cm3 = (duration * 0.034 / 2);


// Si la distancia medida por el sensor 3 es menor que la distancia mínima
if (cm3 < minDistance) {
  Paq2 = 1; // Espacio de estacionamiento 3 ocupado
  digitalWrite(ledPaq2, 0); // LED indicador del espacio 3 apagado
} else {
  Paq2 = 0; // Espacio de estacionamiento 3 disponible
  digitalWrite(ledPaq2, 1); // LED indicador del espacio 3 encendido
}



DESPUES: explican cómo se monitorean los cambios en el estado de los espacios de estacionamiento, específicamente los espacios Paq1 y Paq2. Se verifica si ha habido cambios en el estado actual de ocupación y se actualiza el contador de espacios ocupados (NumparqOcupados) en función de estos cambios, junto con la actualización de los estados anteriores (Paq1Ant y Paq2Ant) para futuras comparaciones.


// Verificar cambios en el estado de los espacios de estacionamiento 1 y 2
if (Paq1 != Paq1Ant) {
// Si hay un cambio en el estado del espacio 1
if (Paq1 == 1) {
NumparqOcupados++; // Incrementar el número de espacios ocupados
} else {
NumparqOcupados--; // Decrementar el número de espacios ocupados
}
Paq1Ant = Paq1; // Actualizar el estado anterior del espacio 1
}

// Verificar cambios en el estado de los espacios de estacionamiento 2 y 3
if (Paq2 != Paq2Ant) {
// Si hay un cambio en el estado del espacio 2
if (Paq2 == 1) {
NumparqOcupados++; // Incrementar el número de espacios ocupados
} else {
NumparqOcupados--; // Decrementar el número de espacios ocupados
}
Paq2Ant = Paq2; // Actualizar el estado anterior del espacio 2
}

Esta función controla el servo motor que simula la apertura y cierre de una puerta. Toma un parámetro mS, que representa el tiempo en milisegundos durante el cual la puerta permanecerá abierta antes de volver a cerrarse. La función mueve el servo primero a la posición correspondiente a la puerta abierta (servoAbierto), espera el tiempo especificado y luego vuelve a mover el servo a la posición de puerta cerrada (servoCerrado).


void abrirPuerta(int mS) {
puertaServo.write(servoAbierto); // Mueve el servo a la posición de puerta abierta
delay(mS); // Espera un tiempo determinado
puertaServo.write(servoCerrado); // Mueve el servo a la posición de puerta cerrada
}

Simulacion En Proteus

imagen_2023-12-13_153703030.png

La diferencia entre el simulador Proteus y Tinkercad, además de su naturaleza (Proteus es un programa de escritorio y Tinkercad es una aplicación web), radica en la potencia de emulación. En este caso, el funcionamiento del sensor requiere tiempos precisos, los cuales en Proteus pueden variar debido al consumo de recursos de la máquina. Gracias a la comunidad y al ingeniero que nos proporcionó este archivo del sensor ultrasónico, podemos simularlo en Arduino. Para lograrlo, es crucial tener la biblioteca instalada en Proteus. Al momento de simular, es importante recordar cargar el archivo hexadecimal incluido en la biblioteca; esto es fundamental para que la simulación funcione correctamente.


long microsecondsToCentimeters(long microseconds) {
  return microseconds / 320 / 2;
}

ASI QUEDARIA EL CODIGO PARA SISMULAR EN PROTEUS


#include <Servo.h>
#include <LiquidCrystal.h>


#define rs 13
#define en 12
#define d4 11
#define d5 10
#define d6 9
#define d7 8


LiquidCrystal lcd(rs, en, d4, d5, d6, d7);


void LCD(String(msg), int(col) = 0, int(row) = 0) {
  lcd.setCursor(col, row);
  lcd.print(msg);
}

const int pingPin1 = 7;  // Trigger Pin of Ultrasonic Sensor
const int echoPin1 = 5;  // Echo Pin of Ultrasonic Sensor


const int pingPin2 = 4;  // Trigger Pin of Ultrasonic Sensor
const int echoPin2 = 3;  // Echo Pin of Ultrasonic Sensor


const int pingPin3 = A0;  // Trigger Pin of Ultrasonic Sensor
const int echoPin3 = A1;  // Echo Pin of Ultrasonic Sensor
                          ///////////////////ledSalidas
const int ledDiponibleVerde = A3;
const int ledDiponibleRojo = A2;
const int ledPaq1 = A4;
const int ledPaq2 = A5;


Servo puertaServo;  // Declarar un objeto de servo

int servoAbierto = 90;  // Ángulo mínimo del servo (ajusta según tus necesidades)
int servoCerrado = 0;   // Ángulo máximo del servo (ajusta según tus necesidades)


float minDistance = 20;   // Distancia mínima en centímetros
float maxDistance = 100;  // Distancia máxima en centímetros


int Numparq = 2;
int NumparqOcupados = 0;
boolean Paq1 = 0, Paq2 = 0;
boolean Paq1Ant = 0, Paq2Ant = 0;
void setup() {
  puertaServo.attach(6);  // Asignar el servo al pin 6
  Serial.begin(9600);

  pinMode(ledDiponibleVerde, OUTPUT);
  pinMode(ledDiponibleRojo, OUTPUT);
  pinMode(ledPaq1, OUTPUT);
  pinMode(ledPaq2, OUTPUT);
  digitalWrite(ledDiponibleVerde, LOW);
  digitalWrite(ledDiponibleRojo, LOW);
  digitalWrite(ledPaq1, LOW);
  digitalWrite(ledPaq2, LOW);


  pinMode(pingPin1, OUTPUT);
  pinMode(echoPin1, INPUT);


  pinMode(pingPin2, OUTPUT);
  pinMode(echoPin2, INPUT);


  pinMode(pingPin3, OUTPUT);
  pinMode(echoPin3, INPUT);


  puertaServo.write(servoCerrado);
  lcd.begin(16, 2);
  LCD("UTL");
  LCD("TEST CODE", 0, 1);
  delay(200);
  lcd.clear();
  LCD("Bienvenido");
}


void loop() {
  long duration, cm1, cm2, cm3;
  pinMode(pingPin1, OUTPUT);
  digitalWrite(pingPin1, LOW);
  delayMicroseconds(2);
  digitalWrite(pingPin1, HIGH);
  delayMicroseconds(10);
  digitalWrite(pingPin1, LOW);


  pinMode(echoPin1, INPUT);
  duration = pulseIn(echoPin1, HIGH);
  cm1 = microsecondsToCentimeters(duration);


  pinMode(pingPin2, OUTPUT);
  digitalWrite(pingPin2, LOW);
  delayMicroseconds(2);
  digitalWrite(pingPin2, HIGH);
  delayMicroseconds(10);
  digitalWrite(pingPin2, LOW);


  pinMode(echoPin2, INPUT);
  duration = pulseIn(echoPin2, HIGH);
  cm2 = microsecondsToCentimeters(duration);
  if (cm2 < minDistance) {
    Paq1 = 1;
    digitalWrite(ledPaq1, 0);
  } else {
    digitalWrite(ledPaq1, 1);


    Paq1 = 0;
  }
  pinMode(pingPin3, OUTPUT);
  digitalWrite(pingPin3, LOW);
  delayMicroseconds(2);
  digitalWrite(pingPin3, HIGH);
  delayMicroseconds(10);
  digitalWrite(pingPin3, LOW);


  pinMode(echoPin3, INPUT);
  duration = pulseIn(echoPin3, HIGH);
  cm3 = microsecondsToCentimeters(duration);
  if (cm3 < minDistance) {
    Paq2 = 1;
    digitalWrite(ledPaq2, 0);
  } else {
    Paq2 = 0;
    digitalWrite(ledPaq2, 1);
  }
  if (cm1 < minDistance) {
    lcd.clear();
    LCD("Bienvenido");
    if (Numparq - NumparqOcupados > 0) {
      delay(200);
      LCD("ADELANTE", 0, 1);
      abrirPuerta(800);
      delay(200);
      lcd.clear();
    } else {
      delay(200);
      lcd.clear();
      LCD("lo sentimos");
      LCD("NO HAY ESPACIO ", 0, 1);
      delay(800);
      lcd.clear();
    }
  } else {


    LCD("parquederos dispomobles:", 0, 0);
    LCD(String(Numparq - NumparqOcupados), 0, 1);
    if (Numparq - NumparqOcupados > 0) {
      digitalWrite(ledDiponibleVerde, 1);
      digitalWrite(ledDiponibleRojo, 0);
    } else {
      digitalWrite(ledDiponibleVerde, 0);
      digitalWrite(ledDiponibleRojo, 1);
    }
  }
  // Enviar datos por el puerto serial
  Serial.println("Distancia_Sen1: ");
  Serial.print(cm1);
  Serial.print("Distancia_Sen2: ");
  Serial.print(cm2);
  Serial.print("Distancia_Sen3: ");
  Serial.print(cm3);


  if (Paq1 != Paq1Ant) {
    if (Paq1 == 1) {
      NumparqOcupados++;
    } else {
      NumparqOcupados--;
    }
    Paq1Ant = Paq1;
  }
  if (Paq2 != Paq2Ant) {
    if (Paq2 == 1) {
      NumparqOcupados++;
    } else {
      NumparqOcupados--;
    }
    Paq2Ant = Paq2;
  }
}
void abrirPuerta(int mS) {
  puertaServo.write(servoAbierto);  // Abrir la puerta
  delay(mS);
  puertaServo.write(servoCerrado);  // Abrir la puerta
}
long microsecondsToCentimeters(long microseconds) {
  return microseconds / 320 / 2;
}