Alarma de pico y placa usando módulo RTC.
Dependencies: QEI TextLCD mbed
Fork of grafica_PID_android by
Diff: main.cpp
- 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