Problema con módulo SIM800L

Hola qué tal compañeros!. He estado trabajando con un PIC18F4550 en PIC CCS 5.070 y un módulo SIM800. He logrado enviar SMS y realizar llamadas a números específicos, pero ahora tengo una necesidad debido a lo que quiero desarrollar: recibir SMS.

Como han de saber, cuando se recibe un sms, el módulo sim800 emite ciertos comandos y respuestas, por lo que antes de poder capturar eso decidí simplemente enviar el comando "AT" para recibir un "OK" como respuesta, y yo capturarlo y verificar que efectivamente sea eso.

Pues he estado intentando y mi algoritmo no logra capturar el \r\nOK\r\n que envía el módulo, simplemente me pone caracteres muy extraños. He leído en varios foros en español e inglés pero nada ha solucionado el problema. Espero puedan ayudarme, aquí les dejo el código:

Código:
#include <18F4550.h>
#device ADC=16

#FUSES NOWDT                    //No Watch Dog Timer
#FUSES WDT128                   //Watch Dog Timer uses 1:128 Postscale
#FUSES FCMEN                    //Fail-safe clock monitor enabled
#FUSES IESO                     //Internal External Switch Over mode enabled
#FUSES PUT                      //Power Up Timer
#FUSES NOBROWNOUT               //No brownout reset
#FUSES BORV21                   //Brownout reset at 2.1V
#FUSES NOVREGEN                 //USB voltage regulator disabled
#FUSES PBADEN                   //PORTB pins are configured as analog input channels on RESET
#FUSES LPT1OSC                  //Timer1 configured for low-power operation
#FUSES NOMCLR                   //Master Clear pin used for I/O
#FUSES STVREN                   //Stack full/underflow will cause reset
#FUSES NOLVP                    //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#FUSES NOXINST                  //Extended set extension and Indexed Addressing mode disabled (Legacy mode)
#FUSES NOPROTECT                //Code not protected from reading
#FUSES NOCPB                    //No Boot Block code protection
#FUSES NOCPD                    //No EE protection
#FUSES NOWRT                    //Program memory not write protected
#FUSES NOWRTC                   //Configuration registers not write protected
#FUSES NOWRTB                   //Boot block not write protected
#FUSES NOWRTD                   //Data EEPROM not write protected
#FUSES NOEBTR                   //Memory not protected from table reads
#FUSES NOEBTRB                  //Boot block not protected from table reads

#use delay(crystal=12MHz)
#use rs232(baud=1200,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=8,stream=PORT1)

#define boton PIN_D1               //boton

///////////////////////////LCD//////////////////////////////////////////////////
#define LCD_ENABLE_PIN PIN_B0
#define LCD_RS_PIN PIN_B1
#define LCD_RW_PIN PIN_B2
#define LCD_DATA4 PIN_D4
#define LCD_DATA5 PIN_D5
#define LCD_DATA6 PIN_D6
#define LCD_DATA7 PIN_D7
#include <lcd.c>

char buffer;
char cmd[20] = {0};
int i=0;
/////////////////////////////INTERRUPCION POR RX///////////////////////////////
#INT_RDA
void  RDA_isr(void) 
{
 
       cmd[i++] = getchar();
    
         
}


/////////////////////////////PROGRAMA PRINCIPAL////////////////////////////////
void main()
{
   //Activamos interrupciones
   enable_interrupts(INT_RDA);
   enable_interrupts(GLOBAL);
   //Inicio de LCD
   lcd_init();
   printf(lcd_putc,"Listo\n");
   while(TRUE)
   {
       //Si presionamos el boton, envia AT:
       if( input(boton) )
       {
          while( input(boton) );       //Rebote
          delay_ms(200);
          
          printf("AT\r");               //Envio AT
          
          lcd_gotoxy(1,2);
          for(int j = 0 ; j <= 7 ; j++)        //Imprimimos
             printf(lcd_putc,"%c",cmd[j]);
          
          i = 0;
          
          output_toggle(PIN_D0);  //Indicador
       } 
          
   }

}


He decidido trabajarlo a 1200 baudios para tener la menor velocidad e intentar capturar ese OK, pero no lo he logrado. De igual forma les dejo una imagen de lo que captura el PIC y el módulo que estoy usando.

Cabe señalar que ya lo probé con la PC y el módulo anda bien y todo al 100%, de igual forma también pude enviar sms y realizar llamadas con el PIC, solamente el problema es al recibir los datos seriales del SIM800 al PIC.

Espero puedan ayudarme, muchas gracias!!!! saludos! :):):)
 

Adjuntos

  • lcd.jpg
    lcd.jpg
    55.5 KB · Visitas: 19
  • sim800.jpg
    sim800.jpg
    83.6 KB · Visitas: 17
Lo que generalmente se hace es recibir los datos y guardarlos en un buffer(un espacio en memoria de n bytes), esperar un carácter identificador ya sea un Enter(0x0D) u otro, con ese identificador lees el buffer y buscas el "OK".

Strcmp();

Revisa esa función para string te puede ser de ayuda.

Saludos!



 
Lo que generalmente se hace es recibir los datos y guardarlos en un buffer(un espacio en memoria de n bytes), esperar un carácter identificador ya sea un Enter(0x0D) u otro, con ese identificador lees el buffer y buscas el "OK".

Strcmp();

Revisa esa función para string te puede ser de ayuda.

Saludos!

Muchas gracias! eso he estado intentando en mi rutina de INT_RDA, si te fijas es un "buffer" que voy aumentado su índice, pero nunca detecta CR o LF :cry: por eso es que no he podido, alguna idea?
 
Yo lo hago de esta forma, tal vez te sirva :

EN la interrupcion :

Como ves espero el retorno de carro 0x0D,ese es mi identificador.
Si lleno el buffer reinicio el indice para no desbordar memoria.

Código:
{

rcByte = RCREG;                     // ReadUSART();

        if(index == data_lenght){           // buffer lleno ?
            index = 0;
            clearRxBuffer();
        }
        
        Rxdata[index] = rcByte;             // Escribir dato en el buffer

        if(Rxdata[index] == 0x0D){          // Comando recibido?
            process_data = 1;
            Rxdata[index] = 0x00;      //adding NULL
            index = 0;                  // reset buffer index
            return;
        }

        index++;                            // incrementar indice del buffer

    }// RX Serial interrupt

Una vez que recibí el identificador activo una bandera para trabajar los datos.
En el main :

Código:
if (process_data == 1) { // hay trama por revisar?
            process_data = 0; // limpio bandera

            if (strcmp(Rxdata, "spray_M") == 0) { // el array coincide con mi string ?
                
                RELAY_M = 0;
                my_delay(spray_time);
                RELAY_M = 1;
                printf("\r\n male done .i.\n");
            }

            else if (strcmp(Rxdata, "spray_F") == 0) {
                
                RELAY_F = 0;
                my_delay(spray_time);
                RELAY_F = 1;
                printf("\r\n female done (l)\n");
            }
}

Saludos!
 
Yo lo hago de esta forma, tal vez te sirva :

EN la interrupcion :

Como ves espero el retorno de carro 0x0D,ese es mi identificador.
Si lleno el buffer reinicio el indice para no desbordar memoria.

Código:
{

rcByte = RCREG;                     // ReadUSART();

        if(index == data_lenght){           // buffer lleno ?
            index = 0;
            clearRxBuffer();
        }
        
        Rxdata[index] = rcByte;             // Escribir dato en el buffer

        if(Rxdata[index] == 0x0D){          // Comando recibido?
            process_data = 1;
            Rxdata[index] = 0x00;      //adding NULL
            index = 0;                  // reset buffer index
            return;
        }

        index++;                            // incrementar indice del buffer

    }// RX Serial interrupt

Una vez que recibí el identificador activo una bandera para trabajar los datos.
En el main :

Código:
if (process_data == 1) { // hay trama por revisar?
            process_data = 0; // limpio bandera

            if (strcmp(Rxdata, "spray_M") == 0) { // el array coincide con mi string ?
                
                RELAY_M = 0;
                my_delay(spray_time);
                RELAY_M = 1;
                printf("\r\n male done .i.\n");
            }

            else if (strcmp(Rxdata, "spray_F") == 0) {
                
                RELAY_F = 0;
                my_delay(spray_time);
                RELAY_F = 1;
                printf("\r\n female done (l)\n");
            }
}

Saludos!

Muchas gracias electroconico!! lo probaré :)
 
hola
espero que aun respondan este post....
hace poco compre el sim900a mini module, igual al que tienes. Lo conecte directamente a aun arduino nano solo para ver que envia.
tengo 3 dias en esto y el puerto RS no muestra nada ya revise voltages, corriente y demas, todo parece estar bien pero no logro capturar un solo byte que muestre nada y tampoco puedo enviar nada al SIM900a.
tienen idea de que puede estar mal?...
PS: ya probe con los baus de 1200 a 115200 y hasta mas de 400 mil.
gracias.
 
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. Mi problema es con la parte de leer el SMS con el PIC. Dejo lo que tengo hecho, en algo le estoy errando.
 

Adjuntos

  • sms - Por ubicacion.rar
    1.1 KB · Visitas: 18

D@rkbytes

Moderador
Mi problema es con la parte de leer el SMS con el PIC
Si lo que quieres es recibir una cadena, usa gets(string);
Donde "string" será un arreglo de x dimensión donde se almacenará la cadena. (Mirar la ayuda del compilador)

Nota: Si estás usando la interrupción del módulo USART, (Hardware) no es necesario usar kbhit();
Esa instrucción únicamente se usa cuando la recepción es por software.

PD:
Esta parte se tardará 8 segundos en borrar el arreglo:
:oops:
C:
void borrar_array()
{
    for(a=0;a<80;a++)
    {
        sms_in[a]=0;
        delay_ms(100);
    }
}
Y "sms_in[]" únicamente lo declaraste con 6 vectores.
 
La variable sms_in [] la declare así para solamente guardar la palabra "Dato".
Y la subrutina de borrar el array le bajo el delay, o directamente se lo saco?
Si lo que quieres es recibir una cadena, usa gets(string);
Donde "string" será un arreglo de x dimensión donde se almacenará la cadena. (Mirar la ayuda del compilador)

Nota: Si estás usando la interrupción del módulo USART, (Hardware) no es necesario usar kbhit();
Esa instrucción únicamente se usa cuando la recepción es por software.

PD:
Esta parte se tardará 8 segundos en borrar el arreglo:
:oops:
C:
void borrar_array()
{
    for(a=0;a<80;a++)
    {
        sms_in[a]=0;
        delay_ms(100);
    }
}
Y "sms_in[]" únicamente lo declaraste con 6 vectores.

Si lo que quieres es recibir una cadena, usa gets(string);
Donde "string" será un arreglo de x dimensión donde se almacenará la cadena. (Mirar la ayuda del compilador)

Yo queria usar kbhit() porque lo que me envía el modulo es un string demasiado grande, con kbhit() puedo guardar caracter por caracter y filtro a partir de que caracter quiero empezar a guardar en el array. Estoy equivocado ???

Esto es lo que el modulo me envía cuando llega una SMS.

40404175_10217159860256641_4388944964302667776_n.jpg
 

D@rkbytes

Moderador
Y la subrutina de borrar el array le bajo el delay, o directamente se lo saco?
Descarta el retardo completamente, no es necesario y sí perjudicial porque atorará todo el programa.
Yo quería usar kbhit() porque lo que me envía el módulo es un string demasiado grande, con kbhit() puedo guardar carácter por carácter y filtro a partir de qué carácter quiero empezar a guardar en el array.
¿Estoy equivocado?
Pues sí estás equivocado, kbhit() como mencioné anteriormente, únicamente se debe usar para verificar datos en el búfer cuando se usa RS-232 por software.
Suele usarse por polling o poleo, o dentro de una interrupción externa que sustituiría la del módulo USART.
Una vez que ocurre una interrupción por hardware, significa que ya hay datos en el búfer, así que el uso de kbhit() es redundante.

Con gets(string); puedes recibir una cadena muy larga de una sola vez, y gets() retornará del bucle circular con toda la cadena en el arreglo, pero hasta que encuentre el carácter de retorno de carro (13 o "'\r")
Como seguramente el módulo SIM800L no envía ese valor al final de la cadena, entonces será necesario configurar en los parámetros RS-232, que retorne después de x tiempo si no hay datos, aunque no se reciba el retorno de carro.
Para eso, tan solo se agrega lo siguiente: TIMEOUT = X (Donde X será el tiempo de espera en milisegundos)

Ahora que si el módulo SM800L envía el retorno de carro al final de la cadena, pues será una gran ventaja.

Si no logras comprender el uso de gets(string); por aquí subí un ejemplo usando un búfer circular, pero no recuerdo en qué post.
Así que tendría que buscarlo en mis archivos.
 
Saludos a todos, espero alguien me pueda ayudar por que estoy que me vuelvo loco con estos módulos que compré que son el Sim800l de Nettigo , en teoría éste módulo debería de conectar con el proveedor inmediatamente que se enciende y que el sim esta ingresado, pero en mi caso no logro que conecte con el proveedor de ninguna manera, tengo el circuito conectado a una fuente de 4V/3A , el manual (que es enorme) no da respuestas claras acerca de cómo realizar consultas para saber que es lo que esta pasando con el sistema.
Se supone que en mi país Costa Rica se soportan las mismas bandas que el modulo por eso lo compré pero igual no logro nada.
¿ Alguien tiene o ha tenido un problema similar y puede ayudarme?!
Gracias
 
¿que te informa el sim800 por la conexión serie?

Cuando esta listo informa y cuando no reconoce el chip de la linea o esta sin él conectado, también lo hace.

La comunicación por defecto es a 9600bps y la puedes realizar con cualquier adaptador USB a RS232 con niveles TTL y adaptador de niveles por que trabaja con 2.8V en la comunicación.
 
SIM800L Interferencias en el RS232 al conectar a GPRS

Hola ,

Estoy probando con el modulo SIM800L, Arduino nano y unos sensores; Una alarma que me registre en una web movimiento y audio... todo va bien, menos la interferencia que ocurre en el puerto RS232 bastantes veces cuando se establece la conexión GPRS 2G, con el PC lo monitorizo

Aquí se llega a hablar de ello Garbage characters randomly received by HardwareSerial when communicating with SIM800L modem · Issue #2198 · espressif/arduino-esp32

Código:
OK␍␊
AT+CREG?␍␍␊
+CREG: 0,1␍␊
␍␊
OK␍␊
AT+SAPBR=3,1,"Contype","GPRS"␍␍␊
OK␍␊
AT+SAPBR=3,1,"APN","tel.hitsmobile.es"␍␍␊
OK␍␊
AT+SAPBR=2,1␍␍␊
+SAPBR: 1,3,"0.0.0.0"␍␊
␍␊
OK␍␊
AT+SAPBR=1,1␍␍␊
OK␍␊
<0x14><0xd5>⇥    <0xca>QA%9)U<0xa8><0xc8>z-5<0xea>AT+HTTPPARA="CID",1␍␍␊
O<0xeb>C<0xe1>

GSM-MODULE-SIM800-5V.jpg
GSM-MODULE-SIM800-5V-B.jpg

El modulo esta alimentado directamente a 4,10V con una fuente dedicada, la parte TX del RS232 del modulo SIM800L la meto en un AO seguidor de tensión por temas de impedancias del Arduino (Baja de entrada en el RX) y el SIM800L(Alta de salida del TX), he intentado con algo de ferrita pero sigue, pues no aclara mucho como ponerla en github.

Para llamadas y SMS no parece que haya problemas pues el modulo no genera tanta señal como con GPRS

¿Que me recomendáis para solucionar el problema?

Gracias
 
Captura de pantalla_2019-11-04_20-01-41.png

Estoy usando de prueba una caja de empalme de plastico, y alejando la antena y poniendole papel de plata en la base parece que no coge interferencia, con una caja metálica debe de ir bien ¿no?
 
No me gusta el RX SIM800, lo mandás directamente con la salida del Arduino y la hoja de datos dice que la Vih máxima es de 2,8v.

¿No te conviene seguir la recomendación del fabricante? En la página 32 tenés el adaptador de tensión usando dos transistores para el Tx y el Rx.

Otra cosa importante, ¿la fuente se cae debajo de 3v durante la conexión?
 

Adjuntos

  • Datasheet_SIM800L.pdf
    2.7 MB · Visitas: 11
A bueno, el mio es el de la foto de antes el SIM800L EVB, es esta placa y lleva (en verde) 2 mosfet para adaptar tensiones a 5V, la fuente de 4,1V es de 3A no varia su voltaje
 

Adjuntos

  • SIM800L EVB.jpg
    SIM800L EVB.jpg
    176.2 KB · Visitas: 6
¿Sería este módulo?:



En ese caso, es correcto lo que decís. Entonces, ¿para qué estás usando ese operacional? No veo la necesidad de adaptar impedancia.

Tené en cuenta que le están faltando capacitores a esa fuente.
 
¿Sería este módulo?:
En ese caso, es correcto lo que decís. Entonces, ¿para qué estás usando ese operacional? No veo la necesidad de adaptar impedancia.
Creo que si es ese esquema, el modulo SIM800L en TX no tiene suficiente amperaje para bajar a 0V (visto con osciloscopio) o cercano al RX hardware del Arduino por que este lleva hasta un led RX que se enciende en 0V, con el AO o 2 transistores como puse antes en push pull va bien

Tené en cuenta que le están faltando capacitores a esa fuente.
La fuente esta bien, de la alimentacion de la placa tengo quitado los 2 diodos para hacer la caidad de tension y alimento directamente al SIM800L con 4,1V

Me esta funcionando bien como dije con la antena alejada y puesto papel de aluminio en la base, el problema es ese que la antena mete interferencia, y estaba probando con una caja de plastico, ¿una de metal evitaria la interferencia de la antena?, recuerdo que los moviles en 2G metian mucha interferencia en equipos de audios, esto es lo mismo
 
Creo que si es ese esquema, el modulo SIM800L en TX no tiene suficiente amperaje para bajar a 0V (visto con osciloscopio) o cercano al RX hardware del Arduino por que este lleva hasta un led RX que se enciende en 0V, con el AO o 2 transistores como puse antes en push pull va bien

Al ser un mosfet, está controlado por tensión. No sé que tan bien funciona el nivel bajo en esa configuración.

Yo particularmente para algo similar (en un módulo G24 de motorola), usé compuertas no inversoras con salidas open-colector para el cambio de nivel. Otra alternativa es usar dos transistores bipolares para la doble inversión o como dice el fabricante un bipolar jugando con el emisor.

Supongo que mediste los niveles de tensión del Rx del Arduino con un OCR y te dió bien.

La fuente esta bien, de la alimentacion de la placa tengo quitado los 2 diodos para hacer la caidad de tension y alimento directamente al SIM800L con 4,1V

Cuando hablo de caída de tensión, me refiero durante el pico de corriente cuando hay mayor consumo, en la página 22 hace mención a una caída de 350mV y los capacitores asociados para evitar una caída mayor, que son de 100uF (Ca) y 1uF (Cb). Esos capacitores no se ven en el adaptador. Luego en la página siguiente habla de evitar estar por debajo de los 3V.

Me esta funcionando bien como dije con la antena alejada y puesto papel de aluminio en la base, el problema es ese que la antena mete interferencia, y estaba probando con una caja de plastico, ¿una de metal evitaria la interferencia de la antena?, recuerdo que los moviles en 2G metian mucha interferencia en equipos de audios, esto es lo mismo

Con el G24 nunca me pasó eso, que se metiera ruido por el puerto serie. Si es normal esa interferencia en los equipos de audio.
 
Arriba