Professional Documents
Culture Documents
StaticVars:
static uint32_t PWMPeriodInMicroSec
static uint8_t RobotDirection
static uint16_t LastLeftDutyCycle
static uint16_t LastRightDutyCycle
static uint32_t LeftEncoderPeriod
static uint32_t LastLeftCapture
static uint32_t RightEncoderPeriod
static uint32_t LasRightCapture
static uint8_t LeftRPMError
static uint8_t LeftTargetRPM
static uint8_t RightRPMError
static uint8_t RightTargetRPM
static uint32_t TargetX
static uint32_t TargetY
static uint32_t TargetHeading
Public Functions:
void InitDCMotor (void)
void SetDutyCycle(uint16_t DutyCycle)
void SetRobotDirection(uint8_t Direction)
void SetTargetPosition(GoalX, GoalY)
void SetTargetHeading(GoalTheta)
void InterruptLeftEncoder(void)
void InterruptRightEncoder(void)
void InterruptSpeedUpdate(void)
Private Functions
static void InitPWM (void)
static void InitEncoderCapture(void)
static void InitSpeedUpdater(void)
void InitDCMotor(void)
Initialize PWM hardware
Initialize Encoder Capture
Initialize Closed Loop Speed Control Timer
Initialize H-Bridge Control
Void SetTargetHeading(GoalTheta)
TargetHeading = GoalTheta
void StopMotors(void)
Set both motors duty cycle to zero
Stop Closed loop timers
Clear RPM error terms for both motors
void InterruptLeftEncoder(void)
Clear source of interrupt
Set CurrentEncoderCapture to current value of Timer A Register
Set EncoderPeriod between events using abs(CurrentEncoderCapture-
LastEncoderCapture)
Update LastEncoderCapture with value of CurrentEncoderCapture
// Encoder Dead Reckoning Position Tracking
If Direction is Foward
Increase X position by DistancePerPulse * cos(Current Heading)
Increase Y position by DistancePerPulse * sin(Current Heading)
If Direction is Backwards
Decrease X position by DistancePerPulse * cos(Current Heading)
Decrease Y position by DistancePerPulse * sin(Current Heading)
If Direction is Counter-Clockwise Turn
Increase heading angle by DistancePerPulse / TurnRadius
If Direction is Clockwise Turn
Decrease heading angle by DistancePerPulse / TurnRadius
void InterruptRightEncoder(void)
Clear source of interrupt
Set CurrentEncoderCapture to current value of Timer A Register
Set EncoderPeriod between events using abs(CurrentEncoderCapture-
LastEncoderCapture)
Update LastEncoderCapture with value of CurrentEncoderCapture
void InterruptSpeedUpdate(void)
For Each Motor (Left, Right):
Clear Interrupt Source
Use Period to find Current RPM
Calculate RPMError as Target RPM – Current RPM
Add to total Integral Term
Clamp integral term to prevent windup
Set Duty cycle based on PID constants and control law
Update Last Error