From 79531f5698f1c10e83edd36e6be12b671b443442 Mon Sep 17 00:00:00 2001 From: 3gg <3gg@shellblade.net> Date: Sat, 4 Dec 2021 22:14:16 -0800 Subject: Add program. --- textil.ino | 201 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 201 insertions(+) create mode 100644 textil.ino diff --git a/textil.ino b/textil.ino new file mode 100644 index 0000000..846cb41 --- /dev/null +++ b/textil.ino @@ -0,0 +1,201 @@ +enum Reles { + Rele1, + Rele2, + Rele3, + MAX_RELE, +}; + +/* Configuracion */ + +// Tiempos de espera antes de emitir senyales de salida de rele. +// Unidades en milisegundos (1s = 1000ms). +const unsigned long TIEMPO_ESPERA_SALIDA_MS[MAX_RELE] = { + 5000, // Rele 1. + 2000, // Rele 2. + 3000, // Rele 3. +}; + +// Pines reles. +// +// Pines 0 y 1 en Arduino UNO son para comunicacion serie, no usar. +const int Rele_Pin[MAX_RELE] = { + 2, // Rele 1. + 3, // Rele 2. + 4, // Rele 3. +}; + +// Pin pulsador. +const int Pulsador_Pin = 5; + +enum Estado { + Estado_Inicial, + Espera_Rele1, + Salida_Rele1, + Espera_Rele2, + Salida_Rele2, + Espera_Rele3, + Salida_Rele3, + Estado_Final, + MAX_ESTADO, +}; + +enum Transicion { + Automatica, // Transicion automatica. + Retardada, // Transicion automatica retardada. + Manual, // Transicion al pulsar boton. +}; + +const Transicion transiciones[MAX_ESTADO] = { + Manual, // Estado_Inicial -> Espera_Rele1 + Retardada, // -> Salida_Rele1 + Manual, // -> Espera_Rele2 + Retardada, // -> Salida_Rele2 + Manual, // -> Espera_Rele3 + Retardada, // -> Salida_Rele3 + Manual, // -> Estado_Final + Automatica, // -> Estado_Inicial +}; + + +/* Entrada digital con debounce. */ + +// Tiempo en el que la senyal debe permanecer con un valor constante para +// que se ejecute la lectura logica de la senyal. +const unsigned long DEBOUNCE_DELAY_MS = 50; + +struct EntradaDigital { + int pin; // Pin de entrada. + int estado; // Estado logico actual, LOW o HIGH. + int ultima_senyal; // Ultima senyal de entrada, LOW o HIGH. + unsigned long debounce_time_ms; // Tiempo del ultimo cambio de estado en la entrada. +}; + +// Lee un cambio de estado de la entrada digital. +// Devuelve cierto si se ejecuta un cambio de estado logico, falso en caso contrario. +bool leer_cambio_de_estado(EntradaDigital& entrada, unsigned long tiempo) { + const int senyal_actual = digitalRead(entrada.pin); + + bool estado_cambiado = false; + + if (senyal_actual != entrada.ultima_senyal) { + entrada.debounce_time_ms = tiempo; + } + else if ( + ((tiempo - entrada.debounce_time_ms) >= DEBOUNCE_DELAY_MS) && + (senyal_actual != entrada.estado) ){ + entrada.estado = senyal_actual; + estado_cambiado = true; + } + + entrada.ultima_senyal = senyal_actual; + return estado_cambiado; +} + + +/* Programa principal. */ + +Estado estado_actual; +EntradaDigital pulsador; +unsigned long tiempo_ultima_transicion; + +// Ejecuta una transicion de estado y devuelve el nuevo estado. +Estado ejecutar_transicion(Estado estado, unsigned long tiempo) { + tiempo_ultima_transicion = tiempo; + return Estado((estado + 1) % MAX_ESTADO); +} + +// Actualiza la salida despues de un cambio de estado. +void actualizar_salida(Estado estado_actual) { + switch (estado_actual) { + case Estado_Inicial: + break; + case Salida_Rele1: + digitalWrite(Rele_Pin[Rele1], HIGH); + break; + case Espera_Rele2: + digitalWrite(Rele_Pin[Rele1], LOW); + break; + case Salida_Rele2: + digitalWrite(Rele_Pin[Rele2], HIGH); + break; + case Espera_Rele3: + digitalWrite(Rele_Pin[Rele2], LOW); + break; + case Salida_Rele3: + digitalWrite(Rele_Pin[Rele3], HIGH); + break; + case Estado_Final: + digitalWrite(Rele_Pin[Rele3], LOW); + break; + default: + break; + } +} + +// Devuelve el tiempo de espera para el estado dado. +unsigned long get_tiempo_espera(Estado estado) { + switch (estado) { + case Espera_Rele1: + return TIEMPO_ESPERA_SALIDA_MS[Rele1]; + case Espera_Rele2: + return TIEMPO_ESPERA_SALIDA_MS[Rele2]; + case Espera_Rele3: + return TIEMPO_ESPERA_SALIDA_MS[Rele3]; + default: + return 0; + } +} + +// Inicializacion. +void setup() { + const unsigned long tiempo = millis(); + + for (int i = 0; i < MAX_RELE; ++i) { + pinMode(Rele_Pin[i], OUTPUT); + digitalWrite(Rele_Pin[i], LOW); + } + pinMode(Pulsador_Pin, INPUT); + + estado_actual = Estado_Inicial; + + pulsador = (EntradaDigital) { + .pin = Pulsador_Pin, + .estado = LOW, + .ultima_senyal = LOW, + .debounce_time_ms = tiempo, + }; + + tiempo_ultima_transicion = tiempo; +} + +// Bucle principal. +void loop() { + const unsigned long tiempo = millis(); + const Estado estado_original = estado_actual; + + switch (transiciones[estado_actual]) { + case Automatica: + estado_actual = ejecutar_transicion(estado_actual, tiempo); + break; + + case Retardada: { + const unsigned long tiempo_espera = get_tiempo_espera(estado_actual); + if ( (tiempo - tiempo_ultima_transicion) >= tiempo_espera ) { + estado_actual = ejecutar_transicion(estado_actual, tiempo); + } + break; + } + + case Manual: { + const bool pulsador_estado_cambiado = leer_cambio_de_estado(pulsador, tiempo); + if (pulsador_estado_cambiado && pulsador.estado == HIGH) { + estado_actual = ejecutar_transicion(estado_actual, tiempo); + } + break; + } + } + + if (estado_actual != estado_original) { + actualizar_salida(estado_actual); + } +} -- cgit v1.2.3