Uso de un celular GSM con PIC o PC

Bueno luego de 14.000 pruebas y errores el PIC manda SMS !

Mis comentarios:

- Probado con la serie PIC16F. (PIC16F877A).
- Cristal usado: 20Mhz.
- debug con el hyperterminal del PicKit2 (Usart TOOL).
- Código de programación en C de CCS.
- Celular usado: T237 (Por comandos AT me dice que es el T230).
- Conexión del teléfono con el PIC de forma directa: TX PIC - RX CEL | RX PIC - TX CEL.

Nota: La fuente con la que se alimente el PIC tiene que estár debidamente filtrada y regulada para evitar posibles funcionamientos erráticos.

Mis aportes hasta el momento:

Código fuente del programa:
Código:
#include <config.h>


void main()
{
   setup_adc(ADC_OFF);
   setup_spi(FALSE);
   setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);
   setup_timer_1(T1_DISABLED);
   setup_timer_2(T2_DISABLED,0,1);
   setup_comparator(NC_NC_NC_NC);
  

   while(true){ 
if(input(PIN_D2)==1){
delay_ms(300);
printf("AT\r\n"); // Le llama la atención al teléfono.  
delay_ms(3000); //espera 5 segundos
printf("AT+CMGF=1\r\n"); //configura modo texto
delay_ms(3000);
printf("AT+CMGS=\"número de teléfono\"\r\n"); // N° del destinatario.
delay_ms(2000); //del celular al que se envia el sms
printf("Esto es una prueba\r\n");
putc(26); //ascii(26)=(ctrl+z) envia el mensaje
printf("\r\n");
delay_ms(5000);

   }
   }
}

Archivo de cabecera:

Código:
#include <16F877A.h>
#device adc=8

#FUSES NOWDT                    //No Watch Dog Timer
#FUSES HS                       //High speed Osc (> 4mhz)
#FUSES PUT                      //Power Up Timer
#FUSES NOPROTECT                //Code not protected from reading
#FUSES NOCPD                    //No EE protection
#FUSES NOBROWNOUT               //No brownout reset
#FUSES LVP                      //Low Voltage Programming on B3(PIC16) or B5(PIC18)
#FUSES NODEBUG                  //No Debug mode for ICD
#FUSES NOWRT                    //Program memory not write protected

#use delay(clock=20000000)
#use rs232(baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=8)

Les dejo también el esquema de conexión del microcontrolador al celular:

En caso de que no se vea bien el esquema en el foro tambíen dejo el rar con todo lo que necesitan para hacer las pruebas.

Parte 1 del proyecto concluida !!!!
 

Adjuntos

  • pic__sms__pic16f877a_628.rar
    75.6 KB · Visitas: 496
Parte2: Recepción de SMS y control de procesos

Mis preguntas al respecto:

- Qué metodo para recibir SMS es el más recomendado PDU o modo texto ?
- Qué método para recibir los SMS en el PIC es el más recomendado Interrupciones o función de preguntas respuestas ?


El que tenga información al respecto comente

PD: Mis especiales agradecimientos a los siguientes usuarios:

Rizy
alepic
ericklarva
Nestor nieto


Por la gran ayuda que me han brindado.

Y los demás gracias por los comentarios sobre sus experiencias y logros.
 
Hola Moyano, gracias por tu agradecimiento ya que no soy especialista en el área del cel pero de programación lo que sea.
Definitivamente el mejor método, por su sencilles, es el de Texto. El PDU es mucho más específico y elaborado, podrías intentarlo solo como desafío.
Para los mensajes yo considero que es mejor preguntarle cada cierto tiempo, aunque en la hoja de comandos AT me pareció ver que hay una forma en la que el Cel avisa de manera inmediata, no estoy muy seguro, pero es en el archivo que postee sobre los Sony ericsson.
Para la cadena de mensajes, sigo pensando en que el encabezado es un número específico de caracteres que pueden ser contados y que sirven como base para guardar solo los que nos interesa y de ahí hacer lo que quieras, ya sea comparar la cadena o checar caracter por caracter.
Excelente que te haya funcionado, por hacer las pruebas con el mio a ver que sale jejeje.
Saludos
 
Voy a probar como decis ahora queda ponerse a programar y hacer dubug con la usart.

Alguien que tenga una idea de como se podría implementar la recepción de mensajes mediante el PIC , comente haber si sacamos algo en concreto.
 
Si el Cel posee la opción de enviar datos sin un comando anterior, con habilitar la interrupción RX sería suficiente y muy cómodo. De lo contrario creo que da igual como se implemente.
Antes que todo considero que deberás checar la trama de inicio para saber con cuantos caracteres está formada esta trama, podrías usar un mensaje en "blanco" o con un texto en específico y un LCD para visualizar cuantos caracteres son o cuales son, igual me pareció ver que envía "," entre cada sección y de ser así solo con detectar que es una "," y contar un número definido de estas podrías detectar fácilmente el texto.
Como el Cel no hace "pausas" entre los caracteres enviados, podrías guardar toda la trama momentánamente y luego checarla con una rutina "for" o "Do-While". O en su caso checar caracter por caracter y guardar lo importante.
Para recibir, si lo hicieras con la interrupción RX, podrías usar la función "getc()" que lee "RXBUFF" y guardar en un buffer el caracter con un puntero o en su caso emplear otra rutina de separación.
Ojalá esto pueda servir de algo.
Saludos
 
hola muy bien hecho estas perfectamente en el avance te comento como yo hago la deteccion del mensaje:
no utilizo interrupciones lo que hago es que cada cierto tiempo estoy enviando los comandos at para lectura de mensaje para ir detectando un mensaje nuevo si existe uno nuevo reliza una subrutina sino sigue en un lazo cerrado el envio de los mensajes.
otro punto yo los guardo de caracter en caracter para separar los datos e ir comparando de caracter en caracter los datos que necesito y listo ya lo tienes aqui esta el codigo con esto esta completo tu proyecto amigo pilas.
como vas a ver a continuacion lo manjeo de caracter en caracter el dato que a mi me sirve es de cir desde donde comienza el mensaje es el caracter 27 asi que ya tienes tu filtro ademas vas a observar la forma como yo comparo para efectuar un evento.
cualquier mejora que le hagas te pido que me avises y lo poostees pues quiero seguir avanzando


Código:
//DEFINICION DE CONSTANTES
//************************
   int n=0x22;    // CODIGO ASCII "
   int cont=0;

//DECLARACION DE VARIABLES
//*************************
   char c1=0,c2=0,c3=0,c4=0,c5=0,c6=0,c7=0,c8=0,c9=0,c10=0,c11=0,c12=0,c13=0,c14=0,c15=0,c16=0,c17=0;
   char c18=0,c19=0,c20=0,c21=0,c22=0,c23=0,c24=0,c25=0,c26=0,c27=0,c28=0,c29=0,c30=0,c31=0,c32=0,c33=0;
   char c34=0,c35=0,c36=0,c37=0,c38=0,c39=0,c40=0,c41=0,c42=0,c43=0,c44=0,c45=0,c46=0,c47=0,c48=0,c49=0;
   char c50=0,c51=0,c52=0,c53=0,c54=0,c55=0,c56=0,c57=0,c58=0,c59=0,c60=0,c61=0,c62=0,c63=0,c64=0,c65=0;
   char c66=0,c67=0,c68=0,c69=0,c70=0,c71=0,c72=0,c73=0,c74=0,c75=0,c76=0,c77=0,c78=0,c79=0,c80=0,c81=0;
   char c82=0,c83=0,c84=0,c85=0,c86=0,c87=0,c88=0,c89=0,c90=0;
//INICIO DE PROGRAMA
//******************
VOID main(VOID) {
//PROGRAMA PRINCIPAL
//*******************
   WHILE (TRUE) {
   c1=0,c2=0,c3=0,c4=0,c5=0,c6=0,c7=0,c8=0,c9=0,c10=0,c11=0,c12=0,c13=0,c14=0,c15=0,c16=0,c17=0;
   c18=0,c19=0,c20=0,c21=0,c22=0,c23=0,c24=0,c25=0,c26=0,c27=0,c28=0,c29=0,c30=0,c31=0,c32=0,c33=0;
   c34=0,c35=0,c36=0,c37=0,c38=0,c39=0,c40=0,c41=0,c42=0,c43=0,c44=0,c45=0,c46=0,c47=0,c48=0,c49=0;
   c50=0,c51=0,c52=0,c53=0,c54=0,c55=0,c56=0,c57=0,c58=0,c59=0,c60=0,c61=0,c62=0,c63=0,c64=0,c65=0;
   c66=0,c67=0,c68=0,c69=0,c70=0,c71=0,c72=0,c73=0,c74=0,c75=0,c76=0,c77=0,c78=0,c79=0,c80=0,c81=0;
   c82=0,c83=0,c84=0,c85=0,c86=0,c87=0,c88=0,c89=0,c90=0;
    delay_ms(2000);
    output_low(pin_A0);
    printf("AT\n\r");
    DELAY_MS(2000);
    printf("AT+CMGF=1\n\r");
    DELAY_MS(2000);
    printf("AT+CPMS=%cME%c\n\r",n,n);
    DELAY_MS(2000);
    printf("AT+CMGL=%cREC UNREAD%c\n\r",n,n);
    c1=getch();c2=getch();c3=getch();c4=getch();c5=getch();c6=getch();c7=getch();c8=getch();c9=getch();
    c10=getch();c11=getch();c12=getch();c13=getch();c14=getch();c15=getch();c16=getch();c17=getch();c18=getch();
    c19=getch();c20=getch();c21=getch();c22=getch();c23=getch();c24=getch();c25=getch();c26=getch();
    //*******************************************************************************
    //*******************************************************************************
     if (c26=='K')   // CHEQUEO SI EXISTE ALGUN MENSAJE DE ACCION O RESPUESTA
        {
        c27=getch();c28=getch();
        c29=getch();c30=getch();c31=getch();c32=getch();c33=getch();c34=getch();c35=getch();c36=getch();
        c37=getch();c38=getch();c39=getch();c40=getch();c41=getch();c42=getch();c43=getch();c44=getch();c45=getch();
        c46=getch();c47=getch();c48=getch();c49=getch();c50=getch();c51=getch();c52=getch();c53=getch();c54=getch();
        c55=getch();c56=getch();c57=getch();c58=getch();c59=getch();c60=getch();c61=getch();c62=getch();c63=getch();
        c64=getch();c65=getch();c66=getch();c67=getch();c68=getch();c69=getch();c70=getch();c71=getch();c72=getch();
        c73=getch();c74=getch();c75=getch();c76=getch();c77=getch();c78=getch();c79=getch();c80=getch();c81=getch();
        c82=getch();c83=getch();c84=getch();c85=getch();c86=getch();c87=getch();c88=getch();c89=getch();c90=getch();
        DELAY_MS(500);
   //*****************************************************************************
            if (c89=='A')   // COMANDO *AE* ACTIVAR ELECTROVALVULA
            {
               if (c90=='E')
               {
                 delay_us(100);
                 output_high(pin_B0);
                 output_low(pin_B2);output_high(pin_C1);
                 delay_us(100);
                }
            }
       //*****************************************************************************
             if (c89=='D') // COMANDO *DE* DESACTIVAR ELECTROVALVULA
             {
              if (c90=='E')
               {
               delay_us(100);
               output_low(pin_B0);
               output_high(pin_B2);output_low(pin_C1);
               delay_us(100);

               }
             }
      //*****************************************************************************
            if (c89=='C')  // COMANDO *CA* CONSUMO ACTUAL
            {
               if (c90=='A')
               {
               delay_us(100);
               output_high(pin_B1);  // activo al master para que transmita datos a la red celular.
               delay_us(100);
               }
            }
        //*****************************************************************************
             if (c89=='B')  // COMANDO *BC* BORRAR CONTADORES SE SEINICIA EL CONSUMO
            {
               if (c90=='C')
               {
               delay_us(100);
               output_high(pin_C2);  // activo al master para que borre contadores
               delay_us(100);
               }
            }
       //*******************************************************************************
        if(input(pin_c0))  // Chequeo si ya termino de transmitir el master a la red celular.
                {
                delay_us(100);
                output_low(pin_b1); //limpio pin de lectura de consumo del master
                output_low(pin_C2); //limpio pin de borrado de contadores
                delay_us(100);
                }
       //*******************************************************************************
             delay_us(1000);
             printf("AT+CMGD=1\n\r");


        }
      //*******************************************************************************
      //*******************************************************************************
      if(c26=='K') // SI NO HAY MENSAJE CHEQUEO EL OK
        {
        delay_us(100);
        output_high(pin_A0);
        delay_us(100);
        }
      //*******************************************************************************
      //*******************************************************************************

  if(input(pin_c0))  // Chequeo si ya termino de transmitir el master a la red celular.
    {
     delay_us(100);
     output_low(pin_b1); //limpio pin de lectura de consumo del master
     output_low(pin_C2); //limpio pin de borrado de contadores
     delay_us(100);
    }
 }
}  // FIN DE PROGRAMA
 
Dios mio!, jejeje. Te comento que pues cada quien se acomoda como puede o siente. Considero que te hubieras ahorrado un buen de espacio y de variables sin todo ese embrollo de los "cXX=getc()" lo hubieras implementado con un "for" y un puntero de memoria o un arreglo de variables. Un posible ejemplo sería:
Código:
for( i=0, i < BUFFSIZE , i++){ // donde BUFFSIZE es el valor máximo del buffer
     CELBUFF[i] = getc();
}
Es una idea general y ya del mismo buffer te auxilias para checar todas las variables o comandos que necesites.
Otra manera para no "desperdiciar" tanta RAM es esta:
Código:
for( i=0, i < BUFFSIZE , i++){ // donde BUFFSIZE es el valor máximo del buffer
     if( i >= OFFSET ){              // Donde OFFSET es el contador donde empezamos a guardar el "texto"
        CELBUFF[i-OFFSET] = getc();// Le restamos el OFFSET para que se guarde desde "cero" en el buffer
     }else  temp = getc();       //Liberamos RXBUFF para el siguiente dato
}
También podemos poner tu "cxx == 'K' " antes de guardar los datos.
Espero esté bien explicado y sirva de ayuda.
Saludos
 
eso te sirve muy bien pero en mi aplicacion no me sirve porque necesito tener almacenados la fecha la hora el numero de donde se envia y el mensaje y como dices no es porque quiero desperdiciar ramm de gusto sino que como dije de esta forma puedes tener almacenado todos los datos que te envia el cell para un posterior procesamiento claro si necesitas tener el control de todo porque es demasiado simple utilizar lo que indicas y de antemano gracias por la observacion
 
Hola como les vá. Al parecer el código es bastante complejo pero voy a encarar el tema desde otro punto de vista para ver que modificaciones puedo hacer.

1° - La plantilla posteada por nestor nieto al principio del post habla de como poder decodificar un PDU sin importar la extensión que tenga y los datos que este lleve.
2° - La plantilla tiene un macro en VB que realiza esa tarea y otras más.
3° - Se podría hacer un programa en VB que tome un mensaje de texto del cel por iterrupción del evento ONCOM. Por lo tanto ya tendriamos un sistema que lee mensajes.
4° - He estudiado como leer posiciones de la memoria del telefono y ver su contenido, asi como también de poder borrar ese contenido.
5° - Lo que se podría hacer es una rutina como la de Rizy pero de la siguiente forma:

a - Establecer la comunicación con el CEL.
b - Si recibimos respuestas positivas de la comunicación , activamos las interrupciones por puerto serie y guardamos todo el mensaje en formato PDU o formato texto.
c - Filtramos las tramas del celular que no sean necesarias.
d - Guardamos en un string el mensaje filtrado con todos sus caracteres.
e - Procesamos el mensaje y según la información que contenga realizamos diferentes acciones.

PD: En cuanto tenga algún código probado les muestro.
 
Hola a todos

Bueno en esta ocación les traigo un programa más que sencillo en donde se muestra como extraer el mensaje de una cadena PDU que recibamos desde el cel. Esta es una versión preliminar para luego poder hacer una aplicación completa que nos permita recibir mensajes desde el CEL.

La aplicación está basada en la plantilla de exel que posteo nestor nieto con anterioridad y está escrita en VB 2005.

Espero les sirva :cool:
 

Adjuntos

  • prueba_en_vb_2005_180.rar
    9 KB · Visitas: 252
Comento que no encuentro todavía la forma de hacer para tomar los datos provenientes desde el cel en formato PDU ( No se como hacer para decodificarlos ).

Voy a ver como puedo hacer para tomar los datos en modo texto... aunque estoy muy trabado con el tema.

Rizi en tu código declaraste que tenés 90 variables. Ahora como se que largo va a tener el texto recibido ?
yo en mi caso solo quiero obtener el texto del mensaje. Como hago para filtrar las demás señales ?
 
en mi codigo si te fijas los caracteres que no te sirven llegan hasta el 26 el resto ya es solo el texto en si del mensaje entonces desde ahi ya puedes ir comparando para ir codificando que evento tiene que ejecutar no es muy dificil intentalo
si logras alguna mejora subela al foro
 
no te confundas en mi codigo declaro que voy a tener 90 variables porque el mensaje que tiene que decodificar el pic es de bastante información asi que no confundas tu tienes que declarar solo los 26 iniciales y el resto ya el mensaje en modo texto desde ahi tu puedes poner las variables que necesites para el manejo de un evento
 
Buenas, en primer lugar quiero agradecerles a todos ya que e seguido desde el principio todo el hilo y gracias a sus comentarios e logrado realizar llamadas y enviar msm con mi pic.
Y tambien quiero activar un relay enviandole un mensaje y todo iba bien esperando que mostraran como hacerlo y lo hicieron pero.....................................lamentablemente no se programar en C solo en asm y me quede re colgado.

Por favor alguien me podria explicar como lograrlo pero en asembler ?
desde ya muchas gracias
 
yo aprendi en asembler pero no me gusto para nada y esta aplicacion creo que se volveria demasiado complicada programar en asembler creao que seria bueno que aprendieras a programar en c o en basic que es mas facil ya que si tu ya programaste todo lo anterior en asembler aprender otro lenguaje sera muy facil para ti y te felicito yo no me hubiera atrevido a programar en asembler esta aplicacion te felicito
 
Realmente no es tán difícil, es cuestión de tener bien claro los comandos para el control usart y el manejo de las variables. De hecho posiblemente sea más comodo con assembler que con el C, porque C en muchas ocasiones usa instrucciones de más.
Es cuestión de configurar bien puertos, variables, el USART, etc.
Para el manejo de las variables una opción rápida es con INDF y FSR.
Es muy posible que sea tequioso y tardado en assembler, pero no es muy difícil.
Saludos
 
Moyano Jonathan dijo:
Parte2: Recepción de SMS y control de procesos

Mis preguntas al respecto:

- Qué metodo para recibir SMS es el más recomendado PDU o modo texto ?
- Qué método para recibir los SMS en el PIC es el más recomendado Interrupciones o función de preguntas respuestas ?


El que tenga información al respecto comente

PD: Mis especiales agradecimientos a los siguientes usuarios:

Rizy
alepic
ericklarva
Nestor nieto


Por la gran ayuda que me han brindado.

Y los demás gracias por los comentarios sobre sus experiencias y logros.

Si quieres mayor compatibilidad debes utilizar el formato PDU, ya que este esta disponible en mayor numero de dispositivos(los que aceptan modo texto tamben aceptan PDU, pero no todos los que aceptan PDU aceptan modo texto).
 
Atrás
Arriba