Introduction
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 the 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 a microcontroller, PC using AT commands.
To interface the SIM900A module with the 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 a microcontroller or PC terminal.
For information about USART in AVR ATmega16/ ATmega32 and how to use it, refer the topic USART in AVR ATmega16/ATmega32 in the ATmega inside section.
SIM900A GSM Module Interfacing With Atmega16/32
Send SMS using SIM900 GSM Module and ATmega16/32
Let’s design a little application in which the user will receive SMS “call me” and immediately user will call that message sender.
SIM900 GSM Module Code for Atmega16
/*
SIM900 GSM Interfacing with ATmega16/32
http://www.electronicwings.com
*/
#define F_CPU 8000000UL /* define Clock Frequency */
#include <avr/io.h>
#include <avr/interrupt.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <stdbool.h>
#include "LCD_16x2_H_file.h" /* include 16x2 LCD Header file */
#include "USART_Interrupt.h" /* include USART Header file */
#define SREG _SFR_IO8(0x3F)
void GSM_Begin();
void GSM_Calling(char *);
void GSM_HangCall();
void GSM_Response();
void GSM_Response_Display();
void GSM_Msg_Read(int);
bool GSM_Wait_for_Msg();
void GSM_Msg_Display();
void GSM_Msg_Delete(unsigned int);
void GSM_Send_Msg(char* , char*);
void GSM_Delete_All_Msg();
char buff[160]; /* buffer to store responses and messages */
char status_flag = 0; /* for checking any new message */
volatile int buffer_pointer;
char Mobile_no[14]; /* store mobile no. of received message */
char message_received[60]; /* save received message */
int position = 0; /* save location of current message */
int main(void)
{
buffer_pointer = 0;
int is_msg_arrived;
memset(message_received, 0, 60);
LCD_Init();
USART_Init(9600); /* initialize USART */
sei();
LCD_String_xy(1,0,"GSM Initializing");
_delay_ms(3000);
LCD_Clear();
LCD_String_xy(1,0,"AT");
GSM_Begin(); /* Start GSM with AT*/
LCD_Clear();
while (1){
/*check if any new message received */
if(status_flag==1){
is_msg_arrived = GSM_Wait_for_Msg(); /*check for message arrival*/
if(is_msg_arrived== true)
{
LCD_Clear();
LCD_String_xy(1,0,"new message"); /* new message arrived */
_delay_ms(1000);
LCD_Clear();
GSM_Msg_Read(position); /* read arrived message */
_delay_ms(3000);
/*check if received message is "call me" */
if(strstr( message_received,"call me")){
GSM_Calling(Mobile_no); /* call sender of message */
LCD_Clear();
LCD_String_xy(1,0,"Calling...");
_delay_ms(15000);
GSM_HangCall(); /* hang call */
LCD_String_xy(1,0,"Hang Call");
_delay_ms(1000);
}
LCD_Clear();
GSM_Msg_Delete(position); /* to save SIM memory delete current message */
LCD_String_xy(1,0,"Clear msg");
GSM_Response();
_delay_ms(1000);
}
is_msg_arrived=0;
status_flag=0;
LCD_Clear();
}
LCD_String_xy(1,0,"waiting for msg");
memset(Mobile_no, 0, 14);
memset(message_received, 0, 60);
}
}
void GSM_Begin()
{
while(1)
{
LCD_Command(0xc0);
USART_SendString("ATE0\r"); /* send ATE0 to check module is ready or not */
_delay_ms(500);
if(strstr(buff,"OK"))
{
GSM_Response();
memset(buff,0,160);
break;
}
else
{
LCD_String("Error");
}
}
_delay_ms(1000);
LCD_Clear();
LCD_String_xy(1,0,"Text Mode");
LCD_Command(0xc0);
USART_SendString("AT+CMGF=1\r"); /* select message format as text */
GSM_Response();
_delay_ms(1000);
}
void GSM_Msg_Delete(unsigned int position)
{
buffer_pointer=0;
char delete_cmd[20];
/* delete message at specified position */
sprintf(delete_cmd,"AT+CMGD=%d\r",position);
USART_SendString(delete_cmd);
}
void GSM_Delete_All_Msg()
{
USART_SendString("AT+CMGDA=\"DEL ALL\"\r"); /* delete all messages of SIM */
}
bool GSM_Wait_for_Msg()
{
char msg_location[4];
int i;
_delay_ms(500);
buffer_pointer=0;
while(1)
{
/*eliminate "\r \n" which is start of string */
if(buff[buffer_pointer]=='\r' || buff[buffer_pointer]== '\n'){
buffer_pointer++;
}
else
break;
}
/* "CMTI:" to check if any new message received */
if(strstr(buff,"CMTI:")){
while(buff[buffer_pointer]!= ',')
{
buffer_pointer++;
}
buffer_pointer++;
i=0;
while(buff[buffer_pointer]!= '\r')
{
msg_location[i]=buff[buffer_pointer]; /* copy location of received message where it is stored */
buffer_pointer++;
i++;
}
/* convert string of position to integer value */
position = atoi(msg_location);
memset(buff,0,strlen(buff));
buffer_pointer=0;
return true;
}
else
{
return false;
}
}
/* ISR routine to save responses/new message */
ISR(USART_RXC_vect)
{
buff[buffer_pointer] = UDR; /* copy UDR (received value) to buffer */
buffer_pointer++;
status_flag = 1; /* flag for new message arrival */
}
void GSM_Send_Msg(char *num,char *sms)
{
char sms_buffer[35];
buffer_pointer=0;
sprintf(sms_buffer,"AT+CMGS=\"%s\"\r",num);
USART_SendString(sms_buffer); /*send command AT+CMGS="Mobile No."\r */
_delay_ms(200);
while(1)
{
if(buff[buffer_pointer]==0x3e) /* wait for '>' character*/
{
buffer_pointer = 0;
memset(buff,0,strlen(buff));
USART_SendString(sms); /* send msg to given no. */
USART_TxChar(0x1a); /* send Ctrl+Z */
break;
}
buffer_pointer++;
}
_delay_ms(300);
buffer_pointer = 0;
memset(buff,0,strlen(buff));
memset(sms_buffer,0,strlen(sms_buffer));
}
void GSM_Calling(char *Mob_no)
{
char call[20];
sprintf(call,"ATD%s;\r",Mob_no);
USART_SendString(call); /* send command ATD<Mobile_No>; for calling*/
}
void GSM_HangCall()
{
LCD_Clear();
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)
{
_delay_ms(2);
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;
}
}
_delay_ms(1);
timeout++;
}
status_flag=0;
}
void GSM_Response_Display()
{
buffer_pointer = 0;
int lcd_pointer = 0;
while(1)
{
/* search for \r\n in string */
if(buff[buffer_pointer]== '\r' || buff[buffer_pointer]== '\n')
{
buffer_pointer++;
}
else
break;
}
LCD_Command(0xc0);
while(buff[buffer_pointer]!='\r') /* display response till "\r" */
{
LCD_Char(buff[buffer_pointer]);
buffer_pointer++;
lcd_pointer++;
if(lcd_pointer==15) /* check for end of LCD line */
LCD_Command(0x80);
}
buffer_pointer = 0;
memset(buff,0,strlen(buff));
}
void GSM_Msg_Read(int position)
{
char read_cmd[10];
sprintf(read_cmd,"AT+CMGR=%d\r",position);
USART_SendString(read_cmd); /* read message at specified location/position */
GSM_Msg_Display(); /* display message */
}
void GSM_Msg_Display()
{
_delay_ms(500);
if(!(strstr(buff,"+CMGR"))) /*check for +CMGR response */
{
LCD_String_xy(1,0,"No message");
}
else
{
buffer_pointer = 0;
while(1)
{
/*wait till \r\n not over*/
if(buff[buffer_pointer]=='\r' || buff[buffer_pointer]== 'n') {
buffer_pointer++;
}
else
break;
}
/* search for 1st ',' to get mobile no.*/
while(buff[buffer_pointer]!=',')
{
buffer_pointer++;
}
buffer_pointer = buffer_pointer+2;
/* extract mobile no. of message sender */
for(int i=0;i<=12;i++)
{
Mobile_no[i] = buff[buffer_pointer];
buffer_pointer++;
}
do
{
buffer_pointer++;
}while(buff[buffer_pointer-1]!= '\n');
LCD_Command(0xC0);
int i=0;
/* display and save message */
while(buff[buffer_pointer]!= '\r' && i<31)
{
LCD_Char(buff[buffer_pointer]);
message_received[i]=buff[buffer_pointer];
buffer_pointer++;
i++;
if(i==16)
LCD_Command(0x80); /* display on 1st line */
}
buffer_pointer = 0;
memset(buff,0,strlen(buff));
}
status_flag = 0;
}
Video of Send SMS using SIM900 using ATmega16/32
Components Used |
||
---|---|---|
ATmega 16 ATmega 16 |
X 1 | |
Atmega32 Atmega32 |
X 1 | |
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. |
X 1 | |
LCD16x2 Display LCD16x2 Display |
X 1 |