/************************************************************************************************
      
   File Name : LINE_FOLLOWER.C
   Program Compiler : C
   Program Description : White line follower Algorithm based program in C.
   Intended AVR Platform : ATMEL AVR ATmega16

   Author : harrypotterjkw 
   Date : 28th October 2007
   Contact info : harrypotterjkr@gmail.com

   Disclaimer/Credit : The material in this file is not completely my original work. In 
                       understanding the idea behind it and the technique of programming
                       the AVR I have taken help from materials from the sites :
                                         societyofrobots.com
                                             sparkfun.com
                         http://www.doc.ic.ac.uk/~ih/doc/stepper/control2/vc/single.c

*************************************************************************************************/
  

//Include necessary header files*****************************************************************

#include<avr/io.h>
#include<a2d.h>
//#include<global.h>


//Declare necessary functions********************************************************************

void msdelay(int);                 //This function causes dealy in milliseconds
void go_unit_left(void);           //This function causes the right stepper to rotate 3.6 degree
void go_unit_right(void);          //This function causes the left stepper to rotate 3.6 degree
void go_unit_straight(void);       //This function causes left stepper motor to rotate ...
                                   //  ...unit step clockwise and the right stepper unit step...
                                   //  ...anticlockwise (unit step=3.6 degree)


//Main function starts here***********************************************************************

int main(void)
{
 //Configure PORTA as input(sensor readings) and PORTC as output port(to drive motors)
 DDRA=0x00;
 PORTA=0x00;       //Turn off pull up resistors
 DDRC=0xFF;


 //Initialize a2d functions and PORTA to act as adc port
 a2dInit();                                 //Initialize analog to digital converter
 a2dSetPrescaler(ADC_PRESCALE_DIV32);       //configure ADC prescaling
 a2dSetReference(ADC_REFERENCE_AVCC);       //Configure ADC reference voltage
 
 //Initialize variables
 int left_sensor=0;
 int right_sensor=0;
 

 //Turn on the indicator led connected to PORTD pin 0 by making PD0 low
 PORTD|=(1<<0);


 //Enter the main infinite loop
 
 while(1)
 {
   
          msdelay(1);   //cause a 1 ms delay
          left_sensor=a2dConvert8bit(0);         //Takes the left and right sensor readings...
          right_sensor=a2dConvert8bit(1);        //...from PA0 and PA1 (ADC0 and ADC1).
          msdelay(1);                           //Another 1 ms delay for the sensor readings to stabelize 
  
          //decision making
  
          if(left_sensor>right_sensor)
              
              go_unit_left();

          else if(left_sensor<right_sensor)

              go_unit_right();

          else
 
              go_unit_straight();

          msdelay(10);
 } 
   
 return 0;
}

//Main function ends here***********************************************************************
//************************************************************************************************

//Other function definitions start here*********************************************************

void msdelay(int x)           //Assuming 1MHz clock speed (default for ATmega16)...
{                             // ...1 clock cycle=1microsecond (us)...
 x=50*x;                      // ...now most of the instructions of AVR are single clock... 
 while(x>0)                   // ...cycle executable. Assuming the assembly code of this ... 
   x--;                       // ...function has 20 instructions (20 for x-- and ...
}                             // ...1 for while) thus x*50*20/(1MHz)= x milliseconds.
                              // The above calculation is approx as actually "while" and ...
                              // ..."x--" take 21 instructions to complete.


void go_unit_left(void)
{
 msdelay(10);
 PORTC=0x01;
 msdelay(10);
 PORTC=0x02;
 msdelay(10);
 PORTC=0x04;
 msdelay(10);
 PORTC=0x08;
 msdelay(10);
}

void go_unit_right(void)
{
 msdelay(10);
 PORTC=0x10;
 msdelay(10);
 PORTC=0x20;
 msdelay(10);
 PORTC=0x40;
 msdelay(10);
 PORTC=0x80;
 msdelay(10); 
}

void go_unit_straight(void)
{
 msdelay(10);
 PORTC=0x18;
 msdelay(10);
 PORTC=0x24;
 msdelay(10);
 PORTC=0x42;
 msdelay(10);
 PORTC=0x81;
 msdelay(10); 
}
    
//Program ends here*************************************************************************
//********************************************************************************************
//********************************************************************************************                    
