Electronic Voting Machine using Atmega16

In this project, we are going to design and develop a simple electronic voting machine using Atmega 16 of AVR family. As I am going to implement this via Interrupt method therefore in this article, we will learn about How to Initialise and use External Interrupt in Atmega 16. Also, I am expecting that you guys have basic knowledge of Interrupts. So, let’s get started.

The Project

In this project-electronic voting machine using Atmega 16, we are going to display the vote count of each candidate in front of the name of candidate itself. We are going to develop the voting system for the size of two people. Because there are total 3 External Interrupts(actually 4-The Reset) therefore, we cannot make a voting system greater than 3 people implementing Interrupt Method using Atmega 16. For more than 3 people system, if we are choosing an Interrupt method, we have to choose any other microcontroller which has more external interrupts or we can choose Polling Method. By using PollingMethod, we can make this system for up to 32 members using Atmega16. But the thing is, polling method is less accurate than the Interrupt method.(For more difference between Polling and Interrupt)

External Interrupt

There are three external interrupts that we can program using Atmega16. These Pins are PIND0(PIN16), PIND1(PIN17), PINB2(PIN3). Here we are going to learn how to activate each interrupt and how to write ISR(Interrupt Service Routine).

So, there are various registers for setting up the Interrupts. These are:

  • MCUCR (MCU Control register)

 

 

Note the bits highlighted. The bits-ISC11, ISC10, ISC01, ISC00 are used set the triggering of the particular interrupt. That means at which part of the signal, it should trigger the ISR. The table below will give you more idea of what I am trying to explain.

Interrupt in AVR

Same is with ISC11 and ISC10, but it’s associated with INT1. So, the value of these bits is going to decide how the interrupt signal is triggering the microcontroller to execute the ISR.

 

  • MCUSR (MCU Control and Status Register)

MCUSR register in Atmega16

You may have noticed that in the first register, the INT2 interrupt is not mentioned. Well, that’s because we are going to control it from this register. INT2 is edge triggered only. Setting the ISC2 bit is going to activate it in edge-triggered mode.

  • GICR  (General Interrupt Control Register)

GICR Register

This register mask/unmask the external interrupts. Setting the bits ‘1’ means you are activating the particular interrupt.

Schematic Diagram

The schematic diagram of the circuit is shown. I have connected the switches in PinD2(INT0) and PIND3(INT1) of the Atmega16. The button connected with INT0 represent candidate”A” and the button connected with INT1 represents candidate “B”. Cool name right?

evm using Atmega16-AVR

The Program

#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>
#include <string.h>
#define F_CPU 4000000UL
char i=0,j=0,m=0;
char D[8]="        ";
	ISR(INT0_vect)
	{_delay_ms(1000);
		m=m+1;// counting the votes of A
	}
	ISR(INT1_vect)
	{
		_delay_ms(1000);
		j=j+1;// counting the votes of B
	}
	int main(void)
 {  
      DDRA=0xff;//output port declaration
	  DDRB=0xff;//output port declaration
	 GICR=(1<<INT0)|(1<<INT1);
	 MCUCR=((1<<ISC01)|(0<<ISC00)|(1<<ISC11)|(0<<ISC10));
	sei();
	LCDcmd(0x01);// clear display screen
	LCDcmd(0x0c);//Display on, Cursor Off
	LCDcmd(0x38);// 8-bit, 2 lines mode// Function set:8-bit, 2 line, 5x7 Dots
	LCDcmd(0x06);
	LCDcmd(0x80);
    while(1)
    {
		
		sprintf(D,"A-%d",m);
		LCDGoto(0,0);
		LCDdisplay(D);
		sprintf(D,"B-%d",j);
		LCDGoto(0,1);
	    LCDdisplay(D);
    }
}
void LCDcmd(char k)
{
	PORTB=k;
	PORTA=0x01;// 0 for RS, 0 for RW, 1 for EN makes 00000001 equals 1.
	_delay_ms(200);
	PORTA=0x00;// 0 for RS, 0 for RW, 0 for EN. High to low pulse required to give EN.
}
void LCDdisplay(char a[])
{
	for(i = 0; i <strlen(a) ; i++ )
	{
		PORTB = a[i];
		PORTA = 0x05;
		_delay_ms(200);
		PORTA = 0x04;
	}
}
void LCDGoto(char x, char y)
{char add;// address
	char c=0x00;
	char b=0x40;
	switch(y)
	{
		case 0: add = c+x;break;// address = 0x00+x- For first row
		case 1: add = b+x;break;// address = 0x40+x- For second row
	}
	char addcmd=(0x80|add);// final address command needed to send.
	LCDcmd(addcmd);// Sending the final address command
}

In the program, there are few things that you may miss. The ISR(INT0_vect) is actually the Interrupt Service Routine written for Interrupt 0. Similarly, the ISR(INT1_vect) is the Interrupt Service Routine written for INT1. The delay introduced is to debounce the switch(prevent it from multiple presses). Then the i and j are the counters who are counting the votes of “A” and “B”. The sei() function is used to activate all the interrupts. Rest of the program is simple enough to understand. Click on the link for LCD Interfacing or for LCDGoto() function.

Execution of  the Program

This program is executed well, both in simulator and hardware.

 

EVM using AVR

 

3 thoughts on “Electronic Voting Machine using Atmega16”

  1. Hi there, I log on to your blogs named “Electronic Voting Machine using Atmega16|Learn External Interrupt”.Your writing style is awesome, keep it up!

  2. Thermo Burn Max Ingredients

    I have to thank you for the efforts you have put in writing this website.
    I’m hoping to view the same high-grade blog posts from you later on as well.
    In fact, your creative writing abilities has inspired me to get my very own site now 😉 effer

Leave a Comment

Your email address will not be published. Required fields are marked *

Share This
Scroll to Top