SIM900A GSM module Interfacing with AVR ATmega16/ATmega32

SIM900A GSM module is a communication device which is used to make or receive calls, send or receive SMS, connecting to the internet over GPRS.

35k views5 min readUpdated Aug 9, 2023
SIM900A GSM module Interfacing with AVR ATmega16/ATmega32

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.

GSM module
Sim900A Module

 

SIM900A GSM Module Interfacing With Atmega16/32

Interfacing Diagram of ATmega 16 With Sim900A
Interfacing Sim900A GSM Module with ATmega 16

 

 

 

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

Powered byMouser Electronics
  • ATmega 16

    ATmega 16

    556-ATMEGA16L-8PU

  • Atmega32

    Atmega32

    556-ATMEGA32-16PU

  • 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.

    170-M031-D

  • LCD16x2 Display

    LCD16x2 Display

    485-1447

Downloads

Comments39

Join the discussion — share a question or tip.

  • CL
    ClaretesNishoban

    will it work for atmega32? I am getting message undeclared USART....... and LCD.....

  • AM
    Amanpratapsingh

    Hi, I checked the code on Atmega16, it is working... But when I dump the same code on Atmega1284P... It is not working... Kindly help

    • AM
      Amanpratapsingh

      I am also using Osc freq 8MHz with 9600 baudrate

  • DZ
    dz1345ddd

    hi code not work.

  • SU
    suwasbohora

    the code is working fine but when the whole system is power off and then on for the first time, lcd display GSM Initializing Error and if i again reset the microcontroller then it works fine, can anybody help me that if the gsm module is not ready for communication after power on then the lcd module again check that the gsm module is ready or not?in this code it does not working. I know gsm module takes little time to initializing but the lcd is not checking if the module is ready or not so how to solve it? please!!!

  • TE
    teswar159

    Hi sir I got a funny issue Im using atmega 16a and gsm module sim 900a when I connect gsm module to USB to TTL and send commands it works fine But when I connect gsm module to the atmega 16a MCU im unable to control it with code Please help me, sir Check the below pics for clarity https://1drv.ms/u/s!AgeRUh26in4nlUHE5ksF2P_NYIkr?e=BwIdXu

  • CH

    Good morning, pls i dont understand what this line of code is doing: if(CRLF_Found++==2)........in gsmresponse function

  • CH
    chandrasekhar3841

    how can I send sms at a fixed time using GPS I am using this GPS module. http://bigbelectronics.in/product.php?product=sim800l-gprs-gsm-module-microsim-card-core-boardquad-band-ttl-serial-port-pcbantenna

  • VO

    hi, i have some proplem: #define SREG _SFR_IO8(0x3F) what does it do? and if i use F_CPU 16Mhz , do code have change? i use atmel studio 6 to compile tks

    • LO
      lokeshc

      This macro is for SREG (Status Register) which is used while dealing with an interrupt routine. whereas 0x3F is an I/O address of SREG. sometimes it is necessary to check the status register before and after interrupt service routine is getting affected or not. If you change the F_CPU 16MHz, then your delay functions need to be changed for the proper 1ms delay.

    • VO

      Replying to @lokeshc

      thanh you. if i dont use (#define SREG _SFR_IO8(0x3F)), will this code have logic error ?

    • LO
      lokeshc

      Replying to @vophungthiennhan1997

      Just comment it. Your code will work.

    • VO

      Replying to @lokeshc

      thank you

  • AN

    What is the code for just sending sms

    • LO
      lokeshc

      Use following function for sending message by just passing number and message string to the following function GSM_SEND_MSG()

  • OM
    omedulislaminfo

    Code is not works !!!!!!!!!!!1

    • LO
      lokeshc

      What happened? Which atmega you are using &amp; what is your oscillator frequency

  • SU
    suwasbohora

    I am wanting if someone call on the number (missed call) then that number should reply with sms. please help

  • RA

    I'm using atmega16a with 8mhz external osci. In beginusart OK is not being returned. The module works with arduino uno. Is it due to baud rate what could be the possible errors?

    • AH
      AhmedIbrahim

      ATMEGA32 , I have the same problem In GSM_begin OK is not being returned , i try it by simulation in proteus .

    • LO
      lokeshc

      Replying to @AhmedIbrahim

      check for the connection first. while building project verify your atmega used in IDE is same as atmega used on hardware.

  • OO
    oozecom11

    Please provide your email address

  • OO
    oozecom11

    Hello. How to sms sending. Can you see me writing source :))

    • LO
      lokeshc

      hello, you can use the following function for sending SMS, void GSM_Send_Msg(char *num,char *sms) In this function you need to provide mobile no. and sms which you want to send. This function is given in above program. you can have a try. all the best!!!

  • BR
    brijeshpratap716

    Bro it's not showing anything on LCD. i have checked my connections many time but it still not showing anything Ans should i have to make any change if i use indian mobile number?? and i am making notice board i don't need of calling..i only wanna that message should display on LCD only then for this purpous will i need to write mobile number in programming???

    • LO
      lokeshc

      But I used the above program for my customized application and it works. Bro if anything is not working for you then you should go step by step. 1st try to implement LCD only. if it is working then test the USART in this code and if everything is working then go for GSM programming.

  • LO
    lokeshc

    May it is because of SIM memory which is limited. So, after few messages received it gets overflow. Here, buffer is clearing continuously so may be buffer is not a problem. Yes but if we want to read large message in that case it should more than 160 characters.

  • AN
    Andre3000· edited

    When we are calling the GSM _Calling () function in main, do we need to hard code the mobile number here like: GSM_Calling("90xxxxxxxx") Or do we need to only use the variable GSM_Calling(Mobile_no)? I figured that the mobile number is supposed to be extracted when a message is sent to the module. However, the call function does not work unless I actually hard code the mobile number. I just need a little further clarification.

    • LO
      lokeshc

      In above program, controller waits for message to receive from user. When call me message received from user then above program extract the Mobile no. from received message and dial a call. So, if you want to use calling function without rely on message then you need to provide mobile no. Otherwise it will extract mobile no. from message.

    • AB
      abhalerao0123

      Replying to @lokeshc

      earlier when I was referring this program I had same doubt but after reading program I cleared my doubt. you can see GSM_Msg_Display() In this function mobile no. is extracted from received message.

    • AN
      Andre3000· edited

      Replying to @abhalerao0123

      Thank you for your help. The number extraction was not working for me until in the for loop for(int i=0;i&lt;=12;i++) { Mobile_no[i] = buff[buffer_pointer]; buffer_pointer++; } I changed i&lt;=12 to 11. I think it may have something to do with Indian mobile numbers and US mobile numbers being of different lengths.

    • LO
      lokeshc

      Replying to @Andre3000

      Yes, it may be.

    • AR
      aramzi

      Replying to @lokeshc

      Hi, I need to responce by message to message received from user, I use GSM_Send_Msg(Mobile_no,"I'll call you later\r"); } But don't work. Please help.

  • RI
    riy

    I have used the files given above, but i cant get anything on the LCD. Can someone please help me as it is urgent.

    • AU
      authorized

      i think you need to check hardware connection again, since most of the time it solves the matters. and when you confirm with your hardware connection then it can be solved with program check/debug. go step by step, after hardware connection check for only lcd working and the remaining

  • EB
    ebenezeridiong

    Tried the simulation with proteus, it works just fine. Thanks to you boss!

    • AH
      AhmedIbrahim

      how , can you send me the simulation

  • PR
    prabueac

    am looking for #include "LCD_16x2_H_file.h" /* include 16x2 LCD Header file */ #include "USART_Interrupt.h" /* include USART Header file */ Where can i find these files ?

    • LO
      londheshardul

      @prabu Appu: I found these files on this same page in Supporting Files--&gt; source code --&gt;ATmega16 Interface with GSM Project File