0% encontró este documento útil (0 votos)
39 vistas37 páginas

Proyecto Final PDF

Fff

Cargado por

j8wq8hnk6h
Derechos de autor
© © All Rights Reserved
Nos tomamos en serio los derechos de los contenidos. Si sospechas que se trata de tu contenido, reclámalo aquí.
Formatos disponibles
Descarga como PDF, TXT o lee en línea desde Scribd
0% encontró este documento útil (0 votos)
39 vistas37 páginas

Proyecto Final PDF

Fff

Cargado por

j8wq8hnk6h
Derechos de autor
© © All Rights Reserved
Nos tomamos en serio los derechos de los contenidos. Si sospechas que se trata de tu contenido, reclámalo aquí.
Formatos disponibles
Descarga como PDF, TXT o lee en línea desde Scribd

Universidad Anáhuac México Norte

Proyecto Final
Estacionamiento con Automatizaciones en Arduino

Programación Estructurada de Microcontroladores

Leonardo Velasco Ojeda


Emilio Arriaga Guzmán
Índice
Introducción........................................................................................................................... 2
Descripción del proyecto...................................................................................................... 3
Funcionalidades................................................................................................................. 3
Lista de componentes........................................................................................................... 4
Simulación.............................................................................................................................. 8
Enlace................................................................................................................................ 8
Esquema Eléctrico................................................................................................................. 9
Circuito..................................................................................................................................12
Diagrama de Flujo del Código............................................................................................ 15
FOTOGRAFÍAS, VIDEOS Y DESCRIPCIÓN........................................................................ 19
RESULTADOS....................................................................................................................... 23
CONCLUSIONES.................................................................................................................. 24
BIBLIOGRAFÍA..................................................................................................................... 25
CÓDIGO.................................................................................................................................27

1
Estacionamiento Automatizado
Introducción
En la actualidad, los sistemas inteligentes aplicados al control vehicular y a la gestión de
estacionamientos han adquirido una relevancia significativa en entornos urbanos,
comerciales y residenciales. La creciente necesidad de soluciones automatizadas que
optimicen el uso del espacio, reduzcan los tiempos de espera y mejoren la experiencia de
los usuarios ha impulsado el desarrollo de tecnologías orientadas a la automatización y
supervisión de estos sistemas. En este contexto, los estacionamientos inteligentes
representan una alternativa eficiente y sostenible frente a los métodos tradicionales de
gestión.

El presente trabajo tiene como objetivo el diseño e implementación de un prototipo funcional


que permita explorar las posibilidades que ofrece la automatización en espacios de
estacionamiento, aplicando principios de electrónica, programación en sistemas embebidos
y análisis de datos. A través de este proyecto se busca no solo demostrar la viabilidad
técnica de integrar múltiples dispositivos para el control de acceso, iluminación y monitoreo,
sino también fomentar un enfoque de diseño orientado a la eficiencia operativa y a la
experiencia del usuario.

Un componente fundamental en el desarrollo de este sistema es la programación, ya que


permite coordinar el funcionamiento de sensores, actuadores y dispositivos de salida
mediante estructuras de control lógicas y eficientes. La implementación en lenguaje C++
para la plataforma Arduino implica el uso de condicionales, bucles, funciones y estructuras
de datos que garantizan una respuesta precisa y coherente ante los estímulos del entorno.
Además, la programación facilita la modularidad del sistema, permitiendo su escalabilidad y
mantenimiento, así como la integración de nuevas funcionalidades sin comprometer la
estabilidad general del conjunto. De este modo, la lógica de control se convierte en el eje
que articula cada elemento del sistema para lograr un comportamiento autónomo e
inteligente.

Desde una perspectiva académica y formativa, este desarrollo permite fortalecer habilidades
de análisis, diseño y resolución de problemas reales mediante el uso de tecnologías
accesibles, versátiles y con potencial de implementación en escenarios reales.

2
Descripción del proyecto

El proyecto consiste en la implementación de un prototipo de estacionamiento inteligente a


pequeña escala, controlado mediante una placa Arduino. Este sistema integra diversos
sensores y dispositivos de salida que trabajan de forma conjunta para automatizar las
funciones principales de un estacionamiento: el control de acceso, la gestión de iluminación,
la detección de vehículos y la visualización en tiempo real del estado del estacionamiento.
El objetivo es demostrar cómo la tecnología embebida puede aplicarse eficazmente en la
optimización de recursos y en la mejora de la experiencia del usuario.

Funcionalidades

1. Control de acceso automatizado


○ Apertura y cierre de una pluma de acceso mediante el accionamiento de un
servomotor.
Activación remota del mecanismo a través de un control infrarrojo (IR), que
permite enviar comandos específicos para abrir o cerrar la barrera.
2. Gestión remota del sistema de iluminación
○ Control de luces LED RGB mediante el mismo control IR, con posibilidad de
seleccionar entre siete colores distintos.
○ Opción de encendido y apagado remoto de la iluminación general del
estacionamiento.
3. Ajuste automático de la intensidad lumínica
○ Regulación automática del brillo de las luces en función de dicha detección,
con el fin de mejorar la visibilidad.
4. Indicadores visuales por espacio de estacionamiento
○ Detección del estado de cada plaza mediante sensores ultrasónicos que
identifican la presencia de un vehículo.
○ Implementación de LEDs RGB colocados en cada plaza de estacionamiento.
El color verde indica un espacio disponible, mientras que el rojo señala que
está ocupado.
5. Conteo en tiempo real de espacios disponibles
○ Monitoreo constante del número de espacios libres u ocupados dentro del
estacionamiento.
○ Visualización clara de esta información en un display de 7 segmentos
ubicado en la entrada del sistema, lo cual permite al usuario saber si hay

3
disponibilidad antes de ingresar.

6. Registro y análisis de datos de uso


○ Captura de información sobre los eventos de entrada y salida de vehículos.
○ Análisis de los datos para determinar tiempos de ocupación.

Estas funcionalidades se coordinan a través de un programa desarrollado en C++ para la


plataforma Arduino, que garantiza una interacción precisa y en tiempo real entre los
diferentes módulos del sistema. El diseño modular permite futuras expansiones, como la
integración con aplicaciones móviles o el monitoreo remoto vía internet.

Lista de componentes
Componente Imagen

Protoboard

Mini protoboard

4
Resistencias

Jumpers H-h H-m M-m

Micro servomotor

Display de 7 segmentos

5
Fotorresistor

Receptor Infrarrojo

Tira de 12 Neo Pixels

Control remoto por IR

6
Sensor de distancia ultrasónico

LEDs rojos

LEDs verdes

7
Simulación

Enlace

https://www.tinkercad.com/things/34RX7iwIANs-exquisite-luulia-curcan/editel?returnTo=https
%3A%2F%2Fwww.tinkercad.com%2Fdashboard&sharecode=bMWrnoMiUpD33gRhmRJ9N
HJvmnf6-wOjthEDQiorFLY

8
Esquema Eléctrico

9
10
11
Circuito

12
13
14
Diagrama de Flujo del Código

15
16
17
18
Fotografías

19
20
21
Vídeo

https://photos.app.goo.gl/GEPyGWx5ZbGDCPyg9

Descripción
Se simuló el funcionamiento de un estacionamiento inteligente, integrando tanto
características típicas de sistemas automatizados modernos como funciones innovadoras
que mejoran la experiencia del usuario.

El sistema se desarrolló utilizando sensores ultrasónicos para la detección de vehículos en


los espacios cuya implementación permite un monitoreo del tiempo de ocupación; acceso
mediante una pluma que utiliza un servomotor; tiras y LEDs para la señalización visual, y un
display de 7 segmentos para mostrar información relevante como el número de espacios
disponibles; implementación de un remoto para control del acceso de vehículos y el color
de la iluminación cuya intensidad es regulada automáticamente mediante un fotorresistor.

22
RESULTADOS
El estacionamiento funcionó de la forma esperada a como lo es en un entorno real.
Aplicamos exitosamente varios sensores y estructuras de datos para el funcionamiento de
nuestro estacionamiento inteligente, simulando de una manera muy acertada el cómo
funciona un estacionamiento en tiempo real.

El sistema implementado permite recopilar y analizar datos en tiempo real sobre el uso de
los cajones de estacionamiento mediante sensores ultrasónicos. Utilizando tres variables
principales (tiempoOcupado, duracionOcupado y estadoPrevio), se registran

eventos de ocupación y liberación, calculando dos métricas clave y posibles acorde a este
proyecto:

1. Tiempo promedio de ocupación por cajón: : Una vez que el sensor ultrasónico
detecta un objeto, comienza un conteo sobre el tiempo que hay un auto estacionado
en ese cajón específicamente, esto podría ayudar a estimar ingresos en caso de ser
un estacionamiento de paga o a encontrar patrones en los usuarios.

La fórmula para calcular el tiempo promedio usamos la siguiente fórmula:

float promedio = conteoUsos[i] > 0 ?


(totalOcupado[i] / conteoUsos[i]) / 1000.0 :
0;

Para este caso, bajo una simulación de 5 minutos obtenemos los siguientes
resultados:
2. Tasa de ocupación por cajón: Esta métrica nos indicaría cuáles son los cajones
donde más autos suelen estacionarse, ayudando a identificar las zonas del
estacionamiento las cuales se usan en mayor o menor medida, pudiendo tomar
acciones preventivas como el redireccionamiento de tráfico a estas zonas con poca
ocupación.

La fórmula utilizada es:

3. float tasa = (totalOcupado[i] * 100.0) / tiempoTotal;

23
El análisis hecho en una simulación de 5 minutos fue el siguiente:

24
Nuestro prototipo de estacionamiento inteligente no solo cumple con las funciones básicas
de control de acceso y disponibilidad, sino que también sienta las bases para el análisis de
datos y la optimización continua del sistema.

25
CONCLUSIONES
Gracias a este proyecto, pudimos aplicar de manera práctica los conocimientos adquiridos a
lo largo del curso, además de aprender de forma autónoma el uso de diversos componentes
electrónicos. La combinación entre electrónica y programación nos permitió crear una
solución innovadora a un problema común en nuestra vida cotidiana, como lo es la gestión
eficiente de espacios de estacionamiento.

Este proyecto demuestra que, con componentes accesibles y una lógica de diseño clara, es
posible desarrollar sistemas inteligentes capaces de recolectar, interpretar y actuar sobre
datos en tiempo real. Además de cumplir con su función operativa, nuestro prototipo sienta
las bases para aplicaciones más avanzadas, como la visualización de métricas, la
predicción de afluencia, implementación de un sistema de cobro automatizado e incluso una
autonomía total del sistema, además de una experiencia de usuario más eficiente y
personalizada.

Las posibilidades que ofrecen los microcontroladores en este tipo de soluciones son
prácticamente infinitas, y es nuestra responsabilidad como futuros ingenieros conocer a
fondo su funcionamiento y potencial. Este tipo de proyectos no solo fortalece nuestras
habilidades técnicas, sino también nuestro compromiso con el desarrollo de tecnología útil,
accesible y orientada a mejorar la calidad de vida en nuestro entorno.

26
BIBLIOGRAFÍA
Adafruit. (Marzo, 2025). AdaFruit Neopixel. Consultado el 05 de mayo del 2025 de:
https://docs.arduino.cc/libraries/adafruit-neopixel/

Joachimsmeyer, Armin (Septiembre, 2024). IR Remote. Consultado el 05 de mayo del 2025


de: https://docs.arduino.cc/libraries/irremote/

27
CÓDIGO
#include <IRremote.hpp>
#include <Servo.h>
#include <Adafruit_NeoPixel.h>

//---- CONFIGURACIÓN DE PINES ----


const int PHOTORESISTOR_PIN = A7;
const int IR_PIN = 11;
const int SERVO_PIN = 28;
// a, b, c, d, e, f, g
const int DISPLAY_PINS[] = {7, 8, 6, 5, 4, 3, 2};
// Tira led
const int NUM_PIXELS = 8;
const int LED_STRIP = 12;
Adafruit_NeoPixel pixels = Adafruit_NeoPixel(NUM_PIXELS, LED_STRIP,
NEO_GRB + NEO_KHZ800);

//---- ESTRUCTURAS DE DATOS ----


// Definir la estructura para el sensor ultrasónico
struct Ultrasonico {
int triggerPin;
int echoPin;
bool estado;
};
// Definir la estructura para los LEDs
struct Led {
int greenPin;
int redPin;
};
// Estructura de botones del control remoto
struct RemoteButtons {
constexpr static uint8_t POWER = 0x9; // Activar / Desactivar pluma
constexpr static uint8_t CERO = 0x16; // Activar
constexpr static uint8_t ONE = 0xC; // Desactivar
constexpr static uint8_t TWO = 0x18; // Blanco
constexpr static uint8_t THREE = 0x5E; // Sin luz
constexpr static uint8_t FOUR = 0x8; // Rojo
constexpr static uint8_t FIVE = 0x1C; // Verde
constexpr static uint8_t SIX = 0x5A; // Azul
constexpr static uint8_t SEVEN = 0x42; // Amarillo
constexpr static uint8_t EIGHT = 0x52; // Magenta
constexpr static uint8_t NINE = 0x4A; // Cian

28
} buttons;

//---- ARREGLOS PARA PARA CONTROLAR CAMBIOS ----


Ultrasonico parkingSpot[3] = {
{40, 41, false}, // Espacio 1
{44, 45, false}, // Espacio 2
{48, 49, false} // Espacio 3
};
Led parkingLight[3] = {
{42, 43},
{46, 47},
{50, 51}
};
// Colores LED strip (orden acorde a los botones)
uint32_t ledColors[] = {
pixels.Color(255, 255, 255), // Blanco
pixels.Color(0, 0, 0), // Sin luz
pixels.Color(255, 0, 0), // Rojo
pixels.Color(0, 255, 0), // Verde
pixels.Color(0, 0, 255), // Azul
pixels.Color(255, 255, 0), // Amarillo
pixels.Color(255, 0, 255), // Magenta
pixels.Color(0, 255, 255) // Cian
};
// Dígitos del display
const bool displayDigits[10][7] = {
{true, true, true, true, true, true, false}, // 0
{false, true, true, false, false, false, false}, // 1
{true, true, false, true, true, false, true}, // 2
{true, true, true, true, false, false, true}, // 3
};

//---- VARIABLES ----


uint32_t selectedColor = ledColors[0]; // Color de la tira LED
inicialmente blanco
int lightValue = 0; // Intensidad de la luz
bool gate = false; // Estado de la pluma
int numSpots = 3; // Spots disponibles
int prevBrightness = -1; // Para evitar actualizar si no
hay cambio

unsigned long tiempoOcupado[3] = {0, 0, 0}; // Marca de tiempo

29
cuando se ocupó
unsigned long duracionOcupado[3] = {0, 0, 0}; // Duración actual
bool estadoPrevio[3] = {false, false, false}; // Para detectar
cambios de estado

// Variables adicionales mínimas para las métricas


unsigned long totalOcupado[3] = {0, 0, 0}; // Tiempo total
acumulado
unsigned int conteoUsos[3] = {0, 0, 0}; // Veces que se ha
ocupado

Servo servoMotor;
// ---- SETUP ----
void setup() {
Serial.begin(9600);
pixels.begin();

// Configurar pines de sensores ultrasónicos y LEDs


for (int i = 0; i < 3; i++) {
pinMode(parkingSpot[i].triggerPin, OUTPUT);
pinMode(parkingSpot[i].echoPin, INPUT);
pinMode(parkingLight[i].greenPin, OUTPUT);
pinMode(parkingLight[i].redPin, OUTPUT);
}

// Configurar pines del display de 7 segmentos


for (int i = 0; i < 7; i++) {
pinMode(DISPLAY_PINS[i], OUTPUT);
}

// Inicializar arrays de métricas


memset(totalOcupado, 0, sizeof(totalOcupado));
memset(conteoUsos, 0, sizeof(conteoUsos));

IrReceiver.begin(IR_PIN, ENABLE_LED_FEEDBACK); //IR receiver


servoMotor.attach(SERVO_PIN); // Servo motor
desactivar(); // Se cierra le pluma
}

30
// ---- BUCLE DE EJECUCIÓN ----
void loop() {
estado_spot();
int libres = contar_spots(); // Guardar espacios libres

if (IrReceiver.decode()) {
uint8_t code = IrReceiver.decodedIRData.command;

// Activar / desactivar pluma solo si hay lugar disponible


if ((code == buttons.POWER || code == buttons.CERO) && !gate &&
libres > 0) {
activar();
} else if ((code == buttons.POWER || code == buttons.ONE) && gate)
{
desactivar();
} else {
cambiar_color(code);
}
IrReceiver.resume();
}

ajustar_luz();

// Generar reporte cada 5 minutos


static unsigned long ultimoReporte = 0;
if(millis() - ultimoReporte > 300000) {
generarReporte();
ultimoReporte = millis();
}

delay(300);
}

// ---- FUNCIONES ----

// Función para cerrar la pluma


void desactivar() {
gate = false;
Serial.println("Desactivando pluma...");
servoMotor.write(0);
}

31
// Función para abrir la pluma
void activar() {
gate = true;
Serial.println("Activando pluma...");
servoMotor.write(90);
}

// Función para medir la distancia en cm con el ultrasónico


long medirDistancia(int trigger, int echo) {
digitalWrite(trigger, LOW);
delayMicroseconds(2);
digitalWrite(trigger, HIGH);
delayMicroseconds(10);
digitalWrite(trigger, LOW);

long duracion = pulseIn(echo, HIGH, 30000); // timeout de 30ms


if (duracion == 0) return 999; // si no hay respuesta, valor muy alto
return duracion / 58;
}

// Función que valida si los espacios de estacionamiento están ocupados


// y cambia el estado de los LEDs
void estado_spot(){
for (int i = 0; i < 3; i++) {
int distancia = medirDistancia(parkingSpot[i].triggerPin,
parkingSpot[i].echoPin);
Serial.print("Sensor ");
Serial.print(i + 1);
Serial.print(": ");
Serial.println(distancia);

bool ocupadoAhora = distancia < 10;

// Detectar cambio de estado: LIBRE -> OCUPADO


if (!estadoPrevio[i] && ocupadoAhora) {
tiempoOcupado[i] = millis(); // Marca de tiempo al ocupar
}

// Si sigue ocupado, mostrar cuánto tiempo ha estado ocupado


if (ocupadoAhora) {

32
duracionOcupado[i] = millis() - tiempoOcupado[i];
Serial.print(">> Tiempo ocupado del spot ");
Serial.print(i + 1);
Serial.print(": ");
Serial.print(duracionOcupado[i] / 1000.0);
Serial.println(" segundos");
}

// Actualizar LEDs
if (ocupadoAhora) {
digitalWrite(parkingLight[i].greenPin, LOW);
digitalWrite(parkingLight[i].redPin, HIGH);
} else {
digitalWrite(parkingLight[i].greenPin, HIGH);
digitalWrite(parkingLight[i].redPin, LOW);
}

// Guardar estados actualizados


estadoPrevio[i] = ocupadoAhora;
parkingSpot[i].estado = ocupadoAhora;

Serial.print("Estado spot ");


Serial.print(i + 1);
Serial.println(ocupadoAhora ? ": OCUPADO" : ": LIBRE");
Serial.println(" -------------------- ");
Serial.println("");

}
}

// Función que valida los espcio de estacionamiento disponibles


// y los muestra en el display de 7 segmentos
int contar_spots() {
int num = 0;
for (int i = 0; i < 3; i++) {
if (parkingSpot[i].estado) num++;
}
num = 3 - num;
num = constrain(num, 0, 3); // evitar overflow
for (int i = 0; i < 7; i++) {

33
digitalWrite(DISPLAY_PINS[i], displayDigits[num][i]);
}
return num;
}

void ajustar_luz() {
lightValue = analogRead(PHOTORESISTOR_PIN);
Serial.print("Fotorresistor: ");
Serial.println(lightValue);

// Mapear de 0 (poca luz) a 600 (mucha luz)


// para que haya más brillo con menos luz
int brightness = map(lightValue, 0, 600, 255, 0);
brightness = constrain(brightness, 0, 255);

// Solo actualizar si el brillo cambió


if (brightness != prevBrightness) {
pixels.setBrightness(brightness);
color_tiraLED();
prevBrightness = brightness;
}
}

// Función que cambiar el color de la tira LED dependiendo del código


// recibido del control remoto
void cambiar_color(uint8_t code) {
switch (code) {
case buttons.TWO: selectedColor = ledColors[0]; break; // Blanco
case buttons.THREE: selectedColor = ledColors[1]; break; // Sin luz
case buttons.FOUR: selectedColor = ledColors[2]; break; // Rojo
case buttons.FIVE: selectedColor = ledColors[3]; break; // Verde
case buttons.SIX: selectedColor = ledColors[4]; break; // Azul
case buttons.SEVEN: selectedColor = ledColors[5]; break; //
Amarillo
case buttons.EIGHT: selectedColor = ledColors[6]; break; // Magenta
case buttons.NINE: selectedColor = ledColors[7]; break; // Cian
default: return; // No hacer nada si no es un botón de color
}
color_tiraLED();
}

// Aplicar color a la tira LED

34
void color_tiraLED(){
for (int i = 0; i < pixels.numPixels(); i++) {
pixels.setPixelColor(i, selectedColor);
}
pixels.show();
}

void actualizarMetricas() {
for(int i = 0; i < 3; i++) {
// Usamos el estado actual del parkingSpot
bool ocupadoAhora = parkingSpot[i].estado;

// Detección de cambios
if(ocupadoAhora && !estadoPrevio[i]) {
tiempoOcupado[i] = millis(); // Registra inicio de ocupación
}
else if(!ocupadoAhora && estadoPrevio[i]) {
// Calcula duración y actualiza acumuladores
duracionOcupado[i] = millis() - tiempoOcupado[i];
totalOcupado[i] += duracionOcupado[i];
conteoUsos[i]++;

// Log inmediato
Serial.print("Cajón ");
Serial.print(i+1);
Serial.print(" liberado. Tiempo: ");
Serial.print(duracionOcupado[i] / 1000.0);
Serial.println(" segundos");
}

estadoPrevio[i] = ocupadoAhora;
}
}

void generarReporte() {
unsigned long tiempoTotal = millis() / 1000; // Segundos desde inicio

Serial.println("\n=== REPORTE ESTADÍSTICO ===");


Serial.println("Cajón | Ocupación | Tiempo Promedio");
Serial.println("------|-----------|----------------");

for(int i = 0; i < 3; i++) {


float tasa = (totalOcupado[i] * 100.0) / tiempoTotal;

35
float promedio = conteoUsos[i] > 0 ?
(totalOcupado[i] / conteoUsos[i]) / 1000.0 : 0;

Serial.print(i+1);
Serial.print(" ");
Serial.print(tasa, 1);
Serial.print("% ");
Serial.print(promedio, 1);
Serial.println(" seg");

// Mostrar también duración actual si está ocupado


if(parkingSpot[i].estado) {
Serial.print(" >> Ocupado actualmente por: ");
Serial.print((millis() - tiempoOcupado[i]) / 1000.0);
Serial.println(" segundos");
}
}
}

36

También podría gustarte