As I think that the readLine function adds some unecessary errors for the lineare loop back of the PID I have modified the code
int get_position(unsigned int *sensor_values, unsigned char readMode)
{
unsigned char i, on_line = 0;
int32_t avg; // this is for the weighted total, which is long
// before division
int sum; // this is for the denominator which is <= 32000
static int last_value=-2500; // assume initially that the line is left.
static int destvec[5]= {-2500,-1000,0,1000,2500}; //respect the distance between the sensors
read_line_sensors_calibrated(sensor_values, readMode);
avg = 0;
sum = 0;
for(i=0;i<5;i++) {
int value = sensor_values[i];
// keep track of whether we see the line at all
if(value > 150) {
on_line += (1 <<i); //by that we know which sensor
}
// only average in values that are above a noise threshold
if(value > 50) {
avg += (int32_t)(value) * destvec[i];
sum += value;
}
}
if(!on_line)
{
play_frequency(800,250,14);
return last_value; //lets assume we do the right if we are blind
}
last_value = (avg/sum);
return last_value;
}
the reason is simply that the sensors do not have the same distance to each other. so once the line reachs the outer sensors …error correction should get a much bigger value.
Additional I added the speed component to the PID. The idea behind that is simply that the distance between
2 measurements increases with the speed. In general it would be better to take the real distance between 2 measurements, but as there is no wheel encoder or other distance measurement …speed is not the worst.
Much better would be a calibrated motor and a timed sensor measurement.
and I renamed the function as readLine could easily mixed with read_line …but the purpose of that readLine is to get the line position.
works fine at full speed:
youtu.be/LJKvO9eZi6E
What i also want to add is a special lost line mode. I would slow down the motors or stop once a near field search
did not bring any success.