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

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

Desconectado martinchd

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

Desconectado martinchd

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

Desconectado Diego E.

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 1086
Re:Recibir SMS con PIC16f877A y SIM800L
« Respuesta #62 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

Desconectado martinchd

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

Desconectado Diego E.

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 1086
Re:Recibir SMS con PIC16f877A y SIM800L
« Respuesta #64 en: 22 de Octubre de 2018, 11:41:30 »
es igual, es una variable de 8 bits

Desconectado martinchd

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

Desconectado alebus26

  • PIC10
  • *
  • Mensajes: 5
Re:Recibir SMS con PIC16f877A y SIM800L
« Respuesta #66 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 !!!