Our team has created an infra-red following robot, this is basically an example if you want to use sensors and want to know how. The sensors are extremely sensitive and more than one sensor is on at any given time. Thus, the algorithm counts the sum of the last four signals, etc… see below.
Basically, if you have a remote control from any TV, you would simply point it and press any button faced towards the eduSensor robot and it will come toward you. The algorithm has proven to be 100% accurate and the robot never wanders off course unless you stop emitting the infra-red signal.
Sample of it working:
http://www.hartrobot.com/eduSensor1.avi
Tools needed: 2 multi-speed motors, 4 infra-red sensors, eduRC.
If you want the full source code, you can leave a message and I’ll get it to you. Here are the changes:
//HartBurn Infrared follower:
/*
Four Sensors, Digital/Analog in pins 1-4
1 - Front sensor
2 - Right sensor
3 - Left sensor
4 - Back sensor
Two motors, PWM output 1 and 8.
1 - Right motor
8 - Left motor
*/
#define forward 1
#define left 2
#define right 3
#define spin 4
#define second 1000/17
#define NULL 0
typedef enum
{
true=1, false=0
} bool;
typedef struct
{
unsigned char value;
int sensor;
int last[4];
int sum;
int action;
} list;
list positions[4];
void add_value(list *ptr);
void sum_values(list *ptr);
int get_state(void);
void search(void);
// Init
IO1 = IO2 = IO3 = IO4 = INPUT;
Set_Number_of_Analog_Channels(FOUR_ANALOG); /* First four pins are analog input */
positions[0].action = forward;
positions[1].action = right;
positions[2].action = spin;
positions[3].action = left;
//Misc functions
void add_value(list *ptr)
{
int i = 0;
for(i = 0; i < 3; i++)
{
ptr->last[0] = ptr->last*;
}
ptr->last[3] = ptr->value;
}
void sum_values(list *ptr)
{
int i = 0;
ptr->sum = 0;
for(i = 0; i < 4; i++)
{
ptr->sum += ptr->last*;
}
}
int get_state(void)
{
int i = 0;
unsigned char min = positions[0].value;
int state = positions[0].action;
for(i = 1; i < 4; i++)
{
if (positions*.value < min)
{
min = positions*.value;
state = positions*.action;
}
}
return state;
}
/* Locates infra-red signals, drives towards them. */
void search(void)
{
static int timer = 0;
int state = 0;
int i = 0;
/* Input signals */
positions[0].value = (unsigned char) (Get_Analog_Value(rc_ana_in01) >> 2); // Forward
positions[1].value = (unsigned char) (Get_Analog_Value(rc_ana_in02) >> 2); // Right
positions[2].value = (unsigned char) (Get_Analog_Value(rc_ana_in03) >> 2); // Spin
positions[3].value = (unsigned char) (Get_Analog_Value(rc_ana_in04) >> 2); // Left
if (timer == 0)
{
pwm01 = 127;
pwm08 = 127;
}
else
timer--;
/* All sensors are receiving full infra-red signal, don't do anything. */
if (positions[0].value + positions[1].value + positions[2].value + positions[3].value <= 0x0F)
return;
/* Continue and output only if possible signals exist, input when no signal
is 255, faint signal < 100, strong < 50, full == 2, short circuit == 0 */
if (positions[0].value < 50 || positions[1].value < 50 || positions[2].value < 50 || positions[3].value < 50)
printf("%d %d %d %d
", (int)positions[0].value, (int)positions[1].value, (int)positions[2].value, (int)positions[3].value);
else
return;
/* Recalculate signal continuity measures, lowest sum is most continuous */
for(i = 0; i < 4; i++)
{
add_value(&positions*);
sum_values(&positions*);
}
state = get_state();
if (state == forward)
{
timer = 50;
pwm01 = 55;
pwm08 = 200;
}
else if(state == left)
{
/* Lag left using forward's timer */
if (timer < 5) timer = 5;
pwm01 = 55;
pwm08 = 55;
}
else if(state == right)
{
/* Lag right using forward's timer */
if (timer < 5) timer = 5;
pwm01 = 200;
pwm08 = 200;
}
else if(state == spin)
{
/* Spin long enough till another sensor is in range */
timer = 20;
pwm01 = 200;
pwm08 = 200;
}
}
void Process_Data_From_Master_uP(void)
{
Getdata(&rxdata); /* Get fresh data from the master microprocessor. */
+search();
Putdata(&txdata);
}