Infrared Sensor Reading Problem

Helo guyz! i am trying to make a line following robot and in this robot I am using IR transmitter and Receiver which will help the robot to follow the line. I am getting value from the sensors using the analog pins but my problem is that i don't get smooth readings from the sensor sometimes it jumps a lot as a result my robot deviates from the line. Is there anyway by using hardware/algorithm to get smooth consistent reading from the IR pairs ?

The simplest way to smooth out the readings, is to read the value 10 times and build an average.
Did you try to use a digital input? For a line follower, black or white is all that matters. ( 0 or 1 )
The digital input has an inbuild threshold. You have to find out, if that is matching with the IR transmitter.

Other ways to filter an analog signal are pretty complicated ( kalman filtering )

For a line follower, black or white is all that matters. ( 0 or 1 )
The digital input has an inbuild threshold. You have to find out, if that is matching with the IR transmitter.

I don't know the process how to read digital values from Ir sensors. Could you proivde some link? about the inbuilt threshold. Can I change it ?

Which sensor model are you using?

One I am thinking of, would mean you have to keep the sensor in close proximity to the line. So how far away from the line is it?

Also, what is the orientation? parallel to the line or perpendicular?

http://store.extremeelectronics.co.in/Line-Sensor-Array.html
@AnalysIR
This kind of sensors. I am having problem regarding the threshold. Suppose the robot will go forward when the sensor read 0 1 1 1 0. here 0 means white surface and 1 means black. But when i ran it on the field the ir value jumps a lot and so the robot can maintain its orientation :/. Any suggestions ?

The Output of 01110 already is a digital Signal. The two outer LEDs see white and the inner three see the line.
When the Output changes to 00110 or 01100 you have to drive a little curve in the right direction.
When it reads 00010 or 01000 you have to make a sharper turn.
when you read 00000, your bot is completely off the line, and you have to drive full circles with rising Diameter until the sensor finds back.

Well its not digital actually i got these 1s and 0s using threshold. If the analog value is greater than threshold value then set it to 1 otherwise 0. I don't know how to directly get digital values fro IR sensor. But how do I smooth my value. I tried using the average but its was not good enough :frowning:

Its not obvious to me how each of the 5 pairs are isolated from each other. So if the one in the middle is transmitting, surely all the others will pick it up.

Two things I would try:

  • Wrap insulation tape around each LED Tx & Rx in a sort of tube shape pointed at the ground to minimise cross-interference.(10 tubes)
  • Cycle through each pair, one at a time and transmit a short pulse for say 1ms and simultaneously 'only' read the associated sensor.

If the first step doesn't work the second should (assuming you can control each pair independently.

If all else fails, you will need to upload some of your code.

Regarding thresholds, you will probably need to regularly adjust for background IR levels from lights or daylight. As the light level changes so too will the thresholds for white/line.

Here is my code @AnalysIR. see if there any bug in my code

#define rep(a,b,c) for(int a = b;a<c;a++)

int sensors[5] = {0, 1, 2, 3, 4} ;         // sensor arrays which are connected to 5 available analog pins
int sensor_reading = 0 ; 
int sen[5] = {0};

double sensors_average = 0.00 ;
double active_sensor = 0.00 ;
double total_sensor = 0.00 ;
double sensors_sum = 0.00;

void sensors_read()
{
        total_sensor = 0;
        active_sensor = 0 ;
        sensors_average = 1 ;
        sensors_sum = 1 ;
        rep(i,0,5)
        {
                sensor_reading = analogRead(sensors[i]) ;
                Serial.print(sensor_reading);
                Serial.print(" ");
                delay(500);
                if(sensor_reading>35)
                {  
                        active_sensor += 1 ;
                        sen[i] = 1 ;
                }
                else
                {
                        sen[i] = 0 ;
                }
                
                //Serial.print(sen[i]);
                //Serial.print(" ");
                //delay(1000);
                //total_sensor = total_sensor + sensor_reading[i] * (i+1) ;// calculate the weighted mean of sensor's reading, 1000 means nothing
                total_sensor += ((i+1) * sen[i]); // calculate the weighted mean of sensor's reading,
                /* to debug */
                /*
                Serial.print(sensors_average);
                Serial.print(' ');
                Serial.print(sensors_sum);
                Serial.print(' ');
                Serial.print(position1);
                Serial.println();
                delay(2000) ;
                */
              
        }
        
        if(total_sensor == 0 && active_sensor == 0)
        {
            total_sensor = 1;
            active_sensor = 100000000;
        }
        sensors_average = total_sensor ;
        sensors_sum = active_sensor ;
        Serial.println();
        //position1 = sensors_average / sensors_sum;
        /*
        Serial.println();
        Serial.print(sensors_average);
        Serial.print(" ");
        Serial.print(sensors_sum);
        Serial.print(" ");
        Serial.print(position1);
        Serial.print(" ");
        delay(1000);
        */
        
}

investigate these lines a bit more...

 if(sensor_reading>35)
             ......and..... 
total_sensor += ((i+1) * sen[i]); // calculate the weighted mean of sensor's reading,

The value of 35 must be validated and may change over time depending on ambient light levels. (Your code doesnt handle that at all)

The next line seems (?) to use the sensor number (i+1) as part of the weighting, which doesn't make sense at all.

I may be wrong as the code was hard to read, because you didn't take the time to remove all the unneccessary comments before uploading.

I suggest you take a step back and just work with the centre emmiter/sensor and get your code working as best you can detecting a line or white. Once you have mastered that and its reliable, you should move on to the next step of adding in more pairs etc.....

The value of 35 must be validated and may change over time depending on ambient light levels. (Your code doesnt handle that at all)

I want to know how do I change the threshold value with time ?