-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathPID Sliding Door.ino
More file actions
147 lines (112 loc) · 3.47 KB
/
Copy pathPID Sliding Door.ino
File metadata and controls
147 lines (112 loc) · 3.47 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
#include <Wire.h>
#include <Servo.h>
#include <Adafruit_VL53L0X.h>
#define TRIG_PIN 4
#define ECHO_PIN 5
#define SERVO_PIN 9 // Servo motor control pin
Servo slidingDoorServo;
Adafruit_VL53L0X lox = Adafruit_VL53L0X();
bool isOpen = 0;
// Create a structure to hold the ranging data
VL53L0X_RangingMeasurementData_t measure;
void setup() {
// Initialize Serial communication
Serial.begin(9600);
Serial.println("Ultrasonic Sensor with Servo Test");
// Set pin modes
pinMode(TRIG_PIN, OUTPUT);
pinMode(ECHO_PIN, INPUT);
// Initialize VL53L0X sensor
if (!lox.begin()) {
Serial.println("Failed to initialize VL53L0X! Check wiring.");
while (1); // Stop execution if sensor initialization fails
}
// Attach servo to its pin
slidingDoorServo.attach(SERVO_PIN);
// Initialize servo position
slidingDoorServo.write(142); // Default closed position
}
int doorPos(){
// Perform a distance measurement
lox.rangingTest(&measure, false); // Pass 'true' to print debug info
// Check if the measurement is valid
if (measure.RangeStatus != 4) { // RangeStatus 4 means out of range
return measure.RangeMilliMeter;
} else return -1;
}
// PID constants
float kp = 0.8; // Proportional constant
float ki = 0.015; // Integral constant (can be tuned)
float kd = 0.6; // Derivative constant
void PIDControl(int setpoint, float* previousError, float* integral) {
int currentPosition = doorPos();
while(setpoint < currentPosition - 3 || setpoint > currentPosition + 3){
if (currentPosition == -1) {
Serial.println("Error: Position out of range!");
return;
}
// Calculate error
float error = setpoint - currentPosition;
// Integral
*integral += error;
// Derivative
float derivative = error - (*previousError);
// Calculate PID output
float output = (kp * error + (ki * (*integral)) + (kd * derivative)) + setpoint;
// Serial.print("output: ");
// Serial.print(output);
// Update previous error
*previousError = error;
int servoInput = constrain(output * 142 / 274, 23, 160);
// Move the servo
slidingDoorServo.write(servoInput);
// Debugging
// Serial.print(" || Setpoint: ");
// Serial.print(setpoint);
currentPosition = doorPos();
// Serial.print(" mm || Current: ");
Serial.println(currentPosition);
// Serial.print(" mm || Servo Input: ");
// Serial.print(servoInput);
// Serial.print(" || error sebelumnya: ");
// Serial.print(*previousError);
// Serial.print(" mm || integral: ");
// Serial.println(*integral);
delay(50);
}
for(int i = 0; i < 25; i++)
Serial.println(doorPos()), delay(100);
}
float previousErrorOpen = 0;
float integralOpen = 0;
void PIDopen() {
PIDControl(52, &previousErrorOpen, &integralOpen); // Open position
delay(250);
Serial.println("Pintu telah dibuka!");
}
float previousErrorClose = 0;
float integralClose = 0;
void PIDclose() {
PIDControl(269, &previousErrorClose, &integralClose); // Closed position
delay(250);
Serial.println("Pintu telah ditutup!");
}
int getDistance() {
digitalWrite(TRIG_PIN, LOW);
delayMicroseconds(2);
digitalWrite(TRIG_PIN, HIGH);
delayMicroseconds(10);
digitalWrite(TRIG_PIN, LOW);
int duration = pulseIn(ECHO_PIN, HIGH);
int distance = duration * 0.344 / 2; // Convert to mm
return distance;
}
void loop() {
if(getDistance() < 115) {
if(!isOpen) PIDopen(), isOpen = 1;
}
else {
if(isOpen) PIDclose(), isOpen = 0;
}
delay(100);
}