PROGRAMA PARA HACER SEGUIMIENTO DE FLOTAS CON GPS Y CONEXION A LA RED GPRS

Dependencies:   mbed DebouncedIn GPS_G

Dependents:   61_RASTREO_GPRS_copy

PROGRAMA PARA HACER SEGUIMIENTO DE FLOTAS CON GPS Y CONEXION A LA RED GPRS

Emplea modem gprs SIM900

vea pagina completa del proyecto.:

https://www.unrobotica.com/proyectos/rastreadorgsm.html

se implementa en una FRDMKL25Z y un modulo Bluepill STM32F103.

/media/uploads/tony63/img6.jpg

main.cpp

Committer:
tony63
Date:
2019-09-03
Revision:
3:cd97b1ddaa23
Parent:
2:f4483748eee0

File content as of revision 3:cd97b1ddaa23:

/*
PROGRAMA PARA HACER SEGUIMIENTO DE FLOTAS CON GPS Y CONEXION A LA RED GPRS
se pueden simular trayectorias gravando archivos kml en google earth y usando
SatGen
version 2.0, sep 3 / 2019

se asigna un APN segun el servicio GPRS de la SIMCARD (claro Colombia)
se asigna un nombre de host de su pagina web
se asigna el path de los archivos y mapas ejecutables en su servidor
se asigna un ciclo de repeticion de lecturas de GPS.

*/

#include "mbed.h"
#include "stdio.h"
#include "string.h"
#include "GPS.h"

Timer t;
DigitalOut LedVerde(LED2);
DigitalOut LedRojo(LED1);
DigitalOut LedAzul(LED3);
InterruptIn button(PTA13);


float lo,la;
char lon[15], lat[15]; // Cadenas a capturar para latitud y longitud.
char gprsBuffer[20];
char resp[15];
Serial GSM(PTE0,PTE1);  // Puertos del FRDM para el Módem.
Serial pc(USBTX,USBRX);
GPS gps(PTE22, PTE23);   // Puerto del FDRM para el GPS.
int result;
int z=0;
int i=0;
int count=0;
int g=0;

//-----------------------------------------------------------------------------------------------------------------------------
// 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 de abajo es muy completa y útil, se encarga de enviar el comando y esperar la respuesta.
// Si todo sale bien retorna un cero (herencia de las funciones contenedoras) que en la programacion hay que validar
// con alguna expresion lógica.
int sendCmdAndWaitForResp(char *cmd, char *resp, int timeout){
    sendCmd(cmd);
    return waitForResp(resp,timeout);
}
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// Esta función de abajo chequea que el módem este vivo, envia AT, le contesta con OK y espera 2 segundos.
int powerCheck(void){ // Este comando se manda para verificar si el módem esta vivo o conectado.
    return sendCmdAndWaitForResp("AT\r\n", "OK", 2);    
}
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// Esta función de abajo chequea el estado de la sim card
// y si todo sale bien retorna un cero que en la programacion hay que validar
// con alguna expresión lógica.
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 de abajo chequea la calidad de la señal
// y si todo sale bien retorna con el valor de señal útil o un -1 si no es aceptable, en la programacion hay que validar
// con alguna expresión lógica.
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;
}

//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

//   detectar  direcion ip
int ip_detect(){
        if (GSM.readable()){
        readBuffer(gprsBuffer,15);
            for(i=0;i<15;i++)
            {
            resp[i]=gprsBuffer[i];
            }  
            cleanBuffer(gprsBuffer,20);
            for(i=0;i<15;i++){
               if(resp[i]== '.'){
               z++;
                                }
                              }
            if(z==3){   //CUENTO TRES PUNTOS LO MAS PROBABLE ES QUE SEA UNA DIRECCION ip
                    pc.printf("llego ip=%d\r\n",z);
                    z=0;
                    return 0;  //RETORNA CON CERO SI LLEGARON TRES PUNTOS
                    } 
        }//fin check GSM modem         
        z=0;
        return -1;  //NO LLEGARON 3 PUNTOS RETORNA CON -1
        }//fin funcion
        
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 
// Esta funcion de abajo inicia la comunicacion GPRS con la red celular, Se compone de un grupo de subfunciones ya definidas previamente
// envia las secuencias de forma ordenada esparando la respuesta adecuada
// si todo sale bien retorna un cero que en la programacion hay que validar
// con alguna expresión lógica.
//*********************************************************************************************************

int init_gprs(void){
        
    if (0 != sendCmdAndWaitForResp("AT\r\n", "OK", 5)){
        return -1;
    }
     if (0 != sendCmdAndWaitForResp("ATE0\r\n", "OK", 5)){  //sin eco
        return -1;
    }
    if (0 != sendCmdAndWaitForResp("AT+CGATT=1\r\n", "OK", 5)){//inicia conexion GPRS
        return -1;
    }
    if (0 != sendCmdAndWaitForResp("AT+CSTT=internet.comcel.com.co,comcel,comcel\r\n", "OK", 5)){ //set apn
        return -1;
    }
    if (0 != sendCmdAndWaitForResp("AT+CIICR\r\n", "OK", 5)){ //habilitar conexion inalambrica
        return -1;
    }
    
    cleanBuffer(gprsBuffer,25);
    sendCmd("AT+CIFSR\r\n"); //obtener direccion ip
    if(0 != ip_detect()){  //esperar la llegada de un direccion IP
        return -1;
    }    
    wait(1);    
    LedVerde=0;//CONEXION OK... PRENDE LED VERDE..
    return 0;
}

//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//ESTA FUNCION DE ABAJO CIERRA UNA CONEXION GPRS

int end_gprs(void){
    if (0 != sendCmdAndWaitForResp("AT+CIPSHUT\r\n", "OK", 5)){
        return -1;
    }
     if (0 != sendCmdAndWaitForResp("AT+CGATT=0\r\n", "SHUT OK", 5)){  
        return -1;
    }
    LedVerde=0;
    LedRojo=1;
    return 0;
  }
  
//++++++++++++++++++++++++++++++++++++++++++++++++++++
//interupcion perdida de energia
//++++++++++++++++++++++++++++++++++++++++++++++++++++

void off_gprs(){
      end_gprs();
      }   

//+++++++++++++++++++++++++++++++++++++++++++++++++++++
//inicio del programa principal
//+++++++++++++++++++++++++++++++++++++++++++++++++++++
int main(){

loop1:g=gps.sample(); //GPS bien conectado????  de primero antes que todo!!!!
      if(g){
        LedAzul=0;//prende led azul GPS ok!!!
        pc.printf("GPS--OK\n\r");
        //si no hay GPS no intentar dada, ni conexion ni envio de datos y esperar el GPS
        goto lop1;
           }
       goto loop1;  //chequeo infinito de un GPS bien instalado...
lop1:
     if(init_gprs()<0){
        LedRojo=0;//PRENDE ROJO, APAGA VERDE
        LedVerde=1;
        goto lop1;//NO SE PUEDE RECONECTAR INFINITAMENTE ESTE SALTO ES PROVISIONAL
        //CONTAR LOS INTENTOS Y DAR SEÑAL DE ERROR PERMANENTE
        }
        button.fall(&off_gprs);//perdida de alimentacion,apagaron carro  ejecuta interupcion
        //que desconecta la conexion GPRS
    while(1){  //si el GPS tiene conexion y datos se envian coordenadas a pagina web
           LedAzul=1;  //APAGAMOS LED AZUL
           if(gps.sample()){  //UN GPS RESPONDE!
                        LedAzul=0;
                        lo = gps.longitude;
                        la = gps.latitude;
                        sprintf (lon, "%f", lo);//pasa de flotante a caracter
                        sprintf (lat, "%f", la);//pasa de flotante a caracter
                        cleanBuffer(gprsBuffer,10);
                        
                     envio1:                        
                            GSM.printf("AT+CIPSTART=\"TCP\",\"unrobotica.com\",\"80\"\r\n");
                            //respuesta a este comando debe ser "CONNECT OK"
                            wait(6);//espero un poquito a que conteste y luego leo el buffer
                            if (GSM.readable()){
                             readBuffer(gprsBuffer,20);
                             pc.printf("%s\r\n",gprsBuffer);
                             for(i=8;i<18;i++)
                             {
                              resp[i]=gprsBuffer[i];
                             }  
                             if(strcmp("CONNECT OK",resp) == 0){ 
                                goto envio2;
                               }                
                            goto envio1; //no llego connect ok
                            }
                            goto envio1;//se repite comando 1. si no encontro respuesta
                     envio2:
                        if(0 = sendCmdAndWaitForResp("AT+CIPSEND\r\n","",5)){  //devuelve control+Z
                        goto envio3;
                        }
                        goto envio2;//no llego control Z  volver a enviar comando AT
                     envio3:   
                        GSM.printf("GET /gpstracker/gps1.php?lat=%s&lon=%s HTTP/1.0\r\n",lat,lon);
                        wait(3);
                     envio4:   
                        GSM.printf("Host: unrobotica.com\n\n");
                        wait(3);
                     envio5:   
                        GSM.printf("\r\n");
                        wait(3);
                     envio6:   
                        GSM.printf("\n\r");
                        wait(6);//espero un poquito a que conteste y luego leo el buffer
                            if (GSM.readable()){
                             readBuffer(gprsBuffer,12);
                             pc.printf("%s\r\n",gprsBuffer);
                             for(i=2;i<9;i++)
                             {
                              resp[i]=gprsBuffer[i];  //send ok
                             }  
                             if(strcmp("SEND OK",resp) == 0){ 
                                wait(50);
                                goto envio2;//reenviar mas datos, todo salio bien
                                
                               }                
                            if(end_gprs()=0){  //desconexion correcta reconectar de nuevo todo
                                goto lop1;
                                }
                              goto lop1;
                            
                        
                        
                        
                        
                        
                        
                        
                        ................
                        if(0 !=sendCmdAndWaitForResp("\n\r","SEND OK",10))
                        {
                         
                        }
                         //mas tarde  devuelve SEND OK ...esto es suficiente para indicarnos que los datos se fueron a la nube
                        //cleanBuffer(gprsBuffer,20);
                        //leer bufer y encontrar respuesta exitosa  devuelve "SEND OK"
                        // GSM.printf("AT+CIPSTART=\"TCP\",\"unrobotica.com\",\"80\"\r\n");
                       // pc.printf("AT+CIPSTART=\"TCP\",\"unrobotica.com\",\"80\"\r\n");                 
                        //readBuffer(gprsBuffer,10);
                        //if((NULL = strstr(gprsBuffer,""))){
                        //  wait(1);
                        //  goto repetir2;
                        LedRojo=1;
                        LedVerde=0; //envio OK
                        }// del test del gps
                        LedRojo=0;   // hay problemas
                        LedVerde=1; 
                         
            }//del while col 13
               
          }//del main col 11