#include <Servo.h>
// 180 horizontal MAX
Servo horizontal; // Servo object for horizontal movement
int servoh = 90; // Initial horizontal servo position
int servohLimitHigh = 180; // Horizontal servo upper limit
int servohLimitLow = 0; // Horizontal servo lower limit
Servo vertical; // Servo object for vertical movement
int servov = 45; // Initial vertical servo position
int servovLimitHigh = 180; // Vertical servo upper limit
int servoLimitLow = 0; // Vertical servo lower limit
// Joystick and switch pin definitions
const int joystickXPin = A4; // Joystick X-axis pin
const int joystickYPin = A5; // Joystick Y-axis pin
const int switchPin = 2; // Switch pin
bool joystickMode = false; // Joystick mode flag
bool switchPressed = false; // Switch pressed flag
// PID control variables
float integralV = 0, integralH = 0; // Integral terms for vertical and horizontal
float previousErrorV = 0, previousErrorH = 0; // Previous error terms for vertical and horizontal
float kp = -0.04, ki = -0.0005, kd = -0.0001; // PID coefficients
float integralMax = 100.0, integralMin = -100.0; // Integral clamping limits
bool autoTuneMode = false;
void autoTuneVertical() {
// Implement Ziegler-Nichols tuning for the vertical servo
// ...
}
void autoTuneHorizontal() {
// Implement Ziegler-Nichols tuning for the horizontal servo
// ...
}
void setup() {
Serial.begin(9600); // Initialize serial communication
horizontal.attach(9); // Attach horizontal servo to pin 9
vertical.attach(10); // Attach vertical servo to pin 10
horizontal.write(90); // Initial horizontal position
vertical.write(45); // Initial vertical position
pinMode(switchPin, INPUT_PULLUP); // Set switch pin mode
delay(3000); // Initial delay
}
void loop() {
int switchState = digitalRead(switchPin); // Read switch state
// Toggle joystick mode on switch press
if (switchState == LOW && !switchPressed) {
joystickMode = !joystickMode; // Toggle joystick mode
switchPressed = true;
if (!joystickMode) {
// Return to initial position
horizontal.write(90);
vertical.write(45);
delay(1000); // Wait before moving to light sensor positions
}
delay(300); // Debounce delay
} else if (switchState == HIGH) {
switchPressed = false; // Reset switch pressed flag
}
if (joystickMode) {
// Read joystick values
int joystickX = analogRead(joystickXPin);
int joystickY = analogRead(joystickYPin);
// Map joystick values to servo positions
servoh = map(joystickX, 0, 1023, servohLimitLow, servohLimitHigh);
servov = map(joystickY, 0, 1023, servoLimitLow, servovLimitHigh);
horizontal.write(servoh);
vertical.write(servov);
} else {
int dtime = 10; // Delay time
int tol = 50; // Tolerance
int lt = analogRead(0); // Light sensor top-left
int rt = analogRead(1); // Light sensor top-right
int ld = analogRead(2); // Light sensor bottom-left
int rd = analogRead(3); // Light sensor bottom-right
int avt = (lt + rt) / 2; // Average of top sensors
int avd = (lt + rd) / 2; // Average of bottom sensors
int avl = (lt + ld) / 2; // Average of left sensors
int avr = (rt + rd) / 2; // Average of right sensors
int dvert = avt - avd; // Vertical difference
int dhoriz = avl - avr; // Horizontal difference
// PID control for vertical servo
integralV += dvert; // Integral term for vertical
// Clamp the integrator
if (integralV > integralMax) {
integralV = integralMax;
} else if (integralV < integralMin) {
integralV = integralMin;
}
float derivativeV = dvert - previousErrorV; // Derivative term for vertical
float outputV = kp * dvert + ki * integralV + kd * derivativeV; // PID output for vertical
previousErrorV = dvert; // Update previous error for vertical
if (-1 * tol > dvert || dvert > tol) {
servov += outputV;
if (servov > servovLimitHigh) {
servov = servovLimitHigh;
} else if (servov < servoLimitLow) {
servov = servoLimitLow;
}
vertical.write(servov);
delay(20);
}
// PID control for horizontal servo
integralH += dhoriz; // Integral term for horizontal
// Clamp the integrator
if (integralH > integralMax) {
integralH = integralMax;
} else if (integralH < integralMin) {
integralH = integralMin;
}
float derivativeH = dhoriz - previousErrorH; // Derivative term for horizontal
float outputH = kp * dhoriz + ki * integralH + kd * derivativeH; // PID output for horizontal
previousErrorH = dhoriz; // Update previous error for horizontal
if (-1 * tol > dhoriz || dhoriz > tol) {
servoh += outputH;
if (servoh > servohLimitHigh) {
servoh = servohLimitHigh;
} else if (servoh < servohLimitLow) {
servoh = servohLimitLow;
}
horizontal.write(servoh);
delay(20);
}
// Print important values to the serial monitor
Serial.print("dvert: ");
Serial.print(dvert);
Serial.print(", dhoriz: ");
Serial.print(dhoriz);
Serial.print(", servov: ");
Serial.print(servov);
Serial.print(", servoh: ");
Serial.print(servoh);
Serial.print(", integralV: ");
Serial.print(integralV);
Serial.print(", integralH: ");
Serial.print(integralH);
Serial.print(", outputV: ");
Serial.print(outputV);
Serial.print(", outputH: ");
Serial.println(outputH);
}
delay(100); // Main loop delay
}
Could you please enclose your whole program in code tags?
Check now
As your topic does not indicate a problem with IDE 1.x it has been moved to a more suitable location on the forum.
What do you mean?
Your topic is about autotune (whatever that is). So that has nothing to do with IDE problems. Hence it was moved.
I assume the following code is not implementing autotune, could someone help me with the the code below???
#include <Servo.h>
// 180 horizontal MAX
Servo horizontal; // Servo object for horizontal movement
int servoh = 90; // Initial horizontal servo position
int servohLimitHigh = 180; // Horizontal servo upper limit
int servohLimitLow = 0; // Horizontal servo lower limit
Servo vertical; // Servo object for vertical movement
int servov = 45; // Initial vertical servo position
int servovLimitHigh = 180; // Vertical servo upper limit
int servoLimitLow = 0; // Vertical servo lower limit
// Joystick and switch pin definitions
const int joystickXPin = A4; // Joystick X-axis pin
const int joystickYPin = A5; // Joystick Y-axis pin
const int switchPin = 2; // Switch pin
bool joystickMode = false; // Joystick mode flag
bool switchPressed = false; // Switch pressed flag
// PID control variables
float integralV = 0, integralH = 0; // Integral terms for vertical and horizontal
float previousErrorV = 0, previousErrorH = 0; // Previous error terms for vertical and horizontal
float kp = -0.04, ki = -0.0005, kd = -0.0001; // PID coefficients
float integralMax = 100.0, integralMin = -100.0; // Integral clamping limits
bool autoTuneMode = false;
void autoTuneVertical() {
// Implement Ziegler-Nichols tuning for the vertical servo
// ...
}
void autoTuneHorizontal() {
// Implement Ziegler-Nichols tuning for the horizontal servo
// ...
}
void setup() {
Serial.begin(9600); // Initialize serial communication
horizontal.attach(9); // Attach horizontal servo to pin 9
vertical.attach(10); // Attach vertical servo to pin 10
horizontal.write(90); // Initial horizontal position
vertical.write(45); // Initial vertical position
pinMode(switchPin, INPUT_PULLUP); // Set switch pin mode
delay(3000); // Initial delay
}
void loop() {
int switchState = digitalRead(switchPin); // Read switch state
// Toggle joystick mode on switch press
if (switchState == LOW && !switchPressed) {
joystickMode = !joystickMode; // Toggle joystick mode
switchPressed = true;
if (!joystickMode) {
// Return to initial position
horizontal.write(90);
vertical.write(45);
delay(1000); // Wait before moving to light sensor positions
}
delay(300); // Debounce delay
} else if (switchState == HIGH) {
switchPressed = false; // Reset switch pressed flag
}
if (joystickMode) {
// Read joystick values
int joystickX = analogRead(joystickXPin);
int joystickY = analogRead(joystickYPin);
// Map joystick values to servo positions
servoh = map(joystickX, 0, 1023, servohLimitLow, servohLimitHigh);
servov = map(joystickY, 0, 1023, servoLimitLow, servovLimitHigh);
horizontal.write(servoh);
vertical.write(servov);
} else {
int dtime = 10; // Delay time
int tol = 50; // Tolerance
int lt = analogRead(0); // Light sensor top-left
int rt = analogRead(1); // Light sensor top-right
int ld = analogRead(2); // Light sensor bottom-left
int rd = analogRead(3); // Light sensor bottom-right
int avt = (lt + rt) / 2; // Average of top sensors
int avd = (lt + rd) / 2; // Average of bottom sensors
int avl = (lt + ld) / 2; // Average of left sensors
int avr = (rt + rd) / 2; // Average of right sensors
int dvert = avt - avd; // Vertical difference
int dhoriz = avl - avr; // Horizontal difference
// PID control for vertical servo
integralV += dvert; // Integral term for vertical
// Clamp the integrator
if (integralV > integralMax) {
integralV = integralMax;
} else if (integralV < integralMin) {
integralV = integralMin;
}
float derivativeV = dvert - previousErrorV; // Derivative term for vertical
float outputV = kp * dvert + ki * integralV + kd * derivativeV; // PID output for vertical
previousErrorV = dvert; // Update previous error for vertical
if (-1 * tol > dvert || dvert > tol) {
servov += outputV;
if (servov > servovLimitHigh) {
servov = servovLimitHigh;
} else if (servov < servoLimitLow) {
servov = servoLimitLow;
}
vertical.write(servov);
delay(20);
}
// PID control for horizontal servo
integralH += dhoriz; // Integral term for horizontal
// Clamp the integrator
if (integralH > integralMax) {
integralH = integralMax;
} else if (integralH < integralMin) {
integralH = integralMin;
}
float derivativeH = dhoriz - previousErrorH; // Derivative term for horizontal
float outputH = kp * dhoriz + ki * integralH + kd * derivativeH; // PID output for horizontal
previousErrorH = dhoriz; // Update previous error for horizontal
if (-1 * tol > dhoriz || dhoriz > tol) {
servoh += outputH;
if (servoh > servohLimitHigh) {
servoh = servohLimitHigh;
} else if (servoh < servohLimitLow) {
servoh = servohLimitLow;
}
horizontal.write(servoh);
delay(20);
}
// Print important values to the serial monitor
Serial.print("dvert: ");
Serial.print(dvert);
Serial.print(", dhoriz: ");
Serial.print(dhoriz);
Serial.print(", servov: ");
Serial.print(servov);
Serial.print(", servoh: ");
Serial.print(servoh);
Serial.print(", integralV: ");
Serial.print(integralV);
Serial.print(", integralH: ");
Serial.print(integralH);
Serial.print(", outputV: ");
Serial.print(outputV);
Serial.print(", outputH: ");
Serial.println(outputH);
}
delay(100); // Main loop delay
}
Here's how it works:
Please, do not create multiple topics with the same subject.
Please, do not create multiple topics with the same subject.
https://forum.arduino.cc/t/how-to-apply-autotune-in-order-to-get-best-pid-controller/1282599/2
Please do not cross post, it wastes peoples time.
Please do not post in "Uncategorized"; see the sticky topics in https://forum.arduino.cc/c/using-arduino/uncategorized/184.
Your topics on the same subject have been merged.
Please read How to get the best out of this forum.
This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.