Objective
Convert the PID output into a valid actuator command that safely drives the motor or servo controlling the beam.
Implementation Guidance
- Map the PID output to a PWM value or servo angle
- Respect mechanical angle limits of the beam
- Ensure smooth transitions when switching motor direction
- Test actuator response independently before running full PID control
- Add safety constraints to prevent sustained maximum output
For Servo Motor:
// actuator.h#ifndef ACTUATOR_H#define ACTUATOR_Hvoid initActuator();void setBeamAngle(float pidOutput);
#endif
// actuator.cpp#include "actuator.h"#include Servo beamServo;const int SERVO_PIN = 9;const int CENTER_ANGLE = 90;const int MAX_DEFLECTION = 30; // +/- 30 degrees from centervoid initActuator() { beamServo.attach(SERVO_PIN); beamServo.write(CENTER_ANGLE);}
void setBeamAngle(float pidOutput) { // Map PID output (-255 to 255) to angle deflection float deflection = map(pidOutput, -255, 255, -MAX_DEFLECTION, MAX_DEFLECTION); // Calculate final angle int angle = CENTER_ANGLE + (int)deflection; // Enforce limits if (angle > CENTER_ANGLE + MAX_DEFLECTION) angle = CENTER_ANGLE + MAX_DEFLECTION; if (angle < CENTER_ANGLE - MAX_DEFLECTION) angle = CENTER_ANGLE - MAX_DEFLECTION; beamServo.write(angle);}
For DC Motor with H-Bridge:
void setMotorOutput(float pidOutput) { int pwmValue = abs((int)pidOutput); if (pwmValue > 255) pwmValue = 255; if (pidOutput > 0) { // Forward direction digitalWrite(DIR_PIN_A, HIGH); digitalWrite(DIR_PIN_B, LOW); } else { // Reverse direction digitalWrite(DIR_PIN_A, LOW); digitalWrite(DIR_PIN_B, HIGH); } analogWrite(MOTOR_PWM_PIN, pwmValue);}
Testing Before Integration
Before running the full PID controller:
- Test servo/motor with fixed angles/speeds
- Verify direction matches expected behavior
- Identify mechanical limits and dead zones
- Check for smooth motion without jerking
Key Takeaways
- Map PID output to actuator range
- Respect mechanical limits
- Test actuator independently first
- Handle direction changes smoothly