En este programa se presenta un localizador satelital, el cual requiere para su funcionamiento un celular Siemens A56, el cual funciona como módem GSM,un GPS (en este caso se tiene una simulación en el software Proteus) y un pulsador sencillo.

Dependencies:   mbed DebouncedIn GPS_G

Files at this revision

API Documentation at this revision

Comitter:
AndresTovar96
Date:
Wed Apr 10 22:21:24 2019 +0000
Commit message:
Localizador satelital con boton de panico

Changed in this revision

DebouncedIn.lib Show annotated file Show diff for this revision Revisions of this file
GPS_G.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.bld Show annotated file Show diff for this revision Revisions of this file
diff -r 000000000000 -r f115f80141ca DebouncedIn.lib
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/DebouncedIn.lib	Wed Apr 10 22:21:24 2019 +0000
@@ -0,0 +1,1 @@
+https://os.mbed.com/users/cmorab/code/DebouncedIn/#dc1131de43e8
diff -r 000000000000 -r f115f80141ca GPS_G.lib
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/GPS_G.lib	Wed Apr 10 22:21:24 2019 +0000
@@ -0,0 +1,1 @@
+https://os.mbed.com/users/joshema216/code/GPS_G/#7f621626d7e9
diff -r 000000000000 -r f115f80141ca main.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp	Wed Apr 10 22:21:24 2019 +0000
@@ -0,0 +1,419 @@
+/*
+Esta tarea se realizó con base en los programas del repositorio del profesor Gustavo Ramírez (tony63)
+Algunos de los programas utilizados fueron:
+- ALARMA_FINCA_GSM7
+- GoogleMapa
+- gsmrecibe1 
+- pdu2
+
+Para la implementación del programa, se requiere un celular Siemens A56 (el cual
+debe tener una SIM con saldo disponible para el envío de mensajes) y un GPS virtual
+cuya simulación se realiza mediante el software Proteus.
+Con este programa, el usuario podrá conocer la ubicación del dispositivo (la cual
+será proporcionada por el GPS virtual) realizando el envío de un mensaje de texto
+a dicho dispositivo. La ubicación llegará al usuario en un mensaje de texto con
+un enlace que lo dirigirá a la página de Google Maps, con el mapa centrado en la
+ubicación del dispositivo.
+Además de esto, el programa permite la implementación de un botón de pánico, cuyo
+funcionamiento es sencillo por medio de un pulsador. Cuando este se acciona, se
+envía un mensaje de texto a un número previamente definido con la palabra SOS.
+*/
+//Declaración de librerías a usar en el programa
+#include "mbed.h"
+#include "DebouncedIn.h"
+#include "stdio.h"
+#include "string.h"
+#include "GPS.h"
+
+DigitalIn sw(PTD6,PullUp); // Se declara un pulsador sw como entrada digital, además se incluye la resistencia PullUp para evitar un cortocircuito en el accionamiento
+
+//Indicadores de estado
+Timer t;
+DigitalOut LedVerde(LED2);
+DigitalOut LedRojo(LED1);
+DigitalOut LedAzul(LED3);
+ 
+//Declaración de puertos
+Serial GSM(PTE0,PTE1);  // Módem GSM
+Serial pc(USBTX,USBRX); // Terminal en el PC
+GPS gps(PTE22, PTE23);   // GPS (Virtual corriendo en Proteus)
+ 
+// Declaración de variables
+// Cadenas
+char DE[255];
+char DS[255];
+char buffer[512]; //
+char resp[6];
+char tam[2];
+char mensaje[100];
+ 
+//Variables y caracteres
+int count;
+int i, K, LENIN, LENOUT, C;
+int c=0;
+char r[]=""; 
+char msg[256];
+int ind;
+int ret = 1;
+ 
+// Esta cadena almacenará el número desde el cual fue enviado el mensaje
+char tel[15];
+ 
+// Coordenadas del GPS virtual
+float lo,la;
+char clo[255], cla[255];
+char la_lo[255];
+ 
+// Formato enlace Google Maps
+char http2[255];
+char http[] = "http://maps.google.com/maps?q=";
+char buf[100];
+ 
+// Secciones de relleno en la cadena del mensaje
+char relleno1[] = "0011000A91";
+char relleno2[] = "0000AA";
+ 
+// Funciones
+void callback(){
+    // Note: you need to actually read from the serial to clear the RX interrupt
+    pc.printf("%c\n", GSM.getc()); 
+}
+ 
+// Esta funcion de abajo lee todo un bufer hasta encontrar CR o LF y el resto lo rellena de
+// $, count es lo que va a leer. Lo leido lo mete en buffer que es una cadena previamente definida
+// incorpora medida de tiempo si se demora mas de tres segundos retorna fracaso con -1
+int readBuffer(char *buffer,int count){
+    int i=0; 
+    t.start();  // start timer
+    while(1) {
+        while (GSM.readable()) {
+            char c = GSM.getc();
+            if (c == '\r' || c == '\n') c = '$';
+            buffer[i++] = c;
+            if(i > count)break;
+        }
+        if(i > count)break;
+        if(t.read() > 3) {
+            t.stop();
+            t.reset();
+            break;
+        }
+    }
+    wait(0.5);
+    while(GSM.readable()){  // display the other thing..
+        char c = GSM.getc();
+    }
+    return 0;
+}
+ 
+// Esta función de abajo limpia o borra todo un "buffer" de tamaño "count",
+// lo revisa elemento por elemento y le mete el caracter null que indica fin de cadena.
+// No retorna nada.
+void cleanBuffer(char *buffer, int count){
+    for(int i=0; i < count; i++) {
+        buffer[i] = '\0';
+    }
+}
+ 
+// Esta función de abajo envia un comando parametrizado como cadena
+// puede ser un comando tipo AT.
+void sendCmd(char *cmd){
+    GSM.puts(cmd);
+}
+ 
+// Esta función de abajo espera la respuesta de un comando que debe ser idéntica a la cadena "resp" y un tiempo "timeout",
+// si todo sale bien retorna un cero que en la programacion hay que validar,
+// si algo sale mal (no se parece o se demora mucho) retorna -1 que debera validarse con alguna expresion logica.
+int waitForResp(char *resp, int timeout){
+    int len = strlen(resp);
+    int sum=0;
+    t.start();
+ 
+    while(1) {
+        if(GSM.readable()) {
+            char c = GSM.getc();
+            sum = (c==resp[sum]) ? sum+1 : 0;// esta linea de C# sum se incrementa o se hace cero segun c
+            if(sum == len)break;  //ya acabo se sale
+        }
+        if(t.read() > timeout) {  // time out chequea el tiempo minimo antes de salir perdiendo
+            t.stop();
+            t.reset();
+            return -1;
+        }
+    }
+    t.stop();                 // stop timer  antes de retornar
+    t.reset();                    // clear timer
+    while(GSM.readable()) {      // display the other thing..
+        char c = GSM.getc();
+    }
+    return 0;
+}
+ 
+// Esta función es muy completa y útil, se encarga de enviar el comando y esperar la respuesta.
+// Si todo sale bien retorna un cero
+int sendCmdAndWaitForResp(char *cmd, char *resp, int timeout){
+    sendCmd(cmd);
+    return waitForResp(resp,timeout);
+}
+ 
+// Esta función verifica si el módem GSM está activo o conectado
+int powerCheck(void){ 
+    return sendCmdAndWaitForResp("AT\r\n", "OK", 2);    
+}
+ 
+// Esta función revisa el estado de la tarjeta SIM
+int checkSIMStatus(void){
+    char gprsBuffer[30];
+    int count = 0;
+    cleanBuffer(gprsBuffer, 30);
+    while(count < 3){
+        sendCmd("AT+CPIN?\r\n");
+        readBuffer(gprsBuffer,30);
+        if((NULL != strstr(gprsBuffer,"+CPIN: READY"))){
+            break;
+        }
+        count++;
+        wait(1);
+    }
+ 
+    if(count == 3){
+        return -1;
+    }
+    return 0;
+}
+ 
+// Esta función verifica la calidad de la señal
+int checkSignalStrength(void){
+    char gprsBuffer[100];
+    int index, count = 0;
+    cleanBuffer(gprsBuffer,100);
+    while(count < 3){
+        sendCmd("AT+CSQ\r\n");
+        readBuffer(gprsBuffer,25);
+        if(sscanf(gprsBuffer, "AT+CSQ$$$$+CSQ: %d", &index)>0) {
+            break;
+        }
+        count++;
+        wait(1);
+    }
+    if(count == 3){
+        return -1;
+    }
+    return index;
+}
+ 
+// Esta funcion permite configurar el módem para la recepción/envío de mensajes
+// Si alguno de estos códigos tarda más de 3 segundos en ejecutarse, arrojará un error
+int init(){
+    if (0 != sendCmdAndWaitForResp("AT\r\n", "OK", 3)){ //Verifica que haya conexión con el módem GSM
+        return -1;
+    }
+    if (0 != sendCmdAndWaitForResp("AT+CNMI=1,1\r\n", "OK", 3)){ //Establece que los mensajes sean enviados a la SIM
+        return -1;
+    }
+    if (0 != sendCmdAndWaitForResp("AT+CMGF=0\r\n", "OK", 3)){ //Da formato a los mensajes como PDU, no como texto
+        return -1;
+    }
+    if (0 != sendCmdAndWaitForResp("AT+CBST=7,0,1\r\n", "OK", 3)){ //Velocidad de transmisión: 9600
+        return -1;
+    }
+    if (0 != sendCmdAndWaitForResp("ATE\r\n", "OK", 3)){ //Asociado al eco en el módem GSM
+        return -1;
+    }
+    LedVerde=0; //Indicador de configuración correcta
+    return 0;
+}
+  
+// Esta función se encarga de leer un mensaje, el cual tiene una ubicación en la memoria determinada por el índice index
+int readSMSpdu(char *message, int index){
+    int i = 0;
+    char gprsBuffer[100];
+    char *p,*s;
+    GSM.printf("AT+CMGR=%d\r\n",index); 
+    cleanBuffer(gprsBuffer,100);
+    readBuffer(gprsBuffer,100);
+    if(NULL == ( s = strstr(gprsBuffer,"+CMGR"))) {
+        return -1;
+    }
+    if(NULL != ( s = strstr(gprsBuffer,"+32"))) {
+        p = s + 6;
+        while((*p != '$')&&(i < 5)) {
+            message[i++] = *(p++);
+        }
+        message[i] = '\0';
+    }
+    return 0;
+}
+ 
+// Esta función elimina los mensajes del módem GSM
+int deleteSMS(int index){
+    char cmd[32];
+    snprintf(cmd,sizeof(cmd),"AT+CMGD=%d\r\n",index);
+    sendCmd(cmd);
+    return 0;
+}
+ 
+// Configuración de la comunicación de los puertos
+int main(){
+    GSM.baud(9600);//Velocidad de transmisión
+    GSM.format(8,Serial::None,1);   
+    LedVerde = 1; //Apaga LED verde
+    LedRojo = 1; //Apaga LED rojo
+    LedAzul = 1; //Apaga LED azul
+    LedRojo = 0; // Enciende LED rojo
+    
+    // Configuración del módem GSM
+    inicio1:        
+        ret = init();
+        if(ret==0){
+            LedRojo = 1;
+            LedVerde = 0; //Se enciende LED verde
+            pc.printf("La configuracion del modem es correcta\n");
+        }
+        else{
+            wait(1);
+            goto inicio1;    
+        }
+        
+    while(1){ 
+        if (GSM.readable()){
+            readBuffer(buffer,110); //Lee el búfer
+            for(i=0; i<5; i++){
+                resp[i] = buffer[i]; //Almacena la lectura del búfer en resp
+            }  
+             
+            if(strcmp("$$+CM", resp) == 0){  //Verifica la llegada de nuevos mensajes comparando la lectura del búfer con el comando AT
+                pc.printf("\nMensaje recibido\r\n"); //Se muestra el aviso de mensaje nuevo
+                cleanBuffer(buffer,10); //Limpia el búfer
+                GSM.printf("AT+CMGL=0\r\n"); //Este comando realiza la extracción del mensaje desde el módem GSM
+                readBuffer(buffer,110); //Lee el búfer nuevamente
+                
+                // Esta sección del programa reorganiza los números del teléfono desde el cual se envía el mensaje y muestra dicho número
+                for(i=0; i<10; i++){
+                    tel[i] = buffer[i+40];
+                }
+                pc.printf("\nNumero desde el cual se envio el mensaje: %c%c%c%c%c%c%c%c%c%c\r\n", tel[1], tel[0], tel[3], tel[2], tel[5], tel[4], tel[7], tel[6], tel[9], tel[8]);  
+                
+                // En esta sección se lee el tamaño del mensaje
+                for(i=0;i<2;i++){
+                    tam[i] = buffer[i+68]; //Lee el tamaño del mensaje a partir de la posición 68 del búfer
+                }      
+                
+                // En esta sección se lee el mensaje
+                for(i=0;i<26;i++){
+                   msg[i] = buffer[i+70]; // Lee un mensaje de máximo 26 caracteres a partir la posición 70 del búfer
+                }
+                
+                deleteSMS(1); //Elimina los mensajes que estén almacenados en el índice especificado de la memoria, en este caso 1
+                readBuffer(buffer, 200); //Se lee el búfer nuevamente
+                /* 
+                En esta sección del programa se compara el mensaje que llegó al
+                teléfono con el mensaje deseado, el cual es "Donde estas?"
+                El código para el mensaje deseado es "C4B79B5C0695E7F4F0FC07"
+                */ 
+                if(strncmp("C4B79B5C0695E7F4F0FC07", msg, 22) == 0){
+                    
+                    LedVerde = 1; 
+                    LedAzul = 0; //Enciende el LED azul, indicando que el mensaje esperado es igual al mensaje recibido
+                    LedRojo = 1;
+                    wait(3);
+                    // Como el mensaje esperado es igual al recibido, se realiza la lectura de las coordenadas del GPS para enviarlas
+                    if(gps.sample()){ //
+                        la = gps.latitude; //Coordenada de latitud
+                        lo = gps.longitude; //Coordenada de longitud
+                            
+                        // Latitud
+                        sprintf (cla, "%f", la); 
+                        pc.printf ( "\nLatitud = %s\n",cla); //Se muestra la latitud obtenida en el GPS
+                        
+                        //Longitud
+                        sprintf (clo, "%f", lo); 
+                        pc.printf ("\nLongitud = %s\n",clo); //Se muestra la longitud obtenida en el GPS
+                    
+                        
+                        // Se concatenan las coordenadas
+                        strcpy(la_lo,cla);
+                        strcat(la_lo,",");
+                        strcat(la_lo,clo);
+                        
+                        //Ajuste de la cadena al formato del enlace de Google Maps
+                        strcpy(DE,http);
+                        strcat(DE,la_lo);         
+                        pc.printf("\nUbicacion en Google Maps: %s\n",DE);
+                        pc.printf("\n");
+                        LENIN = strlen(DE);
+                        
+                        //En esta sección se realiza la conversión de la cadena a octetos
+                        K = 0;
+                        C = 0;
+                        for (i = 0; i < LENIN; i++){
+                            DS[i] = DE[i + C] >> K | DE[i + C + 1] << (7 - K);
+                            if(DS[i] == 0x00) {LENOUT = i; goto salir1;}   
+                            K++;
+                            if (K == 7) {K = 0; C++;} // se chequea que ya se acabaron los bits en un ciclo de conversion.
+                        }
+                        
+                        salir1:
+                            for (i = 0; i < LENIN; i++){
+                                pc.printf("%X", DE[i]);
+                            }
+                        
+                            pc.printf(":\r\n");
+                            for (i = 0; i < LENOUT; i++){
+                                pc.printf("%2X", DS[i]&0x000000FF);
+                            }                        
+                            pc.printf("\r\nLENOUT GPS: %d, LENIN GPS: %2X\r\n", LENOUT, LENIN);
+                        
+                        //Se concatena el mensaje en formato PDU para poder enviarlo
+                        ind = 14 + LENOUT - 1;
+                        
+                        //En esta sección se utiliza el comando AT para enviar el mensaje y se muestra en la terminal del PC y en el módem GSM
+                        GSM.printf("AT+CMGS=%d\r\n",ind);
+                        pc.printf("AT+CMGS=%d\r\n",ind);
+                        pc.printf(relleno1);
+                        GSM.printf(relleno1);
+                        
+                        for (i=0 ;i<=9; i++)  {
+                            pc.printf("%c",tel[i]);
+                            GSM.printf("%c",tel[i]);
+                        }
+                        
+                        pc.printf(relleno2);
+                        GSM.printf(relleno2);
+                        pc.printf("%2X", LENIN);
+                        GSM.printf("%2X", LENIN);
+                         
+                        for (i = 0; i < LENOUT; i++){
+                            pc.printf("%02X", DS[i]&0x000000FF);
+                            GSM.printf("%02X", DS[i]&0x000000FF);
+                        }
+                        wait(1);
+                        GSM.putc((char)0x1A); // Ctrl + Z
+                        GSM.scanf("%s",buf); //Devuelve el estado del mensaje (Enviado o no enviado)
+                        pc.printf("\n>%s\n",buf);
+                    }
+                    
+                    wait(1);
+                    LedAzul = 1;
+                    LedRojo = 1;
+                    LedVerde = 0;
+                    GSM.printf("AT+CMGD=0\r\n"); // Borra el mensaje actual (Índice 0 en la memoria).
+                    pc.printf("%s\n\n", "El mensaje ha sido borrado del celular");
+                    goto inicio1; // Vuelve a la configuración inicial, a la espera de otro mensaje
+                }
+            } 
+        }
+        // Esta función permite la implementación del botón de pánico
+        if (sw==0){ // Si se pulsa el botón, envía el siguiente mensaje
+               GSM.printf("AT+CMGS=16\n\r");
+               wait_ms(200);
+               GSM.printf("0011000A9113874094780000AA03D3E714"); // Mensaje SOS
+               wait_ms(200);
+               GSM.putc((char)0x1A); // Ctrl + Z, indicando el final del mensaje
+               wait(10);
+               }
+               else {
+                   }
+                        
+    }
+}
\ No newline at end of file
diff -r 000000000000 -r f115f80141ca mbed.bld
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mbed.bld	Wed Apr 10 22:21:24 2019 +0000
@@ -0,0 +1,1 @@
+https://os.mbed.com/users/mbed_official/code/mbed/builds/65be27845400
\ No newline at end of file