Autor Tema: Recibir SMS con PIC16f877A y SIM800L  (Leído 16959 veces)

0 Usuarios y 1 Visitante están viendo este tema.

Desconectado martinchd

  • PIC12
  • **
  • Mensajes: 78
Recibir SMS con PIC16f877A y SIM800L
« 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.

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re:Recibir SMS con PIC16f877A y SIM800L
« Respuesta #1 en: 18 de Julio de 2018, 09:27:59 »
Que compilador y que trataste de hacer hasta el momento ?


Desconectado planeta9999

  • Moderadores
  • DsPIC30
  • *****
  • Mensajes: 3520
    • Pinballsp
Re:Recibir SMS con PIC16f877A y SIM800L
« Respuesta #2 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.
« Última modificación: 18 de Julio de 2018, 11:51:48 por planeta9999 »

Desconectado martinchd

  • PIC12
  • **
  • Mensajes: 78
Re:Recibir SMS con PIC16f877A y SIM800L
« Respuesta #3 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.


« Última modificación: 18 de Julio de 2018, 15:43:43 por martinchd »

Desconectado martinchd

  • PIC12
  • **
  • Mensajes: 78
Re:Recibir SMS con PIC16f877A y SIM800L
« Respuesta #4 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.

Desconectado martinchd

  • PIC12
  • **
  • Mensajes: 78
Re:Recibir SMS con PIC16f877A y SIM800L
« Respuesta #5 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.          }
« Última modificación: 18 de Julio de 2018, 15:43:00 por martinchd »

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re:Recibir SMS con PIC16f877A y SIM800L
« Respuesta #6 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>]

Desconectado martinchd

  • PIC12
  • **
  • Mensajes: 78
Re:Recibir SMS con PIC16f877A y SIM800L
« Respuesta #7 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

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re:Recibir SMS con PIC16f877A y SIM800L
« Respuesta #8 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.

Desconectado martinchd

  • PIC12
  • **
  • Mensajes: 78
Re:Recibir SMS con PIC16f877A y SIM800L
« Respuesta #9 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    ((:-)) :)

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re:Recibir SMS con PIC16f877A y SIM800L
« Respuesta #10 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.

Desconectado martinchd

  • PIC12
  • **
  • Mensajes: 78
Re:Recibir SMS con PIC16f877A y SIM800L
« Respuesta #11 en: 20 de Julio de 2018, 00:25:39 »
pero el SIM no lo envia simpre al final <CR><LF>. ?

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re:Recibir SMS con PIC16f877A y SIM800L
« Respuesta #12 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.

Desconectado martinchd

  • PIC12
  • **
  • Mensajes: 78
Re:Recibir SMS con PIC16f877A y SIM800L
« Respuesta #13 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.    }

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re:Recibir SMS con PIC16f877A y SIM800L
« Respuesta #14 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.


 

anything