TODOPIC

Microcontroladores PIC => Todo en microcontroladores PIC => Mensaje iniciado por: martinchd en 18 de Julio de 2018, 02:09:38

Título: Recibir SMS con PIC16f877A y SIM800L
Publicado por: martinchd en 18 de Julio de 2018, 02:09:38
Hola chicos, estoy haciendo un pluviómetro digital con envíos de datos a través de SMS. Tengo un problema, necesito que al enviar una palabra por ejemplo, "Dato" al SIM800L me envie un SMS con el dato del sensor. Me podrian ayudar, la parte de enviar el SMS la tengo.
Título: Re:Recibir SMS con PIC16f877A y SIM800L
Publicado por: KILLERJC en 18 de Julio de 2018, 09:27:59
Que compilador y que trataste de hacer hasta el momento ?

Título: Re:Recibir SMS con PIC16f877A y SIM800L
Publicado por: planeta9999 en 18 de Julio de 2018, 11:49:26
 
Yo no usaría SMS, es una tecnología muy antigua y cara (pagas por mensaje).

El SIM800L creo que tiene GPRS y hoy en día todos los proveedores te ofrecen tarifas planas con al menos 1Gb de datos, solo hay que ver si tienes red 2G con ese operador, y puedes usar el SIM800L por GPRS.

Hasta que agotes 1Gb de datos enviando mensajes cortos por GPRS, puedes gestionar miles de mensajes a coste cero. Además, por GPRS el envío es inmediato, prácticamente instantaneo, mientras que un SMS puede sufrir retrasos considerables en la entrega.
Título: Re:Recibir SMS con PIC16f877A y SIM800L
Publicado por: martinchd en 18 de Julio de 2018, 15:09:15
Que compilador y que trataste de hacer hasta el momento ?

KILLERJC uso compilador CCS  hasta el momento tengo esto.


Título: Re:Recibir SMS con PIC16f877A y SIM800L
Publicado por: martinchd en 18 de Julio de 2018, 15:12:03

Yo no usaría SMS, es una tecnología muy antigua y cara (pagas por mensaje).

El SIM800L creo que tiene GPRS y hoy en día todos los proveedores te ofrecen tarifas planas con al menos 1Gb de datos, solo hay que ver si tienes red 2G con ese operador, y puedes usar el SIM800L por GPRS.

Hasta que agotes 1Gb de datos enviando mensajes cortos por GPRS, puedes gestionar miles de mensajes a coste cero. Además, por GPRS el envío es inmediato, prácticamente instantaneo, mientras que un SMS puede sufrir retrasos considerables en la entrega.

Planeta9999 - El tema que el pluviometro va en el campo y con duras penas se puede enviar un sms. es un sms al dia no seria tanto el costo y por el retardo del sms no seria problema.
Título: Re:Recibir SMS con PIC16f877A y SIM800L
Publicado por: martinchd en 18 de Julio de 2018, 15:15:31
Código: C++
  1. #include <16F877.h>
  2. #FUSES XT,NOWDT,NOPROTECT,PUT,NOBROWNOUT,NOLVP    
  3. #use delay(clock=4M)
  4.                
  5. #include <lcd.c>
  6. #use fast_io(a)
  7. #use fast_io(b)
  8. #use RS232(BAUD=9600,BITS=8,PARITY=N,XMIT=PIN_C6,RCV=PIN_C7)
  9.  
  10. //***************************manejo del hc-sr04 *******************************
  11. #define pin_tigger pin_a5
  12. #define pin_echo pin_a4
  13. #define NoDetect_mili 38
  14. #define Nodetect_micro 38000
  15.  
  16. //*******************declaracion de variables globales*************************
  17.          float temperatura_ambiente= 20.0;                                       //se guardara la temperatura medida por el sensor Lm 35, global.
  18.          int input=1;
  19.                  
  20. //************************declaracion de funciones*****************************
  21.                                                      
  22. //***********************control de interrupciones*****************************
  23.  
  24.  
  25. //*****************************Funcion principal*******************************
  26.          void main(){                                                           //funcion principal.
  27.          
  28.          set_tris_a(0x10);                                                     //a4 como entrada(echo sensor ultrasonico) resto como salida.
  29.          output_low(pin_tigger);                                               //se asegura que no comenzara encendido el sensor de distancia.
  30.          set_tris_b(0x00);                                                     //puerto b todo como salida(display lcd ).
  31.          lcd_init();                                                           //incializa el lcd.
  32.          printf(LCD_PUTC, "\f  Iniciando.\n");
  33.          delay_ms(20000);                                                      //Tiempo hasta que SIM800L tome señal
  34.          setup_timer_1(T1_INTERNAL|T1_DIV_BY_1);                               //configura timer 1: modo reloj con paso de 1 micro seg a 4MHZ.
  35.          disable_interrupts(GLOBAL);                                           //deshabilito interrupción.
  36.          
  37. //******************************Ciclo infinito*********************************
  38.          int16 tiempo_micro;                                                   //variable que guarda la captura del timer 1 en microseg(tiempo de ida y vuelta del eco).
  39.          float tiempo_mili;                                                    //variable que guarda la captura del timer 1 en miliseg(tiempo de ida y vuelta del eco).
  40.          
  41.          while(true){                                                          //ciclo infinito principal.
  42.                                                                                //adbvierte si es true que el mensaje de error ya si imprimio.
  43.          while(true){                                                          //ciclo infinito 2.
  44.          
  45.          output_high(pin_tigger);                                              //manda pulso de 10 micro segundos para exitar al sensor.
  46.          delay_us(10);                                                         //
  47.          output_low(pin_tigger);                                               //termina pulso de excitacion.                
  48.  //******************detecta error del sensor hc-sr04**************************        
  49.          set_timer1(1);                                                        //tiempo de espera al sensor maximo: antes de declarar error.
  50.          while(!input(pin_echo) && get_timer1() <10000) {}                     //solo saldra de este ciclo si: el senso puso la salida en alto o  si termino el tiempo estimado para lo anteior.
  51.          if(input(pin_echo)) break;                                            //cambio el pin_echo a alto(sensor funcionando) salta a la primera linea despues del ciclo infinito actual.
  52.                                                                                            
  53.          else {
  54.          printf(LCD_PUTC, "\f sensor digital\n");                              //si: imprime falla en el sensor.
  55.          printf(LCD_PUTC, "No resp...\n");                                     //
  56.          printf(LCD_PUTC, "tiempo agotado!");                                  //
  57.          delay_ms(100); }                                                      //
  58.          }                                                                     //fin ciclo infinito 2.
  59.  //****************************************************************************        
  60.          //get_timer1();                                                       //detiene el timer 1.
  61.          set_timer1(0);                                                        //cambio: carga el tmr1 y comienza una nueva cuenta.
  62.          while(input(pin_echo)) {}                                             //espere a que el pin echo cambie a bajo(retorno del eco).
  63.          
  64.          tiempo_micro = get_timer1();                                          //guarda el tiempo que duro en regresar el pulso(reloj timer 1) en la variable: tiempo_rebote.
  65.          
  66.          float distancia;                                                      //guarda el valor del timer 1 en la medida del rebote ultrasonico por el hc-sr04
  67.          //calculamos la distancia:
  68.          distancia =90-((((tiempo_micro * 0.000001)*(331.4 + (0.61 * temperatura_ambiente)))/2)*1000);
  69.          //se divide entre dos por que la distancia sera el doble ya que la señal tendra que retornar.
  70.                    
  71.            
  72.          
  73.          tiempo_mili = tiempo_micro * 0.001;                                   //convierte micro a milisegundos(comentar para dejar en microseg y cambiar abajo por micro).
  74.                  
  75.          if(tiempo_mili >= NoDetect_mili){                                     //fuera de rango?
  76.          printf(lcd_putc, "\f Sensor Digital\n");                              //si: imprime mensaje fuera de rango.
  77.          printf(LCD_PUTC, "Tiempo= %f ms\n",tiempo_mili);                      //muestra el tiempo.
  78.          printf(LCD_PUTC, "Dist= NO");                                         //
  79.          delay_ms(200);                                                        //
  80.          continue; }                                                           //vuelve a la iteraccion principal(while).
  81.          
  82.          printf(lcd_putc, "\f Sensor Digital\n");
  83.          printf(LCD_PUTC, "Lluvia= %f mm ",distancia);
  84.          delay_ms(200);
  85.             if(input==1)
  86.                   {
  87.                         delay_ms(500);
  88.                         delay_ms(5000);
  89.                         char sms[20];
  90.                        
  91.                         sprintf(sms,"%f",distancia);
  92.                         printf("AT+CMGF=1\r\n");  // Seleccionor modo texto
  93.                         delay_ms(500);                
  94.                                                  // Enviar SMS al numero
  95.                         printf("AT+CMGS=\"xxxxxxxxxx\"\r\n");
  96.                         delay_ms(500);
  97.                                                  // Con el texto
  98.                         printf("Lluvia caida -> %s mm \n\n    --> AGRODATA <--  \r\n",sms);                
  99.                         delay_ms(500);
  100.                                                  // Se envia el SMS
  101.                         putchar(0x1a);
  102.                      
  103.                         delay_ms(3000);
  104.                         printf("AT+CMGF=1\r\n");  // Seleccionor modo texto
  105.                         delay_ms(500);                
  106.                                                  // Enviar SMS al numero
  107.                         printf("AT+CMGS=\"xxxxxxxxxx\"\r\n");
  108.                         delay_ms(500);
  109.                                                  // Con el texto
  110.                         printf("Lluvia caida -> %s mm \n\n    --> AGRODATA <--  \r\n",sms);                
  111.                         delay_ms(500);
  112.                                                  // Se envia el SMS
  113.                         putchar(0x1a);
  114.                         delay_ms(500);
  115.                         printf("\r\n");
  116.                         input++;
  117.                   }
  118.          delay_ms(80);
  119.          
  120.                  
  121.          }    
  122.          }
Título: Re:Recibir SMS con PIC16f877A y SIM800L
Publicado por: KILLERJC en 18 de Julio de 2018, 15:34:06
Primero que nada cambiale cuanto antes los numeros de telefono a tu codigo.

Segundo, podrias hacer que envie el mensaje solo si cambio algo, si sigue igual entonces no. Asi reducis el costo, y no tiene caso avisar si no cambio nada.

Y para esto:

Citar
necesito que al enviar una palabra por ejemplo, "Dato" al SIM800L me envie un SMS con el dato del sensor.
Primero necesitas leer los mensajes con:

Código: [Seleccionar]
AT+CMGR=<index>[,<mode>]
Si no pones el modo, es normal, la idea es que leas siempre el indice 0. El cual puede devolver cualquiera de estas respuestas:

Citar
1) If text mode (+CMGF=1) and Command successful:
for SMS-DELIVER:
+CMGR: <stat>,<oa>[,<alpha>],<scts>[,<tooa>,<fo>,<pid>,<dcs>,<sca>,<tosca>,<length>]<CR><LF><data>
for SMS-SUBMIT:
+CMGR: <stat>,<da>[,<alpha>][,<toda>,<fo>,<pid>,<dcs>[,<vp>],<sca>,<tosca>,<length>]<CR><LF><data>
for SMS-STATUS-REPORTs:
 Smart Machine Smart Decision
SIM800 Series_AT Command Manual_V1.09 118 2015-08-03
+CMGR: <stat>,<fo>,<mr>[,<ra>][,<tora>],<scts>,<dt>,<st>
for SMS-COMMANDs:
+CMGR: <stat>,<fo>,<ct>[,<pid>[,<mn>][,<da>][,<toda>],<length><CR><LF><cdata>]
for CBM storage:
+CMGR: <stat>,<sn>,<mid>,<dcs>,<page>,<pages><CR><LF><data>
2) If PDU mode (+CMGF=0) and Command successful:
+CMGR: <stat>[,<alpha>],<length><CR><LF><pdu>
OK

3) If error is related to ME functionality:
+CMS ERROR: <err>

Leido ese pedazo de texto, luego te queda discriminar el dato... del dato revisar si aparece la palabra "Dato" o si queres asegurarte que convierta cualquier mayuscula en minuscula y luego lo comapre con "dato". Si lo encuentra procedes a enviar el mensaje

Y finalmente borrar el mensaje:

Código: [Seleccionar]
AT+CMGD=<index>[,<delflag>]
Título: Re:Recibir SMS con PIC16f877A y SIM800L
Publicado por: martinchd en 18 de Julio de 2018, 15:53:06
si eso lo tengo entendido.. como hago para discriminar lo que me envia el SIM al PIC y solo comparar la palabra "Dato". 

Alto asi.

while (true){
IF (kbhit () ){                //Detecto si hay un carácter en la entrada
gets(dato);                   //Leer Mensaje de llegada después del enter que envía el SIM900
}

if(dato[1]== 'D' &&dato[2]== 'a' &&dato[3]=='t' &&dato[4]=='o'){   //Detecta si el mensaje dice "Dato"

o ahi estoy comparando los primeros 4 caracteres que me devuelve el SIM de la funcion AT + CMGR que es

+CMGR: "REC READ","+xxxxxxxxxxxx",,"07/02/18,00:12:05+32"
Dato
Título: Re:Recibir SMS con PIC16f877A y SIM800L
Publicado por: KILLERJC en 18 de Julio de 2018, 17:33:00
Algo parecido. Primero envias para leer, luego con el gets vas a conseguir primero esto:

Código: [Seleccionar]
+CMGR: "REC READ","+xxxxxxxxxxxx",,"07/02/18,00:12:05+32"
El dato va a quedar aparte.. si usas de nuevo el gets deberias conseguir lo que sigue.
El problema es que si el SIM no envia una <CR><LF> luego del mensaje no va a salir hasta que llegue un nuevo <CR><LF>.

Para comparar podes usar la funcion strncmp

Código: C
  1. int strncmp(const char *str1, const char *str2, size_t n)

Y lo usarias asi:
Código: C
  1. if (strncmp(dato,"Dato",4) == 0)
  2. {
  3.    // lo enviado comienza con "Dato"
  4. }

Observa que solo observo los 4 primeros valores, asi que "Datoaeqweqworioqerowehrioe" es valido tambien.
Se podria usar strcmp, pero al no tener un limite de caracteres, si es que el array dato[] no posee una finalizacion con un caracter nulo, nunca va a terminar

PD: Recorda que el array dato, deberia poder guardar toda la cadena que le llegue.

-----------------------------------------------

La otra es usar getc en ves de gets, asi recibis caracter por caracter.
Título: Re:Recibir SMS con PIC16f877A y SIM800L
Publicado por: martinchd en 19 de Julio de 2018, 00:31:41
te referis a usar primero un gets, el cual me toma lo q retorna el SIM y luego otro gets(sms) con el contenido del msj?

algo asi..

char msj[]="Dato";
printf("AT+CMGR=1\r");
gets(SIM);
gets(SMS);

estuve viendo la funcion strcmp() -> que compara dos string podria ser?

usandola asi..


if (strcmp(SMS,msj)==0)
  {
       // el sms coincide con la palabra "Dato"
  }




podria ser algo asi ??


muchisimasssss gracias por la ayuda  KILLERJC    ((:-)) :)
Título: Re:Recibir SMS con PIC16f877A y SIM800L
Publicado por: KILLERJC en 19 de Julio de 2018, 10:17:53
Citar
podria ser algo asi ??

Si, pero voy a darte un par de cosas que debes tener en cuenta:

- Necesitas verificar que lo que llego sea realmente la respuesta de lo que pediste. es decir que SIM contenga al menos "+CMGR" al comienzo, Esto lo podes hacer con strncmp (observa la n enrte medio)
- Si no se envia ningun <CR><LF> luego del mensaje de texto el gets va a tener no solo el mensaje de texto sino cualquier otra cosa que le llegue, asi que si usas strcmp puede que no te lo tome como correcto. Ejemplo, si llega algo asi:

SMS = "Dato+CMGR: \"REC READ\",\"+xxxxxxxxxxxx\",,\"07/02/18,00:12:05+32\""

strcmp(SMS,msj) // Esto va a fallar.
strncmp(SMS,msj,sizeof msj)  // Esto va a funcionar.

Y no solo eso si no que vas a tener que esperar alguna otra respuesta si no posee el <CR><LF>

- Preparate para recibir el mensaje mas largo posible, o utiliza otro metodo para que lo que recibis no sea excesivamente largo. Lo peor que puede pasar es que tengas un array chico, como uno de 10 lugares y quieras escribirle 15, produciendo un overflow y muchos problemas mas. Una de las quejas de C es que esto debe ser tomado en cuenta por el programador y no hay nada que el compilador te advierta o en runtime te avise.
Título: Re:Recibir SMS con PIC16f877A y SIM800L
Publicado por: martinchd en 20 de Julio de 2018, 00:25:39
pero el SIM no lo envia simpre al final <CR><LF>. ?
Título: Re:Recibir SMS con PIC16f877A y SIM800L
Publicado por: KILLERJC en 20 de Julio de 2018, 00:45:23
Al menos el datasheet no muestra nada, podrias ver si realmente ocurre, para mi si deberia hacerlo, pero el PDF que encontre no dice nada.
Título: Re:Recibir SMS con PIC16f877A y SIM800L
Publicado por: martinchd en 20 de Julio de 2018, 02:14:26
trate de varias formar y no logro tomar el contenido del SMS. estoy tratando primero de obtener el contenido del SMS que seria la palabra "Dato" y mostrarla en un LCD.
Este es el programa que probé.




Código: C
  1. #include <16F877a.h>
  2. #include <stdio.h>
  3. #include <string.h>
  4. #use delay(clock = 4000000)
  5. #fuses XT,NOWDT,NOLVP
  6. #use fast_IO(B)  
  7. #use RS232(BAUD=9600,BITS=8,PARITY=N,XMIT=PIN_C6,RCV=PIN_C7)
  8. #include <lcd.c>
  9.  
  10. char msj[]="Dato";
  11. char SMS[];
  12. char SIM[];
  13.  
  14.  
  15. void main()
  16.  
  17.    {
  18.    
  19.     set_tris_b(0x00);
  20.     lcd_init();
  21.     delay_ms(200);
  22.     printf(lcd_putc,"Please wait... \n");
  23.     delay_ms(9000);
  24.     printf("AT+CMGF=1\r");
  25.    
  26.     while (true)
  27.         {
  28.          printf(lcd_putc,"\f Esperando SMS \n");
  29.          printf("AT+CMGR=1\r");
  30.          delay_ms(200);
  31.          gets(SIM);
  32.          delay_ms(200);
  33.          gets(SMS);
  34.          delay_ms(200);
  35.          if(strncmp(SMS,msj,sizeof msj)==0)
  36.            {
  37.             printf(lcd_putc,"\f Llego un SMS \n");
  38.             delay_ms(500);
  39.             printf(lcd_putc,"SMS = %c",SMS);
  40.             printf("AT+CMGL=ALL");
  41.            }
  42.          
  43.         }
  44.    }
Título: Re:Recibir SMS con PIC16f877A y SIM800L
Publicado por: KILLERJC en 20 de Julio de 2018, 12:28:31
Esto esta mal:

Código: C
  1. char SMS[];
  2. char SIM[];

Los delays SON MALOS en la recepcion, lo mejor es que comiences a usar interrupciones
Usa uno solo... total se reescribe:

Código: C
  1. char SMS[60];
  2.  
  3. void main()
  4.  
  5.    {
  6.    
  7.     set_tris_b(0x00);
  8.     lcd_init();
  9.     delay_ms(200);
  10.     printf(lcd_putc,"Please wait... \n");
  11.     delay_ms(9000);
  12.      
  13.     while (true)
  14.         {
  15.          printf(lcd_putc,"\f Esperando SMS \n");
  16.          delay_ms(500);
  17.          printf("AT+CMGR=1\r");
  18.          gets(SMS);
  19.          gets(SMS);
  20.          SMS[15] = '\0';   // En caso de que sea mucho mas grande que el LCD.... solo por las dudas
  21.          printf(lcd_putc,"%s",SMS);
  22.  //      if(strncmp(SMS,msj,sizeof msj)==0)
  23.  //      {
  24.  //      }
  25.          delay_ms(2000);    // Una pequeña espera mas antes de enviar de nuevo.
  26.    }

Proba algo asi... La idea es que no existan "delays" entre medio, y muestre lo que tiene SMS sea lo que sea... Si ahi dentro comienza con Dato, bueno ya podes avanzar y usar el strncmp, si no lo dice, lo mejor es probar de forma externa con algun conversor USB-TTL y para ver como es la respuesta que envia.
Título: Re:Recibir SMS con PIC16f877A y SIM800L
Publicado por: martinchd en 21 de Julio de 2018, 15:56:04
Lo probe y no funciona!!!   :5] 

probe algo asi y tampoco funciona.


Código: C
  1. char SMS[60];
  2.  
  3. void main()
  4.  
  5.    {
  6.    
  7.     set_tris_b(0x00);
  8.     lcd_init();
  9.     delay_ms(200);
  10.     printf(lcd_putc,"Please wait... \n");
  11.     delay_ms(9000); //Tiempo hasta que inicie SIM00L
  12.      
  13.     while (true)
  14.         {
  15.          printf(lcd_putc,"\f Esperando SMS \n");
  16.          delay_ms(500);
  17.          IF (kbhit () )
  18.                { //Detecto si hay un carácter en la entrada
  19.                 gets(SMS); //Leer Mensaje de llegada después del enter que envía el SIM800
  20.                 SMS[15] = '\0';   // En caso de que sea mucho mas grande que el LCD.... solo por las dudas
  21.                 printf(lcd_putc,"%s",SMS);
  22.                
  23.  //      if(strncmp(SMS,msj,sizeof msj)==0)
  24.  //      {
  25.  //      }
  26.          delay_ms(2000);    // Una pequeña espera mas antes de enviar de nuevo.
  27.                }
  28.         }
  29.    }
Título: Re:Recibir SMS con PIC16f877A y SIM800L
Publicado por: KILLERJC en 21 de Julio de 2018, 20:13:27
Que es lo que llega por la UART?

Tal ves estes recibiendo otra cosa que no es lo que vos crees.
Título: Re:Recibir SMS con PIC16f877A y SIM800L
Publicado por: martinchd en 22 de Julio de 2018, 16:54:49
lo probe grabando el pic y no me imprime nada en el lcd.
Título: Re:Recibir SMS con PIC16f877A y SIM800L
Publicado por: KILLERJC en 22 de Julio de 2018, 18:15:41
Estamos partiendo de que el SIM regresa exactamente eso, sabemos si esta regresando al menos algo ?
Es muy dificil tratar de "solucionar" algo que ni siquiera se sabe el porque esta fallando.

Y te lo vuelvo a decir, NO uses delays. El PIC solo puede guardar 1 solo caracter, maximo 2 en las familias mas bajas, si llega otro debido a que esta en el delay tendrias un problema.
Deberias recibir por interrupciones o de ultima en caso de prueba quitar las demoras.

Sabiendo lo que llega luego podes programar lo que deseas, lo mas simple es usar un conversor TTL-USB para enviarle el comando al SIM y ver que devuelve.
Título: Re:Recibir SMS con PIC16f877A y SIM800L
Publicado por: martinchd en 22 de Julio de 2018, 23:08:18
no estoy muy lucho en esta parte de programación.
con interrupción como lo podria hacer?
Título: Re:Recibir SMS con PIC16f877A y SIM800L
Publicado por: KILLERJC en 23 de Julio de 2018, 21:56:05
Algo asi.. realmente no uso CCS, y seguramnte tenga errores:

Código: C
  1. char bufferRX[2][17];
  2. int8 indiceBuff = 0;
  3. int8 indice = 0;
  4. int1 mostrar;
  5.  
  6. #int_rda
  7. void serial_isr() {
  8.  
  9.   if(kbhit()){
  10.     bufferRX[indiceBuff][indice] = getc();
  11.     indice++;
  12.     if(indice >= sizeof bufferRX)
  13.     {
  14.       indice = 0;
  15.       bufferRX[indiceBuff][16] = '\0'; //Una proteccion por las dudas
  16.       indiceBuff ^= 1;
  17.       mostrar = 1;
  18.     }
  19.   }
  20. }
  21.  
  22.  
  23. void main()
  24. {
  25.    
  26.     set_tris_b(0x00);
  27.     lcd_init();
  28.     delay_ms(200);
  29.     printf(lcd_putc,"Please wait... \n");
  30.     delay_ms(9000); //Tiempo hasta que inicie SIM00L
  31.    
  32.     enable_interrupts(int_rda);
  33.     enable_interrupts(global);
  34.  
  35.     while(TRUE)
  36.     {
  37.       if(mostrar)
  38.       {
  39.         mostrar = 0;
  40.         printf(lcd_putc,"\f%s",&bufferRX[indiceBuff^1][0]);
  41.       }
  42.     }
  43. }
Título: Re:Recibir SMS con PIC16f877A y SIM800L
Publicado por: martinchd en 24 de Julio de 2018, 00:03:34
Dale KILLERJC voy a jugar un rato con estoy y te comento los resultados.. Muchas gracias...  ((:-)) ((:-)) ((:-)) ((:-)) ((:-)) 8) 8) 8)
Título: Re:Recibir SMS con PIC16f877A y SIM800L
Publicado por: martinchd en 24 de Julio de 2018, 01:36:41
En el If(mostrar) no tendria q ir alguna sentencia.. ? 
Título: Re:Recibir SMS con PIC16f877A y SIM800L
Publicado por: KILLERJC en 24 de Julio de 2018, 09:32:12
En el If(mostrar) no tendria q ir alguna sentencia.. ?

el contenido del if, tenes 2 posibilidades, si es 0 es igual a falso, si es cualquier otro valor es igual a verdadero. asi que si mostrar es 1 va a entrar.

Me olvide de poner alguna sentencia para que le escriba al SIM, ponelo ANTES del while, sin delays entre medio.
La idea del codigo es tener 2 buffer de 16 bytes. Llena un buffer y habilita para que se muestre en el LCD, mientras cambia de buffer y comienza a llenar el otro y asi continuamente. rogando que lo del LCD no sea tan lento como que se llene el buffer antes.
Título: Re:Recibir SMS con PIC16f877A y SIM800L
Publicado por: martinchd en 25 de Julio de 2018, 15:28:45
a que te referís a una sentencia para que le escriba al SIM..
Título: Re:Recibir SMS con PIC16f877A y SIM800L
Publicado por: martinchd en 25 de Julio de 2018, 18:38:13
una duda.. yo cuando envio un sms del telefono al modulo SIM800L, inmediatamente me manda una cadena de caracter al puerto UART ?
si es asi. cual seria esa cadena de caracter ?
Título: Re:Recibir SMS con PIC16f877A y SIM800L
Publicado por: KILLERJC en 25 de Julio de 2018, 20:52:16
Tenes que configurarlo con el +CNMI y luego vas a recibir los mensajes que corresponden apenas llega un SMS:

https://www.developershome.com/sms/resultCodes3.asp
Título: Re:Recibir SMS con PIC16f877A y SIM800L
Publicado por: martinchd en 26 de Julio de 2018, 00:43:20
cuando lo compilo me tira este Warning.. en el While...  tenes idea cual es el motivo?

Interrupts disabled during call to prevent re-entrancy:

Título: Re:Recibir SMS con PIC16f877A y SIM800L
Publicado por: KILLERJC en 26 de Julio de 2018, 09:18:40
Que codigo?
Título: Re:Recibir SMS con PIC16f877A y SIM800L
Publicado por: martinchd en 26 de Julio de 2018, 23:23:01
En el ciclo while me lo tira. Me marca las llave del ciclo.
Título: Re:Recibir SMS con PIC16f877A y SIM800L
Publicado por: KILLERJC en 26 de Julio de 2018, 23:46:35
No se donde es que ve que posiblemente exista una re-entrada, pero es cualquiera el warning que tira.
Título: Re:Recibir SMS con PIC16f877A y SIM800L
Publicado por: martinchd en 28 de Julio de 2018, 09:41:09
La verdad que me esta haciendo renegar bastante... ya me ira a salir.    :D :D :D :D :D
Título: Re:Recibir SMS con PIC16f877A y SIM800L
Publicado por: martinchd en 08 de Agosto de 2018, 11:19:47
No me doy cuenta en que me estoy equivocando, no puedo recibir SMS.

Código: C
  1. #include <16F877a.h>
  2. #include <stdio.h>
  3. #include <string.h>
  4. #use delay(clock = 4000000)
  5. #fuses XT,NOWDT,NOLVP
  6. #use fast_IO(B)  
  7. #use RS232(BAUD=9600,BITS=8,PARITY=N,XMIT=PIN_C6,RCV=PIN_C7)
  8. #include <lcd.c>
  9.  
  10. char bufferRX[2][17];
  11. int8 indiceBuff = 0;
  12. int8 indice = 0;
  13. int1 mostrar;
  14.  
  15. #int_rda
  16. void serial_isr() {
  17.  
  18.   if(kbhit()){
  19.     bufferRX[indiceBuff][indice] = getc();
  20.     indice++;
  21.     if(indice >= sizeof bufferRX)
  22.     {
  23.       indice = 0;
  24.       bufferRX[indiceBuff][16] = '\0'; //Una proteccion por las dudas
  25.       indiceBuff ^= 1;
  26.       mostrar = 1;
  27.     }
  28.   }
  29. }
  30.  
  31.  
  32. void main()
  33. {
  34.    
  35.     set_tris_b(0x00);
  36.     lcd_init();
  37.     delay_ms(200);
  38.     printf(lcd_putc,"Please wait... \n");
  39.     delay_ms(9000); //Tiempo hasta que inicie SIM00L
  40.     printf(lcd_putc," \fEsperando SMS... \n");
  41.    
  42.     enable_interrupts(int_rda);
  43.     enable_interrupts(global);
  44.    
  45.     printf("AT+CNMI=2,2,0,0,0");
  46.     printf("AT+CMGF=1");
  47.    
  48.     while(TRUE)
  49.     {
  50.       if(mostrar)
  51.       {
  52.         mostrar = 0;
  53.         printf(lcd_putc,"\f%s",&bufferRX[indiceBuff^1][0]);
  54.       }
  55.     }
  56. }


Título: Re:Recibir SMS con PIC16f877A y SIM800L
Publicado por: martinchd en 03 de Septiembre de 2018, 18:44:00
Hola.. retome con el proyecto, conecte el modulo a HyperTerminal y cuando llega un sms el modulo manda por puerte serie esto:

+CMT: "+5493534xxxxxx","","18/09/01,19:14:34-12"
Prueba

lo estoy haciendo por interrupcion y cuando llega el sms al puerto UART lo almaceno en un buffer. lo que no sabria es en que posicion del buffer comienza el cuerpo del sms.

Código: C++
  1. #include <16F877a.h>
  2. #include <stdio.h>
  3. #include <string.h>
  4. #use delay(clock = 4000000)
  5. #fuses DEBUG,XT,NOWDT,NOPUT,NOPROTECT,NOBROWNOUT,NOCPD
  6. #use fast_io(a)
  7. #use fast_io(b)  
  8. #use RS232(BAUD=9600,BITS=8,PARITY=N,XMIT=PIN_C6,RCV=PIN_C7)
  9. #include <lcd.c>
  10.  
  11. char dato [80];
  12. int a=0;
  13. int b=0;
  14. char c=0;
  15.  
  16. #int_rda
  17. void serial_isr ()
  18.    {
  19.     if (kbhit())
  20.       {
  21.        c=getc();
  22.        dato[b]=c;
  23.        b++;
  24.       }
  25.    }
  26.    
  27. void borrar_array()
  28.    {
  29.      for(a=0;a<75;a++)
  30.       {
  31.       dato[a]=0;
  32.       delay_ms(50);
  33.       }
  34.    a=0;
  35.    b=0;
  36.    c=0;
  37.    }
  38.  
  39. void main()
  40.    {
  41.    
  42.    set_tris_a (0x00) ;
  43.    output_high(pin_a3);     // Tiempo hasta que toma señal el modulo
  44.       delay_ms(3000);      
  45.    output_low(pin_a3);      
  46.       delay_ms(3000);      
  47.    output_high(pin_a3);
  48.       delay_ms(3000);  
  49.    output_low(pin_a3);
  50.       delay_ms(3000);
  51.    output_high(pin_a3);
  52.       delay_ms(3000);  
  53.    output_low(pin_a3)
  54.    ;
  55.    enable_interrupts(global);
  56.    enable_interrupts(int_rda);
  57.    
  58.    printf("AT+CMGF=1\n\r");
  59.    printf("AT+CNMI=2,2,0,0,0\n\r");
  60.    printf("AT+CMGL=1,4\n\r"); //BORRAMOS SMS
  61.    borrar_array();
  62.    
  63.    
  64.    while(true)
  65.     {
  66.      
  67.       if(dato[75]=='D' &&dato[76]=='a' &&dato[77]=='t' &&dato[78]=='o')
  68.       {
  69.       output_high(pin_a3);
  70.       delay_ms(3000);delay_ms(3000);delay_ms(3000);  
  71.       output_low(pin_a3);
  72.       printf("AT+CMGL=1,4\n\r"); //BORRAMOS SMS
  73.       borrar_array();
  74.       }
  75.      
  76.     }  
  77.    }

Título: Re:Recibir SMS con PIC16f877A y SIM800L
Publicado por: KILLERJC en 03 de Septiembre de 2018, 22:44:07
podes contar las comas, esperar un CR LF... Va a depender del la respuesta del SIM800.
Título: Re:Recibir SMS con PIC16f877A y SIM800L
Publicado por: martinchd en 04 de Septiembre de 2018, 18:43:36
se puede hacer también con strstr() ??? de esta forma?

Código: C++
  1. while(true)
  2.     {
  3.      
  4.       if(strstr(sms_in,dato)!=NULL)
  5.       {
  6.       output_high(pin_a3);
  7.       delay_ms(3000);delay_ms(3000);delay_ms(3000);  
  8.       output_low(pin_a3);
  9.       printf("AT+CMGD=1,4\n\r"); //BORRAMOS SMS
  10.       borrar_array();
  11.       }
  12.      
  13.     }
Título: Re:Recibir SMS con PIC16f877A y SIM800L
Publicado por: KILLERJC en 04 de Septiembre de 2018, 23:57:55
Si podrias.

Pero para que funcione tu ejemplo se deben cumplir dos cosas.

1 - sms_in debe estar completo antes de entrar en el while, sino no tiene sentido.
2 - Se supone que tu substring (dato) se encuentra una unica ves en sms_in, y sea "especial" y unico.
Título: Re:Recibir SMS con PIC16f877A y SIM800L
Publicado por: martinchd en 05 de Septiembre de 2018, 09:42:14
A estar completo te referís a que el string que tiene que tener la cantidad de caracteres que le declaro ? porque ese es el motivo por el cual no puedo hacerlo por ubicación en el string, porque no logro saber cual es la longitud del string, sabiendo que el modulo de devuelve esto. -> 

+CMT: "+5493534xxxxxx","","18/09/01,19:14:34-12"
Dato



Si si.. la palabra Dato, va a estar una sola vez en el string.
Título: Re:Recibir SMS con PIC16f877A y SIM800L
Publicado por: KILLERJC en 05 de Septiembre de 2018, 12:25:14
Citar
A estar completo te referís a que el string que tiene que tener la cantidad de caracteres que le declaro ?

Me refiero a que que pasaria si en el array tenes mas cosas supongamos esto y Dato no completo.
Código: [Seleccionar]
+CMzz: Zzzz,zzz,zzzzzzzzz,zzzzzzzzz,zzzzz,zzzz,zzz
+CMT: "+5493534xxxxxx","","18/09/01,19:14:34-12"
Da

No se como llenas el array vos, pero supongamos que llenas desde el 0 hasta el maximo del array y volves a llenar desde 0, te puede suceder esto:

Código: [Seleccionar]
to+CMzz: Zzzz,zzz,zzzzzzzzz,zzzzzzzzz,zzzzz,zzzz,zzz
+CMT: "+5493534xxxxxx","","18/09/01,19:14:34-12"
Da

La unica que se me ocurre es... Esperar por +CMT, cuando se encuntre CMT, esperar por el CR o LF que envia antes del mensaje, Encontrado cualquiera de los 2 caracteres empezar a guardar en un array el mensaje.

Pero esto lo trabajas en la interrupcion cuando esta llegando el mensaje letra a letra, y no tomar todo junto.
Título: Re:Recibir SMS con PIC16f877A y SIM800L
Publicado por: martinchd en 05 de Septiembre de 2018, 14:01:23
el CR y LF, en que posición es que llega en el mensaje?
Título: Re:Recibir SMS con PIC16f877A y SIM800L
Publicado por: KILLERJC en 05 de Septiembre de 2018, 17:32:06
Antes de "Dato", y luego de cualquier respuesta del SIM800


+CMzz: Zzzz,zzz,zzzzzzzzz,zzzzzzzzz,zzzzz,zzzz,zzz   <- Aca un CR LF
+CMT: "+5493534xxxxxx","","18/09/01,19:14:34-12" <- Aca un CR LF
Dato <- Aca un CR LF
OK  <- Aca un CR LF
Título: Re:Recibir SMS con PIC16f877A y SIM800L
Publicado por: martinchd en 05 de Septiembre de 2018, 20:00:23
Esta mal esta interrupción para que solo me guarde en el buffer lo que yo quiero.

Código: C++
  1. #int_rda
  2. void serial_isr ()
  3.    {
  4.     if (kbhit())
  5.       {
  6.        c=getc();
  7.       if (c=="D"){sms_in [0]=c;}else continue;
  8.       if (c=="a"){sms_in [1]=c;}else continue;
  9.       if (c=="t"){sms_in [2]=c;}else continue;
  10.       if (c=="o"){sms_in [3]=c;}else continue;
  11.        
  12.       }
  13.    }
Título: Re:Recibir SMS con PIC16f877A y SIM800L
Publicado por: KILLERJC en 06 de Septiembre de 2018, 08:35:25
Que pasaria con tu codigo si te llega esto:

Código: [Seleccionar]
Dxxxxxaxxxxxtxxxxxo
Si vas a esperar Dato perfectamente y queres lo mas simple de realizar, entonces:

Código: C
  1. #int_rda
  2. void serial_isr ()
  3.    {
  4.     if (kbhit())
  5.       {
  6.         sms_in[0] = sms_in[1];
  7.         sms_in[1] = sms_in[2];
  8.         sms_in[2] = sms_in[3];
  9.         sms_in[4] = getc();
  10.         sms_in[5] = 0x00;
  11.         if(!strcmp(sms_in,"Dato"))
  12.         {
  13.           //Llego Dato
  14.         }
  15.       }
  16.    }

Lo anterior se puede realizar con un memcpy, pero es para que lo veas
Título: Re:Recibir SMS con PIC16f877A y SIM800L
Publicado por: martinchd en 06 de Septiembre de 2018, 10:05:21
porque decis que me puede llegar otro tipos caracteres erróneos, el modulo no manda bien la información, las veces que lo probé en el hyperterminal, me envía bien la informacion.

(http://[attachment id=1 msg=406779][/attachment])
Título: Re:Recibir SMS con PIC16f877A y SIM800L
Publicado por: martinchd en 06 de Septiembre de 2018, 10:15:07
Debo tener algún problema en la recepción de la información, proveniente de modulo, porque trato de imprimir el buffer para ver que me llega y no me imprime nada.
Título: Re:Recibir SMS con PIC16f877A y SIM800L
Publicado por: KILLERJC en 06 de Septiembre de 2018, 14:04:45
No me refiero a que el modulo entregue caracteres extraños, sino que vos tenes que asegurarte de que SI o SI únicamente reconozca "Dato" todo seguido ,  y no que reconozca un caracter 'D' y luego si llega una 'a' luego de pasado otros caracteres lo tome como correcto y continuacion de "Dato".

El continue no se que efecto tendria, siempre lo use sobre un loop ( for/while ) pero asumiendo cualquiera de las 2 opciones que puede haber que serian:
- Que salga de la interrupcion,
- Que no tenga efecto y siga al otro if

Ambas posibilidades harian que tu codigo no funcione como debe ser.
Título: Re:Recibir SMS con PIC16f877A y SIM800L
Publicado por: martinchd en 06 de Septiembre de 2018, 16:12:12
No se si el "continue" u otra cosa, pero algo mal hay seguro.. no hay forma de que me reconozca bien el sms o que guarde la palabra dato.. O también  puede que tenga algo mal en el while(true) 
Título: Re:Recibir SMS con PIC16f877A y SIM800L
Publicado por: martinchd en 07 de Septiembre de 2018, 17:02:23
No hay forma de recibir nada.. ninguno de los programas que intento hacer me funcionan.  :5] :5] :5] :5] :5] :5] :5]
trato de imprimir el buffer en un display lcd para ver que me llega y no me imprime nada.
Título: Re:Recibir SMS con PIC16f877A y SIM800L
Publicado por: martinchd en 07 de Septiembre de 2018, 17:21:07
Subo nuevamente el código por si alguno encuentra alguno problema o me puede ayudar de alguna otra forma.

Código: C++
  1. //LCD module connections
  2. #define LCD_RS_PIN PIN_B0
  3. #define LCD_RW_PIN PIN_B1
  4. #define LCD_ENABLE_PIN PIN_B2
  5. #define LCD_DATA4 PIN_B3
  6. #define LCD_DATA5 PIN_B4
  7. #define LCD_DATA6 PIN_B5
  8. #define LCD_DATA7 PIN_B6
  9. //End LCD module connections
  10.  
  11. #include <16F877.h>
  12. #include <stdio.h>
  13. #include <string.h>
  14. #FUSES XT,NOWDT,NOPROTECT,PUT,NOBROWNOUT,NOLVP    
  15. #use delay(clock=4M)
  16. #use RS232(BAUD=9600,BITS=8,PARITY=N,XMIT=PIN_C6,RCV=PIN_C7)
  17.                          
  18. #include <lcd.c>
  19.  
  20. #USE standard_io(b)
  21.  
  22.  
  23. char sms_in [80];
  24. char dato []="Dato";
  25. int a=0;
  26. int b=0;
  27. int i=0;
  28. char c=0;
  29.  
  30.  
  31.  
  32. #int_RDA
  33.  
  34. void serial_isr (void)
  35.    {
  36.     if (kbhit())
  37.       {
  38.        c=getc();
  39.        sms_in[i++]=c;
  40.       }
  41.    }
  42.    
  43. void borrar_array()
  44.    {
  45.      for(a=0;a<80;a++)
  46.       {
  47.       sms_in[a]=0;
  48.       delay_ms(100);
  49.       }
  50.    a=0;
  51.    b=0;
  52.    c=0;
  53.    }
  54.  
  55. void main()
  56.    {
  57.    lcd_init();
  58.    
  59.    set_tris_a (0x00) ;
  60.    
  61.    output_high(pin_a3);     // Tiempo hasta que toma señal el modulo
  62.       delay_ms(3000);      
  63.    output_low(pin_a3);      
  64.       delay_ms(3000);      
  65.    output_high(pin_a3);
  66.       delay_ms(3000);  
  67.    output_low(pin_a3);
  68.       delay_ms(3000);
  69.    output_high(pin_a3);
  70.       delay_ms(3000);  
  71.    output_low(pin_a3);
  72.       delay_ms(3000);
  73.    
  74.    
  75.    enable_interrupts(int_rda);
  76.    enable_interrupts(global);
  77.    
  78.    printf("AT+CMGF=1\n\r");
  79.    printf("AT+CNMI=2,2,0,0,0\n\r");
  80.    printf("AT+CMGD=1,4\n\r"); //BORRAMOS SMS
  81.      
  82.      delay_ms(3000);
  83.    
  84.    printf(LCD_PUTC, "\fEsperando SMS \n");
  85.    delay_ms(3000);
  86.    borrar_array();
  87.    
  88.    
  89.    while(true)
  90.     {
  91.      
  92.      if(0!=strstr(sms_in,dato))
  93.      {
  94.       printf(LCD_PUTC, "\f%s",sms_in);
  95.       output_high(pin_a3);
  96.       delay_ms(3000);delay_ms(3000);delay_ms(3000);  
  97.       output_low(pin_a3);
  98.       printf("AT+CMGD=1,4\n\r"); //BORRAMOS SMS
  99.       borrar_array();
  100.       i=0;
  101.      }
  102.      
  103.     }  
  104.    }
Título: Re:Recibir SMS con PIC16f877A y SIM800L
Publicado por: KILLERJC en 09 de Septiembre de 2018, 22:48:52
Agregale una proteccion para el indice:

Código: C
  1. void serial_isr (void)
  2.    {
  3.     if (kbhit())
  4.       {
  5.        c=getc();
  6.        sms_in[i++]=c;
  7.        if (i >= sizeof sms_in) i=0;
  8.       }
  9.    }

Imprimir 80 caracteres:

Código: C
  1. printf(LCD_PUTC, "\f%s",sms_in);

En un LCD de 16 lugares no creo que veas mucho, y que deberias asegurarte de tener un caracter nulo al final de recibir todo, o de ultima al menos en el index 79.
Título: Re:Recibir SMS con PIC16f877A y SIM800L
Publicado por: martinchd en 10 de Septiembre de 2018, 17:02:17
si sii... en el Display no va a entrar toda la cadena, pero tendría que mostrar lo que entre, o no???
Título: Re:Recibir SMS con PIC16f877A y SIM800L
Publicado por: martinchd en 18 de Septiembre de 2018, 09:19:30
Como puedo hacer para ver si me entra a la interrupción, para ver si esta guardando algo en el buffer. Porque no hay forma de que me hago algo el programa. Hice algo asi para ver si esta entrando a la interrupcion. Esta bien?? o como lo podria hacer.

Código: C++
  1. #int_RDA
  2.  
  3. void serial_isr (void)
  4.    {
  5.     if (kbhit())
  6.       {
  7.        c=getc();
  8.        sms_in[i]=c;
  9.        i++;
  10.        sms_in[79]="\0";
  11.        sms_in[78]="A";
  12.       }
  13.    }
  14.    
  15. void main()
  16.    {
  17.    lcd_init();
  18.    
  19.    set_tris_a (0x00) ;
  20.    
  21.    enable_interrupts(int_rda);
  22.    enable_interrupts(global);
  23.    
  24.    printf("AT+CMGF=1\n\r");
  25.    printf("AT+CNMI=2,2,0,0,0\n\r");
  26.    printf("AT+CMGD=1,4\n\r"); //BORRAMOS SMS
  27.      
  28.    delay_ms(9000);
  29.    
  30.    printf(LCD_PUTC, "\fEsperando SMS \n");
  31.  
  32.    while(true)
  33.     {
  34.     if(sms_in[78]=="A")
  35.      {
  36.       printf(LCD_PUTC, "\f%s",sms_in);
  37.       output_high(pin_a3);
  38.       delay_ms(3000);delay_ms(3000);delay_ms(3000);  
  39.       output_low(pin_a3);
  40.      }
  41.     }  
  42.    }
Título: Re:Recibir SMS con PIC16f877A y SIM800L
Publicado por: vdiazg en 26 de Septiembre de 2018, 04:25:56
Hace años publique como solucionar tu problema

http://www.todopic.com.ar/foros/index.php?topic=40019.msg333244#msg333244

Como puedo hacer para ver si me entra a la interrupción, para ver si esta guardando algo en el buffer. Porque no hay forma de que me hago algo el programa. Hice algo asi para ver si esta entrando a la interrupcion. Esta bien?? o como lo podria hacer.

Código: C++
  1. #int_RDA
  2.  
  3. void serial_isr (void)
  4.    {
  5.     if (kbhit())
  6.       {
  7.        c=getc();
  8.        sms_in[i]=c;
  9.        i++;
  10.        sms_in[79]="\0";
  11.        sms_in[78]="A";
  12.       }
  13.    }
  14.    
  15. void main()
  16.    {
  17.    lcd_init();
  18.    
  19.    set_tris_a (0x00) ;
  20.    
  21.    enable_interrupts(int_rda);
  22.    enable_interrupts(global);
  23.    
  24.    printf("AT+CMGF=1\n\r");
  25.    printf("AT+CNMI=2,2,0,0,0\n\r");
  26.    printf("AT+CMGD=1,4\n\r"); //BORRAMOS SMS
  27.      
  28.    delay_ms(9000);
  29.    
  30.    printf(LCD_PUTC, "\fEsperando SMS \n");
  31.  
  32.    while(true)
  33.     {
  34.     if(sms_in[78]=="A")
  35.      {
  36.       printf(LCD_PUTC, "\f%s",sms_in);
  37.       output_high(pin_a3);
  38.       delay_ms(3000);delay_ms(3000);delay_ms(3000);  
  39.       output_low(pin_a3);
  40.      }
  41.     }  
  42.    }
Título: Re:Recibir SMS con PIC16f877A y SIM800L
Publicado por: martinchd en 02 de Octubre de 2018, 17:03:53
Hola vdiazg, me podrías pasar esa porte del programa ?
Título: Re:Recibir SMS con PIC16f877A y SIM800L
Publicado por: martinchd en 04 de Octubre de 2018, 18:13:20
Sigo sin lograr recibir el SMS   :5] :5] :5] :5] :x :x :x
no me doy cuenta en que le estaré errando.
Título: Re:Recibir SMS con PIC16f877A y SIM800L
Publicado por: vdiazg en 14 de Octubre de 2018, 23:44:23
vamos por partes:
1. Usas algún simulador para probar tu programa?
    Siempre es bueno probar cada parte de tu programa con el IDE de microchip o en todo caso con un simulador (Proteus por ejemplo)
2. Haz probado las funciones basicas del Modulo GSM con una PC (mediante un terminal)
    Como esperas saber que recibir o si lo que recibes es correcto sin antes chequearlo con una PC, aveces el datasheet del sim se ve confuso. Prueba todas las funciones y escribe todas las respuestas del sim, diseña incluso un cuadro de cada byte recibido
3. Para este tipo de proyectos lo optimo es usar interrupcion (por USART) si dominas el manejo de esa interrupcion, ya tendras casi todo resuelto.
4. Dentro de la interrupcion por usart tiene que haber la menor cantidad de codigo posible.
5. El analisis de las respuestas obtenidas del sim se logra con las funciones del CCS, pero hacerlas tu mismo resulta mas gratificante y en algunos casos hasta te tome menos memoria
6. El sim por defecto tiene un comando para indicarte que llego un SMS y no lanzarte el contenido sin previo aviso (AT+CNMI=2,2,0,0,0)
7. Revisa el post que te puse; cualquier consulta al whatsapp (inbox).
Título: Re:Recibir SMS con PIC16f877A y SIM800L
Publicado por: Diego E. en 16 de Octubre de 2018, 21:08:48
Hola, en este momento estoy haciendo una aplicación con el SIM800L, enviar y recibir mensajes, para recibir los mensajes estoy utilizando esta rutina en una interrupción, en el cuerpo del mensaje envío un caracter que inicia la cadena (*) y otro que la finaliza (#), los caracteres van llegando y se van cargando en un array, pero cuando llega el caracter inicial se reinicia un contador y esta es la referencia para contar los caracteres que llegan, cuando llega el caracter final invoco una rutina que decodifica los caracteres que está en el array

Además tuve el siguiente inconveniente, no sé si te esté pasando algo igual, el SIM800L en el pin TX envía niveles de 2.8V, el PIC no me estaba tomando esto como un nivel alto, le enviaba datos pero el PIC no los reconocía, tuve que elevar el voltaje con unos transistores y por la velocidad de estos tuve que bajarme a 4800 bps.

Código: CSS
  1. #int_rda                                //Vector de interrupcion de la recepcion de datos
  2. void interrupcion_rx()  //por el usart
  3. {
  4.         int respaldo;
  5.         respaldo = getc();
  6.        
  7.         if(respaldo == '*')
  8.                 {con_recepcion = 0; modo_recepcion = 0;}
  9.                                
  10.         dato_recibido[con_recepcion] = respaldo;
  11.                                
  12.         if(respaldo == '#')
  13.                 {decodificar();}
  14. }
Título: Re:Recibir SMS con PIC16f877A y SIM800L
Publicado por: martinchd en 16 de Octubre de 2018, 21:16:06
Hola, en este momento estoy haciendo una aplicación con el SIM800L, enviar y recibir mensajes, para recibir los mensajes estoy utilizando esta rutina en una interrupción, en el cuerpo del mensaje envío un caracter que inicia la cadena (*) y otro que la finaliza (#), los caracteres van llegando y se van cargando en un array, pero cuando llega el caracter inicial se reinicia un contador y esta es la referencia para contar los caracteres que llegan, cuando llega el caracter final invoco una rutina que decodifica los caracteres que está en el array

Además tuve el siguiente inconveniente, no sé si te esté pasando algo igual, el SIM800L en el pin TX envía niveles de 2.8V, el PIC no me estaba tomando esto como un nivel alto, le enviaba datos pero el PIC no los reconocía, tuve que elevar el voltaje con unos transistores y por la velocidad de estos tuve que bajarme a 4800 bps.

Código: CSS
  1. #int_rda                                //Vector de interrupcion de la recepcion de datos
  2. void interrupcion_rx()  //por el usart
  3. {
  4.         int respaldo;
  5.         respaldo = getc();
  6.        
  7.         if(respaldo == '*')
  8.                 {con_recepcion = 0; modo_recepcion = 0;}
  9.                                
  10.         dato_recibido[con_recepcion] = respaldo;
  11.                                
  12.         if(respaldo == '#')
  13.                 {decodificar();}
  14. }

Probé de capturar la cadena de un millón de formas.. alomejor puede ser por el problema que me estas diciendo de los niveles lógicos.. 
Título: Re:Recibir SMS con PIC16f877A y SIM800L
Publicado por: martinchd en 18 de Octubre de 2018, 11:00:04
Hola, en este momento estoy haciendo una aplicación con el SIM800L, enviar y recibir mensajes, para recibir los mensajes estoy utilizando esta rutina en una interrupción, en el cuerpo del mensaje envío un caracter que inicia la cadena (*) y otro que la finaliza (#), los caracteres van llegando y se van cargando en un array, pero cuando llega el caracter inicial se reinicia un contador y esta es la referencia para contar los caracteres que llegan, cuando llega el caracter final invoco una rutina que decodifica los caracteres que está en el array

Además tuve el siguiente inconveniente, no sé si te esté pasando algo igual, el SIM800L en el pin TX envía niveles de 2.8V, el PIC no me estaba tomando esto como un nivel alto, le enviaba datos pero el PIC no los reconocía, tuve que elevar el voltaje con unos transistores y por la velocidad de estos tuve que bajarme a 4800 bps.

Código: CSS
  1. #int_rda                                //Vector de interrupcion de la recepcion de datos
  2. void interrupcion_rx()  //por el usart
  3. {
  4.         int respaldo;
  5.         respaldo = getc();
  6.        
  7.         if(respaldo == '*')
  8.                 {con_recepcion = 0; modo_recepcion = 0;}
  9.                                
  10.         dato_recibido[con_recepcion] = respaldo;
  11.                                
  12.         if(respaldo == '#')
  13.                 {decodificar();}
  14. }

En que consiste esta decodificacion ?
 con esa "decodificacion" también la usas para salir de la interrupción?
Título: Re:Recibir SMS con PIC16f877A y SIM800L
Publicado por: Diego E. en 18 de Octubre de 2018, 15:55:55
Es muy sencillo, el PIC por el rx puede recibir muchos caractares provenientes del SIM800L, necesitaría una ram muy extendida para almacenarlos todos, yo lo que hice fue configurar un array con 20 variables que se llama dato_recibido, cada que entra un caracter un contador se va incrementando y el dato recibido es llevado a este array en la posición correspondiente al contador, siempre se compara el caracter que llega con el ASCII '*', si son iguales se reinicia el contador, cuando llega el ASCII '#' se finaliza la recepción y se llama la rutina decodificar, donde se compara los datos del array con mis palabras claves y si son iguales realiza la función.

Debes ir verificando el valor del contador, ya que si se pasa de 20 se desborda el array

Yo hice mis pruebas llevando primero los datos del SIM a mi PC y verificando que llegue el dato enviado, luego desde el PC le envié datos al PIC, por último conecté el SIM800L con el PIC, como no me funcionó fue entonces que descubrí que era un tema de niveles lógicos, yo lo resolví con transistores para pasar los niveles de 2.8V a 5V.

No sé si alguien más haya tenido este inconveniente y como lo solucionaron



Código: CSS
  1. #int_rda                                //Vector de interrupcion de la recepcion de datos
  2. void interrupcion_rx()  //por el usart
  3. {
  4.         int respaldo;
  5.         respaldo = getc();
  6.        
  7.         if(respaldo == '*')
  8.                 {con_recepcion = 0; modo_recepcion = 0;}
  9.                                
  10.         dato_recibido[con_recepcion] = respaldo;
  11.                                
  12.         if(respaldo == '#')
  13.                 {decodificar();}                               
  14.        
  15.         con_recepcion++;
  16.         if(con_recepcion == 19)
  17.                 {con_recepcion = 0;}
  18. }
  19. ///////////////////////////////////////////////////////////////////////////////
  20. void decodificar()
  21. {
  22.         if(dato_recibido[1] == 'S' && dato_recibido[2] == 'I')
  23.        
  24.                 {
  25.                         output_high(buzzer);                   
  26.                 }
  27.        
  28.         if(dato_recibido[1] == 'N' && dato_recibido[2] == 'O')
  29.        
  30.                 {
  31.                         output_low(buzzer);                    
  32.                 }
  33. }
Título: Re:Recibir SMS con PIC16f877A y SIM800L
Publicado por: martinchd en 19 de Octubre de 2018, 12:37:32
Es muy sencillo, el PIC por el rx puede recibir muchos caractares provenientes del SIM800L, necesitaría una ram muy extendida para almacenarlos todos, yo lo que hice fue configurar un array con 20 variables que se llama dato_recibido, cada que entra un caracter un contador se va incrementando y el dato recibido es llevado a este array en la posición correspondiente al contador, siempre se compara el caracter que llega con el ASCII '*', si son iguales se reinicia el contador, cuando llega el ASCII '#' se finaliza la recepción y se llama la rutina decodificar, donde se compara los datos del array con mis palabras claves y si son iguales realiza la función.

Debes ir verificando el valor del contador, ya que si se pasa de 20 se desborda el array

Yo hice mis pruebas llevando primero los datos del SIM a mi PC y verificando que llegue el dato enviado, luego desde el PC le envié datos al PIC, por último conecté el SIM800L con el PIC, como no me funcionó fue entonces que descubrí que era un tema de niveles lógicos, yo lo resolví con transistores para pasar los niveles de 2.8V a 5V.

No sé si alguien más haya tenido este inconveniente y como lo solucionaron



Código: CSS
  1. #int_rda                                //Vector de interrupcion de la recepcion de datos
  2. void interrupcion_rx()  //por el usart
  3. {
  4.         int respaldo;
  5.         respaldo = getc();
  6.        
  7.         if(respaldo == '*')
  8.                 {con_recepcion = 0; modo_recepcion = 0;}
  9.                                
  10.         dato_recibido[con_recepcion] = respaldo;
  11.                                
  12.         if(respaldo == '#')
  13.                 {decodificar();}                               
  14.        
  15.         con_recepcion++;
  16.         if(con_recepcion == 19)
  17.                 {con_recepcion = 0;}
  18. }
  19. ///////////////////////////////////////////////////////////////////////////////
  20. void decodificar()
  21. {
  22.         if(dato_recibido[1] == 'S' && dato_recibido[2] == 'I')
  23.        
  24.                 {
  25.                         output_high(buzzer);                   
  26.                 }
  27.        
  28.         if(dato_recibido[1] == 'N' && dato_recibido[2] == 'O')
  29.        
  30.                 {
  31.                         output_low(buzzer);                    
  32.                 }
  33. }

me esta pasado eso creo.. lo elevaste con un transistor emisor comun o utilizaste dos en otra configuración.. ?
Título: Re:Recibir SMS con PIC16f877A y SIM800L
Publicado por: martinchd en 19 de Octubre de 2018, 20:47:30
no se si esta bien como lo estoy haciendo.. mi duda es cuando entra a interrupción, sale de la interrupción cuando deja de entrar información o hay que hacerla salir si o si..  medí la tensión de salida del TX del modulo SIM880L y si es de 2,8 Volt. le puse un transistor y me eleva la tensión a 4,5 Volt. pero el programa no me funciona. no se si le estaré errando en algo.

Código: C++
  1. #include <16F877.h>
  2. #FUSES XT,NOWDT,NOPROTECT,PUT,NOBROWNOUT,NOLVP    
  3. #use delay(clock=4M)
  4. #use RS232(BAUD=9600,BITS=8,PARITY=N,XMIT=PIN_C6,RCV=PIN_C7)
  5. #USE standard_io(b)
  6.  
  7.  
  8. int a=0;
  9. char sms_in[80]; // Buffer de recepción
  10. char letra_sms;
  11. int flag=0;
  12. int posicion_sms=0;
  13.  
  14.  
  15.  
  16. #int_rda
  17. void serial_isr() {          // Interrupción recepción serie USART
  18.  
  19.  int  posicion_sms=0x00;     // Índice: siguiente char en cbuff
  20.       letra_sms=getc();
  21.       if(letra_sms=='D')
  22.            {
  23.            posicion_sms=0;
  24.            }
  25.      
  26.       sms_in[posicion_sms++]=letra_sms;
  27.       flag=1;
  28. }
  29.      
  30.  
  31. void borrar_array()
  32.    {
  33.      for(a=0;a<80;a++)
  34.       {
  35.       sms_in[a]='x';
  36.       }
  37.    }
  38.    
  39. void main()
  40.    {
  41.  
  42.    set_tris_a (0x00) ;
  43.  
  44.    enable_interrupts(global);
  45.    enable_interrupts(int_rda);
  46.  
  47.    printf("AT+CMGF=1\n\r"); //Habita el modo texto de los sms
  48.    delay_ms(500);
  49.    printf("AT+CNMI=2,2,0,0,0\n\r");//los sms se envían directamente al puerto serie
  50.    delay_ms(500);
  51.    printf("AT+CMGDA=DEL ALL\n\r"); //BORRAMOS SMS
  52.    delay_ms(9000);
  53.    borrar_array();
  54.    
  55.  
  56.    while(true)
  57.     {
  58.      output_high(pin_a2);          //Indicador que esta esperando SMS
  59.      delay_ms(300);
  60.      enable_interrupts(int_rda);    // Habilitamos la interrupción por recepción serie
  61.      enable_interrupts(global);    
  62.      if(flag==1)
  63.      {        
  64.       disable_interrupts(int_rda);    // deshabilitamos la interrupción serie mientras procesamos
  65.       if(sms_in[0]=='D'&& sms_in[1]=='a'&& sms_in[2]=='t'&& sms_in[3]=='o')
  66.            {    
  67.             output_high(pin_a3);
  68.             output_low(pin_a2);
  69.             delay_ms(5000);  
  70.             output_low(pin_a3);
  71.             printf("AT+CMGDA=DEL ALL\n\r"); //BORRAMOS SMS
  72.             borrar_array();
  73.            }    
  74.       }
  75.      }
  76.     }
Título: Re:Recibir SMS con PIC16f877A y SIM800L
Publicado por: Diego E. en 20 de Octubre de 2018, 09:58:19
Cuando entra un caracter se genera la interrupción, se ejecuta el código que tienes dentro de la interrupción e inmediatamente sale de la interrupción, esto lo hace automático, hasta que llegue un nuevo caracter

No puedes definir la variable posicion_sms dentro de la interrupción, porque cada vez que entre un caracter se reinicia el contador, debes definirla por fuera de esta instancia

La variable flag se está siempre, sólo debería encenderse cuando llegue el dato correcto

Intenta hacer este ejercicio, debe funcionar y así comprenderás como puedes capturar los datos

Código: CSS
  1. #int_rda                                //Vector de interrupcion de la recepcion de datos
  2. void interrupcion_rx()  //por el usart
  3. {
  4.         int respaldo;
  5.         respaldo = getc();
  6.        
  7.         if(respaldo == '*')
  8.                 {con_recepcion = 0; modo_recepcion = 0;}
  9.                                
  10.         dato_recibido[con_recepcion] = respaldo;
  11.                                
  12.         if(respaldo == '#')
  13.                 {decodificar();}                                
  14.        
  15.         con_recepcion++;
  16.         if(con_recepcion == 19)
  17.                 {con_recepcion = 0;}
  18. }
  19. ///////////////////////////////////////////////////////////////////////////////
  20. void decodificar()
  21. {
  22.         if(dato_recibido[1] == 'S' && dato_recibido[2] == 'I')
  23.        
  24.                 {
  25.                         output_high(buzzer);                    
  26.                 }
  27.        
  28.         if(dato_recibido[1] == 'N' && dato_recibido[2] == 'O')
  29.        
  30.                 {
  31.                         output_low(buzzer);                    
  32.                 }
  33. }

en la imagen está el esquema para elevar el voltajes con dos transistores
Título: Re:Recibir SMS con PIC16f877A y SIM800L
Publicado por: martinchd en 20 de Octubre de 2018, 17:18:25
Cuando entra un caracter se genera la interrupción, se ejecuta el código que tienes dentro de la interrupción e inmediatamente sale de la interrupción, esto lo hace automático, hasta que llegue un nuevo caracter

No puedes definir la variable posicion_sms dentro de la interrupción, porque cada vez que entre un caracter se reinicia el contador, debes definirla por fuera de esta instancia

La variable flag se está siempre, sólo debería encenderse cuando llegue el dato correcto

Intenta hacer este ejercicio, debe funcionar y así comprenderás como puedes capturar los datos

Código: CSS
  1. #int_rda                                //Vector de interrupcion de la recepcion de datos
  2. void interrupcion_rx()  //por el usart
  3. {
  4.         int respaldo;
  5.         respaldo = getc();
  6.        
  7.         if(respaldo == '*')
  8.                 {con_recepcion = 0; modo_recepcion = 0;}
  9.                                
  10.         dato_recibido[con_recepcion] = respaldo;
  11.                                
  12.         if(respaldo == '#')
  13.                 {decodificar();}                                
  14.        
  15.         con_recepcion++;
  16.         if(con_recepcion == 19)
  17.                 {con_recepcion = 0;}
  18. }
  19. ///////////////////////////////////////////////////////////////////////////////
  20. void decodificar()
  21. {
  22.         if(dato_recibido[1] == 'S' && dato_recibido[2] == 'I')
  23.        
  24.                 {
  25.                         output_high(buzzer);                    
  26.                 }
  27.        
  28.         if(dato_recibido[1] == 'N' && dato_recibido[2] == 'O')
  29.        
  30.                 {
  31.                         output_low(buzzer);                    
  32.                 }
  33. }

en la imagen está el esquema para elevar el voltajes con dos transistores


Porque definís la variable "respaldo" como entero.. no es un caracter ?
Título: Re:Recibir SMS con PIC16f877A y SIM800L
Publicado por: Diego E. en 22 de Octubre de 2018, 11:41:30
es igual, es una variable de 8 bits
Título: Re:Recibir SMS con PIC16f877A y SIM800L
Publicado por: martinchd en 01 de Noviembre de 2018, 15:12:08
Bueno gente, después de tanto renegar pude hacer lo que necesitaba, gracias a la ayuda de todos ustedes y especialmente de Diego E. . muy agradecidos, subo el código.
Uno de los grandes problemas que tenia es de la tensión de los niveles lógicos, tuve que hacer un circuito con dos transistores para elevar el nivel, y el otro problema era la fuente que tiene que ser si o si de 2A para arriba.

Código: C++
  1. #include <16F877.h>
  2. #FUSES XT,NOWDT,NOPROTECT,PUT,NOBROWNOUT,NOLVP    
  3. #use delay(clock=4M)
  4. #use RS232(BAUD=9600,BITS=8,PARITY=N,XMIT=PIN_C6,RCV=PIN_C7)
  5. #USE standard_io(b)
  6.  
  7.  
  8.  
  9. char dato_recibido[20]; // Buffer de recepción
  10. int con_recepcion=0;
  11.  
  12. void decodificar()
  13. {
  14.         if(dato_recibido[1] == 'a' && dato_recibido[2] == 't')
  15.        
  16.                 {
  17.                        output_low(pin_a1);
  18.                        output_low(pin_a2);
  19.                        output_high(pin_a3);
  20.                        
  21.                 }
  22.        
  23. }  
  24.  
  25.  
  26. #int_rda                                //Vector de interrupcion de la recepcion de datos
  27. void interrupcion_rx()  //por el usart
  28. {
  29.         output_high(pin_a1);
  30.         char respaldo;
  31.         respaldo = getc();
  32.        
  33.         if(respaldo == 'D')
  34.                 {con_recepcion = 0;
  35.                 }
  36.                                
  37.         dato_recibido[con_recepcion] = respaldo;
  38.                                
  39.         if(respaldo == 'o')
  40.                 {decodificar();}                                
  41.        
  42.         con_recepcion++;
  43.         if(con_recepcion == 19)
  44.                 {con_recepcion = 0;}
  45. }
  46. ///////////////////////////////////////////////////////////////////////////////
  47.  
  48.    
  49. void main()
  50.    {
  51.    enable_interrupts(global);
  52.    enable_interrupts(int_rda);
  53.  
  54.    set_tris_a (0x00) ;
  55.  
  56.    
  57.    delay_ms(10000);
  58.    printf("AT+CMGF=1\r\n"); //Habita el modo texto de los sms
  59.    delay_ms(1500);
  60.    printf("AT+CNMI=2,2,0,0,0\r\n");//los sms se envían directamente al puerto serie
  61.    delay_ms(1500);
  62.    printf("AT+CMGDA=DEL ALL\r\n"); //BORRAMOS SMS
  63.    delay_ms(1500);
  64.    output_low(pin_a1);
  65.  
  66.    while(true)
  67.      {
  68.      
  69.       output_high(pin_a2);          //Indicador que esta esperando SMS
  70.       delay_ms(1000);
  71.       output_low(pin_a2);
  72.       delay_ms(1000);
  73.       output_low(pin_a3);
  74.       output_low(pin_a1);
  75.      
  76.      }
  77.    
  78.     }
Título: Re:Recibir SMS con PIC16f877A y SIM800L
Publicado por: alebus26 en 02 de Noviembre de 2019, 21:22:28
Buenas  te quería hacer una consulta  tenemos  el problema de recibir  SMS  con el sim 800l v2  me podrías  dar una mano con la explicación de como lo solucionaste  lo que queremos es que  al recibir  un mensaje con la palabra "Compuerta" se prenda un LED   y con otra palabra   especifica  se apague  el led muchas gracias !!!