Codigo Control Ascensor Arduino

#include /* ==================================================================================================== =======

Views 150 Downloads 2 File size 45KB

Report DMCA / Copyright

DOWNLOAD FILE

Recommend stories

Citation preview

#include /* ==================================================================================================== ===================================== CONSTANTES ==================================================================================================== ===================================== */ // Constantes de configuración de pines y nombres para su testeo const int PLANTAS = 3;

// Ascensor con tres plantas // Parámetros de ángulo de giro del servo

const int ANGULOMAXIMO = 180; const int ANGULOMINIMO = 0; const int PASO = 30; const int outServo = 3; los pines asociados al PWM

// Salida del servo. Pendiente de ubicar. Utilizar para el control

// Pines de salida del BCD 7 segementos. Muestra la planta actual = 10; = 11; = 12; = 13; // Led's que simulan el sentido de giro del motor del ascensor const int subidaMotor = 0; const int bajadaMotor = 1; const const const const

int int int int

outPinA outPinB outPinC outPinD

// Led´s que indican el estado en que nos encontramos const int ledReposo = 2; const int ledEntreplanta = A0; const int ledPuerta = A2; const int fCarrera pin analógico const int sensorPuerta

= A4;

// Sensor de final de carrera del motor subida bajada. Lectura de

= A5;

// Sensor de seguridad de la puerta. Lectura de pin analógico

// Pines de entrada de la botonera del ascensor y botón de cada planta const int botAscensor[PLANTAS] = {4,5,6}; // Dentro se indica el número del pin utilizado const int botPlanta[PLANTAS] = {7,8,9}; //int fCarreraPlanta[PLANTAS -1]; a la planta --> parar el ascensor //int sensorPuerta[PLANTAS -1]; por cada planta

// Sensor de final de carrera que avisa de llegada // Sensor de seguridad de cierre de puertas --> uno

/* ==================================================================================================== ===================================== VARIABLES ==================================================================================================== ===================================== */ // Configuración del servomotor // Crear un objeto servo // posición de servo

Servo puertaServo; int posicionServo = 0;

// Registros utilizados para el funcionamiento del Ascensor. De la planta a PLANTAS -1] int botonesAscensor[PLANTAS]; // Array de pulsadores del teclado del ascensor int pulsadoresPlanta[PLANTAS]; // Array de pulsadores de cada planta //int finalCarrPlanta[PLANTAS]; // Array de finales de carrera para cada planta // Variables para conocer el estado y ubicación del ascensor

[1

int planta = 0; // Indica la planta actual donde se encuentra el ascensor. Se actualiza al llegar a una nueva planta int estadoAscensor = 0; // '0' --> reposo, '1' --> subir, '2' --> bajar boolean estadoReposo = false; // Variable semáforo para no re-escribir en los puertos de salida. Reposo planta boolean estadoPuerta = false; // Variable semáforo para no re-escribir en los puertos de salida. Puerta int estado = 0; // Para la máquina de estados del ascensor // Variables de ayuda a la secuencias de funcionamiento boolean encendidoMotor = false; boolean abriendoPuerta = false; int parpadeo = LOW; // Variables para el parpadeo de led long milisegundosAnteriores = 0; // Almacena la última vez que el LED se ha actualizado. Se utilizan variables long ya que el tiempo se mide en milisegundos // Rápidamente se convertirá en un número más grande que se puede almacenar en un int long periodo = 500; // Intervalo de parpadeo del LED (milisegundos) // Variables de filtrado de ruido en la lectura de sensores ópticos long miliSegAntLectura = 0; // Variable que almacena la última lectura de 'millis()' para comparar el tiempo transcurrido long intervalo = 350; // Tiempo de espera para eliminar ruido boolean lecturaOptico = false; // Variable para leer la primera activación y rechazar el resto durante un tiempo determinado 'intervalo' // Variables de lectura pulsadores int anteriorLeido = LOW; // Lectura anterior del pulsador de entrada /* ==================================================================================================== ===================================== FUNCIONES ==================================================================================================== ===================================== */ // Lectura de la entrada indicada en 'pin' boolean antiRebote(int pin){ boolean pulsado = false; int leido = digitalRead(pin); variable local if (leido == HIGH && anteriorLeido == LOW) pulsado = true;

// Lee el estado del pin y la almacena en una

// Si el pulsador cambia de 0 a 1

anteriorLeido = leido; return pulsado; } // Retardo de tiempo indicado en tiempo para filtrar ruido en las lecturas // Anchura del tiempo de antirrebote --> ( miliSegActuales - miliSegAntLectura > X mseg ) boolean retardo(){ unsigned long miliSegActuales = millis(); if(miliSegActuales - miliSegAntLectura > intervalo){ miliSegAntLectura = miliSegActuales; // Guarda la última vez que se ha cumplido el tiempo de filtro y actualiza la variable 'miliSegAntLectura' if (lecturaOptico) // Si ya se ha cumplido el tiempo del filtro y se ha leído el primer cambio en el sensor, se cambia lecturaOptico = false; // 'lecturaOptico = false' para iniciar una nueva captura del senor } return lecturaOptico; }

// Lee el sensor óptico del pin analógico correspondiente. Con filtro antirrebote int lecturaSensorOptico(int sensor){ int lectura = LOW; unsigned long miliSegActuales = millis(); if (analogRead(sensor) se puede volver a capturar un nuevo dato lectura = HIGH; // Hay activación del sensor lecturaOptico = HIGH; } return lectura; } // Lectura de los pulsadores de la botonera del ascensor y de cada planta void lecturaPulsadores(){ for (int i = 0; i < PLANTAS; i++){ if (antiRebote(botAscensor[i])){ botonesAscensor[i] = HIGH; } if (antiRebote(botPlanta[i])){ pulsadoresPlanta[i] = HIGH; } } } // Indica el número de planta en que se encuentra void numeroPlanta(int num){ // Convierte un número decimal a binario y lo saca por los pines de salida 0-3 digitalWrite(outPinD, HIGH && (num & B00001000)); digitalWrite(outPinC, HIGH && (num & B00000100)); digitalWrite(outPinB, HIGH && (num & B00000010)); digitalWrite(outPinA, HIGH && (num & B00000001)); } // Indica si se ha pulsado algún botón de la planta indicada boolean botonPulsado(int planta){ return (botonesAscensor[planta]== HIGH) || (pulsadoresPlanta[planta]== HIGH); } // Indica que se ha pulsado algún botón distinto al de la planta donde está el ascensor boolean llamadaAscensor(int planta){ boolean llamada = false; for (int i = 0; i < PLANTAS; i++){ if (i != planta){ if (botonesAscensor[i] == HIGH || pulsadoresPlanta[i] == HIGH) llamada = true; } } return llamada; } /* ------------------------------------------------------------------------------------------------------------------------------- */ // Sensor de llegada a planta. Llama a la función de lectura del sensor, escribe en la posición correspondiente y luego lo verifica boolean sensorFinalCarrera(int sensor, int planta){ // finalCarrPlanta[planta] = lecturaSensorOptico(sensor); // Para cuando se dispone de un sensor por planta return lecturaSensorOptico(sensor) == HIGH; // Verifico si se ha activado el sensor de final de carrera } /* ······························· ························ */ // Para el motor del ascensor

Funciones para control del motor de subida/bajada del ascensor

void pararMotor(){ // apagar el led correspondiente de simulado de funcionamiento digitalWrite(subidaMotor, LOW); digitalWrite(bajadaMotor, LOW); encendidoMotor = false; } // Arranque en sentido de subida. Simulado con un led boolean arranqueMotorSubida(){ digitalWrite(subidaMotor, HIGH); return true; } // Arranque en sentido de bajada. Simulado con un led boolean arranqueMotorBajada(){ digitalWrite(bajadaMotor, HIGH); return true; } /* ···································································································· ···················· */ // Encendido con parpadeo de led de estado void parpadeoLedEstado(int pin){ unsigned long milisegundosActuales = millis(); if(milisegundosActuales - milisegundosAnteriores > periodo) { milisegundosAnteriores = milisegundosActuales; // Guarda la última vez que parpadeaba el LED parpadeo = !parpadeo; // Conmuta el valor escrito en el pin digitalWrite(pin, parpadeo); } } // Encendido de led de estado boolean ledEstadoEncendido(int pin){ digitalWrite(pin, HIGH); return true; } // Apagado de led de estado boolean ledEstadoApagado(int pin){ digitalWrite(pin, LOW); return false; } // Incrementa o disminuye una posición el valor de planta void actualizarPlanta(){ if (estadoAscensor == 1) // Ascensor subiendo planta++; else if (estadoAscensor == 2) // Ascensor bajando planta--; } // se comprueba que el sentido es de subida boolean subidaAscensor(){ return (estadoAscensor == 1); } // Se comprueba que el sentido es de bajada boolean bajadaAscensor(){ return (estadoAscensor == 2); } // Determina el sentido de subida/bajada indicándolo en la variable // 'estadoAscensor' : '0' --> reposo, '1' --> subir, '2' --> bajar int sentidoAscensor(int planta){ // Si el ascensor está subiendo

int i = planta; while (i < PLANTAS){ if (botonesAscensor[i] == 1 || pulsadoresPlanta[i] == 1){ return 1; // Hay que ascender } i++; } // Si el ascensor está bajando i = planta; while (i > -1){ if (botonesAscensor[i] == 1 || pulsadoresPlanta[i] == 1){ return 2; // Hay que descender } i--; } return 0; // Estado de reposo } /* ------------------------------------------------------------------------------------------------------------------------------- */ // Se borra en la planta correspondiente los botones que ahí se hayan pulsado void borradoRegistroPlanta(int planta){ botonesAscensor[planta] = 0; pulsadoresPlanta[planta] = 0; } // Sensor de seguridad de cierre de la puerta ante obstáculos boolean sensorSeguridadPuerta(int sensor){ // sensorPuerta[planta] = lecturaSensorOptico(sensor); // Para cuando se dispone de un sensor por planta para cada puerta return lecturaSensorOptico(sensor) == HIGH; // Verifico que se ha activado el sensor } /* ······························· Funciones para control del motor paso a paso de la puerta del ascensor ························ */ // Indica que la puerta está completamente abierta boolean puertaAbierta(){ return posicionServo == ANGULOMAXIMO; } // Indica que la puerta está completamente cerrada boolean puertaCerrada(){ return posicionServo == ANGULOMINIMO; }

// Se ha abierto completamente

// Se ha cerrado completamente

// Detiene el cierre de la puerta --> por algún obstáculo void paradaPuerta(){ delay(2000); // Detiene el funcionamiento del motor paso a paso } // Detiene la puerta en la última posición conocida void detenerPuerta(){ puertaServo.write(posicionServo); delay(500); } // Abre completamente la puerta desde la posición en la que se encontraba en ese momento boolean aperturaEmergenciaPuerta(){ while (posicionServo < ANGULOMAXIMO){ posicionServo = posicionServo + PASO; puertaServo.write(posicionServo); delay(50); } return true; }

//

Valores en puerto serie (0-180)

// Se abre la puerta del ascensor, durante un tiempo determinado // OJO --> hay que tener en cuenta que no se debe activar o tener en cuenta el sensor de seguridad de la puerta boolean aperturaPuerta(){ if (posicionServo < ANGULOMAXIMO){ posicionServo = posicionServo + PASO; puertaServo.write(posicionServo); delay(50); } return true;

//

Valores en puerto serie (0-180)

} // Indica cuando se ha terminado de cerrar la puerta, tras un tiempo, de entrada del ascensor boolean cierrePuerta(){ if (posicionServo > ANGULOMINIMO){ posicionServo = posicionServo - PASO; puertaServo.write(posicionServo); delay(100); } return true;

//

Valores en puerto serie (0-180)

} /* ···································································································· ··························· */ /* ==================================================================================================== ===================================== INICIALIZACIÓN Y CONFIGURACIÓN ==================================================================================================== ===================================== */ void setup() { // Configuración de los pines digitales como entrada pinMode(fCarrera, INPUT); for (int i = 0; i < PLANTAS; i++){ pinMode(botAscensor[i], INPUT); // Dentro se indica el número del pin utilizado pinMode(botPlanta[i] , INPUT); botonesAscensor[i] = LOW; pulsadoresPlanta[i] = LOW; // finalCarrPlanta[i]= LOW; // Cuando se tiene un sensor de final carrera por planta } // Configuración pinMode(outPinD, pinMode(outPinC, pinMode(outPinB, pinMode(outPinA,

de los pines digitales como salida. BCD 7 Segmentos OUTPUT); OUTPUT); OUTPUT); OUTPUT);

// Configuración de led's de estado pinMode(ledEntreplanta, OUTPUT); pinMode(ledReposo, OUTPUT); pinMode(ledPuerta, OUTPUT); // Led's de simulación del motor pinMode(subidaMotor, OUTPUT); pinMode(bajadaMotor, OUTPUT); // Configuración del servo de apertura/cierre de puerta puertaServo.attach(outServo); // Asocia el servo al pin 3

puertaServo.write(ANGULOMINIMO);

// Inicializa la posición del servo

} /* ==================================================================================================== ========================================= EJECUCIÓN DE LA APLICACIÓN ==================================================================================================== ========================================== */ void loop(){ lecturaPulsadores(); Ascensor

// Lectura de todos los pulsadores del

switch(estado){ /* xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx */ case 0: if (botonPulsado(planta)){ y se está en la misma planta.

ESTADO DE REPOSO EN PLANTA n

// En reposo, si se pulsa para abrir la puerta // Ya sea planta de destino o para seguir

subiendo o bajando estado = 2; estadoReposo = ledEstadoApagado(ledReposo); } else if (llamadaAscensor(planta)){

// Si se pulsa un boton para subir o bajar

estado = 1; estadoReposo = ledEstadoApagado(ledReposo); } else if (!estadoReposo){ entra una vez para no sobre-escribir los puertos

// Condición de reposo en una planta. Solo

estadoReposo = ledEstadoEncendido(ledReposo); numeroPlanta(planta); } break; /* xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx ESTADO DE ENTREPLANTA xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx */ /* xxxxx Activa el motor para subir/bajar el ascensor, y espera la activación del final de carrera de la siguiente planta xxxxxxxx */ case 1: parpadeoLedEstado(ledEntreplanta); if (sensorFinalCarrera(fCarrera, planta)){ planta. Ascendiendo o descendiendo

// Indicador de entreplanta con parpadeo // Espera a pasar por la siguiente

actualizarPlanta(); numeroPlanta(planta);

// Se actualiza la planta de llegada // Planta a la que llegamos

if

// Llegada a planta deseada

(botonPulsado(planta)){ pararMotor(); ledEstadoApagado(ledEntreplanta); estado = 0;

} } else if (!encendidoMotor){ arrancado el motor estadoAscensor = sentidoAscensor(planta); se está en reposo. La ascensión es preferente

// Condición inicial. Aún no se ha

// Devuelve si se va a subir, bajar o

if (subidaAscensor()){ encendidoMotor = arranqueMotorSubida(); } else if (bajadaAscensor()){ encendidoMotor = arranqueMotorBajada(); }

// Se está subiendo. // Se está bajando

} break; /* xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx */

ESTADO DE APERTURA/CIERRE DE PUERTA

case 2: // Si se activa el sensor de seguridad de la puerta --> Algún obstáculo if (sensorSeguridadPuerta(sensorPuerta) && !abriendoPuerta){ // Si se activa el sensor de seguridad y se está cerrando la puerta detenerPuerta(); // Detiene el cierre de la puerta aperturaEmergenciaPuerta(); // Apertura de emergencia paradaPuerta(); // Mantiene la puerta abierta durante 3 segundos abriendoPuerta = true; } // Proceso normal: apertura + espera + cierre de puerta else { // No se activa el sensor de seguridad if (botonPulsado(planta)){ // Apertura de puerta // Cada pasada, se desplaza una distancia determinada por PASO del servo if(!estadoPuerta){ // Inicio estado de apertura/cierre de puerta. Solo entra una vez para no sobre-escribir los puertos estadoPuerta = ledEstadoEncendido(ledPuerta); } aperturaPuerta(); abriendoPuerta = true; if (puertaAbierta()){ borradoRegistroPlanta(planta); botón de planta, se abren las puertas paradaPuerta(); } } else if (puertaCerrada()){ estadoPuerta = ledEstadoApagado(ledPuerta); estado = 0; se encuentra el ascensor } else if(!botonPulsado(planta)){ abriendoPuerta = false; cierrePuerta(); } } break; } }

// Por si alguien vuelve a pulsar el

// La puerta ya está cerrada // Vuelve a reposo en la planta donde // Proceso de cierre de puerta