motors Module
Files:
Interface:
Function: InitMotors
Arguments: None.
Returns: None.
Description:Initializes PWM signals for the Motors
Function: SetPWMOffset
Arguments: Character representing the offset value.
Returns: None.
Description:Sets an offset to increase/decrease the magnitude of SimpleMove
commands.
Function: SimpleMove
Arguments: Floats representing the Left and Right duty cycles.
Returns: None.
Description:Implements Drive-Brake via and H-bridge. Sends PWM signal to the
robot left and right wheel.
-100 (full backwards) to 0 (stopped) to 100 (full forwards)
Function: ControlLawMove
Arguments: Characters representing requesting Left and Right duty cycles
Returns: None.
Description:Sets the module level variables with the requested RPMs for use by
the interrupt Encoder.
Function: EncoderInterrupt
Arguments: LongByInts structure representing previous time and LongByInts structure representing current time
Returns: None.
Description:Function to run in Interrupt response routine for either encoder. Takes pointers so it
can modify the correct variables.
Pseudo-Code:
void InitMotors(void)
Enable PWM0,PWM1,PWM2,PWM3
Set clock A and B to /4
Set PWM Output polarity as initially high
Set clock select to scaled clock A and B
Set scale for A
Set scale for B
Map PWM output to U0, U1, U2, U3
Set all four PWM periods
Initialize all for duties to 0
void SetPWMOffset(unsigned char Offset)
Return Offset
void SimpleMove(float LeftDuty, float RightDuty)
If Left Duty is 0
Stop Left
Else If Left Duty > 0
Make Left go backwards
Else
Make Left go forwards
If Right Duty is 0
Stop Right
Else If Right Duty > 0
Make Right go backwards
Else
Make Right go forwards
void ControlLawMove(char RequestedLeftRPM, char RequestedRightRPM)
Set LeftRPMTarget to static variable RequestedLeftRPM
Set RightRPMTarget to static variable RequestedRightRPM
static unsigned char EncoderInterrupt(LongByInts *LastTime,LongByInts ThisTime)
If TOF is pending, and captured time after rollover handle TOF
Increment overflow counter
Clear flag
Calculate Period between encoder ticks
Calculate Encoder Ticks Per Minute
Return Encoder Revolutions per Minute
Interrupts:
void interrupt _Vec_tim1ovf Tim0OverflowInterrupt(void)
Increments the overflow counter for timer 0, for absolute timing purposes
Increment Overflow Counter
Clear Overflow interrup flag
void interrupt _Vec_tim0ch4 LeftEncoder(void)
void interrupt _Vec_tim0ch5 RightEncoder(void)
Interrupt response routine for the Right Encoder - input capture
Set ThisTime to value of timer tick counter
Call EncoderInterrupt function
Calculate the difference between the current RPM and the previosuly measured RPM
Calculate LeftRPM and RightRPM
Ignore "average out" misreads, indicated by spikes in RPM
Start Encoder Timer
Clear interrupt flag
void interrupt _Vec_tim0ch6 ControlLaw(void)
Interrupt response routine for updating control laws every 100ms - output compare
Clear interrupt flag
Enable Interrupts
If Left Encode Timer is Expired
Set LeftRPM to 0
Else
Set ThisRPM to LeftRPM;
Calculate RPMError as LeftRPMTarget - ThisRPM;
Update Error Sum as LeftSumError += RPMError
Calculate LeftDutyRequest as ((RPMError * pGain) + (LeftSumError * iGain));
Implement Anti-windup
If Right Encode Timer is Expired
Set RightRPM to 0
Else
Set ThisRPM to RightRPM;
Calculate RPMError as RightRPMTarget - ThisRPM;
Update Error Sum as RightSumError += RPMError
Calculate RightDutyRequest as ((RPMError * pGain) + (RightSumError * iGain));
Implement Anti-windup
Call SimpleMove with LeftDutyRequest and RightDutyRequest
Schedule next output compare event