Alarma de pico y placa usando módulo RTC.

Dependencies:   QEI TextLCD mbed

Fork of grafica_PID_android by Nicolás Villegas Echavarría

Revision:
4:d57cde44861e
Parent:
3:2e823b16a4a1
--- a/main.cpp	Sat May 13 20:36:07 2017 +0000
+++ b/main.cpp	Sat Jun 03 01:10:48 2017 +0000
@@ -7,247 +7,408 @@
 #include "mbed.h"
 #include "QEI.h"
 #include "TextLCD.h"
+#include "Rtc_Ds1307.h"
 
+Rtc_Ds1307 rtc(PTC9, PTC8);
 Serial GSM(PTE0,PTE1);  // Módulo Bluetooh
 TextLCD lcd(PTB10, PTB11, PTE2, PTE3, PTE4, PTE5); // rs, e, d4-d7
-QEI encoder (PTA13, PTD5, NC, 10);
+QEI encoder (PTA13, PTD5, NC, 300);
+DigitalOut alarma(PTA5);
+DigitalOut carro(PTA4);
+DigitalOut led2(LED2);
 Timer t;
 
 AnalogIn y(PTC2);   // Entrada análoga: Salida del sistema
 AnalogOut u(PTE30); // Salida análoga: Señal de control
 
-DigitalOut led1(LED1);
-DigitalOut led2(LED2);
-DigitalOut led3(LED3);
-
 DigitalIn button3(PTC16); // Botón del encoder
 DigitalIn button4(PTC17); // Pulsador
 
 // Códigos movimiento del cursor:
-int C1=0x0F;
-int C2=0x18; // desplaza izquierda
-int C3=0x1A; // desplaza derecha
-int C4=0x0C; // quito cursor bajo
+const int C1 = 0x0F; // Habilitar cursor
+const int C2 = 0x18; // Desplazar pantalla izq.
+const int C4 = 0x0C; // Quitar cursor
+
+const char abc[] = {'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'}; // Abecedario para seleccionar la placa.
+char* dias[] = {"Dia", "Dom", "Lun", "Mar", "Mie", "Jue", "Vie", "Sab"}; // Dias de la semana para la configuración del reloj.
+int p1 = 0, p2 = 0, p3 = 0, p4 = 0, p5 = 0, p6 = 0; // 6 dígitos de la placa.
 
-int cambio = 0, diferencia = 0;
-float pid, o, ai, ad, ap, med, err, setpoint;
-float err_v;
-int spnum = 0, kinum = 0, kpnum = 0 ,kdnum = 0, pos = 1;
-int j,k; 
-long t_pid = 0, t_btn = 0;
+bool menu = true;
+bool min45 = false, min30 = false, min15 = false, min0 = false; // Indican si faltan X minutos para pico y placa.
+bool alarma45 = false, alarma30 = false, alarma15 = false, alarma0 = false; // Indican si ya sonó o no la alarma correspondiente.
+bool pico_y_placa = false; // Es verdadero si en el dia actual el carro tiene pico y placa, independientemente de la hora.
+bool correccion = false; // Se identificaron rangos de horas para los cuales la configuración del reloj salía mal. Puede ser un problema de la librería o del integrado. Esta variable ayuda a mostrar y configurar la hora correcta.
+int dia = 0, mes = 0, anno = 0, day = 1, hora = 0, min = 0; // Variables para almacenar las opciones de configuración del reloj.
+int cambio = 0, diferencia = 0; // Variables del encoder.
+int pos = 0;
 
 int main() {
     
-    // Se asigna baudrate y se configura el puerto serie de la USART
+    carro = 1;
+    alarma = 0;
     
+    Rtc_Ds1307::Time_rtc tm = {};
     GSM.baud(9600);   
     GSM.format(8,Serial::None,1);
     t.start();
     
-    for (int i = 3; i < 24; ++i) {
-        lcd.cls();
-        lcd.locate(0,0);
-        lcd.printf("**Control PID**");
-        wait_ms(1000/i);
+    lcd.cls();
+    lcd.locate(0,0);
+    lcd.printf("**Pico y placa**");
+    wait(1);
+    // Animación de bienvenida:
+    for (int i = 0; i < 16; ++i) {
+        lcd.writeCommand(C2);
+        wait(0.1);
+    }
+    lcd.cls();
+    
+menu:
+    // En este menu se escoge entre ingresar la placa o configurar el reloj.
+    wait(0.3);
+    lcd.cls();
+    lcd.writeCommand(C1);
+    lcd.locate(0,0);
+    lcd.printf("Menu");
+    lcd.locate(0,1);
+    lcd.printf("1.Placa 2.Config");
+    lcd.locate(0,1);
+    lcd.printf("1"); 
+    //
+    menu = true;
+    
+    while(true) {
+        if (!button3) {
+            menu = !menu;
+            if (menu) { 
+                lcd.locate(0,1);
+                lcd.printf("1");
+            }
+            else {
+                lcd.locate(8,1);
+                lcd.printf("2");
+            }
+            wait(0.5);
+        }
         
-        ++i;
-        lcd.cls();
-        lcd.locate(1,0);
-        lcd.printf("**Control PID**");
-        wait_ms(1000/i);
+        if (!button4) {
+            wait(0.5);
+            if (menu)  goto init;
+            if (!menu) goto config;
+        } 
+    }
+    
+config:
+    
+    pos = 5;
+    lcd.cls();
+    lcd.writeCommand(C1);
+    lcd.locate(0,1);
+    lcd.printf("DD/MM/YY   HH:MM");
+    lcd.locate(0,0);
+    lcd.printf("Config.      Dia");
+    
+    // Se usa el botón del encoder para pasar la variable configurada y el encoder para ajustar su valor.
+    // Usando el pulsador se guarda la configuración.
+    while (true) {
+        
+        diferencia=(encoder.getPulses() - cambio);
+        cambio=encoder.getPulses();
         
-        ++i;
-        lcd.cls();
-        lcd.locate(1,1);
-        lcd.printf("**Control PID**");
-        wait_ms(1000/i);
-        
-        ++i;
-        lcd.cls();
-        lcd.locate(0,1);
-        lcd.printf("**Control PID**");
-        wait_ms(1000/i);
+        if (diferencia != 0) {
+            
+            switch (pos) {
+                case 0:
+                    dia += diferencia;
+                    if (dia > 31) dia = 1;
+                    if (dia < 1) dia = 31;
+                    lcd.locate(0,1);
+                    lcd.printf("%02d", dia);
+                    break;
+                case 1:
+                    mes += diferencia;
+                    if (mes > 12) mes = 1;
+                    if (mes < 1) mes = 12;
+                    lcd.locate(3,1);
+                    lcd.printf("%02d", mes);
+                    break;
+                case 2:
+                    anno += diferencia;
+                    if (anno > 99) anno = 0;
+                    if (anno < 0) anno = 99;
+                    lcd.locate(6,1);
+                    lcd.printf("%02d", anno);
+                    break;
+                case 3:
+                    hora += diferencia;
+                    if (hora > 23) hora = 0;
+                    if (hora < 0) hora = 23;
+                    lcd.locate(11,1);
+                    lcd.printf("%02d", hora);
+                    break;
+                case 4:
+                    min += diferencia;
+                    if (min > 59) min = 0;
+                    if (min < 0) min = 59;
+                    lcd.locate(14,1);
+                    lcd.printf("%02d", min);
+                    break;
+                case 5:
+                    day += diferencia;
+                    if (day < 1) day = 7;
+                    if (day > 7) day = 1;
+                    lcd.locate(13, 0);
+                    lcd.printf("%s", dias[day]); 
+                    break;
+            }
+        }
+            
+        if (!button3) {
+            if (++pos > 5) pos = 0;
+            wait(0.3);
+        }
+        if (!button4) {
+            
+            if ((hora >= 18 && hora <= 23) || (hora >= 0 && hora <= 3) || (hora >= 8 && hora <= 13))
+                correccion = true;
+            else
+                correccion = false;
+                
+            wait(0.3);
+            lcd.cls();
+            lcd.printf("Guardado!");
+            menu = true;
+            tm.date = dia;
+            tm.mon = mes;
+            tm.year = 2000 + anno;
+            tm.hour = hora;
+            tm.min = min;
+            tm.sec = 0;
+            tm.wday = day;
+            rtc.setTime(tm, true, false);
+            wait(1);
+            lcd.cls();
+            goto menu;
+        }      
     }
 
 init:
     
+    // Se escribe la placa usando el encoder.
     lcd.cls();
     lcd.writeCommand(C1);
-      
-    lcd.locate(8,0);
-    lcd.printf("Ki=%d", kinum);
-    
+    lcd.locate(0,0);
+    lcd.printf("Ingrese placa:");
     lcd.locate(0,1);
-    lcd.printf("Kd=%d", kdnum);
-    
-    lcd.locate(8,1);
-    lcd.printf("**PID**");
-    
-    lcd.locate(0,0);
-    lcd.printf("Kp=%d", kpnum);
-    
-    bool state = 1;
+    lcd.printf("%c%c%c%1d%1d%1d", abc[p1], abc[p2], abc[p3], p4, p5, p6);
+    lcd.writeCommand(0xC0); // Cursor en (0,1)
+    pos = 0;
     
     while(true) {
 
-        diferencia=(encoder.getPulses() - cambio)*3;
+        diferencia=(encoder.getPulses() - cambio);
         cambio=encoder.getPulses();
         
-        if (diferencia != 0 && state) {
+        if (diferencia != 0) {
             switch (pos) {
+                case 0:
+                    lcd.locate(0,1);
+                    p1 += diferencia;
+                    if (p1 > 25) p1 = 0;
+                    if (p1 < 0) p1 = 25;
+                    lcd.printf("%c", abc[p1]);
+                    break;
                 case 1:
-                    kpnum += diferencia;
-                    
-                    if (kpnum >= 999)
-                        kpnum = 999;
-                    else if (kpnum < 0)
-                        kpnum = 0;
-                        
-                    lcd.locate(3,0);
-                    lcd.printf("    ");
-                    lcd.locate(3,0);
-                    lcd.printf("%d", kpnum);
+                    lcd.locate(1,1);
+                    p2 += diferencia;
+                    if (p2 > 25) p2 = 0;
+                    if (p2 < 0) p2 = 25;
+                    lcd.printf("%c", abc[p2]);
                     break;
                 case 2:
-                    kinum += diferencia;
-                    
-                    if (kinum >= 999)
-                        kinum = 999;
-                    else if (kinum < 0)
-                        kinum = 0;
-
-                    lcd.locate(11,0);
-                    lcd.printf("    ");
-                    lcd.locate(11,0);
-                    lcd.printf("%d", kinum);
+                    lcd.locate(2,1);
+                    p3 += diferencia;
+                    if (p3 > 25) p3 = 0;
+                    if (p3 < 0) p3 = 25;
+                    lcd.printf("%c", abc[p3]);
                     break;
                 case 3:
-                    kdnum += diferencia;
-                    
-                    if (kdnum >= 999)
-                        kdnum = 999;
-                    else if (kdnum < 0)
-                        kdnum = 0;
-
                     lcd.locate(3,1);
-                    lcd.printf("    ");
-                    lcd.locate(3,1);
-                    lcd.printf("%d", kdnum);
+                    p4 += diferencia;
+                    if (p4 > 9) p4 = 0;
+                    if (p4 < 0) p4 = 9;
+                    lcd.printf("%d", p4);
+                    break;
+                case 4:
+                    lcd.locate(4,1);
+                    p5 += diferencia;
+                    if (p5 > 9) p5 = 0;
+                    if (p5 < 0) p5 = 9;
+                    lcd.printf("%d", p5);
+                    break;
+                case 5:
+                    lcd.locate(5,1);
+                    p6 += diferencia;
+                    if (p6 > 9) p6 = 0;
+                    if (p6 < 0) p6 = 9;
+                    lcd.printf("%d", p6);
                     break;
             }
-        }
-        
-        if (diferencia != 0 && !state) {
-            
-            spnum += diferencia;
-              
-            if (spnum >= 999) spnum = 999;
-            else if (spnum < 0) spnum = 0;
-                
-            lcd.locate(10,0);
-            lcd.printf("   ");
-            lcd.locate(10,0);
-            lcd.printf("%d", spnum);
-        }
-            
+        }      
 
-        if (!button3) { // Cambia la posición de ingreso de parámetros
-            led3 = !led3;
-            switch(pos++) {
-                case 3:
-                    pos = 1;
-                    lcd.locate(3,0);
-                    lcd.printf("%d", kpnum);
-                    break;
-                case 1:
-                    lcd.locate(11,0);
-                    lcd.printf("%d", kinum);
-                    break;
-                case 2:
-                    lcd.locate(3,1);
-                    lcd.printf("%d", kdnum);
-                    break;
-            }
+        if (!button3) {
+            led2 = !led2;
+            pos++;
+            pos = pos % 6;
             wait(0.2);
         }
 
-        if (!button4 && state) {
+        if (!button4) {
             lcd.cls();
-            lcd.locate(8,1);
-            lcd.printf("**PID**");
             lcd.locate(0,0);
-            lcd.printf("Set-Point=");
-            lcd.locate(10,0);
-            lcd.printf("%d", spnum);
-            wait(0.2);
-            state = 0;
-        }
-        else if (!button4 && !state) {
-            wait(0.2);
+            lcd.printf("Guardado!");
+            wait(2);
             break;
         }
         wait(0.1);        
     }
     
-
- // Transición
-    lcd.writeCommand(C4); // Escribimos un comando segun el manual del módulo LCD para quitar cursor bajo
+reloj:
+    
+    // En esta sección se muestran la placa, el reloj y los avisos de alarma.
+    lcd.writeCommand(C4);
     lcd.cls();
-    lcd.locate(0,0); lcd.printf("y=");
-    lcd.locate(8,0); lcd.printf("e=");
-    lcd.locate(0,1); lcd.printf("r=");
-    lcd.locate(8,1); lcd.printf("u=");
+    lcd.locate(0,0); 
+    lcd.printf("%c%c%c%d%d%d", abc[p1], abc[p2], abc[p3], p4, p5, p6);
+    
+    while (true) {
+        
+        if (!button4) {
+            wait(0.3);
+            goto menu;
+        }
+        
+        lcd.locate(0,1);
+        
+        if (rtc.getTime(tm)) {
+            
+            if (((tm.hour >= 22 && tm.hour <= 27) || (tm.hour >= 4 && tm.hour <= 7) || (tm.hour >= 12 && tm.hour <= 15)) && correccion)
+                lcd.printf("%02d:%02d:%02d     %s", tm.hour-4, tm.min, tm.sec, dias[tm.wday]);
+            else
+                lcd.printf("%02d:%02d:%02d     %s", tm.hour, tm.min, tm.sec, dias[tm.wday]);
 
-loop:   
-
-    if (t.read_ms() - t_pid > 10) {
+            wait(1);
+        }
+        
+        // Se checkea si el automovil tiene pico y placa (Hora y dia): *********
         
-        med = y.read()*999;
-        err = spnum - med;      // Se calcula el error
-        ap = kpnum*err*0.01f;   // Se calcula la acción proporcional    
-        ai += kinum*err*0.01f;  // Cálculo de la integral del error
-        ad = kdnum*(err - err_v)*0.01f; // Cálculo de la acción derivativa
-        pid = ap + ai + ad;
-           
-        if (pid <= 0) pid = 0;
-        if (pid > 999) pid = 999;
+        if (tm.wday == 2 && p6 >= 2 && p6 <= 5) { // Lunes
+            pico_y_placa = true;
+            lcd.locate(9,0);
+            lcd.printf("Hoy P&P");
+        }
+        else if (tm.wday == 3 && p6 >= 6 && p6 <= 9) { // Martes
+            pico_y_placa = true;
+            lcd.locate(9,0);
+            lcd.printf("Hoy P&P");
+        }
+        else if (tm.wday == 4 && p6 >= 0 && p6 <= 3) { // Miercoles
+            pico_y_placa = true;
+            lcd.locate(9,0);
+            lcd.printf("Hoy P&P");
+        }
+        else if (tm.wday == 5 && p6 >= 4 && p6 <= 7) { // Jueves
+            pico_y_placa = true;
+            lcd.locate(9,0);
+            lcd.printf("Hoy P&P");
+        }
+        else if (tm.wday == 6 && (p6 == 8 || p6 == 9 || p6 == 0 || p6 == 1)) { // Viernes
+            pico_y_placa = true;
+            lcd.locate(9,0);
+            lcd.printf("Hoy P&P");
+        }
+        else {
+            pico_y_placa = false;
+            lcd.locate(9,0);
+            lcd.printf("       ");
+        }
         
-        setpoint = spnum;
-        GSM.printf("#%3.0f%3.0f&", med, setpoint);
+        int hora_c;
         
-        lcd.locate(3,0);  lcd.printf("%3.0f ", med);
-        lcd.locate(3,1);  lcd.printf("%3d ", spnum);
-        lcd.locate(11,0); lcd.printf("%3.0f ", err);
-        lcd.locate(11,1); lcd.printf("%3.0f ", pid);
+        if (((tm.hour >= 22 && tm.hour <= 27) || (tm.hour >= 4 && tm.hour <= 7) || (tm.hour >= 12 && tm.hour <= 16)) && correccion)
+            hora_c = 100*(tm.hour-4) + tm.min;
+        else
+            hora_c = 100*tm.hour + tm.min;
 
-        err_v = err;
-        o = pid/999;
-        u.write(o);
-        
-        t_pid = t.read_ms();
-    }
-    else {
-        
-        diferencia=(encoder.getPulses() - cambio)*6;
-        cambio=encoder.getPulses();
-        
-        if (diferencia != 0) {
-            spnum += diferencia;
-            if (spnum >= 999) spnum = 999;
-            else if (spnum < 0) spnum = 0;
+        if ((hora_c >= 700 && hora_c < 830) || (hora_c >= 1730 && hora_c < 1900))
+            min0 = true;
+        else
+            min0 = false;
+            
+        if ((hora_c >= 615 && hora_c < 700) || (hora_c >= 1645 && hora_c < 1730))
+            min45 = true;
+        else
+            min45 = false;
+            
+        if ((hora_c >= 630 && hora_c < 700) || (hora_c >= 1700 && hora_c < 1730))
+            min30 = true;
+        else
+            min30 = false;
+            
+        if ((hora_c >= 645 && hora_c < 700) || (hora_c >= 1715 && hora_c < 1730))
+            min15 = true;
+        else
+            min15 = false;
+            
+        if((hora_c == 830 || hora_c == 1900) && tm.sec < 10) {
+            alarma0 = false; alarma15 = false;
+            alarma30 = false; alarma45 = false;
         }
-            
+        
+         
+        // Se disparan las alarmas: ********************************************
+        
+        if (pico_y_placa && min45 && !alarma45) {
+            alarma45 = true;
+            lcd.cls();
+            lcd.printf(" *** Faltan *** \n *** 45 min ***");
+            for (int a = 0; a < 10; ++a) {
+                alarma = !alarma;
+                wait(1);
+            }
+            goto reloj;
+        }
+        if (pico_y_placa && min30 && !alarma30) {
+            alarma30 = true;
+            lcd.cls();
+            lcd.printf(" *** Faltan *** \n *** 30 min ***");
+            for (int a = 0; a < 20; ++a) {
+                alarma = !alarma;
+                wait(0.5);
+            }
+            goto reloj;
+        }
+        if (pico_y_placa && min15 && !alarma15) {
+            alarma15 = true;
+            lcd.cls();
+            lcd.printf(" *** Faltan *** \n *** 15 min ***");
+            for (int a = 0; a < 40; ++a) {
+                alarma = !alarma;
+                wait(0.25);
+            }
+            goto reloj;
+        }
+        if (pico_y_placa && min0 && !alarma0) {
+            alarma0 = true;
+            lcd.cls();
+            lcd.printf(" *** Pico y *** \n ***  placa *** ");
+            alarma = 1;
+            carro = 0;
+            goto reloj;
+        }
+        if (!pico_y_placa) {
+            alarma = 0;
+            carro = 1;
+        }
     }
-    
-    if (!button4) {
-        u.write(0);
-        med = 0;
-        err = 0;
-        pid = 0;
-        
-        goto init;
-    }
-    else
-        goto loop;
-        
 }
\ No newline at end of file