Lee voltajes por la red GSM

Dependencies:   mbed

Fork of AnalogMeasurements_GSM by Juan Pablo Viana Villa

Revision:
0:d7d64e8b652a
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp	Sat Nov 21 16:58:55 2015 +0000
@@ -0,0 +1,444 @@
+/*==========================================================================================
+PROGRAMA PARA EL ENVÍO DE MEDICIONES ANALÓGICAS MEDIANTE RED GSM.
+ING. JUAN PABLO VIANA VILLA
+UNIVERSIDAD NACIONAL DE COLOMBIA - SEDE MEDELLÍN
+
+DESCRIPCIÓN DEL FUNCIONAMIENTO:
+El programa comienza realizando la inicialización del modem GSM mediante el envío de comandos "AT", se configuraron 10 intentos de conexión, en caso de no recibir respuesta del modem el programa terminará y será necesario reiniciar la plataforma KL25z.
+Una vez detectada actividad por parte del modem el programa ingresa en un bucle infinito y se pone a la espera de recibir un mensaje de texto.
+El programa está constantemente tratando de leer el modem, una vez detecta el mensaje SMS entrante (+CMTI), envía al modem el comando AT para la lectura de la cadena recibida y se activa una variable bandera para el envío de la respuesta.
+NOTA: La cadena entrante sólo es útil para encontrar el número remitente, no se programó restricción alguna sobre el mensaje (sirve cualquiera).
+Una vez leído el mensaje e identificado el remitente se sensa el valor de entrada analógica como valor de punto flotante. Se incluye una secuencia de líneas que convierten el valor medido en caracteres ASCII de la forma "Volt=x.xV" y estos a su vez son convertidos en octetos para proceder a su envío.
+La trama PDU generada se despliega en pantalla en el pc monitor y es enviada al modem GSM finalizando con el caracter ASCII submit (26 - 0x1A) para de esta manera finalizar la transmisión del valor.
+==========================================================================================
+*/
+#include "mbed.h"
+#include "mbed.h"
+#include "stdio.h"
+#include "string.h"
+
+//DEFINO PUERTOS Y ENTRADAS;
+Serial pc(USBTX, USBRX);//Puerto Serial monitor;
+AnalogIn A(PTB1); //Entrada analógica;
+Serial GSM(PTE0,PTE1); //Puerto GSM. TX - RX
+Timer t; //Un temporizador.
+
+
+DigitalOut LedVerde(LED2);
+DigitalOut LedRojo(LED1);
+DigitalOut LedAzul(LED3);
+
+//DEFINO VARIABLES GLOBALES
+char DE[30] ="Volt=3.3V";
+char DS[30];
+char Tel[11]="1359252144";
+int i=0;
+int LENOUT;
+int LENIN;
+float V_float;
+int V_int;
+char bf[100]; //En esta variable voy a leer lo que mande el GMS;
+
+
+//DEFINO VARIABLES DE LAS FUNCIONES RECICLADAS;
+
+void Rx_interrupt();
+int position=0;
+int intentos=0;
+int lenpack=6;
+int ret=1;
+int longi=0;
+char tel[11];
+char buffer[100];
+char buffermsg[100];
+char buffer1[100];
+char datos[100];
+char NUMBER[13]; 
+char resp[6];  
+char CMT[]="+CMTI";
+char tam[2];
+int index;
+int count;
+int j = 0;
+int c=0;
+unsigned char CtrlZ = 0x1A;  // comodin de emision controlZ
+bool Flag = false; // bandera 
+char r[]=""; //Cadena de recepcion de la trama PDU si se usa!!
+char msg[256];
+char char1;
+
+
+//Flush serial para el buffer
+void FlushGSM(void) { 
+char1 = 0;
+ while (GSM.readable()){
+     char1 = GSM.getc();}
+     return;}
+
+void callback() {
+    // Note: you need to actually read from the serial to clear the RX interrupt
+    pc.printf("%c\n", GSM.getc());
+    
+}
+
+/*==================================================================================================================================================================
+A Continuación se añaden una serie de funciones que se usarán posteriormente en el programa principal y que son provistas por  el usuario Tony63;
+Su funcionamiento se ha verifcado solo hasta el alcance de este programa.
+==================================================================================================================================================================*/
+
+
+
+
+//****************************************************************************************************************
+//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 funcion 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 funcion de abajo envia un comando parametrizado como cadena
+puede ser un comando tipo AT
+*/
+//***************************************************************************************
+void sendCmd(char *cmd)
+{
+    GSM.puts(cmd);
+}
+//****************************************************************************************
+/* esta funcion de abajo espera la respuesta de un comando que debe ser identica 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 funcion de abajo es muy completa e util 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 logica
+*/
+//***************************************************************************************
+int sendCmdAndWaitForResp(char *cmd, char *resp, int timeout)
+{
+    sendCmd(cmd);
+    return waitForResp(resp,timeout);
+}
+/* esta funcion de abajo chequea que el modem este vivo  envia AT y le contesta con OK y espera 2 segundos
+*/
+//***************************************************************************************
+int powerCheck(void)// este comando se manda para verificar si el modem esta vivo o conectado
+{
+    return sendCmdAndWaitForResp("AT\r\n", "OK", 2);    
+}
+/* esta funcion 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 expresion logica
+*/
+//***************************************************************************************
+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 funcion de abajo chequea la calidad de la señal
+y si todo sale bien retorna con el valor de señal util o un -1 si no es aceptable, en la programacion hay que validar
+con alguna expresion logica
+*/
+//***************************************************************************************
+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 de abajo inicaliza el modem se compone de un grupo de subfunciones ya definidas previamente
+primero chequea que este vivo
+segundo chequea el estado de la simcard
+tercero chequea la intencidad de señal celular
+cuarto aplica la configuracion
+y si todo sale bien retorna un cero que en la programacion hay que validar
+con alguna expresion logica
+*/
+//***************************************************************************************
+int init()
+{
+    if (0 != sendCmdAndWaitForResp("AT\r\n", "OK", 3)){
+        return -1;
+        }
+    if (0 != sendCmdAndWaitForResp("AT+CNMI=1,1\r\n", "OK", 3)){
+        return -1;
+        }
+    if (0 != sendCmdAndWaitForResp("AT+CMGF=0\r\n", "OK", 3)){
+        return -1;
+        }
+    if (0 != sendCmdAndWaitForResp("AT+CBST=0,0,1\r\n", "OK", 3)){
+        return -1;
+        }
+        LedVerde=0;
+        return 0;
+        }
+  
+/* esta funcion de abajo intenta leer un mensaje de texto en formato PDU o HEX
+y si todo sale bien retorna un cero que en la programacion hay que validar
+con alguna expresion logica
+*/
+//***************************************************************************************
+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 funcion de abajo borra mensajes SMS del modem
+y si todo sale bien retorna un cero que en la programacion hay que validar
+con alguna expresion logica
+*/
+//***************************************************************************************
+int deleteSMS(int index)
+{
+    char cmd[32];
+    snprintf(cmd,sizeof(cmd),"AT+CMGD=%d\r\n",index);
+    sendCmd(cmd);
+    return 0;
+}
+/*============================================================================================*/
+
+int main()
+{
+
+int EnviarMensaje=0; //Bandera para el envío de SMS;    
+int TEMP;
+wait(10);
+pc.printf("Comienza programa de envio de mediciones analogicas mediante SMS.\r\n Se estan configurando los puertos seriales.\r\n");
+
+//Las siguientes líneas tienen como fin configurar los puertos seriales;
+       GSM.baud(9600);//configura los baudios de la FRDMKL25Z en 9600
+       GSM.format(8,Serial::None,1); //configura el formato de los datos de la UART 
+       GSM.printf("ATE0\r\n");
+ //Las siguientes líneas tienen como fin borrar los mensajes almacenados en el teléfono;
+    for(i=0;i<6;i++)
+    {
+          GSM.printf("AT+CMGD=%d\r\n",i);
+          wait(0.2);
+    }
+
+i=0;
+//Las siguientes líneas tienen por objetivo detectar el modem y realizar algunas configuaciones. Básicamente se le pregunta al módulo "AT", a lo que él debe respoder "OK"
+
+while(init()<0)
+{
+       LedVerde=1; //Apago el led;
+       LedRojo=1;//Apago el led;
+       LedAzul=1;//Apago el led;
+       
+       i++;
+       if (i==10){pc.printf("Ha sido imposible establecer conexion con el modem GSM. \n\r El programa terminara y debera iniciar nuevamente la KL25z\n\r");LedRojo=0;wait(1);LedRojo=1;return 0;}
+} 
+wait(0.5); //Esta línea no tiene ningún sentido, solo espero para que el programa parezca más interesante.
+pc.printf("Se ha realizado la conexion exitosamente, ahora puede comenzar el envio de informacion. \r\n");
+       LedVerde=1; //Apago el led;
+       LedRojo=1;//Apago el led;
+       LedAzul=1;//Apago el led;
+              
+/*Inicia ciclo infinito*/           
+    while (true) {
+        
+ if (EnviarMensaje ==1)
+ {  
+pc.printf("****************************************************************************\r\n");     
+//Las siguientes líneas tienen como fin leer el voltaje y convertirlo en ASCII;
+V_float=A.read()*3.3; 
+V_int=V_float*10; //Multiplico por 10 y almaceno en una variable tipo entero para tomar un decimal y eliminar el punto flotante;
+TEMP=V_int/10; 
+DE[5]=TEMP+48; //Convierto el valor el caracter;
+V_int = V_int-TEMP*10;
+DE[7]=V_int + 48;//Convierto el valor en caracter;      
+//Las siguientes líneas tienen por objeto la conversión de una cadena de caracteres a octetos que puedan enviarse mediante PDU;
+        
+        
+        DE[0]=86;//V
+        DE[1]=111;//o
+        DE[2]=108;//l
+        DE[3]=116;//t
+        DE[4]=61;//=
+        //D[5]=;
+        DE[6]=46;//.
+        //D[7]=;//.
+        DE[8]=86;//V
+        
+        
+        pc.printf("\r\nVoltaje: %s\r\n", DE);
+        LENIN=strlen(DE); //Se mide el tamaño de la cadena;
+        for(i=0;i<LENIN;i++)
+        {DE[i]=DE[i]&0x000000FF;} //Convierto en formato 0x00;
+        
+        for (i=0;i < LENIN;i++)
+        {
+            DS[i]=(DE[i]>>i|DE[i+1]<<(7-i));
+            LENOUT=i+1;
+            if(DS[i]==0){DS[i]='\0';break;}
+        }        
+        
+        pc.printf("\r\n ENVIAR SMS: ");
+        pc.printf("AT+CMGS=21\r\n");
+        wait(0.2);
+        GSM.printf("AT+CMGS=21\r\n"); //Indico al modem GSM que se enviará una trama PDU de longitud 21;
+        wait(0.2);
+        pc.printf("0011000A91");
+        GSM.printf("0011000A91"); //Identificación del mensaje y del protocolo;
+        pc.printf("%s", Tel);
+        GSM.printf("%s", Tel); //Destinatario del mensaje;
+        pc.printf("0000AA09");
+        GSM.printf("0000AA09");//Longtitud  del mensaje y otros parámetros;
+        
+        for(i=0;i<LENOUT-1;i++)
+        {
+            pc.printf("%2X",DS[i]&0x000000FF);
+            GSM.printf("%2X",DS[i]&0x000000FF); //Mensaje en octetos;
+
+        }
+wait(0.5);
+
+GSM.putc(0x1A); //Caracter ASCII 26 para el envío del SMS;
+EnviarMensaje=0;                
+}//Enviar mensaje;
+
+//inicia la recepcion de un mensaje de texto
+       if (GSM.readable()) {
+            readBuffer(buffer,100);
+            pc.printf("%s\r\n",buffer);
+            for(i=0;i<5;i++)
+            {
+            resp[i]=buffer[i];
+            }  
+             
+            pc.printf("%s\r\n",resp);
+            if(strcmp("$$+CM",resp) == 0){  //COMPARA resp con "+CMTI"
+                pc.printf("****************************************************************************\r\n");
+                pc.printf("Nuevo Mensaje de texto. \r\n");
+                EnviarMensaje=1;
+                cleanBuffer(buffer,10);
+                wait(0.5);
+                GSM.printf("AT+CMGL=0\r\n");//envio comando para leer mensaje
+                pc.printf("AT+CMGL=0\r\n");
+                //if (GSM.readable()) {
+                GSM.printf("AT+CMGD=0\r\n");    
+                readBuffer(buffer,100);
+                pc.printf("Cadena recibida: %s\r\n",buffer);
+                wait(5);
+                i=0;
+                   //leer telefono
+                for(i=0;i<10;i++){
+                       Tel[i]=buffer[i+40];
+                       }
+                pc.printf("%Remitente: %s\r\n",Tel); //Almaceno el número de teléfono del remitente
+      
+
+                   
+                   cleanBuffer(buffer,100);//ejecurar orden
+                               
+                }
+            }
+    }//while
+}
+