APS SO

Dependencies:   WebSocketClient mbed

Fork of APS_SO by Ian Bolfarini

Files at this revision

API Documentation at this revision

Comitter:
ianwillianb
Date:
Fri Dec 15 20:07:49 2017 +0000
Parent:
1:3da12598c635
Commit message:
finalizado;

Changed in this revision

WebSocketClient.lib Show annotated file Show diff for this revision Revisions of this file
main.cpp Show annotated file Show diff for this revision Revisions of this file
mbed-os.lib Show annotated file Show diff for this revision Revisions of this file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/WebSocketClient.lib	Fri Dec 15 20:07:49 2017 +0000
@@ -0,0 +1,1 @@
+https://developer.mbed.org/teams/mbed_example/code/WebSocketClient/#efa2c147bee1
--- 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", &eth);
+        //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);
+        
+  
+   
+         
+         
+
+}
+ 
+
+
+
+ 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mbed-os.lib	Fri Dec 15 20:07:49 2017 +0000
@@ -0,0 +1,1 @@
+https://github.com/ARMmbed/mbed-os/#c9e63f14085f5751ff5ead79a7c0382d50a813a2