Ian Bolfarini
/
APS_SO
APS_SO
Diff: main.cpp
- Revision:
- 2:27a7a42b2bae
- Parent:
- 1:3da12598c635
diff -r 3da12598c635 -r 27a7a42b2bae main.cpp --- a/main.cpp Sat Oct 28 22:45:10 2017 +0000 +++ b/main.cpp Fri Dec 15 20:07:49 2017 +0000 @@ -1,27 +1,49 @@ #include "mbed.h" +#include "rtos.h" #include "Rtc_Ds1307.h" +#include "EthernetInterface.h" +#include "Websocket.h" +#include <iostream> +#include <string> -//Inicialização do Led RGB -DigitalOut led(LED_BLUE); +//Objeto da ethernet +EthernetInterface eth; //Inicialização do RTC Rtc_Ds1307 rtc(D14,D15); //Estrutura responsável por armazenar os dados do RTC Rtc_Ds1307::Time_rtc alarm_time ; +//Estrutura responsável por armazenar a data/hora de ativação do alarme +Rtc_Ds1307::Time_rtc a_time_start ; +Rtc_Ds1307::Time_rtc a_time_end ; +int range = 3; // uma flag mantida em "1" caso o tempo atual lido do rtc esteja dentro do intervalo de funcionamento do alarme e, caso contrário, setada para "0". //Estabelece comunicação serial para DEBUG Serial gSerial(USBTX, USBRX); - - //Ajuste da hora atraves da interface serial +//variavel de estado do alarme: 0 - desarmado devido ao horario, 1 - armado, 2 - disparando, 3- desarmado pelo usuario +int state = 0; //incia em zero desarmado, é ajustado na thread de controle caso o horario esteja no range de alarme ativado +DigitalIn enable(D8); //a variável enable lê o sinal do sensor de presença, que está conectado na entrada D8. Variável enable será true ou false conforme haja sinal ou não do sensor. +DigitalOut led_red(LED_RED); //led vermelho +DigitalOut led_green(LED_GREEN); //led verde +DigitalOut led_blue(LED_BLUE); //led azul +DigitalOut buzzer(D9); //buzzer + + +//Declaracao das Threads +Thread *RtcRead; //le o RTC e atualiza a estrutura +Thread *SetRange; //Verifica se está dentro do range - entre tempo de inicio e tempo de fim +Thread *LedThread; //controla leds de status e buzzer +Thread *SetState; //verifica e ajusta os estados - armado, desarmado, disparando, desarmado forçado +Thread *PrintRange; //imprime valores de estado e range e hora atual - para debug +Thread *SocketThread; //thread das sockets + +//Ajuste da hora atraves da interface serial, so para ajuste do relogio void set_time_serial() { - int hora, min, seg, dia, mes, ano, opt; + int hora, min, seg, dia, mes, ano, opt, d_sem; gSerial.printf("\n1-Ajuste de Hora, 2-Ajuste de Data, 3-Ajuste de Data/Hora: "); gSerial.scanf("%d",&opt); - /* if(opt >=1 && opt <=3){ - - - } */ + if(opt == 1 || opt ==3 ) { @@ -35,9 +57,6 @@ alarm_time.hour = hora; alarm_time.min = min; alarm_time.sec = seg; - //alarm_time.date = 28; - //alarm_time.mon = 10; - //alarm_time.year = 2017; rtc.setTime(alarm_time, true, false); rtc.getTime(alarm_time); gSerial.printf("\nHora Ajustada: %2d:%02d:%02d \n",alarm_time.hour,alarm_time.min,alarm_time.sec); @@ -54,13 +73,14 @@ if(opt==2 || opt ==3) { - gSerial.printf("Insira a data(DIA MES ANO): "); - gSerial.scanf("%d %d %d", &dia, &mes, &ano); - if((dia < 32 && dia >0 && mes<13 && mes>0 && ano>2000) && !(mes == 2 && dia >=29 ) && !((mes == 4 || mes == 6 || mes == 9 || mes == 11) && dia >30)) + gSerial.printf("Insira a data(DIA MES ANO DIA-SEMANA(1-7)): "); + gSerial.scanf("%d %d %d %d", &dia, &mes, &ano, &d_sem); + if((dia < 32 && dia >0 && mes<13 && mes>0 && ano>2000) && !(mes == 2 && dia >=29 ) && !((mes == 4 || mes == 6 || mes == 9 || mes == 11) && dia >30) && (d_sem>0 &&d_sem<8)) { rtc.getTime(alarm_time); + alarm_time.wday = d_sem; alarm_time.date = dia; alarm_time.mon = mes; alarm_time.year = ano; @@ -75,57 +95,436 @@ } - else gSerial.printf("Opcao Invalida!.\n"); + else gSerial.printf("Opcao Invalida!.\n"); + + } + + void set_range () { + + while(1) { + /* pode-se ter 3 situações: + // a hora de início da ativação do alarme é numericamente menor que a hora do encerramento + // a hora de início da ativação é igual à hora de fim + // a hora de início da ativação é numericamente maior que a hora de fim + */ + if (a_time_start.hour < a_time_end.hour) { // Neste caso, o range está contido todo dentro de um dia (entre 0:00 e 23:59) mas as horas de início e fim do alarme são diferentes. + if (a_time_start.hour < alarm_time.hour && alarm_time.hour < a_time_end.hour) {// Neste caso o valor do RTC está entre o horário de ligada e o de desligada + printf("muda range = 1\n"); + range = 1; + } + else if (a_time_start.hour == alarm_time.hour) { // Neste caso a hora do RTC é igual à de um dos extremos (início do range) + if (a_time_start.min <= alarm_time.min) + range = 1; + else range = 0; + } + else if (a_time_end.hour == alarm_time.hour) { // Neste caso a hora do RTC é igual à do último extremo (fim do range) + if (a_time_end.min >= alarm_time.min) + range = 1; + else range = 0; + } + else range = 0; + } + + else if (a_time_start.hour == a_time_end.hour) { // Neste caso a hora de ativamento e de desarme do alarme é a mesma. Mas o caso específico será destrinchado nos "ifs" aninhados + if (a_time_start.min < a_time_end.min) { + if (alarm_time.hour == a_time_start.hour) { + if (a_time_start.min <= alarm_time.min && alarm_time.min <= a_time_end.min) + range = 1; + else range = 0; + } + else range = 0; + } + else if (a_time_start.min > a_time_end.min) { + if (alarm_time.hour == a_time_end.hour) { + if (a_time_start.min > alarm_time.min && alarm_time.min > a_time_end.min) + range = 0; + else range = 1; + } + else range = 1; + } + else if(a_time_start.min == a_time_end.min) range = 0; + } + + else if (a_time_start.hour > a_time_end.hour) { // Neste caso, o range está contido em um período que compreende dois dias - alarme permanece ativado na transição de 23:59 para 0:00. As horas de início e fim do alarme são diferentes. + if (a_time_start.hour > alarm_time.hour && alarm_time.hour > a_time_end.hour) + range = 0; + else if (a_time_end.hour == alarm_time.hour) { + if (a_time_end.min < alarm_time.min) + range = 0; + else range = 1; + } + else if (a_time_start.hour == alarm_time.hour) { + if (a_time_start.min > alarm_time.min) + range = 0; + else range = 1; + } + else range = 1; + } + + } + +} + void set_state () { + + while (1) { + + if (state != 3) { //se estado é 3 o alarme foi desabilitado pelo usuario, logo não são necessarios teste + if (range == 0 && state == 1) state = 0; //se nao esta no range e estado =1(armado), desarma automatico + if (range == 1 && state == 0) state = 1; //se esta no range mas estado = 0 (desarmado), arma automatico + if (range == 1 && state == 1) { //estado armado e no range + if (enable) state = 2; //se o sensor pir mandar um sinal em alto, manda para o estado 2 (armado) + } + } + + + + + } + + } + + //thread resposavel por verificar a hora + void rtc_read (){ + + while(1){ + rtc.getTime(alarm_time); + } + + + } + +void led_thread() +{ + //apaga todos os leds antes de acender os leds desejados + led_blue=1; + led_green=1; + led_blue =1; + + + while(true){ + +if(state == 0 || state==3) { //neste caso o alarme não está ativo - estado desarmado ou desarmado forçado + + + led_green = 1; + led_blue = 1; + led_red =0; + + + } + + + if(state == 1) //se estiver armado só liga o led verde + + { + + led_green = 0; + led_blue = 1; + led_red =1; + + + + } + + + if(state == 2) //estado disparado: acionamento dos leds vermelho e azul alternado em 0.5s, buzzer é ativo junto com os leds na mesma frequência + + { //desliga todos os leds para assegurar que somente os desejados estarão ligados neste estado + led_red=1; + led_blue=1; + led_green =1; + + led_red =0; //liga o led vermelho + buzzer = 0; //liga o buzzer, ativo em 0 devido ao transistor PNP + wait(0.5); //aguarda meio segundo + led_red = 1; //desliga o led vermelho + led_blue = 0; //liga o led azul + buzzer = 1; //desliga o buzzer + wait(0.5); //aguarda 0.5s + led_blue=1; //desliga o led azul + + + + } + + } + + +} + +//thread para estabelecer comunicação via sockets +void socket_thread(){ + + //inicia um comunicação via socket com o seguinte servidor + Websocket ws("ws://192.168.2.2:8555/ws", ð); + //conecta + int connect_error = ws.connect(); + //wait para o sensor exibir mensagem de comunicação + wait(1); + + + +//buffer de entrada, guarda dados do servidor +char buf_in[20]; +//ponteiro usado na função strtok_r +char *token; +//char para o codigo para indicar que o servidor deve exibir o menu +char menu_return[2]; + + + + + //loop da thread + while(true){ + + + + //se receber dados via socket + if (ws.read(buf_in)) { + //cria uma cópia do buffer para ser "thread safe" + char *rest = buf_in; + //corta a string entre espaços + token = strtok_r(rest, " ", &rest); + //converte o primeiro dado para int. opt indica qual operação sera realiza, é sempre o primeiro dado da string recebida + int opt = atoi(token); + //se for 1, realiza a modificação do horario de inicio e fim de operação do alarme + if(opt ==1){ + //divide a string e converte os dados para int + token = strtok_r(rest, " ", &rest); + int start_hour = atoi(token); + token = strtok_r(rest, " ", &rest); + int start_min = atoi(token); + token = strtok_r(rest, " ", &rest); + int start_sec = atoi(token); + token = strtok_r(rest, " ", &rest); + int end_hour = atoi(token); + token = strtok_r(rest, " ", &rest); + int end_min = atoi(token); + token = strtok_r(rest, " ", &rest); + int end_sec = atoi(token); + //faz atribuições + a_time_start.hour = start_hour; + a_time_start.min = start_min; + a_time_start.sec = start_sec; + a_time_end.hour = end_hour; + a_time_end.min = end_min; + a_time_end.sec = end_sec; + + + sprintf (menu_return, "99"); //codigo de retorno ao menu para a aplicação no pc + ws.send(menu_return); //envia código indicando que a operação foi finalizada e aplicação deve retornar ao menu + + + + } - - } - -void ajus_data_hora() - -{ - - char hadj; - gSerial.printf("Deseja ajustar a hora? - Caso sim digite s: "); - gSerial.scanf("%c",&hadj); - if(hadj=='s') - { - set_time_serial(); - - } - -} - + //opção 2 usuario habilita ou desabilita o alarme mesmo que esteja dentro do range de tempo de funcionamento + if(opt == 2) + { + char en_dis[25]; + //se o estado for diferente de 3 (desarmado pelo usuario), seta em 3 + if(state!=3){ + + printf("opt: %d\n",opt); + state =3; + + printf("state: %d\n",state); + //envia feedback para a aplicação + sprintf (en_dis, "Sistema Desabilitado"); + ws.send(en_dis); + + } + //caso for 3 habilita o alarme + else if(state==3){ + + printf("opt: %d\n",opt); + state =0; + + //envia feedback para a aplicação + sprintf (en_dis, "Sistema Habilitado"); + ws.send(en_dis); -int main() -{ + + } + wait(1); + sprintf (menu_return, "99"); //codigo de retorno ao menu + ws.send(menu_return); + } + + // envia para a aplicação feedback de seu status + if(opt == 3) + { char state_text[60]; + + if(state == 0){ + sprintf (state_text, "Alarme Desabilitado - Fora do Periodo de Funcionamento"); + ws.send(state_text); + } + if(state == 1){ + sprintf (state_text, "Alarme Habilitado"); + ws.send(state_text); + } + if(state == 2){ + sprintf (state_text, "Alarme Disparado!!!"); + ws.send(state_text); + } + if(state == 3){ + sprintf (state_text, "Alarme Desabilitido pelo Usuario"); + ws.send(state_text); + } + wait(1); + sprintf (menu_return, "99"); //codigo de retorno ao menu + ws.send(menu_return); + + } //fim do opt==3 + + + + //informa para a aplicação, que deve voltar ao menu principal + if(opt == 8 || opt == 6) + + { + char back_to_menu1[2]; + sprintf(back_to_menu1,"99"); + ws.send(back_to_menu1); + + + } + - char hadj; //opcao do ajuste do rtc - gSerial.printf("Deseja ajustar a hora? - Caso sim digite s: "); - gSerial.scanf("%c",&hadj); - if(hadj=='s') //caso seja digitado s exibe as opcoes de ajuste - { - set_time_serial(); + } + + //caso dispare + if(state==2){ + //buffer de entrada + char state_2[1]; + //para sair do loop + int input =1; + //manda código para a apicação informando que o alarme disparou + char disp[2]; + //int resposavel por armazenar a resposta da aplicação + int state_20; + sprintf(disp,"88"); //codigo 88 alarme disparado + ws.send(disp); + //loop para receber a resposta + while(input){ + //se receber dados da aplicação + if(ws.read(state_2)){ + + + //converte para int o dado recebido + state_20 = atoi(state_2); + + + + } + + //se for 9 (indica que o usuario desabilitou o alarme) + if(state_20 == 9) { + + + //alarme desabilitado, volta para 0, deixa para a thread set_state decidir o proximo estado + state = 0; + //condicao para sair do loop + input = 0; + + + } + + + + }//fim do while do state 2 + + + + }//fim do if state=2 + + + + + }//fim do while + + + + + + } - - while (true) { +//thread explicitamente usada para debug, nao realiza trabalho útil. É dispensável para o funcionamento do sistema +void print_range(){ + +while(true){ + +//hora do rtc +gSerial.printf("Hora: %2d:%02d:%02d \n",alarm_time.hour,alarm_time.min,alarm_time.sec); +//valor do range +gSerial.printf("Valor Range: %d\n", range); +//valor de hora de inicio e fim da ativação ajustado via aplicação +gSerial.printf("para a estrutura: start_hour: %d start_min: %d start_sec: %d end_hour: %d end_min: %d end_sec: %d \n",a_time_start.hour,a_time_start.min,a_time_start.sec,a_time_end.hour,a_time_end.min,a_time_end.sec); + +wait(1); + + + +} + + +} + + - rtc.getTime(alarm_time); - led = !led; - gSerial.printf("\r"); - gSerial.printf("Hora: %2d:%02d:%02d \n",alarm_time.hour,alarm_time.min,alarm_time.sec); - wait(1); - } - - - - - -} \ No newline at end of file + + int main() + { + buzzer = 1; //desativa o buzzer. Como usamos um transistor pnp para chavear o buzzer, a lógica é inversa. O buzzer deve ser desativado pois a saida default da porta é 0 + enable.mode(PullDown); //coloca na entrada um resistor de pull-down para ler 0, a não ser que exista uma entrada em 1 vindo do sensor PIR + + int x = eth.set_dhcp(true); //ativa dhcp + int i=eth.connect(); //conecta + //verifica conexão para debug apenas + gSerial.printf("DHCP status: %i \r\n",x); + gSerial.printf("connect status: %i \r\n",i); + gSerial.printf("IP Address is %s\n\r", eth.get_ip_address()); + + + + + + //Iniciando o alarme com valor default inicial + a_time_start.hour = 0; + a_time_start.min = 10; + + //Iniciando o alarme com valor default final + a_time_end.hour = 6; + a_time_end.min = 50; + + + + wait(2); //aguarda 2s para o sensor PIR gerar uma saida consistente + + //Inicialização das Threads + SetRange = new Thread(set_range); + RtcRead = new Thread(rtc_read); + PrintRange = new Thread(print_range); + SetState = new Thread(set_state); + LedThread = new Thread(led_thread); + SocketThread = new Thread(socket_thread); + + + + + + +} + + + + +