este programa recibe ordenes codificadas en mensajes de texto y envia mensajes cuando pulsan un boton use Alarma1 y Alarma2 de prueba...regresa por pulsador Alarma1. captura el numero de telefono de quien manda la orden

Dependencies:   DebouncedIn mbed

Fork of CLASEDELGSM by Gustavo Ramirez

Este programa se probo y valido verificando que no se bloquea salvo se quede sin credito la SIMCARD se puede adaptar a cualquier aplicación de telemetría GSM o GPRS, ya que las funciones de librería lo permiten. Se adapta fácil a un rastreador satelital o monitoreo de variables si se usan los programas PDU1 y PDU2 para pasar entre octetos y septetos y viceversa.

baje el programa de abajo para determinar cadenas completas PDU en modo Hex y determine sus propias claves use el menú mandos del teléfono/enviar mensajes. Este programa monitorea completamente la actividad del modem facilitandonos la apropiación de la dinámica de codificación de mensajes PDU

/media/uploads/tony63/movilon.rar

/media/uploads/tony63/movilon1.png

puede bajar también TERMITE

http://www.compuphase.com/software_termite.htm

ejecutarlo con privilegios de administrador

baje este documento donde explico bastante como se codifica en PDU y multiples ejemplos y experimentos con el modem GSM/GPRS

/media/uploads/tony63/practicassms.rar

main.cpp

Committer:
tony63
Date:
2016-05-11
Revision:
6:08dac00ecff7
Parent:
5:4cece0df6a3b

File content as of revision 6:08dac00ecff7:

/*************************Alarma Contra Robo*******ver:01.may 10 2016 **************************************************
Como modem usa un celular SIEMENS a56i (ver compatibilidad mandos AT otros modems)
Envia el mensaje intruso y otras cosas (mire el codigo de abajo)
Como modem GSM usa un celular SIEMENS A56i
El conector se distingue asi: 
Cable verde es RX conectelo a PTE0  cable blanco es TX conectelo a PTE1 (placa FRDMKL25Z de NXP antes freescale)
La alarma se dispara segun la señal digital de entrada de un sensor PIR que se le filtra el ruido por medio de
una validacion por retardo
La alarma puede hacer accionamientos como:
Accionamiento Permanente de una sirena
Accionaminto temporizado de una sirena
Accionamiento de un Mensaje de voz reperido y temporizado con un modulo de voz parallax
puede marcar un telefono fijo y uno de celular e inyectar audio, como voz robotizada a la linea de audio
usando un modulo GSM/GPRS SIM900 para arduino con entradas y salidas de audio
puede leer coordenadas de gps y enviarlas con el link de googlemaps.
//   OJO CON ESTO
//   conector del siemens cable verde es RX conectelo a PTE0  cable blanco es TX conectelo a PTE1

ESTA ALARMA SE PUEDE PROBAR DE LA SIGUIENTE FORMA
LOS TELEFONOS ESTAN PREGRAVADOS O CON UN CAMBIO SIMPLE EN EL PROGRAMA EL SISTEMA PUEDE CONTESTAR
CON EL TELEFONO QUE LO LLAMO
EN EL CASO DE RASTREADORES
HAY UN SUICHE QUE SE LLAMA PIR UBICADO EN PTA13..SI SE PULSA POR UN INSTANTE DE TIEMPO
EL LED VERDE DESTELLA INDICANDO QUE SE ENVIO EL MENSAJE AL NUMERO CODIFICADO EN LA CADENA SEGUN LAS TRAMAS PDU
ENVIA EL MENSAJE "HAY INTRUSOS EN LA FINCA...."

EN EL CASO DE ENVIAR ORDENES SE DISEÑARON DOS
SI SE ENVIA UN MENSAJE CON Alarma1 prende el led azul 5 segundos y retorna a verde
SI se envia el mensaje con Alarma2 prende el led rojo 5 segundos y retorna a verde
si el telefono falla da indicacion con rojo
el sistema reintenta de forma infinita la configuracion hasta que lo logra
*****se verifico que no se de bloqueo y asi resulto bajo intensas pruebas********
este sistema detecta el mensaje, el tamaño del mensaje y el numero telefonico de quien llama pero etos parametros no se estan usando
se podrian usar en programas mas complejos como rastreadores satelitales o sistemas de monitoreo de variablees fisicas
que se consultan por medio de ordenes previas segun algun Mensaje corto.

*/
#include "mbed.h"
#include "DebouncedIn.h"
#include "stdio.h"
#include "string.h"
Timer t;
DigitalOut LedVerde(LED2);
DigitalOut LedRojo(LED1);
DigitalOut camara(PTE20 );
DigitalOut sirena(PTE21 );
DigitalOut luces(PTE22 );
DigitalOut audio(PTE23 );
DigitalOut LedAzul(LED3);
DebouncedIn PIR(PTA13);  //señal que inicia el envio del mensaje
DebouncedIn button1(PTC12);  //señal que inicia el envio del mensaje
Serial GSM(PTE0,PTE1); //Configura puerto UART1 de la FRDMKL25Z
Serial voz(PTA2,PTA1); //Configura puerto UART0 de la FRDMKL25Z
Serial pc(USBTX,USBRX);//Configura puerto USB a la consola serial del PC conectado.
void Rx_interrupt();
int position=0;
int intentos=0;
int lenpack=6;
int ret=1;
int longi=0;
char tel[11];
char DE[50];
char buffer[200];
//char buffermsg[200];
//char buffer1[200];
//char datos[200];
char NUMBER[13]; 
char resp[6];  
char CMT[]="+CMTI";
char tam[2];
int index;
int count;
int i = 0;
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[50];
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());
    
}
//****************************************************************************************************************
//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=7,0,1\r\n", "OK", 3)){ //velocidad fija a 9600, modem asincronico no transparente
        return -1;
        }
    if (0 != sendCmdAndWaitForResp("ATE\r\n", "OK", 3)){ //se le quita el eco al modem GSM
        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;
}
//********Esta funcion devuelve la confirmacion del mensaje a quien lo envio**************************
int recibe_ok(){
        GSM.printf("AT+CMGS=32\n\r");
        pc.printf("AT+CMGS=32\n\r");
        wait_ms(100);
        GSM.printf("0011000A91%s0000AA15CDB27B1E569741F2F2382D4E93DFA0E7321402",tel);
        pc.printf("0011000A91%s0000AA15CDB27B1E569741F2F2382D4E93DFA0E7321402",tel);
        wait_ms(100);
        GSM.putc((char)0x1A);
        return 0;
        }
//************************************************************************************
//*****************SE INICIA EL PROGRAMA PRINCIPAL*******************************************************
int main() {
        //configuramos 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     
        LedVerde=1;  //APAGO LOS LEDS
        LedRojo=1;
        LedAzul=1;
        LedRojo=0;  // PRENDO EL LED ROJO 
        //quito el eco del modem
                
//****************CONFIGURAMOS EL MODEM GSM (TELEFONO CELULAR SIEMENS A56i)
inicio1:        
        ret = init();
        if(ret==0){
        LedRojo=1;
        LedVerde=0;
        }
        else{
        wait(1);
        goto inicio1;    
        }
     
//RUTINA PRINCIPAL*******************************************************************************************
    
//*********************************************************************************************************************
while(1){ 
        //***************ALARMA POR ACTIVACION PIR***************************************************         
       if (PIR.falling())
         { 
          wait(1);
          if (!PIR)
           {
              
//**********se envia la palabra "Hay Intrusos En La Finca de Rionegro"
//******Gustavo        
        GSM.printf("AT+CMGS=50\n\r");
        wait_ms(100);
        GSM.printf("0011000A9113223717370000AA2A21970B19CE83926EBABC3E7FCF41453788190699D3EE7118442E83A4E9B7BB7C96BF5DAE10");
        wait_ms(100);
        GSM.putc((char)0x1A);
        for(i=0;i<60;i++){      //por mas ruido se envia un mensaje cada minuto
               LedVerde=1;
               wait(0.5);
               LedVerde=0;
               wait(0.5);
          }      
        }
        }
// **************apartir de aca se pueden escribir mas alarmas o mensajes de salida activar leds salidas o generar respuestas
        
           


//***************inicia la recepcion de un mensaje de texto**********************************
//la comparacion de estos mensajes constituye generar accionamiento abrir o cerrar circuitos o contestar mensajes
 
       if (GSM.readable()) {
            readBuffer(buffer,110);
            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("llego MSG\r\n");
                cleanBuffer(buffer,10);
                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,110);
                pc.printf("%s\r\n",buffer);
                //leer telefono
                for(i=0;i<10;i++){
                       tel[i]=buffer[i+40];
                       }
                pc.printf("%s-\r\n",tel);        
                //leer tamaño
                   for(i=0;i<2;i++){
                       tam[i]=buffer[i+68];
                   }
                   pc.printf("%s-\r\n",tam);        
                   //leer mensaje
                    for(i=0;i<20;i++){
                       msg[i]=buffer[i+70];  //OJO SE LEE EL MENSAJE APARTIR DE LA POSICION 70 14 caracteres
                   }
                   pc.printf("%s-\r\n",msg);        
                   //decodificar mensaje
                   //comparar mensaje
                   deleteSMS(1);//se borra los mensajes por medio de una funcion
                   readBuffer(buffer,200);
                   readBuffer(buffer,200);
                   if(strncmp("417658DE0EC700",msg,14) == 0){  //COMPARA resp con "417658DE0EC700" que es Alarma1
                   recibe_ok();
                   LedVerde=1;
                   LedAzul=0;
                   wait(15);
                   LedAzul=1;
                   LedVerde=0;
                   }
                   if(strncmp("417658DE0ECB00",msg,14) == 0){  //COMPARA resp con "417658DE0ECB00" que es Alarma2
                   recibe_ok();
                   LedVerde=1;
                   LedRojo=0;
                   wait(15);
                   LedRojo=1;
                   LedVerde=0;
                   }
                   if(strncmp("C3703B2C0F83DE6E",msg,16) == 0){  //COMPARA resp con "417658DE0ECB00" que es Camara on
                   recibe_ok();
                   camara=1;
                   }
                   if(strncmp("C3703B2C0F83DE66",msg,16) == 0){  //COMPARA resp con "417658DE0ECB00" que es Camara of
                   recibe_ok();
                   camara=0;
                   }
                   if(strncmp("D3B4BCEC0E83DE6E",msg,16) == 0){  //COMPARA resp con "D3B4BCEC0E83DE6E" que es Sirena on
                   recibe_ok();
                   sirena=1;
                   wait(30);                        //prende la sirena 30 segundos
                   sirena=0;
                   }
/*                 if(strncmp("        ",msg,16) == 0){  //COMPARA resp con " " que es luz on
                   recibe_ok();
                   luces=1;
                   wait(30);                        //prende la luz 30 segundos
                   luces=0;
                   }
                   if(strncmp(" ",msg,16) == 0){  //COMPARA resp con "" que es Msg1
                   recibe_ok();
                   }
                   if(strncmp(" ",msg,16) == 0){  //COMPARA resp con "" que es Msg2
                   recibe_ok();
                   }  
                   if(strncmp(" ",msg,16) == 0){  //COMPARA resp con "" que es Msg3
                   recibe_ok();
                   }
                   if(strncmp(" ",msg,16) == 0){  //COMPARA resp con "" que es Msg123
                   recibe_ok();
                   }
*/                   
                   //strncmp(str1, str2, 6) compara hasta 6 caracteres
                   //recibe_ok();
                   
                   //ejecurar orden si esta es mas que prender leds
                   readBuffer(buffer,200);
                   cleanBuffer(buffer,110);
                               
                }
            }
               

        }


//**********************************************************************************************************************           
loop1: LedRojo=0;
       wait(0.3);
       LedRojo=1;
       wait(0.3);  
       goto loop1;
 
}

/*
si se manda para enviar mensaje
AT+CMGS=20
   //un salto de linea y el simbolo mayor
> 
patrones de alarma y mensajes
Camara on

da esto
 +CMGL: 1,0,,26
0791751330512411040AA1132237173700006150709060250A09C3703B2C0F83DE6E

Camara of da esto
+CMGL: 2,0,,26
0791751330080089040AA1132237173700006150709001520A09C3703B2C0F83DE66
mensaje=C3703B2C0F83DE66
OK

Sirena on
da esto

+CMGL: 3,0,,26
0791751330512411040AA1132237173700006150709031540A09D3B4BCEC0E83DE6E
mensaje=D3B4BCEC0E83DE6E
OK

Sirena of

da esto
+CMGL: 4,0,,26
0791751330512411040AA1132237173700006150709051750A09D3B4BCEC0E83DE66
mensaje=D3B4BCEC0E83DE66
OK

Alarma 1

+CMGL: 1,0,,25
0791751330512411040AA1132237173700006150702153640A08417658DE0E8362
mensaje=417658DE0E8362
5

Mensaje recibido ok!
AT+CMGS=31
0011000A9113223717370000AA14CDB27B1E569741F2F2382D4E93DFA0F73A04

AT+CMGS=32
0011000A9113223717370000AA15CDB27B1E569741F2F2382D4E93DFA0E7321402



void recibe_ok(void){
        GSM.printf("AT+CMGS=31\n\r");
        wait_ms(200);
        GSM.printf("0011000A91");
        GSM.printf("%str",tel);
        GSM.printf("0000AA14CDB27B1E569741F2F2382D4E93DFA0F73A04\n\r"); // Mensaje recibido ok!
        wait_ms(200);
        GSM.putc((char)0x1A);
        }

*/