-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathgoodcode.ino
More file actions
152 lines (127 loc) · 3.83 KB
/
Copy pathgoodcode.ino
File metadata and controls
152 lines (127 loc) · 3.83 KB
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
// --- PINS ---
// Motor Driver Pins
#define Lpwm_pin 5
#define Rpwm_pin 6
int pinLB = 3;
int pinLF = 4;
int pinRB = 7;
int pinRF = 8;
// --- TUNING PARAMETERS ---
float Kp = 25;
float Kd = 15;
// --- SPEED CONTROL VARIABLES ---
int BASE_SPEED = 150; // Starting speed (Straight line speed)
int MAX_SPEED = 150;
int MIN_SPEED = 100; // Minimum speed to prevent stalling
// *** CURVE HANDLING ***
int SPEED_DROP = 50; // How much to slow down on sharp turns
int lastError = 0;
// --- 5-SENSOR SETUP ---
const int SENSOR_RIGHT = A0;
const int SENSOR_LEFT = A1;
const int SENSOR_MIDDLE_RIGHT = A2;
const int SENSOR_MIDDLE_LEFT = A3;
const int SENSOR_MIDDLE = A5;
void setup() {
// Motor Pins
pinMode(pinLB, OUTPUT);
pinMode(pinLF, OUTPUT);
pinMode(pinRB, OUTPUT);
pinMode(pinRF, OUTPUT);
pinMode(Lpwm_pin, OUTPUT);
pinMode(Rpwm_pin, OUTPUT);
// Sensor Pins
pinMode(SENSOR_LEFT, INPUT);
pinMode(SENSOR_RIGHT, INPUT);
pinMode(SENSOR_MIDDLE_LEFT, INPUT);
pinMode(SENSOR_MIDDLE_RIGHT, INPUT);
pinMode(SENSOR_MIDDLE, INPUT);
// Serial
Serial.begin(115200);
Serial.println("Arduino Ready - Line Following Mode");
}
void loop() {
runPDLineFollower();
}
// *** LINE FOLLOWING FUNCTION ***
void runPDLineFollower() {
// 1. READ SENSORS
int FL = digitalRead(SENSOR_LEFT);
int ML = digitalRead(SENSOR_MIDDLE_LEFT);
int M = digitalRead(SENSOR_MIDDLE);
int MR = digitalRead(SENSOR_MIDDLE_RIGHT);
int FM = digitalRead(SENSOR_RIGHT);
// 2. CALCULATE POSITION
int error = 0;
int activeSensors = FL + ML + M + MR + FM;
if (activeSensors > 0) {
// Weights: -2000, -1000, 0, 1000, 2000
long weightedSum = (FL * -2000) + (ML * -1000) + (M * 0) + (MR * 1000) + (FM * 2000);
error = weightedSum / activeSensors;
} else {
// Memory: If lost, steer hard in direction of last known error
if (lastError > 0) error = 2500;
else error = -2500;
}
// 3. CALCULATE PID VALUE
int P = error;
int D = error - lastError;
int correction = (Kp * P) + (Kd * D);
lastError = error;
// 4. DYNAMIC SPEED THROTTLING (The New Logic)
// We use a temporary variable for speed so we don't mess up the global BASE_SPEED
int currentSpeed = BASE_SPEED;
// If error is greater than 1000 (meaning we are not centered), slow down.
// 1000 usually means the middle sensor is off the line and a side sensor is on.
if (abs(error) > 1000) {
currentSpeed = BASE_SPEED - SPEED_DROP;
// Ensure we don't drop below minimum or the robot will stall in the turn
if (currentSpeed < MIN_SPEED) {
currentSpeed = MIN_SPEED;
}
}
// 5. APPLY TO MOTORS
int leftMotorSpeed = currentSpeed + correction;
int rightMotorSpeed = currentSpeed - correction;
// 6. CONSTRAIN SPEEDS
leftMotorSpeed = constrain(leftMotorSpeed, -MAX_SPEED, MAX_SPEED);
rightMotorSpeed = constrain(rightMotorSpeed, -MAX_SPEED, MAX_SPEED);
// 7. DRIVE
setLeftMotor(leftMotorSpeed);
setRightMotor(rightMotorSpeed);
}
// --- MOTOR HELPERS ---
void setLeftMotor(int speed) {
if (speed > 0) {
digitalWrite(pinLB, LOW);
digitalWrite(pinLF, HIGH);
analogWrite(Lpwm_pin, speed);
} else if (speed < 0) {
digitalWrite(pinLB, HIGH);
digitalWrite(pinLF, LOW);
analogWrite(Lpwm_pin, abs(speed));
} else {
digitalWrite(pinLB, HIGH);
digitalWrite(pinLF, HIGH);
analogWrite(Lpwm_pin, 0);
}
}
void setRightMotor(int speed) {
if (speed > 0) {
digitalWrite(pinRB, LOW);
digitalWrite(pinRF, HIGH);
analogWrite(Rpwm_pin, speed);
} else if (speed < 0) {
digitalWrite(pinRB, HIGH);
digitalWrite(pinRF, LOW);
analogWrite(Rpwm_pin, abs(speed));
} else {
digitalWrite(pinRB, HIGH);
digitalWrite(pinRF, HIGH);
analogWrite(Rpwm_pin, 0);
}
}
void stopRobot() {
setLeftMotor(0);
setRightMotor(0);
}