Hi friends !
Here I am showing a microcontroller based project called the "GSM Based Voting System". Using this system you can ask your users to vote for any of the four options. Four available options are identified by a letters 'A', 'B', 'C' and 'D'. User can vote for any option by sending a text message to the mobile number.
For example if you want to create a poll like this.
Which is your favorite phone brand?
A: Nokia
B: Apple
C: Samsung
D: L.G.
So your user can vote for any of the four brands by sending a message like this
VOTE x
where x is the choice he/she wish to vote for. For example if they want to vote for Nokia, then they should send a message like this :
VOTE A
The number of vote received for each option is shown in real time on the LCD Module. The votes are stored in the internal EEPROM of the AVR so they are not lost on power failures. That means even if you switch off the device and switch it on after few days (or few years!) it will remember the votes !
![]() |
Fig. SMS Based Voting System |
![]() |
Fig. Vote Count Display |
![]() |
Fig. Voting Success ! |
![]() |
Fig. Reply for Correct and Incorrect Votes. |
Things Required and Estimate Cost
| S. No. | Item | Image | Cost |
| 1 |
Contains the core AVR circuit including 5v regulator, reset, ISP. It also includes easy interface for 2x16 character LCD. |
Rs.1264 |
|
| 2 |
For getting connected to the GSM Network. |
Rs.1699 |
|
| 3 | Single Pin Female to Female Burg Wires Used to interconnect the two boards.
|
Rs. 50 |
|
| 4 |
To upload the program to the development board. |
Rs. 489 |
|
| 5 |
To power up xBoard v2.0 and the GSM Module. You need two of these. |
Rs. 360 |
|
| TOTAL | Rs. 3862 |
- Also required is a working SIM card with available balance.
- And a working mobile phone to send a testing vote to the system.
Schematic for the Project
The project is based around AVR ATmega32 microcontroller which is connected to a 16x2 LCD Module and a SIM300 GSM Module. We have used xBoard 2.0 development board to accelerate our development process. It is a ready made ATmega32 board with built in 16x2 LCD Module and many other common peripherals. So if you are working with xBoard 2.0 then you only need to connect the GSM Module. It involves connecting only three wires!
Fig. SIM300 and ATmega32 Schematic |
We have made the prototype using xBoard development board because it has ATmega32 core circuit, 5v power supply circuit and the LCD module.
Fig. SIM300 and ATmega32 Connection |
![]() |
Fig. SIM300's PINs |
![]() |
Fig. xBoard's USART PINs |
![]() |
Fig. GSM Module connected with ATmega32 |
After completing the connection, power up xBoard 2.0 using a 12v 500 ma DC adaptor. And program the board with the HEX file for the project(download available at the end of article). Then insert a SIM card in SIM300 module and power it up using a 12v 2A DC Adaptor. Restart the xBoard 2.0 using its reset button.
Here are some links for your help.
- For programming xBoard 2.0 you will need an USB AVR Programmer.
- The steps of programming are given here: http://xboard.extremeelectronics.co.in/Programming.htm
- More information on various parts of xBoard 2.0 are here: http://xboard.extremeelectronics.co.in/Know_xBoard.htm
NOTE
The board shown below is the new version of SIM300 Modem, it can also be used to make this project. New version is much smaller and low cost.
Fig. SIM300 Module New Version |
Source Code for the Project
/******************************************************************************
SMS Based Voting System.
NOTICE
--------
NO PART OF THIS WORK CAN BE COPIED, DISTRIBUTED OR PUBLISHED WITHOUT A
WRITTEN PERMISSION FROM EXTREME ELECTRONICS INDIA. THE LIBRARY, NOR ANY PART
OF IT CAN BE USED IN COMMERCIAL APPLICATIONS. IT IS INTENDED TO BE USED FOR
HOBBY, LEARNING AND EDUCATIONAL PURPOSE ONLY. IF YOU WANT TO USE THEM IN
COMMERCIAL APPLICATION PLEASE WRITE TO THE AUTHOR.
Change Log
21 Dec 2012 - Added EEPROM Initialization on first boot, added function
SIM300SetTextMode()
WRITTEN BY:
AVINASH GUPTA
me@avinashgupta.com
*******************************************************************************/
#include <avr/io.h>
#include <util/delay.h>
#include <avr/eeprom.h>
#include <string.h>
#include "lib/lcd/lcd.h"
#include "lib/sim300/sim300.h"
#include "lib/usart/usart.h"
void Halt();
void Reply(const char *num,uint8_t stat);
int main(void)
{
//Initialize LCD Module
LCDInit(LS_NONE);
//Intro Message
LCDWriteString("Msg Based Voting");
LCDWriteStringXY(0,1,"By Avinash Gupta");
_delay_ms(1000);
LCDClear();
//Initialize SIM300 module
LCDWriteString("Initializing ...");
int8_t r= SIM300Init();
_delay_ms(1000);
//Check the status of initialization
switch(r)
{
case SIM300_OK:
LCDWriteStringXY(0,1,"OK !");
break;
case SIM300_TIMEOUT:
LCDWriteStringXY(0,1,"No response");
Halt();
case SIM300_INVALID_RESPONSE:
LCDWriteStringXY(0,1,"Inv response");
Halt();
case SIM300_FAIL:
LCDWriteStringXY(0,1,"Fail");
Halt();
default:
LCDWriteStringXY(0,1,"Unknown Error");
Halt();
}
_delay_ms(1000);
//Set message format to text
r= SIM300SetTextMode();
LCDClear();
LCDWriteString("Set Text Mode ..");
_delay_ms(1000);
//Check the result of above operation
switch(r)
{
case SIM300_OK:
LCDWriteStringXY(0,1,"OK !");
break;
case SIM300_TIMEOUT:
LCDWriteStringXY(0,1,"No response");
Halt();
case SIM300_FAIL:
LCDWriteStringXY(0,1,"Fail");
Halt();
default:
LCDWriteStringXY(0,1,"Unknown Error");
Halt();
}
_delay_ms(1000);
//IMEI No display
LCDClear();
char imei[16];
r=SIM300GetIMEI(imei);
if(r==SIM300_TIMEOUT)
{
LCDWriteString("Comm Error !");
Halt();
}
LCDWriteString("Device IMEI:");
LCDWriteStringXY(0,1,imei);
_delay_ms(1000);
//Manufacturer ID
LCDClear();
char man_id[48];
r=SIM300GetManufacturer(man_id);
if(r==SIM300_TIMEOUT)
{
LCDWriteString("Comm Error !");
Halt();
}
LCDWriteString("Manufacturer:");
LCDWriteStringXY(0,1,man_id);
_delay_ms(1000);
//Manufacturer ID
LCDClear();
char model[48];
r=SIM300GetModel(model);
if(r==SIM300_TIMEOUT)
{
LCDWriteString("Comm Error !");
Halt();
}
LCDWriteString("Model:");
LCDWriteStringXY(0,1,model);
_delay_ms(1000);
//Check Sim Card Presence
LCDClear();
LCDWriteString("Checking SIMCard");
_delay_ms(1000);
r=SIM300IsSIMInserted();
if (r==SIM300_SIM_NOT_PRESENT)
{
//Sim card is NOT present
LCDWriteStringXY(0,1,"No SIM Card !");
Halt();
}
else if(r==SIM300_TIMEOUT)
{
//Communication Error
LCDWriteStringXY(0,1,"Comm Error !");
Halt();
}
else if(r==SIM300_SIM_PRESENT)
{
//Sim card present
LCDWriteStringXY(0,1,"SIM Card Present");
_delay_ms(1000);
}
//Network search
LCDClear();
LCDWriteStringXY(0,0,"SearchingNetwork");
uint8_t nw_found=0;
uint16_t tries=0;
uint8_t x=0;
while(!nw_found)
{
r=SIM300GetNetStat();
if(r==SIM300_NW_SEARCHING)
{
LCDWriteStringXY(0,1,"%0%0%0%0%0%0%0%0%0%0%0%0%0%0%0%0");
LCDWriteStringXY(x,1,"%1");
LCDGotoXY(17,1);
x++;
if(x==16) x=0;
_delay_ms(50);
tries++;
if(tries==600)
break;
}
else
break;
}
LCDClear();
if(r==SIM300_NW_REGISTERED_HOME)
{
LCDWriteString("Network Found");
}
else
{
LCDWriteString("Cant Connt to NW!");
Halt();
}
_delay_ms(1000);
LCDClear();
//Show Provider Name
char pname[32];
r=SIM300GetProviderName(pname);
if(r==0)
{
LCDWriteString("Comm Error !");
Halt();
}
LCDWriteString(pname);
_delay_ms(1000);
//Voting system
uint16_t votes[4];
votes[0]=eeprom_read_word((const uint16_t *)0);
votes[1]=eeprom_read_word((const uint16_t *)2);
votes[2]=eeprom_read_word((const uint16_t *)4);
votes[3]=eeprom_read_word((const uint16_t *)6);
if(votes[0]==0xFFFF)
{
//No valid data on eeprom, so set all votes to 0
votes[0]=votes[1]=votes[2]=votes[3]=0;
//Clear EEPROM too
eeprom_write_word((uint16_t *)0,0);
eeprom_write_word((uint16_t *)2,0);
eeprom_write_word((uint16_t *)4,0);
eeprom_write_word((uint16_t *)6,0);
}
//Wait for MSG
uint8_t id;
char oa[20];//Origin Address ()the number from where the msg came
UFlushBuffer();
while(1)
{
LCDClear();
uint8_t x=0;
LCDWriteStringXY(0,0,"A= B=");
LCDWriteStringXY(0,1,"C= D=");
LCDWriteIntXY(2,0,votes[0],4);
LCDWriteIntXY(9,0,votes[1],4);
LCDWriteIntXY(2,1,votes[2],4);
LCDWriteIntXY(9,1,votes[3],4);
while(SIM300WaitForMsg(&id)!=SIM300_OK)
{
if(x)
{
LCDWriteStringXY(15,0,"%3");
x=0;
}
else
{
LCDWriteStringXY(15,0,"%4");
x=1;
}
}
LCDWriteStringXY(15,0,"%2");
_delay_ms(1000);
//Now read the msg
char msg[300];
r=SIM300ReadMsg(id,msg,oa);
if(r==SIM300_OK)
{
if(strcasecmp(msg,"VOTE A")==0)
{
votes[0]++;
eeprom_write_word((uint16_t *)0,votes[0]);
Reply(oa,1);
}
else if(strcasecmp(msg,"VOTE B")==0)
{
votes[1]++;
eeprom_write_word((uint16_t *)2,votes[1]);
Reply(oa,1);
}
else if(strcasecmp(msg,"VOTE C")==0)
{
votes[2]++;
eeprom_write_word((uint16_t *)4,votes[2]);
Reply(oa,1);
}
else if(strcasecmp(msg,"VOTE D")==0)
{
votes[3]++;
eeprom_write_word((uint16_t *)6,votes[3]);
Reply(oa,1);
}
else
{
//Invalid Choice
Reply(oa,0);
}
_delay_ms(3000);
}
else
{
LCDClear();
LCDWriteString("Err Reading Msg !");
_delay_ms(3000);
}
//Finally delete the msg
if (SIM300DeleteMsg(id)!=SIM300_OK)
{
LCDWriteString("Err Deleting Msg !");
_delay_ms(3000);
}
}
Halt();
}
void Halt()
{
while(1);
}
void Reply(const char *num,uint8_t stat)
{
uint8_t ref;
int8_t r;
if(stat)
r=SIM300SendMsg(num,"Your vote has been successfully registered, Thank ! :)",&ref);
else
r=SIM300SendMsg(num,"Invalid vote ! Please send VOTE x, where x can be A,B,C or D.Thanks!",&ref);
if(r==SIM300_OK)
{
return;
}
else if(r==SIM300_TIMEOUT)
{
LCDClear();
LCDWriteStringXY(0,0,"Can't Send Reply!");
LCDWriteStringXY(0,1,"Time out !");
_delay_ms(3000);
}
else
{
LCDClear();
LCDWriteStringXY(0,0,"Can't Send Reply!");
LCDWriteStringXY(0,1,"Fail !");
_delay_ms(3000);
}
}
The source code is written in C language and compiled using the avr-gcc compiler with the help of latest Atmel Studio 6 IDE. The source code is dependent on the following libraries.
- The LCD Library.
- The USART Library.
- The SIM300 library.
Notes
- If you are using a new ATMega32 MCU from the market set the LOW FUSE as 0x3F and HIGH FUSE are 0xC9.
- If you get NO display on LCD, adjust the contrast adjust preset RV1.
- Brownout detector is Enabled to prevent corruption of EEPROM, Brownout level is set to 4.0 volts. The above fuse bits ensure the proper brown out detector settings.
![]() |
Fig.: Setting the Fuse bytes. |
Reference
This project is based on SIM300 GSM Module, following tutorial explains more about the module :
Downloads
Help Us!
We try to publish beginner friendly tutorials for latest subjects in embedded system as fast as we can. If you like these tutorials and they have helped you solve problems, please help us in return. You can donate any amount as you like securely using a Credit or Debit Card or Paypal.
We would be very thankful for your kind help.
By
Avinash Gupta
Facebook,
Follow on Twitter.
www.AvinashGupta.com
me@avinashgupta.com











Hello Avinash,
Your tutorials on GSM interface has really boosted my moral to venture in this area. Great job indeed. I had a project in my mind but could not get started due to lack of exposure, which your tutorials have given me. I seek a little guidance from you in this regard. It is as follows:-
Make a call to GSM module and get a voice message recorded. Then send a sms containing few mobile numbers. Now, the GSM module should call each of these numbers and play the recorded message.
Thanks in advance
give the advantage of this project
Hi, A , avinash can you please send me some data sheets or some IEE papers on the same for my refference. this would help me for my seminar.
Please reply me.
Thanks You
Rupa.
Dear Sir,
I have build a same project as an interest and learning basics of GSM module. I have compiled and downloaded the program. However, when one vote registered it automatically halted sometimes only VOTE A works nad vote B not works some time vice versa.
Can you please guide me?
What is your Order ID for purchase of xBoard and GSM Module?
Hi kiran… I’m also trying the same project. In that It simply waits for a msg. Not receiving any msg. Do i need to change anything in the code or connections? please let me know.
would you mind plz give me the pcb layout for the sms based voting system.
can this project turn to STUDENT RESULT CHECKER SMS RETRIEVAL?
May i know why do we use L1 and C3?
how do i reset all the counters???