mide voltaje por gsm

Dependencies:   mbed

Fork of AnalogMeasurements_GSM by Juan Pablo Viana Villa

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers main.cpp Source File

main.cpp

00001 /*==========================================================================================
00002 PROGRAMA PARA EL ENVÍO DE MEDICIONES ANALÓGICAS MEDIANTE RED GSM.
00003 ING. JUAN PABLO VIANA VILLA
00004 UNIVERSIDAD NACIONAL DE COLOMBIA - SEDE MEDELLÍN
00005 
00006 DESCRIPCIÓN DEL FUNCIONAMIENTO:
00007 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.
00008 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.
00009 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.
00010 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).
00011 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.
00012 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.
00013 ==========================================================================================
00014 */
00015 #include "mbed.h"
00016 #include "mbed.h"
00017 #include "stdio.h"
00018 #include "string.h"
00019 
00020 //DEFINO PUERTOS Y ENTRADAS;
00021 Serial pc(USBTX, USBRX);//Puerto Serial monitor;
00022 AnalogIn A(PTB1); //Entrada analógica;
00023 Serial GSM(PTE0,PTE1); //Puerto GSM. TX - RX
00024 Timer t; //Un temporizador.
00025 
00026 
00027 DigitalOut LedVerde(LED2);
00028 DigitalOut LedRojo(LED1);
00029 DigitalOut LedAzul(LED3);
00030 
00031 //DEFINO VARIABLES GLOBALES
00032 char DE[30] ="Volt=3.3V";
00033 char DS[30];
00034 char Tel[11]="1359252144";
00035 int i=0;
00036 int LENOUT;
00037 int LENIN;
00038 float V_float;
00039 int V_int;
00040 char bf[100]; //En esta variable voy a leer lo que mande el GMS;
00041 
00042 
00043 //DEFINO VARIABLES DE LAS FUNCIONES RECICLADAS;
00044 
00045 void Rx_interrupt();
00046 int position=0;
00047 int intentos=0;
00048 int lenpack=6;
00049 int ret=1;
00050 int longi=0;
00051 char tel[11];
00052 char buffer[100];
00053 char buffermsg[100];
00054 char buffer1[100];
00055 char datos[100];
00056 char NUMBER[13]; 
00057 char resp[6];  
00058 char CMT[]="+CMTI";
00059 char tam[2];
00060 int index;
00061 int count;
00062 int j = 0;
00063 int c=0;
00064 unsigned char CtrlZ = 0x1A;  // comodin de emision controlZ
00065 bool Flag = false; // bandera 
00066 char r[]=""; //Cadena de recepcion de la trama PDU si se usa!!
00067 char msg[256];
00068 char char1;
00069 
00070 
00071 //Flush serial para el buffer
00072 void FlushGSM(void) { 
00073 char1 = 0;
00074  while (GSM.readable()){
00075      char1 = GSM.getc();}
00076      return;}
00077 
00078 void callback() {
00079     // Note: you need to actually read from the serial to clear the RX interrupt
00080     pc.printf("%c\n", GSM.getc());
00081     
00082 }
00083 
00084 /*==================================================================================================================================================================
00085 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;
00086 Su funcionamiento se ha verifcado solo hasta el alcance de este programa.
00087 ==================================================================================================================================================================*/
00088 
00089 
00090 
00091 
00092 //****************************************************************************************************************
00093 //esta funcion de abajo lee todo un bufer hasta encontrar CR o LF y el resto lo rellena de
00094 //$, count es lo que va a leer.Lo leido lo mete en buffer que es una cadena previamente definida
00095 //incorpora medida de tiempo si se demora mas de tres segundos retorna fracaso con -1
00096 //**************************************************************************************************************** 
00097 int readBuffer(char *buffer,int count)
00098 {
00099     int i=0; 
00100     t.start();  // start timer
00101     while(1) {
00102         while (GSM.readable()) {
00103             char c = GSM.getc();
00104             if (c == '\r' || c == '\n') c = '$';
00105             buffer[i++] = c;
00106             if(i > count)break;
00107         }
00108         if(i > count)break;
00109         if(t.read() > 3) {
00110             t.stop();
00111             t.reset();
00112             break;
00113         }
00114     }
00115     wait(0.5);
00116     while(GSM.readable()) {  // display the other thing..
00117         char c = GSM.getc();
00118     }
00119     return 0;
00120 }
00121 //********************************************************************************
00122 /* esta funcion de abajo limpia o borra todo un "buffer" de tamaño "count"
00123 lo revisa elemento por elemento y le mete el caracter null que indica fin de cadena
00124 no retorna nada
00125 */
00126 //***************************************************************************************
00127 void cleanBuffer(char *buffer, int count)
00128 {
00129     for(int i=0; i < count; i++) {
00130         buffer[i] = '\0';
00131     }
00132 }
00133 /* esta funcion de abajo envia un comando parametrizado como cadena
00134 puede ser un comando tipo AT
00135 */
00136 //***************************************************************************************
00137 void sendCmd(char *cmd)
00138 {
00139     GSM.puts(cmd);
00140 }
00141 //****************************************************************************************
00142 /* esta funcion de abajo espera la respuesta de un comando que debe ser identica a la cadena "resp" y un tiempo timeout"
00143 si todo sale bien retorna un cero que en la programacion hay que validar
00144 si algo sale mal ( no se parece o se demora mucho )retorna -1 que debera validarse con alguna expresion logica
00145 */
00146 //***************************************************************************************
00147 int waitForResp(char *resp, int timeout)
00148 {
00149     int len = strlen(resp);
00150     int sum=0;
00151     t.start();
00152 
00153     while(1) {
00154         if(GSM.readable()) {
00155             char c = GSM.getc();
00156             sum = (c==resp[sum]) ? sum+1 : 0;// esta linea de C# sum se incrementa o se hace cero segun c
00157             if(sum == len)break;  //ya acabo se sale
00158         }
00159         if(t.read() > timeout) {  // time out chequea el tiempo minimo antes de salir perdiendo
00160             t.stop();
00161             t.reset();
00162             return -1;
00163         }
00164     }
00165     t.stop();                 // stop timer  antes de retornar
00166     t.reset();                    // clear timer
00167     while(GSM.readable()) {      // display the other thing..
00168         char c = GSM.getc();
00169     }
00170 
00171     return 0;
00172 }
00173 /* esta funcion de abajo es muy completa e util se encarga de enviar el comando y esperar la respuesta
00174 si todo sale bien retorna un cero(herencia de las funciones contenedoras) que en la programacion hay que validar
00175 con alguna expresion logica
00176 */
00177 //***************************************************************************************
00178 int sendCmdAndWaitForResp(char *cmd, char *resp, int timeout)
00179 {
00180     sendCmd(cmd);
00181     return waitForResp(resp,timeout);
00182 }
00183 /* esta funcion de abajo chequea que el modem este vivo  envia AT y le contesta con OK y espera 2 segundos
00184 */
00185 //***************************************************************************************
00186 int powerCheck(void)// este comando se manda para verificar si el modem esta vivo o conectado
00187 {
00188     return sendCmdAndWaitForResp("AT\r\n", "OK", 2);    
00189 }
00190 /* esta funcion de abajo chequea el estado de la sim card
00191 y si todo sale bien retorna un cero que en la programacion hay que validar
00192 con alguna expresion logica
00193 */
00194 //***************************************************************************************
00195 int checkSIMStatus(void)
00196 {
00197     char gprsBuffer[30];
00198     int count = 0;
00199     cleanBuffer(gprsBuffer,30);
00200     while(count < 3) {
00201         sendCmd("AT+CPIN?\r\n");
00202         readBuffer(gprsBuffer,30);
00203         if((NULL != strstr(gprsBuffer,"+CPIN: READY"))) {
00204             break;
00205         }
00206         count++;
00207         wait(1);
00208     }
00209 
00210     if(count == 3) {
00211         return -1;
00212     }
00213     return 0;
00214 }
00215 /* esta funcion de abajo chequea la calidad de la señal
00216 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
00217 con alguna expresion logica
00218 */
00219 //***************************************************************************************
00220 int checkSignalStrength(void)
00221 {
00222     char gprsBuffer[100];
00223     int index,count = 0;
00224     cleanBuffer(gprsBuffer,100);
00225     while(count < 3) {
00226         sendCmd("AT+CSQ\r\n");
00227         readBuffer(gprsBuffer,25);
00228         if(sscanf(gprsBuffer, "AT+CSQ$$$$+CSQ: %d", &index)>0) {
00229             break;
00230         }
00231         count++;
00232         wait(1);
00233     }
00234     if(count == 3) {
00235         return -1;
00236     }
00237     return index;
00238 }
00239 
00240 /* esta funcion de abajo inicaliza el modem se compone de un grupo de subfunciones ya definidas previamente
00241 primero chequea que este vivo
00242 segundo chequea el estado de la simcard
00243 tercero chequea la intencidad de señal celular
00244 cuarto aplica la configuracion
00245 y si todo sale bien retorna un cero que en la programacion hay que validar
00246 con alguna expresion logica
00247 */
00248 //***************************************************************************************
00249 int init()
00250 {
00251     if (0 != sendCmdAndWaitForResp("AT\r\n", "OK", 3)){
00252         return -1;
00253         }
00254     if (0 != sendCmdAndWaitForResp("AT+CNMI=1,1\r\n", "OK", 3)){
00255         return -1;
00256         }
00257     if (0 != sendCmdAndWaitForResp("AT+CMGF=0\r\n", "OK", 3)){
00258         return -1;
00259         }
00260     if (0 != sendCmdAndWaitForResp("AT+CBST=0,0,1\r\n", "OK", 3)){
00261         return -1;
00262         }
00263         LedVerde=0;
00264         return 0;
00265         }
00266   
00267 /* esta funcion de abajo intenta leer un mensaje de texto en formato PDU o HEX
00268 y si todo sale bien retorna un cero que en la programacion hay que validar
00269 con alguna expresion logica
00270 */
00271 //***************************************************************************************
00272 int readSMSpdu(char *message, int index)
00273 {
00274     int i = 0;
00275     char gprsBuffer[100];
00276     char *p,*s;
00277     GSM.printf("AT+CMGR=%d\r\n",index);
00278     cleanBuffer(gprsBuffer,100);
00279     readBuffer(gprsBuffer,100);
00280     if(NULL == ( s = strstr(gprsBuffer,"+CMGR"))) {
00281         return -1;
00282     }
00283     if(NULL != ( s = strstr(gprsBuffer,"+32"))) {
00284         p = s + 6;
00285         while((*p != '$')&&(i < 5)) {
00286             message[i++] = *(p++);
00287         }
00288         message[i] = '\0';
00289     }
00290     return 0;
00291 }
00292 /* esta funcion de abajo borra mensajes SMS del modem
00293 y si todo sale bien retorna un cero que en la programacion hay que validar
00294 con alguna expresion logica
00295 */
00296 //***************************************************************************************
00297 int deleteSMS(int index)
00298 {
00299     char cmd[32];
00300     snprintf(cmd,sizeof(cmd),"AT+CMGD=%d\r\n",index);
00301     sendCmd(cmd);
00302     return 0;
00303 }
00304 /*============================================================================================*/
00305 
00306 int main()
00307 {
00308 
00309 int EnviarMensaje=0; //Bandera para el envío de SMS;    
00310 int TEMP;
00311 wait(10);
00312 pc.printf("Comienza programa de envio de mediciones analogicas mediante SMS.\r\n Se estan configurando los puertos seriales.\r\n");
00313 
00314 //Las siguientes líneas tienen como fin configurar los puertos seriales;
00315        GSM.baud(9600);//configura los baudios de la FRDMKL25Z en 9600
00316        GSM.format(8,Serial::None,1); //configura el formato de los datos de la UART 
00317        GSM.printf("ATE0\r\n");
00318  //Las siguientes líneas tienen como fin borrar los mensajes almacenados en el teléfono;
00319     for(i=0;i<6;i++)
00320     {
00321           GSM.printf("AT+CMGD=%d\r\n",i);
00322           wait(0.2);
00323     }
00324 
00325 i=0;
00326 //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"
00327 
00328 while(init()<0)
00329 {
00330        LedVerde=1; //Apago el led;
00331        LedRojo=1;//Apago el led;
00332        LedAzul=1;//Apago el led;
00333        
00334        i++;
00335        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;}
00336 } 
00337 wait(0.5); //Esta línea no tiene ningún sentido, solo espero para que el programa parezca más interesante.
00338 pc.printf("Se ha realizado la conexion exitosamente, ahora puede comenzar el envio de informacion. \r\n");
00339        LedVerde=1; //Apago el led;
00340        LedRojo=1;//Apago el led;
00341        LedAzul=1;//Apago el led;
00342               
00343 /*Inicia ciclo infinito*/           
00344     while (true) {
00345         
00346  if (EnviarMensaje ==1)
00347  {  
00348 pc.printf("****************************************************************************\r\n");     
00349 //Las siguientes líneas tienen como fin leer el voltaje y convertirlo en ASCII;
00350 V_float=A.read()*3.3; 
00351 V_int=V_float*10; //Multiplico por 10 y almaceno en una variable tipo entero para tomar un decimal y eliminar el punto flotante;
00352 TEMP=V_int/10; 
00353 DE[5]=TEMP+48; //Convierto el valor el caracter;
00354 V_int = V_int-TEMP*10;
00355 DE[7]=V_int + 48;//Convierto el valor en caracter;      
00356 //Las siguientes líneas tienen por objeto la conversión de una cadena de caracteres a octetos que puedan enviarse mediante PDU;
00357         
00358         
00359         DE[0]=86;//V
00360         DE[1]=111;//o
00361         DE[2]=108;//l
00362         DE[3]=116;//t
00363         DE[4]=61;//=
00364         //D[5]=;
00365         DE[6]=46;//.
00366         //D[7]=;//.
00367         DE[8]=86;//V
00368         
00369         
00370         pc.printf("\r\nVoltaje: %s\r\n", DE);
00371         LENIN=strlen(DE); //Se mide el tamaño de la cadena;
00372         for(i=0;i<LENIN;i++)
00373         {DE[i]=DE[i]&0x000000FF;} //Convierto en formato 0x00;
00374         
00375         for (i=0;i < LENIN;i++)
00376         {
00377             DS[i]=(DE[i]>>i|DE[i+1]<<(7-i));
00378             LENOUT=i+1;
00379             if(DS[i]==0){DS[i]='\0';break;}
00380         }        
00381         
00382         pc.printf("\r\n ENVIAR SMS: ");
00383         pc.printf("AT+CMGS=21\r\n");
00384         wait(0.2);
00385         GSM.printf("AT+CMGS=21\r\n"); //Indico al modem GSM que se enviará una trama PDU de longitud 21;
00386         wait(0.2);
00387         pc.printf("0011000A91");
00388         GSM.printf("0011000A91"); //Identificación del mensaje y del protocolo;
00389         pc.printf("%s", Tel);
00390         GSM.printf("%s", Tel); //Destinatario del mensaje;
00391         pc.printf("0000AA09");
00392         GSM.printf("0000AA09");//Longtitud  del mensaje y otros parámetros;
00393         
00394         for(i=0;i<LENOUT-1;i++)
00395         {
00396             pc.printf("%2X",DS[i]&0x000000FF);
00397             GSM.printf("%2X",DS[i]&0x000000FF); //Mensaje en octetos;
00398 
00399         }
00400 wait(0.5);
00401 
00402 GSM.putc(0x1A); //Caracter ASCII 26 para el envío del SMS;
00403 EnviarMensaje=0;                
00404 }//Enviar mensaje;
00405 
00406 //inicia la recepcion de un mensaje de texto
00407        if (GSM.readable()) {
00408             readBuffer(buffer,100);
00409             pc.printf("%s\r\n",buffer);
00410             for(i=0;i<5;i++)
00411             {
00412             resp[i]=buffer[i];
00413             }  
00414              
00415             pc.printf("%s\r\n",resp);
00416             if(strcmp("$$+CM",resp) == 0){  //COMPARA resp con "+CMTI"
00417                 pc.printf("****************************************************************************\r\n");
00418                 pc.printf("Nuevo Mensaje de texto. \r\n");
00419                 EnviarMensaje=1;
00420                 cleanBuffer(buffer,10);
00421                 wait(0.5);
00422                 GSM.printf("AT+CMGL=0\r\n");//envio comando para leer mensaje
00423                 pc.printf("AT+CMGL=0\r\n");
00424                 //if (GSM.readable()) {
00425                 GSM.printf("AT+CMGD=0\r\n");    
00426                 readBuffer(buffer,100);
00427                 pc.printf("Cadena recibida: %s\r\n",buffer);
00428                 wait(5);
00429                 i=0;
00430                    //leer telefono
00431                 for(i=0;i<10;i++){
00432                        Tel[i]=buffer[i+40];
00433                        }
00434                 pc.printf("%Remitente: %s\r\n",Tel); //Almaceno el número de teléfono del remitente
00435       
00436 
00437                    
00438                    cleanBuffer(buffer,100);//ejecurar orden
00439                                
00440                 }
00441             }
00442     }//while
00443 }
00444