-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathsatoru_PID_LineFollow.ino
196 lines (167 loc) · 5.55 KB
/
satoru_PID_LineFollow.ino
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
/* //////////////////////////////////////////////////////////////*
* *******LINE FOLLOWER BOT USING PID ALGORITHM*******************
*
* Authur: Thilina Satoru *
* NIBM: Higher Diploma - Robotic Application Development *
* Date: 12/24/2021 *
*///////////////////////////////////////////////////////////////*
#include "configuration.h"
// Flags for modes //
#define STOPPED 0
#define ON_LINE 1
#define OFF_LINE 2
#define TURN_LEFT 3
#define TURN_RIGHT 4
#define CROSS 5
bool reading[sInputs]; //Digital readings of sensors into array
int coefficient[sInputs] = {-4000, -3000, -2000, -1000, 1000, 2000, 3000, 4000}; // Coefficient of error values (-4000 is to Leftmost sensor)
float error = 0; //difference between the desired final output, => ("error=0") AND the actual one, => ("error = coeficient*sensor reading")
float PID_output = 0; // calculated PID value/the difference
short mode; // mode of the sensor postion logic
int sum; // sum of digital sensor array. 'if all black sum=8'
bool isGoal;
#include "DebuggFunctions.h"
#include "MortorFunctions.h"
void setup() { ///////////////////////////////////////// START SETUP ///////////////////////////////////////////////////////////////////////////////////////////
isGoal = false;
// set pins as output/input
pinMode(INA_M1, OUTPUT);
pinMode(INB_M1, OUTPUT);
pinMode(INC_M2, OUTPUT);
pinMode(IND_M2, OUTPUT);
Serial.begin(115200); // serial monitor
}////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// END SETUP ////////////////////////////////
void loop() { ////////////////////////////////////////// START LOOP ///////////////////////////////////////////////////////////////////////////////////////////
if(!isGoal){ // destination not arrived
IR_read();
checkReading();
IR_debug();
switch(mode){
case STOPPED:
M_stop();
break;
case ON_LINE:
Serial.print("+++ON LiNE++");
calculatePID();
motorPIDcontrol();
break;
case OFF_LINE:
M_turn_Left180();
break;
case TURN_RIGHT:
delay(300);
while(sum == 0 ){
Serial.print("+++ while R +++");
M_turn_Right90();
IR_read();
}
break;
case TURN_LEFT:
delay(300);
while(sum == 0){
Serial.print("+++ while L+++");
M_turn_Left90();
IR_read();
}
break;
case CROSS:
doCross();
break;
}
}
else{
// loop ended, destination arrived
}
}/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// END LOOP //////////////////////////////
void IR_read(){
sum = 0;
error = 0;
// Through out whole sensor array,
for(int i; i < sInputs; i++){
reading[i] = digitalRead(sensorPins[i]) ; // digital read, and put to sensor reading array
error = error + ( reading[i]* coefficient[i] ); // calculate corresponding, 'sum of errors' for sensors which have "1".
sum = sum + reading[i]; // calculate how many 1's are detected in the reading
}
}
void checkReading(){
if(sum == 0){ // if sum=0, all readings are '0' and all white
mode = OFF_LINE;
}
else if(sum == 8){
mode = CROSS;
}
else if(sum > 2 && sum < 7){ // if there are several lines detected as '1'
//mode = ON_LINE;
if(reading[0] == 1 && reading[1] == 1 && reading[2] == 1){
mode = TURN_LEFT;
}
else if(sum < 4){
mode = ON_LINE;
}
else if(reading[5] == 1 && reading[6] == 1 && reading[7] == 1){
right_LCross();
}
}
else if(sum < 4){
mode = ON_LINE;
}
}
void calculatePID(){ // PID error algorithm
float PP = 0, II = 0, DD = 0;
float previousError = 0, previousI = 0;
float I = I + error;
PP = Kp * error; //Kp*P p = error
II = Ki * I; //Ki*I I = I + error
DD = Kd * (error - previousError); //Kd*D d = error - previousError
PID_output = (PP + II + DD) / 1000; // devide by 1000, because coefficients are thousand values
previousError = error;
//Serial.print(PID_output);
}
void motorPIDcontrol(){ // Apply PID to motors
LeftSpeed = initSpeed + PID_output;
RightSpeed = initSpeed - PID_output;
/// limit: max. mortor speed = 255 and min. = 0
if(LeftSpeed < 0)
LeftSpeed = 0;
if(LeftSpeed > maxSpeed)
LeftSpeed = maxSpeed;
if(RightSpeed < 0)
RightSpeed = 0;
if(RightSpeed > maxSpeed)
RightSpeed = maxSpeed;
M_drive(LeftSpeed,RightSpeed);
}
void right_LCross(){
M_stop();
delay(50);
M_drive(100,100);
delay(200);
M_stop();
delay(10);
IR_read();
delay(10);
if(sum > 1 && sum < 4){
mode = ON_LINE;
}
else{
mode = TURN_RIGHT;
}
}
void doCross(){
M_stop();
delay(50);
M_drive(100,100);
delay(200);
M_stop();
delay(10);
IR_read();
delay(10);
if(sum > 1 && sum < 4){
M_turn_Left90();
delay(500);
}
else if(sum > 6){
M_stop();
isGoal = true;
}
}