#include "ClearCore.h"
#define motor0 ConnectorM0
#define motor1 ConnectorM1
#define baudRate 9600
#define SerialPort ConnectorUsb
#define HANDLE_ALERTS (0)
int32_t velocityLimit = 10000;
int32_t accelerationLimit = 100000;
bool SynchronizedMove(int32_t distance);
void PrintAlerts();
void HandleAlerts();
int main() {
Connector::CPM_MODE_STEP_AND_DIR);
motor0.HlfbMode(MotorDriver::HLFB_MODE_HAS_BIPOLAR_PWM);
motor1.HlfbMode(MotorDriver::HLFB_MODE_HAS_BIPOLAR_PWM);
motor0.HlfbCarrier(MotorDriver::HLFB_CARRIER_482_HZ);
motor1.HlfbCarrier(MotorDriver::HLFB_CARRIER_482_HZ);
motor0.VelMax(velocityLimit);
motor1.VelMax(velocityLimit);
motor0.AccelMax(accelerationLimit);
motor1.AccelMax(accelerationLimit);
SerialPort.Mode(Connector::USB_CDC);
SerialPort.Speed(baudRate);
uint32_t timeout = 5000;
SerialPort.PortOpen();
while (!SerialPort &&
Milliseconds() - startTime < timeout) {
continue;
}
motor0.EnableRequest(true);
SerialPort.SendLine("Motor 0 Enabled");
motor1.EnableRequest(true);
SerialPort.SendLine("Motor 1 Enabled");
SerialPort.SendLine("Waiting for HLFB...");
while ( (motor0.HlfbState() != MotorDriver::HLFB_ASSERTED ||
motor1.HlfbState() != MotorDriver::HLFB_ASSERTED) &&
!motor0.StatusReg().bit.AlertsPresent &&
!motor1.StatusReg().bit.AlertsPresent) {
SerialPort.SendLine("Waiting for HLFB to assert on both motors");
}
}
if (motor0.StatusReg().bit.AlertsPresent ||
motor1.StatusReg().bit.AlertsPresent) {
SerialPort.SendLine("Motor alert detected.");
PrintAlerts();
if(HANDLE_ALERTS){
HandleAlerts();
} else {
SerialPort.SendLine("Enable automatic alert handling by setting HANDLE_ALERTS to 1.");
}
SerialPort.SendLine("Enabling may not have completed as expected. Proceed with caution.");
SerialPort.SendLine();
} else {
SerialPort.SendLine("Motor Ready");
}
while (true) {
SynchronizedMove(6400);
SynchronizedMove(19200);
SynchronizedMove(-12800);
SynchronizedMove(-6400);
SynchronizedMove(-6400);
}
}
bool SynchronizedMove(int32_t distance) {
if (motor0.StatusReg().bit.AlertsPresent || motor1.StatusReg().bit.AlertsPresent ) {
SerialPort.SendLine("Motor alert detected.");
PrintAlerts();
if(HANDLE_ALERTS){
HandleAlerts();
} else {
SerialPort.SendLine("Enable automatic alert handling by setting HANDLE_ALERTS to 1.");
}
SerialPort.SendLine("Move canceled.");
SerialPort.SendLine();
return false;
}
SerialPort.Send("Moving distance: ");
SerialPort.SendLine(distance);
motor0.Move(distance);
motor1.Move(distance);
while ( (!motor0.StepsComplete() || motor0.HlfbState() != MotorDriver::HLFB_ASSERTED ||
!motor1.StepsComplete() || motor1.HlfbState() != MotorDriver::HLFB_ASSERTED) &&
!motor0.StatusReg().bit.AlertsPresent && !motor1.StatusReg().bit.AlertsPresent ){
SerialPort.SendLine("Waiting for HLFB to assert on both motors");
}
if (motor0.StatusReg().bit.AlertsPresent || motor1.StatusReg().bit.AlertsPresent){
motor0.MoveStopAbrupt();
motor1.MoveStopAbrupt();
SerialPort.SendLine("Motor alert detected.");
PrintAlerts();
if(HANDLE_ALERTS){
HandleAlerts();
} else {
SerialPort.SendLine("Enable automatic fault handling by setting HANDLE_ALERTS to 1.");
}
SerialPort.SendLine("Motion may not have completed as expected. Proceed with caution.");
SerialPort.SendLine();
return false;
}
}
SerialPort.SendLine("Move Done");
return true;
}
void PrintAlerts(){
SerialPort.SendLine("Alerts present on motor0: ");
if(motor0.AlertReg().bit.MotionCanceledInAlert){
SerialPort.SendLine(" MotionCanceledInAlert "); }
if(motor0.AlertReg().bit.MotionCanceledPositiveLimit){
SerialPort.SendLine(" MotionCanceledPositiveLimit "); }
if(motor0.AlertReg().bit.MotionCanceledNegativeLimit){
SerialPort.SendLine(" MotionCanceledNegativeLimit "); }
if(motor0.AlertReg().bit.MotionCanceledSensorEStop){
SerialPort.SendLine(" MotionCanceledSensorEStop "); }
if(motor0.AlertReg().bit.MotionCanceledMotorDisabled){
SerialPort.SendLine(" MotionCanceledMotorDisabled "); }
if(motor0.AlertReg().bit.MotorFaulted){
SerialPort.SendLine(" MotorFaulted ");
}
SerialPort.SendLine("Alerts present on motor1: ");
if(motor1.AlertReg().bit.MotionCanceledInAlert){
SerialPort.SendLine(" MotionCanceledInAlert "); }
if(motor1.AlertReg().bit.MotionCanceledPositiveLimit){
SerialPort.SendLine(" MotionCanceledPositiveLimit "); }
if(motor1.AlertReg().bit.MotionCanceledNegativeLimit){
SerialPort.SendLine(" MotionCanceledNegativeLimit "); }
if(motor1.AlertReg().bit.MotionCanceledSensorEStop){
SerialPort.SendLine(" MotionCanceledSensorEStop "); }
if(motor1.AlertReg().bit.MotionCanceledMotorDisabled){
SerialPort.SendLine(" MotionCanceledMotorDisabled "); }
if(motor1.AlertReg().bit.MotorFaulted){
SerialPort.SendLine(" MotorFaulted ");
}
}
void HandleAlerts(){
if(motor0.AlertReg().bit.MotorFaulted){
SerialPort.SendLine("Faults present on motor0. Cycling enable signal to motor to clear faults.");
motor0.EnableRequest(false);
motor0.EnableRequest(true);
}
if(motor1.AlertReg().bit.MotorFaulted){
SerialPort.SendLine("Faults present on motor1. Cycling enable signal to motor to clear faults.");
motor1.EnableRequest(false);
motor1.EnableRequest(true);
}
SerialPort.SendLine("Clearing alerts on both motors.");
motor0.ClearAlerts();
motor1.ClearAlerts();
}