GSM module Interfacing with PIC18F4550

Overview of GSM

Global System for Mobile communication (GSM) is a digital cellular system used for mobile devices. It is an international standard for mobile which is widely used for long-distance communication.

There are various GSM modules available in market like SIM900, SIM700, SIM800, SIM808, SIM5320, etc.

SIM900A module allows users to send/receive data over GPRS, send/receive SMS, and make/receive voice calls.

It communicates serially with the devices like microcontroller, PC using AT commands.

To interface the SIM900A module with a cellular network, it requires a SIM card provided by a network operator.

For more information about Sim900A and how to use it, refer to the topic Sim900A GSM/GPRS Module in the sensors and modules section.

The GSM/GPRS module uses USART communication to communicate with the controller or PC terminal.

For information about USART in PIC18F4550 and how to use it, refer to the topic USART in PIC18F4550 in the PIC inside section.

This is the picture of SIM900 GSM Module
SIM900A GSM Module

 

Connection Diagram of SIM900A GSM Module to PIC18F4550

This is the picture of GSM Module Interfacing with PIC microcontroller
GSM Module Interfacing with PIC microcontroller

 

SIM900A GSM Code for PIC18F4550

/*
* SIM900A Interfacing with PIC18F4550
* http://www.electronicwings.com
*/

#include <pic18f4550.h>
#include "Configuration_Header_File.h"
#include "LCD_16x2_8-bit_Header_File.h"
#include "USART_Header_File.h"
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

void GSM_Init();
void GSM_Calling(char *);
void GSM_HangCall();
void GSM_Response();
void GSM_Response_Display();
void GSM_Msg_Read(int);
void GSM_Wait_for_Msg();
void GSM_Msg_Display();
void GSM_Msg_Delete(unsigned int);
void GSM_Send_Msg(const char* , const char*);

char buff[160];  /* buffer to store responses and messages */
volatile char status_flag;  /* monitor to check for any new message */
volatile int a;

void main(void) 
{
    a=0;
    OSCCON =0x72;  /* set internal oscillator Freq = 8 MHz*/
    LCD_Init();  /* initialize LCD */
    INTCONbits.GIE=1;  /* enable Global Interrupt */
    INTCONbits.PEIE=1;  /* enable Peripheral Interrupt */
    PIE1bits.RCIE=1;  /* enable Receive Interrupt */
    MSdelay(100);
    USART_Init(9600);  /* initialize USART communication */        
    GSM_Init();  /* check GSM responses and initialize GSM */
    
    LCD_Clear();
    LCD_String("Sending SMS...");
    MSdelay(3000);
    
    GSM_Send_Msg("8983923089","TEST");  /*send sms on "mobile no."*/
    MSdelay(3000);
    LCD_Clear();
    while(1)
    {   
        /* waiting for message to receive */
        status_flag=0;
        if(status_flag)
        {
            LCD_Clear();
            LCD_String_xy(0,0,"New msg arrive");
            MSdelay(1000);
            LCD_Clear();
            GSM_Wait_for_Msg();  /*wait for new message to read */                        
            status_flag = 0;            
        }
    }
    
}

void GSM_Init()
{   
    while(1)
    {   
        LCD_Command(0xc0);
        USART_SendString("ATE0\r");  /* send AT to check module is ready or not*/
        MSdelay(500);
        if(strstr(buff,"OK"))
        {
            GSM_Response();  /* find response and display it on LCD16x2 */
            memset(buff,0,160);
            break;
        }
        else
        {    
            LCD_String("Error");
        }
    }
    MSdelay(2000);

    LCD_Clear();
	LCD_String_xy(0,0,"Text Mode"); 
    LCD_Command(0xc0);
	USART_SendString("AT+CMGF=1\r");  /* select message format as text */
    GSM_Response();
	MSdelay(3000);
    
    LCD_Clear();
	LCD_String_xy(0,0,"Mfd name");  
    LCD_Command(0xc0);
	USART_SendString("AT+GMI\r");  /* identify manufacturer */
    GSM_Response();
	MSdelay(3000);
    
    LCD_Clear();
	LCD_String_xy(0,0," Model No.");
    LCD_Command(0xc0);
	USART_SendString("AT+GMM\r");  /* find model no. */
    GSM_Response();
	MSdelay(3000);
    
	LCD_Clear();
	LCD_String_xy(0,0,"  IMEI No. ");
    LCD_Command(0xc0);
	USART_SendString("AT+GSN\r");  /* find IMEI no. of module */
    GSM_Response();
	MSdelay(3000);
        
    LCD_Clear();
	LCD_String_xy(0,0,"Service Provider");
    LCD_Command(0xc0);
	USART_SendString("AT+CSPN?\r");  /* find service provider name */
    GSM_Response();
	MSdelay(3000);

}

void GSM_Msg_Delete(unsigned int position)
{
    
    a=0;
    char delete_cmd[20];    
    sprintf(delete_cmd,"AT+CMGD=%d\r",position);  /* delete message at specified position */
    USART_SendString(delete_cmd);
    MSdelay(100);
    memset(buff,0,strlen(buff));
}
void GSM_Wait_for_Msg()
{
    char i,val[4];
    int position;
    LCD_Clear();
    a=0;
    while(1)
    {
        if(buff[a]==0x0d || buff[a]==0x0a)  /*eliminate "\r \n" which is start of string */
        {
            a++;
        }
        else
            break;
    }
    
    if(strstr(buff,"CMTI:"))  /* check if any new message received */
    {   
        while(buff[a]!=',')
        {
            a++;
        }
        a++;
        
        i=0;
        while(buff[a]!=0x0d)
        {
            val[i]=buff[a];
            a++;
            i++;
        } 
    position = atoi(val);
    if(position>20)
    {
        LCD_String_xy(0,0,"Msg mem full");
        memset(buff,0,strlen(buff));
        return;
    }
    memset(buff,0,strlen(buff));
    a=0;
    GSM_Msg_Read(position);  /* read message which is recently arrived from position */
    }    
}

void interrupt ISR()
{
    if(RCIF)
    {
        buff[a] = RCREG;  /* read received byte from serial buffer */
        a++;
        
        if(RCSTAbits.OERR)  /* check if any overrun occur due to continuous reception */
        {           
            CREN = 0;
            NOP();
            CREN=1;
        }
        status_flag=1;  /* use for new message arrival */
    }

}

void GSM_Send_Msg(const char *num,const char *sms)
{
    int i;
    char sms_buffer[35];
    a=0;
    sprintf(sms_buffer,"AT+CMGS=\"%s\"\r",num);
    USART_SendString(sms_buffer);  /*send command AT+CMGS="Mobile No."\r */
    MSdelay(200);
    while(1)
    {
        if(buff[a]==0x3e)  /* wait for '>' character*/
        {
            a=0;
            memset(buff,0,strlen(buff));
            USART_SendString(sms);  /* send msg to given no. */
            USART_TxChar(0x1a);  /* send Ctrl+Z then only message will transmit*/
            break;
        }  
        a++;
    }        
    MSdelay(300);
    a=0;
    memset(buff,0,strlen(buff));
    memset(sms_buffer,0,strlen(sms_buffer));
}

void GSM_Calling(char *mobile)
{
    char call[20];
    sprintf(call,"ATD%s;\r",mobile);  /* send command ATD8007xxxxxx; for calling*/
    USART_SendString(call);    
}

void GSM_HangCall()
{
    USART_SendString("ATH\r");  /*send command ATH\r to hang call*/
}

void GSM_Response()
{
    unsigned int timeout=0;
    int CRLF_Found=0;
    char CRLF_buff[2];
    int Response_Length=0;
    while(1)
    {
        if(timeout>=60000)  /*if timeout occur then return */
            return;
        Response_Length = strlen(buff);		
        if(Response_Length)
        {
            MSdelay(1);
            timeout++;
            if(Response_Length==strlen(buff))	
            {
                for(int i=0;i<Response_Length;i++)
                {
                    memmove(CRLF_buff,CRLF_buff+1,1);
                    CRLF_buff[1]=buff[i];
                    if(strncmp(CRLF_buff,"\r\n",2))
                    {
                        if(CRLF_Found++==2)	/* search for \r\n in string */
                        {
                            GSM_Response_Display();
                            return;
                        }
                    }

                }
                CRLF_Found =0;
            }
    }
    MSdelay(1);
    timeout++;
 }
}

void GSM_Response_Display()
{
    a=0;
    while(1)
    {
        if(buff[a]==0x0d || buff[a]==0x0a)
        {
            a++;
        }
        else
            break;
    }
    LCD_String_xy(1,0,"                   ");
    LCD_Command(0xc0);
    while(buff[a]!=0x0d)
    {  
        LCD_Char(buff[a]);
        a++;
        if(a==15)
            LCD_Command(0x80);
    }
    a=0;
        memset(buff,0,strlen(buff));
        
}

void GSM_Msg_Read(int position)
{
    int i,k;
    char flag,read_cmd[10];
    i=0;
    sprintf(read_cmd,"AT+CMGR=%d\r",position);
    USART_SendString(read_cmd);                 
    MSdelay(1000);
    GSM_Msg_Display();
}

void GSM_Msg_Display()
{
    
    if(!(strstr(buff,"+CMGR")))  /*check for +CMGR response */
    {
            LCD_String_xy(0,0,"No message");   
    }   
    else
    {   
        a=0;
        
        while(1)
        {
            if(buff[a]==0x0d || buff[a]==0x0a)  /*wait till \r\n not over*/
            {
                a++;
            }
            else
                break;
        }
        while(buff[a]!=0x3a)  /*wait till string not equal to ':' */
        {
            a++;
        }
     do
        {        
            a++;
        }while(buff[a-1]!=0x0a);
        
        LCD_Command(0xC0);
        int i=0;
            while(buff[a]!=0x0d && i<31)
            {
                    LCD_Char(buff[a]);
                    a++;
                    i++;
                    if(i==16)  /* if received message is greater than 16(for display message)*/
                        LCD_Command(0x80);  /* resume display of message from 1st line */
                    
            }
        
            a=0;
            memset(buff,0,strlen(buff));
    }
    status_flag = 0;
}

 

Video of SMS Sending using GSM Modem with PIC18F4550


Components Used

SIM900A GSM GPRS Module
SIM900A is dual band GSM/GPRS 900/1800MHz module board used to utilize GSM and GPRS services around the globe. It is used to make/receive voice calls, send/receive text messages, connect to and access the internet over GPRS.
1
PICKit 4 MPLAB
PICKit 4 MPLAB
1
PIC18f4550
PIC18f4550
1
LCD16x2 Display
LCD16x2 Display
1

Downloads

SIM900 AT Commands Manual Download
GSM Interfacing with PIC18F4550 Project File Download
Ad