#include "ClearCore.h"
#define motor ConnectorM0
#define baudRate 9600
#define SerialPort ConnectorUsb
#define HANDLE_MOTOR_FAULTS (0)
double commandedVelocity = 0;
int32_t maxVelocityCW = 1000;
int32_t maxVelocityCCW = 1000;
double velocityResolution = 2.0;
bool MoveAtVelocity(double velocity);
void HandleMotorFaults();
int main() {
Connector::CPM_MODE_A_DIRECT_B_DIRECT);
motor.HlfbMode(MotorDriver::HLFB_MODE_HAS_BIPOLAR_PWM);
motor.HlfbCarrier(MotorDriver::HLFB_CARRIER_482_HZ);
motor.MotorInAState(false);
motor.MotorInBState(false);
SerialPort.Mode(Connector::USB_CDC);
SerialPort.Speed(baudRate);
uint32_t timeout = 5000;
SerialPort.PortOpen();
while (!SerialPort &&
Milliseconds() - startTime < timeout) {
continue;
}
motor.EnableRequest(true);
SerialPort.SendLine("Motor Enabled");
SerialPort.SendLine("Waiting for HLFB...");
SerialPort.SendLine("Waiting for HLFB...");
while (motor.HlfbState() != MotorDriver::HLFB_ASSERTED &&
!motor.StatusReg().bit.MotorInFault) {
continue;
}
if (motor.StatusReg().bit.MotorInFault) {
SerialPort.SendLine("Motor fault detected.");
if(HANDLE_MOTOR_FAULTS){
HandleMotorFaults();
} else {
SerialPort.SendLine("Enable automatic fault handling by setting HANDLE_MOTOR_FAULTS to 1.");
}
SerialPort.SendLine("Enabling may not have completed as expected. Proceed with caution.");
SerialPort.SendLine();
} else {
SerialPort.SendLine("Motor Ready");
}
while (true) {
MoveAtVelocity(500);
MoveAtVelocity(-100);
MoveAtVelocity(-750);
MoveAtVelocity(1000);
MoveAtVelocity(0);
}
}
bool MoveAtVelocity(double velocity) {
if (velocity == commandedVelocity) {
return false;
}
if (velocity > maxVelocityCCW || velocity < -maxVelocityCW) {
SerialPort.Send("An invalid velocity of ");
SerialPort.Send(velocity);
SerialPort.SendLine(" RPM has been requested.");
return false;
}
if (motor.StatusReg().bit.MotorInFault) {
if(HANDLE_MOTOR_FAULTS){
SerialPort.SendLine("Motor fault detected. Move canceled.");
HandleMotorFaults();
} else {
SerialPort.SendLine("Motor fault detected. Move canceled. Enable automatic fault handling by setting HANDLE_MOTOR_FAULTS to 1.");
}
return false;
}
SerialPort.Send("Commanding ");
SerialPort.Send(velocity);
SerialPort.SendLine(" RPM");
int32_t currentVelocityRounded = round(commandedVelocity / velocityResolution);
int32_t targetVelocityRounded = round(velocity / velocityResolution);
int32_t velocityDifference = labs(targetVelocityRounded - currentVelocityRounded);
for (int32_t i = 0; i < velocityDifference; i++) {
if (velocity > commandedVelocity) {
motor.MotorInAState(true);
motor.MotorInBState(true);
motor.MotorInAState(false);
motor.MotorInBState(false);
}
else {
motor.MotorInBState(true);
motor.MotorInAState(true);
motor.MotorInBState(false);
motor.MotorInAState(false);
}
}
commandedVelocity = velocity;
SerialPort.SendLine("Ramping Speed... Waiting for HLFB");
while (motor.HlfbState() != MotorDriver::HLFB_ASSERTED &&
!motor.StatusReg().bit.MotorInFault) {
continue;
}
if (motor.StatusReg().bit.MotorInFault) {
SerialPort.SendLine("Motor fault detected.");
if(HANDLE_MOTOR_FAULTS){
HandleMotorFaults();
} else {
SerialPort.SendLine("Enable automatic fault handling by setting HANDLE_MOTOR_FAULTS to 1.");
}
SerialPort.SendLine("Motion may not have completed as expected. Proceed with caution.");
SerialPort.SendLine();
return false;
} else {
SerialPort.SendLine("Move Done");
return true;
}
SerialPort.SendLine("Target Velocity Reached");
return true;
}
void HandleMotorFaults(){
SerialPort.SendLine("Handling fault: clearing faults by cycling enable signal to motor.");
motor.EnableRequest(false);
motor.EnableRequest(true);
}