#include "ClearCore.h"
#define motor ConnectorM0
#define LockSensor ConnectorDI6
#define AnalogSensor ConnectorA9
#define baudRate 9600
#define SerialPort ConnectorUsb
#define HANDLE_MOTOR_FAULTS (0)
double positionZeroPWM = 0;
double positionMaxPWM = 10000;
void HandleMotorFaults();
void LockSensorCallback();
bool CommandPosition(int32_t commandedPosition);
int main() {
AnalogSensor.Mode(Connector::INPUT_ANALOG);
Connector::CPM_MODE_A_DIRECT_B_PWM);
motor.HlfbMode(MotorDriver::HLFB_MODE_HAS_BIPOLAR_PWM);
motor.HlfbCarrier(MotorDriver::HLFB_CARRIER_482_HZ);
LockSensor.Mode(Connector::INPUT_DIGITAL);
LockSensor.InterruptHandlerSet(LockSensorCallback, InputManager::CHANGE, true);
motor.MotorInAState(LockSensor.State());
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...");
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) {
float analogVoltage = AnalogSensor.AnalogVoltage();
int32_t commandedPosition =
static_cast<int32_t>(round(analogVoltage / 10 * positionMaxPWM));
CommandPosition(commandedPosition);
}
}
bool CommandPosition(int32_t commandedPosition) {
if (abs(commandedPosition) > abs(positionMaxPWM) ||
abs(commandedPosition) < abs(positionZeroPWM)) {
SerialPort.SendLine("Move rejected, invalid position 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("Moving to position: ");
SerialPort.SendLine(commandedPosition);
double scaleFactor = 255 / abs(positionMaxPWM - positionZeroPWM);
uint8_t dutyRequest = abs(commandedPosition - positionZeroPWM) * scaleFactor;
motor.MotorInBDuty(dutyRequest);
return true;
}
void LockSensorCallback() {
motor.MotorInAState(LockSensor.State());
}
void HandleMotorFaults(){
SerialPort.SendLine("Handling fault: clearing faults by cycling enable signal to motor.");
motor.EnableRequest(false);
motor.EnableRequest(true);
}