aboutsummaryrefslogtreecommitdiff
path: root/textil.ino
diff options
context:
space:
mode:
author3gg <3gg@shellblade.net>2021-12-04 22:14:16 -0800
committer3gg <3gg@shellblade.net>2021-12-04 22:14:16 -0800
commit79531f5698f1c10e83edd36e6be12b671b443442 (patch)
tree95ae349505858e5f555ee0902c340d42832e9b2e /textil.ino
parent80fccb82658b6ac240ffb8dc4ce0f2653462cae0 (diff)
Add program.
Diffstat (limited to 'textil.ino')
-rw-r--r--textil.ino201
1 files changed, 201 insertions, 0 deletions
diff --git a/textil.ino b/textil.ino
new file mode 100644
index 0000000..846cb41
--- /dev/null
+++ b/textil.ino
@@ -0,0 +1,201 @@
1enum Reles {
2 Rele1,
3 Rele2,
4 Rele3,
5 MAX_RELE,
6};
7
8/* Configuracion */
9
10// Tiempos de espera antes de emitir senyales de salida de rele.
11// Unidades en milisegundos (1s = 1000ms).
12const unsigned long TIEMPO_ESPERA_SALIDA_MS[MAX_RELE] = {
13 5000, // Rele 1.
14 2000, // Rele 2.
15 3000, // Rele 3.
16};
17
18// Pines reles.
19//
20// Pines 0 y 1 en Arduino UNO son para comunicacion serie, no usar.
21const int Rele_Pin[MAX_RELE] = {
22 2, // Rele 1.
23 3, // Rele 2.
24 4, // Rele 3.
25};
26
27// Pin pulsador.
28const int Pulsador_Pin = 5;
29
30enum Estado {
31 Estado_Inicial,
32 Espera_Rele1,
33 Salida_Rele1,
34 Espera_Rele2,
35 Salida_Rele2,
36 Espera_Rele3,
37 Salida_Rele3,
38 Estado_Final,
39 MAX_ESTADO,
40};
41
42enum Transicion {
43 Automatica, // Transicion automatica.
44 Retardada, // Transicion automatica retardada.
45 Manual, // Transicion al pulsar boton.
46};
47
48const Transicion transiciones[MAX_ESTADO] = {
49 Manual, // Estado_Inicial -> Espera_Rele1
50 Retardada, // -> Salida_Rele1
51 Manual, // -> Espera_Rele2
52 Retardada, // -> Salida_Rele2
53 Manual, // -> Espera_Rele3
54 Retardada, // -> Salida_Rele3
55 Manual, // -> Estado_Final
56 Automatica, // -> Estado_Inicial
57};
58
59
60/* Entrada digital con debounce. */
61
62// Tiempo en el que la senyal debe permanecer con un valor constante para
63// que se ejecute la lectura logica de la senyal.
64const unsigned long DEBOUNCE_DELAY_MS = 50;
65
66struct EntradaDigital {
67 int pin; // Pin de entrada.
68 int estado; // Estado logico actual, LOW o HIGH.
69 int ultima_senyal; // Ultima senyal de entrada, LOW o HIGH.
70 unsigned long debounce_time_ms; // Tiempo del ultimo cambio de estado en la entrada.
71};
72
73// Lee un cambio de estado de la entrada digital.
74// Devuelve cierto si se ejecuta un cambio de estado logico, falso en caso contrario.
75bool leer_cambio_de_estado(EntradaDigital& entrada, unsigned long tiempo) {
76 const int senyal_actual = digitalRead(entrada.pin);
77
78 bool estado_cambiado = false;
79
80 if (senyal_actual != entrada.ultima_senyal) {
81 entrada.debounce_time_ms = tiempo;
82 }
83 else if (
84 ((tiempo - entrada.debounce_time_ms) >= DEBOUNCE_DELAY_MS) &&
85 (senyal_actual != entrada.estado) ){
86 entrada.estado = senyal_actual;
87 estado_cambiado = true;
88 }
89
90 entrada.ultima_senyal = senyal_actual;
91 return estado_cambiado;
92}
93
94
95/* Programa principal. */
96
97Estado estado_actual;
98EntradaDigital pulsador;
99unsigned long tiempo_ultima_transicion;
100
101// Ejecuta una transicion de estado y devuelve el nuevo estado.
102Estado ejecutar_transicion(Estado estado, unsigned long tiempo) {
103 tiempo_ultima_transicion = tiempo;
104 return Estado((estado + 1) % MAX_ESTADO);
105}
106
107// Actualiza la salida despues de un cambio de estado.
108void actualizar_salida(Estado estado_actual) {
109 switch (estado_actual) {
110 case Estado_Inicial:
111 break;
112 case Salida_Rele1:
113 digitalWrite(Rele_Pin[Rele1], HIGH);
114 break;
115 case Espera_Rele2:
116 digitalWrite(Rele_Pin[Rele1], LOW);
117 break;
118 case Salida_Rele2:
119 digitalWrite(Rele_Pin[Rele2], HIGH);
120 break;
121 case Espera_Rele3:
122 digitalWrite(Rele_Pin[Rele2], LOW);
123 break;
124 case Salida_Rele3:
125 digitalWrite(Rele_Pin[Rele3], HIGH);
126 break;
127 case Estado_Final:
128 digitalWrite(Rele_Pin[Rele3], LOW);
129 break;
130 default:
131 break;
132 }
133}
134
135// Devuelve el tiempo de espera para el estado dado.
136unsigned long get_tiempo_espera(Estado estado) {
137 switch (estado) {
138 case Espera_Rele1:
139 return TIEMPO_ESPERA_SALIDA_MS[Rele1];
140 case Espera_Rele2:
141 return TIEMPO_ESPERA_SALIDA_MS[Rele2];
142 case Espera_Rele3:
143 return TIEMPO_ESPERA_SALIDA_MS[Rele3];
144 default:
145 return 0;
146 }
147}
148
149// Inicializacion.
150void setup() {
151 const unsigned long tiempo = millis();
152
153 for (int i = 0; i < MAX_RELE; ++i) {
154 pinMode(Rele_Pin[i], OUTPUT);
155 digitalWrite(Rele_Pin[i], LOW);
156 }
157 pinMode(Pulsador_Pin, INPUT);
158
159 estado_actual = Estado_Inicial;
160
161 pulsador = (EntradaDigital) {
162 .pin = Pulsador_Pin,
163 .estado = LOW,
164 .ultima_senyal = LOW,
165 .debounce_time_ms = tiempo,
166 };
167
168 tiempo_ultima_transicion = tiempo;
169}
170
171// Bucle principal.
172void loop() {
173 const unsigned long tiempo = millis();
174 const Estado estado_original = estado_actual;
175
176 switch (transiciones[estado_actual]) {
177 case Automatica:
178 estado_actual = ejecutar_transicion(estado_actual, tiempo);
179 break;
180
181 case Retardada: {
182 const unsigned long tiempo_espera = get_tiempo_espera(estado_actual);
183 if ( (tiempo - tiempo_ultima_transicion) >= tiempo_espera ) {
184 estado_actual = ejecutar_transicion(estado_actual, tiempo);
185 }
186 break;
187 }
188
189 case Manual: {
190 const bool pulsador_estado_cambiado = leer_cambio_de_estado(pulsador, tiempo);
191 if (pulsador_estado_cambiado && pulsador.estado == HIGH) {
192 estado_actual = ejecutar_transicion(estado_actual, tiempo);
193 }
194 break;
195 }
196 }
197
198 if (estado_actual != estado_original) {
199 actualizar_salida(estado_actual);
200 }
201}