I have a map and my robot is moving on this map using the PID algorithm. Since I need manual intervention in some turns, I run the system by creating various scenario functions (30 of them). When I start the system from the beginning, my robot starts to turn around after about 20 scenarios. When I start from the middle, it finishes successfully. Apart from this, I tried all the parts with various scenarios. I tried all the scenarios by moving away from the start line and this problem started to occur one scenario ahead each time. What could be the cause of this?
#include <QTRSensors.h>
#define Rpwm1 6
#define RDir1 7
#define RDir2 8
#define Lpwm1 11
#define LDir1 10
#define LDir2 9
#define Buzzer 3
QTRSensors qtr;
const uint8_t SensorCount = 8;
uint16_t sensorValues[SensorCount];
float LeftBaseSpeed = 60 ;
float RightBaseSpeed = 60 ;
float TurnTime=100; //milisaniye
float TurnSpeed=80;
float StraightSpeed=70;
float StraightTime=70;
float CheckTime=300;
float Kp = 0.0275;//0.0275;//0.07
float Kd =0.15 ;//0.3 ;//0.275;// 0.1 ; // 2
float Ki =0.0001; //0.0001;// 0.0001 ; //0.0001
int FinalError = 0;
int Error = 0;
int ExtraSpeed = 0;
int RightSpeed = 0;
int LeftSpeed = 0;
int Integral = 0;
int Val = 0;
int donus=22;
int senaryo=22;
int baslangicZamani=0;
unsigned int Position = 3500;
byte WhiteLine = 0;
void setup()
{
// configure the sensors
qtr.setTypeAnalog();
qtr.setSensorPins((const uint8_t[]){A0, A1, A2, A3, A4, A5,A6,A7}, SensorCount);
qtr.setEmitterPin(2);
pinMode(Rpwm1, OUTPUT);
pinMode(Lpwm1, OUTPUT);
pinMode(RDir1, OUTPUT);
pinMode(RDir2, OUTPUT);
pinMode(LDir1, OUTPUT);
pinMode(LDir2, OUTPUT);
pinMode(Buzzer, OUTPUT);
// pinMode(LED1, OUTPUT);
// pinMode(LED2, OUTPUT);
// pinMode(MZ80, INPUT_PULLUP);
// pinMode(startbuton, INPUT_PULLUP);
delay(500);
pinMode(LED_BUILTIN, OUTPUT);
digitalWrite(LED_BUILTIN, HIGH); // turn on Arduino's LED to indicate we are in calibration mode
// Serial.begin(9600);
for (uint16_t i = 0; i < 200; i++)
{
qtr.calibrate();
}
digitalWrite(LED_BUILTIN, LOW);
Blink();// turn off Arduino's LED to indicate we are through with calibration
delay(1000);
}
void loop()
{
switch(senaryo)
{
case 0:Senaryo0();break;
case 1:Senaryo1();break;
case 2:Senaryo2();break;
case 3:Senaryo3();break;
case 4:Senaryo4();break;
case 5:Senaryo5();break;
case 6:Senaryo6();break;
case 7:Senaryo7();break;
case 8:Senaryo8();break;
case 9:Senaryo9();break;
case 10:Senaryo10();break;
case 11:Senaryo11();break;
case 12:Senaryo12();break;
case 13:Senaryo13();break;
case 14:Senaryo14();break;
case 15:Senaryo15();break;
case 16:Senaryo16();break;
case 17:Senaryo17();break;
case 18:Senaryo18();break;
case 19:Senaryo19();break;
case 20:Senaryo20();break;
case 21:Senaryo21();break;
case 22:Senaryo22();break;
case 23:Senaryo23();break;
case 24:Senaryo24();break;
case 25:Senaryo25();break;
case 26:Senaryo26();break;
case 27:Senaryo27();break;
case 28:Senaryo28();break;
case 29:Senaryo29();break;
case 30:Senaryo30();break;
case 31:Senaryo31();break;
case 32:Senaryo32();break;
default:MotorsSpeed(0,0);break;
}
// WriteSensorValues();
}
void Senaryo0()
{
ReadLine();
CheckStraight();
if(donus==1)
{
senaryo=1;
}
}
void Senaryo1()
{
ReadLine();
CheckRightTurn(CheckTime);
if(donus==2)
{
senaryo=2;
}
}
void Senaryo2()
{
ReadLine();
CheckLeftTurn(CheckTime);
if(donus==3)
{
senaryo=3;
}
}
void Senaryo3()
{
ReadLine();
CheckRightTurn(CheckTime);
if(donus==4)
{
senaryo=4;
}
}
void Senaryo4()
{
ReadLine();
CheckLeftTurn(CheckTime);
if(donus==5)
{
senaryo=5;
}
}
void Senaryo5()
{
ReadLine();
CheckRightTurn(CheckTime);
if(donus==6)
{
senaryo=6;
}
}
void Senaryo6()
{
ReadLine();
CheckLeftTurn(CheckTime);
if(donus==7)
{
senaryo=7;
}
}
void Senaryo7()
{
ReadLine();
CheckRight90Turn(CheckTime);
if(donus==8)
{
senaryo=8;
}
}
void Senaryo8()
{
ReadLine();
CheckRightTurn(CheckTime);
if(donus==9)
{
RightTurn(TurnSpeed,TurnTime);
senaryo=9;
}
}
void Senaryo9()
{
ReadLine();
// CheckRightTurn();
CheckLeftTurn(CheckTime);
if(donus==10)
{
//RightTurn(TurnSpeed,TurnTime);
//LeftTurn(TurnSpeed,TurnTime);
senaryo=10;
}
}
void Senaryo10()
{
ReadLine();
// CheckRightTurn();
CheckRightTurn(CheckTime);
if(donus==11)
{
// RightTurn(TurnSpeed,TurnTime);
//LeftTurn(TurnSpeed+20,TurnTime);
senaryo=11;
}
}
void Senaryo11()
{
ReadLine();
// CheckRightTurn();
CheckLeftTurn(CheckTime);
if(donus==12)
{
// RightTurn(TurnSpeed);
LeftTurn(TurnSpeed,TurnTime+75);
senaryo=12;
}
}
void Senaryo12()
{
ReadLine();
// CheckRightTurn();
CheckLeftTurn(CheckTime);
if(donus==13)
{
// RightTurn(TurnSpeed);
LeftTurn(TurnSpeed,TurnTime+90);
senaryo=13;
}
}
void Senaryo13()
{
ReadLine();
GoStraight(StraightSpeed,StraightTime);
CheckLeftTurn(CheckTime);
if(donus==14)
{
senaryo=14;
}
}
void Senaryo14()
{
ReadLine();
CheckRightTurn(CheckTime);
if(donus==15)
{
RightTurn(TurnSpeed,TurnTime);
senaryo=15;
}
}
void Senaryo15()
{
ReadLine();
CheckRightTurn(CheckTime);
if(donus==16)
{
RightTurn(TurnSpeed,TurnTime);
senaryo=16;
}
}
void Senaryo16()
{
ReadLine();
CheckLeftTurn(CheckTime);
if(donus==17)
{
senaryo=17;
}
}
void Senaryo17()
{
ReadLine();
CheckLeftTurn(CheckTime);
if(donus==18)
{
senaryo=18;
}
}
void Senaryo18()
{
ReadLine();
CheckRightTurn(CheckTime);
if(donus==19)
{
senaryo=19;
}
}
void Senaryo19()
{
ReadLine();
CheckLeftTurn(CheckTime);
if(donus==20)
{
LeftTurn(TurnSpeed,TurnTime+75);
GoStraight(70,400);
senaryo=20;
WhiteLine=1;
}
}
void Senaryo20()
{
ReadLine();
CheckBlackLine();
if(donus==21)
{
senaryo=21;
}
}
void Senaryo21()
{
ReadLine();
CheckLeft90Turn(CheckTime);
if(donus==22)
{
LeftTurn(TurnSpeed,TurnTime);
senaryo=22;
}
}
void Senaryo22()
{
ReadLine();
CheckLeft90Turn(CheckTime);
if(donus==23)
{
//LeftTurn(TurnSpeed,TurnTime+100);
senaryo=23;
}
}
void Senaryo23()
{
ReadLine();
CheckLeft90Turn(CheckTime);
if(donus==24)
{
LeftTurn(TurnSpeed,TurnTime);
senaryo=24;
}
}
void Senaryo24()
{
CheckLeft90Turn(CheckTime);
ReadLine();
if(donus==25)
{
LeftTurn(TurnSpeed,TurnTime);
senaryo=25;
}
}
void Senaryo25()
{
CheckRight90Turn(CheckTime);
ReadLine();
if(donus==26)
{
RightTurn(TurnSpeed,TurnTime+100);
senaryo=26;
}
}
void Senaryo26()
{
ReadLine();
CheckLeft90Turn(CheckTime);
if(donus==27)
{
LeftTurn(TurnSpeed,TurnTime);
senaryo=27;
}
}
// BEŞGENİN OLDUĞU YER
void Senaryo27()
{
ReadLine();
CheckLeftTurn(CheckTime);
if(donus==28)
{
LeftTurn(TurnSpeed,TurnTime);
senaryo=28;
}
}
void Senaryo28()
{
ReadLine();
CheckRightTurn(CheckTime);
if(donus==29)
{
//RightTurn(TurnSpeed,TurnTime+200);
senaryo=29;
}
}
void Senaryo29()
{
ReadLine();
CheckRightTurn(CheckTime);
if(donus==30)
{
//RightTurn(TurnSpeed,TurnTime+200);
senaryo=30;
}
}
void Senaryo30()
{
ReadLine();
CheckRightTurn(CheckTime);
if(donus==31)
{
//RightTurn(TurnSpeed,TurnTime+200);
senaryo=31;
}
}
void Senaryo31()
{
ReadLine();
CheckRightTurn(CheckTime);
if(donus==32)
{
//RightTurn(TurnSpeed,TurnTime+200);
senaryo=32;
}
}
void Senaryo32()
{
ReadLine();
CheckStraight();
if(donus==33)
{
//RightTurn(TurnSpeed,TurnTime+200);
while(true)
{
MotorsSpeed(0,0);
}
senaryo=33;
}
}
void GoStraight(int speed,int time)
{
do
{
MotorsSpeed(speed,speed);
}while(baslangicZamani+time>millis());
}
void WriteSensorValues()
{
uint16_t position;
if(WhiteLine==1)
{
position = qtr.readLineWhite(sensorValues);
}
else
{
position = qtr.readLineBlack(sensorValues);
}
for (uint8_t i = 0; i < SensorCount; i++)
{
Serial.print(sensorValues[i]);
Serial.print('\t');
}
Serial.println(position);
delay(250);
}
void ReadLine()
{
if(WhiteLine==1)
{
Position = qtr.readLineWhite(sensorValues);
}
else
{
Position = qtr.readLineBlack(sensorValues);
}
Error = Position - 3500;
Integral += Error;
// Integral = constrain(Integral, INTEGRAL_MIN, INTEGRAL_MAX);
int Verify = Kp * Error + Kd * (Error - FinalError) + Ki * Integral;
FinalError = Error;
RightSpeed = RightBaseSpeed + Verify + ExtraSpeed ;
LeftSpeed = LeftBaseSpeed - Verify + ExtraSpeed ;
RightSpeed = constrain(RightSpeed, -250, 250);
LeftSpeed = constrain(LeftSpeed, -250, 250);
MotorsSpeed(LeftSpeed, RightSpeed);
}
void MotorsSpeed(int RightSpeed, int LeftSpeed) {
if (RightSpeed <= 0) {
RightSpeed = abs(RightSpeed);
analogWrite(Rpwm1, RightSpeed);
digitalWrite(RDir1, HIGH);
digitalWrite(RDir2, LOW);
}
else {
analogWrite(Rpwm1, RightSpeed);
digitalWrite(RDir1, LOW);
digitalWrite(RDir2, HIGH);
}
if (LeftSpeed <= 0) {
LeftSpeed = abs(LeftSpeed);
analogWrite(Lpwm1, LeftSpeed);
digitalWrite(LDir1, HIGH);
digitalWrite(LDir2, LOW);
}
else {
analogWrite(Lpwm1, LeftSpeed);
digitalWrite(LDir1, LOW);
digitalWrite(LDir2, HIGH);
}
}
void CheckBlackLine()
{
if(sensorValues[0]<200 &&sensorValues[1] <200 &&sensorValues[2]<200&&sensorValues[3]>700&& sensorValues[4]>700 &&sensorValues[5]<200 &&sensorValues[6]<200&&sensorValues[7]<200)
{
WhiteLine=0;
donus++;
}
}
void CheckRightTurn(float checkTime)
{
if(sensorValues[1]>900 &&( (millis()- baslangicZamani) >=checkTime ) )
{
baslangicZamani=millis();
donus++;
}
}
void CheckRight90Turn(float checkTime)
{
if(sensorValues[1]>900&& sensorValues[0]>900 &&( (millis()- baslangicZamani) >=checkTime ) )
{
baslangicZamani=millis();
donus++;
}
}
void CheckLeft90Turn(float checkTime)
{
if(sensorValues[7]>900&& sensorValues[6]>900 &&( (millis()- baslangicZamani) >=checkTime ) )
{
baslangicZamani=millis();
donus++;
}
}
void CheckLeftTurn(float checkTime)
{
if(sensorValues[6]>900 &&( (millis()- baslangicZamani) >=checkTime ))
{
baslangicZamani=millis();
donus++;
}
}
void RightTurn(int turnSpeed,int turnTime)
{
int startTime=millis();
do
{
MotorsSpeed(turnSpeed,-turnSpeed);
}while(startTime+turnTime>millis());
}
void LeftTurn(int turnSpeed,int turnTime)
{
int startTime=millis();
do
{
MotorsSpeed(-turnSpeed,turnSpeed);
}while(startTime+turnTime>millis());
}
void CheckStraight()
{
int baslangicZamani=millis();
if(sensorValues[0]>700 &&sensorValues[1] >700 &&sensorValues[2]>700&&sensorValues[3]>700&& sensorValues[4]>700 &&sensorValues[5] >700 &&sensorValues[6]>700&&sensorValues[7]>700)
{
do
{
MotorsSpeed(150,150);
}while(baslangicZamani+100>millis());
donus++;
}
}
void Stop()
{
while(true)
{
MotorsSpeed(0,0);
}
}
void Blink() {
for (int i = 0; i < 10; i++) {
// digitalWrite(Led, LOW);
digitalWrite(Buzzer, LOW);
delay(180);
// digitalWrite(Led, HIGH);
digitalWrite(Buzzer, HIGH);
delay(180);
}
digitalWrite(Buzzer, LOW);
}