Hello All, Welcome to the third part of the Obstacle Avoiding Robot Tutorial. Till now we have completed the mechanical construction and made the sensor for our robot. I have shown you how to control the motors and read values from sensor in last two parts of the tutorial. In this tutorial we create the master program for our robot. The job of the program is simple, to read values from the sensors, make a decision and command two motors. In this way our robot will roam about the room avoiding obstacles in its path.

In our program we define three constants, namely RTHRES,CTHRES and LTHRES in the following way :-

//Threshold Values For Sensor Triggering
#define RTHRES 195
#define CTHRES 275
#define LTHRES 195

The constant value next to them is the triggering values. You can get this values as described in previous tutorial. Simply run the IR Sensor Test program and bring any obstacle near the sensor at about 15cm (6 inches) and note down these values against respective sensor threshold values. Do same for all three sensor. Now the program knows when the value comes near this threshold value, the sensor has a obstacle in front of it. Note that the value shown above is may not match with the values you obtained, that OK.

In our program, we start by Initializing the Motor Subsystem and the ADC Subsystem.

//Initialize motor subsystem
MotorInit();
//Init ADCs
InitADC();

Then we start moving the robot forward. This is archived using the Call to MotorA and MotorB functions. The first argument is the direction which can be

  • MOTOR_STOP
  • MOTOR_CW
  • MOTOR_CCW

The second argument is the speed which can be between 0 and 255. We use 255 here to move at full speed.

More details on using motor with xAPI is here in xBoard v2.0's docs.

//Start Moving Forward
MotorA(MOTOR_CW,255);  //Motor A (right motor) moves Clockwise
MotorB(MOTOR_CCW,255); //Motor B (left motor) moves Counter Clockwise

If you are wondering how the above code drives our robo forward, then you need to understand the differential drive system which is described in details here.

Once our robot starts moving forward, we go inside an infinite loop, testing if some obstacle is in front of the sensor and if so turn the robot.

Code listing for Obstacle Avoiding Robot.


/******************************************************************************

Simple Obstacle Avoiding Robot Program.

Compiler : avr-gcc toolchain
IDE: AVR Studio from Atmel

For More Info Log On to 
www.eXtremeElectronics.co.in

Copyright 2008-2010 eXtreme Electronics India

                                    
                                     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.


WRITTEN BY:

AVINASH GUPTA
me@avinashgupta.com

*******************************************************************************/
#include <avr/io.h>
#include <util/delay.h>

#include "motor.h"

//Threshold Values For Sensor Triggering
#define RTHRES 195
#define CTHRES 275
#define LTHRES 195

//Function To Initialize the ADC Module
void InitADC()
{
   ADMUX=(1<<REFS0);                                     // For Aref=AVcc;

   ADCSRA=(1<<ADEN)|(1<<ADPS2)|(1<<ADPS1)|(1<<ADPS0);    //Rrescalar div factor =128

}

/* 

Function To Read ADC Channel

Argument: Channel Number between 0-7
Return Value : Between 0-1023

*/
uint16_t ReadADC(uint8_t ch)
{
   //Select ADC Channel ch must be 0-7
   ch=ch&0b00000111;
   ADMUX&=0b11100000;
   ADMUX|=ch;

   //Start Single conversion

   ADCSRA|=(1<<ADSC);

   //Wait for conversion to complete
   while(!(ADCSRA & (1<<ADIF)));

   //Clear ADIF by writing one to it

   //Note you may be wondering why we have write one to clear it

   //This is standard way of clearing bits in io as said in datasheets.
   //The code writes '1' but it result in setting bit to '0' !!!

   ADCSRA|=(1<<ADIF);

   return(ADC);
}
/* 

Simple Wait Function

Argument: NONE
Return Value : NONE

*/
void Wait()
{
   uint8_t i;
   for(i=0;i<10;i++)
      _delay_loop_2(0);
}


void main()
{
   //Initialize motor subsystem
   MotorInit();

   //Init ADCs
   InitADC();

   //Wait
   Wait();

   //Start Moving Forword

   MotorA(MOTOR_CW,255);   //Motor A (right motor) moves Clockwise
   MotorB(MOTOR_CCW,255);  //Motor B (left motor) moves Counter Clockwise

   while(1)
   {

      //Varriable To store sensor values

      uint16_t sensor_l,sensor_c,sensor_r;

      //Read Sensor Values
      sensor_r=ReadADC(0);//Right Sensor
      sensor_c=ReadADC(1);//Center Sensor
      sensor_l=ReadADC(2);//Left Sensor


      if(sensor_c > CTHRES)
      {

         //Start Rotating Left
         MotorA(MOTOR_CW,255);   //Motor A (right motor) moves Clockwise
         MotorB(MOTOR_CW,255);   //Motor B (left motor) moves Clockwise


         //Now Rotate till Path is NOT Clear
         while((sensor_r >(RTHRES-10)) || (sensor_c>(CTHRES-10)))
         {
            //Read Sensor Values
            sensor_r=ReadADC(0);//Right Sensor

            sensor_c=ReadADC(1);//Center Sensor

            _delay_loop_2(30000);
         }

         //Now Path is Clear So Move Forword
         MotorA(MOTOR_CW,255);   //Motor A (right motor) moves Clockwise

         MotorB(MOTOR_CCW,255);  //Motor B (left motor) moves Counter Clockwise


      }

      if(sensor_r > RTHRES)
      {

         //Start Rotating Left
         MotorA(MOTOR_CW,255);   //Motor A (right motor) moves Clockwise

         MotorB(MOTOR_CW,255);   //Motor B (left motor) moves Clockwise


         //Now Rotate Until Path is Clear
         while(sensor_r >(RTHRES-10))
         {
            //Read Sensor Values

            sensor_r=ReadADC(0);//Right Sensor

            _delay_loop_2(30000);
         }

         //Now Path is Clear So Move Forword
         MotorA(MOTOR_CW,255);   //Motor A (right motor) moves Clockwise

         MotorB(MOTOR_CCW,255);  //Motor B (left motor) moves Counter Clockwise


      }

      if(sensor_l > LTHRES)
      {
         //Start Rotating Right
         MotorA(MOTOR_CCW,255);  //Motor A (right motor) moves Counter Clockwise

         MotorB(MOTOR_CCW,255);  //Motor B (left motor) moves Clockwise


         //Now Rotate Until Path is Clear
         while(sensor_l >(LTHRES-10))
         {
            //Read Sensor Values

            sensor_l=ReadADC(2);//Left Sensor

            _delay_loop_2(30000);
         }

         //Now Path is Clear So Move Forword
         MotorA(MOTOR_CW,255);   //Motor A (right motor) moves Clockwise

         MotorB(MOTOR_CCW,255);  //Motor B (left motor) moves Counter Clockwise


      }

      _delay_loop_2(0);
   }
}

Downloads

<< Go To "Obstacle Avoiding Robot Part II"

By
Avinash Gupta
www.AvinashGupta.com
me@avinashgupta.com