Here's a few charts of the data from our analog IR sensor looking for the light at various distances. The data uses a moving average, so the code will have to take that into account.
The plan is to do the following:
We tried this and at further distances, the robot would start to drive in the correct direction. But since it is not checking when it is driving towards the light, it tended to wander off the path where it should be going.
Adding onto what we found in our previous experiment, we implemented the following:
void seekLight() {
int servoForwardDegree = 90; //this value makes the servo point forward.
int lightSensorStopThreshold = 700;
int iravg[4] = {0,0,0,0};
int total=0;
for (int i=0; i<4;i++) total+=iravg[i]=analogRead(analogIRPin);
int iravgindex=0;
int lowest = analogRead(analogIRPin);
leftMotorSpeed = -leftMotorDefaultSpeed*0.9; //sets motors to eighty percent
rightMotorSpeed = rightMotorDefaultSpeed;
leftTick=0;
enableRotaryInterrupts();
if (!myservo.attached()) myservo.attach(servoPin);
myservo.write(servoForwardDegree); // sets the servo position according to the current degree
long now = millis();
while (millis()-now<1000);
//scan for light source
Forward(0); //sends motor speeds to motor
while (leftTick<50) { //approx one revolution
total=total-iravg[iravgindex]+(iravg[iravgindex]=analogRead(analogIRPin));
if (lowest>iravg[iravgindex]) lowest=iravg[iravgindex];
iravgindex=(iravgindex+1)%4; //saves lowest value
analogIRSensor=total/4;
if (useSave) saveData(useSave);
updateMenu();
}
Stop(0);
delay(200); //wait for moemntum.
Forward(0);
//turn until we find the low range again
while (analogIRSensor>(lowest+30)) {
total=total-iravg[iravgindex]+(iravg[iravgindex]=analogRead(analogIRPin));
iravgindex=(iravgindex+1)%4;
analogIRSensor=total/4;;
}
leftTick=0;
//turn until we come back out of the low range
while (analogIRSensor<(lowest+35)){
total=total-iravg[iravgindex]+(iravg[iravgindex]=analogRead(analogIRPin));
iravgindex=(iravgindex+1)%4;
analogIRSensor=total/4;;;
}
Stop(0);
delay(200);
//find middle of light range
int currentTickCount=leftTick; //current ticks counted through low range
leftMotorSpeed=-leftMotorSpeed;
rightMotorSpeed=-rightMotorSpeed;
leftTick=0;
Forward(0);
while (leftTick<currentTickCount/2); //go back half the ticks in the low range
Stop(0);
delay(200);
//go toward light
leftMotorSpeed=leftMotorDefaultSpeed;
rightMotorSpeed=rightMotorDefaultSpeed*1.1;
Forward(0);
bool clockwise=true; //initial direction of servo
int degree;
myservo.write(degree=servoForwardDegree-20);
now = millis();
while (millis()-now<1000);
total=0;
for (int i=0; i<4;i++) total+=iravg[i]=analogRead(analogIRPin);
iravgindex=0;
int timeStopSensorActivated=0;
while (1) {
Forward(0);
int minDegree;
int minimum=1024;
int d=0;
for (degree; (clockwise) ? degree<=servoForwardDegree+20 : degree>=servoForwardDegree-20; (clockwise) ? degree++ : degree--) {
//move servo
if (!myservo.attached()) myservo.attach(servoPin);
myservo.write(degree); // sets the servo position according to the current degree
now = millis();
while(millis()-now<10); //wait for sensor to get there.
//servoOff();
if (degree==servoForwardDegree) {
servoOff();
delay(100);
checkForObstacle(1);
if (timeToStop) break;
if (!myservo.attached()) myservo.attach(servoPin);
}
//calculating moving average
total=total-iravg[iravgindex]+(iravg[iravgindex]=analogRead(analogIRPin));
iravgindex=(iravgindex+1)%4;
analogIRSensor=total/4;;
//if minimum is found, add as minDegree from 2 degrees before/after depending on direction of servo
if (analogIRSensor<minimum) { minimum=analogIRSensor; (clockwise) ? minDegree=degree-2 : minDegree=degree+2; }
//continually check for STOP line.
//if (analogRead(A1)>lightSensorStopThreshold && timeStopSensorActivated==0) timeStopSensorActivated=millis();
//else if (analogRead(A1)<lightSensorStopThreshold) timeStopSensorActivated=0;
//if ((millis()-timeStopSensorActivated>50 && timeStopSensorActivated>0) || ((d=microsecondsToCentimeters(ping()))<10 && d!=0)) { timeToStop=true; break; }
currentPingDistance=microsecondsToCentimeters(ping());
if (analogRead(A1)>lightSensorStopThreshold) { timeToStop=true; break; }
//log the data
if (useSave) saveData(useSave);
}
if (timeToStop) break;
clockwise=!clockwise;
leftMotorSpeed=leftMotorDefaultSpeed*0.95*0.85-17*(servoForwardDegree-minDegree)/20;
rightMotorSpeed=rightMotorDefaultSpeed*1.05*0.85+17*(servoForwardDegree-minDegree)/20;
}
servoOff();
Stop(0);
currentMenu=draw;
}