ClearCore Library
Loading...
Searching...
No Matches
PulseBurstPositioning.cpp

Return to SDK Examples for Microchip Studio

1/*
2 * Title: PulseBurstPositioning
3 *
4 * Objective:
5 * This example demonstrates control of the ClearPath-MCPV operational mode
6 * Pulse Burst Positioning.
7 *
8 * Description:
9 * This example enables a ClearPath motor and executes a repeating pattern of
10 * positional move commands. During operation, various move statuses are
11 * written to the USB serial port.
12 *
13 * Requirements:
14 * 1. A ClearPath motor must be connected to Connector M-0.
15 * 2. The connected ClearPath motor must be configured through the MSP software
16 * for Pulse Burst Positioning mode (In MSP select Mode>>Position>>Pulse
17 * Burst Positioning, then hit the OK button).
18 * 3. The ClearPath motor must be set to use the HLFB mode "ASG-Position
19 * w/Measured Torque" with a PWM carrier frequency of 482 Hz through the MSP
20 * software (select Advanced>>High Level Feedback [Mode]... then choose
21 * "ASG-Position w/Measured Torque" from the dropdown, make sure that 482 Hz
22 * is selected in the "PWM Carrier Frequency" dropdown, and hit the OK
23 * button).
24 * 4. Ensure the Trigger Pulse Time in MSP is set to 20ms. To configure, click
25 * the "Setup..." button found under the "Trigger Pulse" label on the MSP's
26 * main window, fill in the text box, and hit the OK button. Setting this to
27 * 20ms allows trigger pulses to be as long as 60ms, which will accommodate
28 * our 25ms pulses used later.
29 *
30 * ** Note: Homing is optional, and not required in this operational mode or in
31 * this example. This example makes its first move in the positive direction,
32 * assuming any homing move occurs in the negative direction.
33 *
34 * ** Note: Set the Input Resolution in MSP the same as your motor's Positioning
35 * Resolution spec if you'd like the pulses sent by ClearCore to command a
36 * move of the same number of Encoder Counts, a 1:1 ratio.
37 *
38 * Links:
39 * ** ClearCore Documentation: https://teknic-inc.github.io/ClearCore-library/
40 * ** ClearCore Manual: https://www.teknic.com/files/downloads/clearcore_user_manual.pdf
41 * ** ClearPath Manual (DC Power): https://www.teknic.com/files/downloads/clearpath_user_manual.pdf
42 * ** ClearPath Manual (AC Power): https://www.teknic.com/files/downloads/ac_clearpath-mc-sd_manual.pdf
43 * ** ClearPath Mode Informational Video: https://www.teknic.com/watch-video/#OpMode10
44 *
45 *
46 * Copyright (c) 2020 Teknic Inc. This work is free to use, copy and distribute under the terms of
47 * the standard MIT permissive software license which can be found at https://opensource.org/licenses/MIT
48 */
49
50#include "ClearCore.h"
51
52// Defines the motor's connector as ConnectorM0
53#define motor ConnectorM0
54
55// The TRIGGER_PULSE_TIME is set to 25ms to ensure it is within the
56// Trigger Pulse Range defined in the MSP software (Default is 20ms, which
57// allows a range of pulses up to 60ms)
58#define TRIGGER_PULSE_TIME 25
59
60// Select the baud rate to match the target device.
61#define baudRate 9600
62
63// Specify which serial to use: ConnectorUsb, ConnectorCOM0, or ConnectorCOM1.
64#define SerialPort ConnectorUsb
65
66// This example has built-in functionality to automatically clear motor alerts,
67// including motor shutdowns. Any uncleared alert will cancel and disallow motion.
68// WARNING: enabling automatic alert handling will clear alerts immediately when
69// encountered and return a motor to a state in which motion is allowed. Before
70// enabling this functionality, be sure to understand this behavior and ensure
71// your system will not enter an unsafe state.
72// To enable automatic alert handling, #define HANDLE_ALERTS (1)
73// To disable automatic alert handling, #define HANDLE_ALERTS (0)
74#define HANDLE_ALERTS (0)
75
76// Declares user-defined helper functions.
77// The definition/implementations of these functions are at the bottom of the sketch.
78bool MoveDistance(int32_t pulseNum);
79void PrintAlerts();
80void HandleAlerts();
81
82int main() {
83 // To command for Pulse Burst Positioning, use the step and direction
84 // interface with the acceleration and velocity limits set to their
85 // maximum values. The ClearPath will then take the pulses and enforce
86 // the motion profile constraints.
87
88 // Sets all motor connectors into step and direction mode.
89 MotorMgr.MotorModeSet(MotorManager::MOTOR_ALL,
90 Connector::CPM_MODE_STEP_AND_DIR);
91
92 // Set the motor's HLFB mode to bipolar PWM
93 motor.HlfbMode(MotorDriver::HLFB_MODE_HAS_BIPOLAR_PWM);
94 // Set the HFLB carrier frequency to 482 Hz
95 motor.HlfbCarrier(MotorDriver::HLFB_CARRIER_482_HZ);
96
97 // Sets the maximum velocity and acceleration for each command.
98 // The move profile in this mode is determined by ClearPath, so the two
99 // lines below should be left as is. Set your desired speed and accel in MSP
100 motor.VelMax(INT32_MAX);
101 motor.AccelMax(INT32_MAX);
102
103 // Sets up serial communication and waits up to 5 seconds for a port to open.
104 // Serial communication is not required for this example to run.
105 SerialPort.Mode(Connector::USB_CDC);
106 SerialPort.Speed(baudRate);
107 uint32_t timeout = 5000;
108 uint32_t startTime = Milliseconds();
109 SerialPort.PortOpen();
110 while (!SerialPort && Milliseconds() - startTime < timeout) {
111 continue;
112 }
113
114 // Enables the motor; homing will begin automatically if homing is enabled
115 // in MSP.
116 motor.EnableRequest(true);
117 SerialPort.SendLine("Motor Enabled");
118
119 // Waits for HLFB to assert (waits for homing to complete if applicable)
120 SerialPort.SendLine("Waiting for HLFB...");
121 while (motor.HlfbState() != MotorDriver::HLFB_ASSERTED &&
122 !motor.StatusReg().bit.AlertsPresent) {
123 continue;
124 }
125 // Check if motor alert occurred during enabling
126 // Clear alert if configured to do so
127 if (motor.StatusReg().bit.AlertsPresent) {
128 SerialPort.SendLine("Motor alert detected.");
129 PrintAlerts();
130 if(HANDLE_ALERTS){
131 HandleAlerts();
132 } else {
133 SerialPort.SendLine("Enable automatic alert handling by setting HANDLE_ALERTS to 1.");
134 }
135 SerialPort.SendLine("Enabling may not have completed as expected. Proceed with caution.");
136 SerialPort.SendLine();
137 } else {
138 SerialPort.SendLine("Motor Ready");
139 }
140
141 while (true) {
142 // Move 6400 counts (positive direction) then wait 1000ms
143 MoveDistance(6400);
144 Delay_ms(1000);
145 // Move 19200 counts farther positive, then wait 1000ms
146 MoveDistance(19200);
147 Delay_ms(1000);
148
149 // Generates a trigger pulse on the enable line so the next move uses the
150 // Alt Speed Limit.
151 motor.EnableTriggerPulse(1, TRIGGER_PULSE_TIME, true);
152
153 // Move back 12800 counts (negative direction), then wait 1000ms
154 MoveDistance(-12800);
155 Delay_ms(1000);
156 // Move back 6400 counts (negative direction), then wait 1000ms
157 MoveDistance(-6400);
158 Delay_ms(1000);
159 // Move back to the start (negative 6400 pulses), then wait 1000ms
160 MoveDistance(-6400);
161 Delay_ms(1000);
162 }
163}
164
165/*------------------------------------------------------------------------------
166 * MoveDistance
167 *
168 * Command "distance" number of step pulses away from the current position
169 * Prints the move status to the USB serial port
170 * Returns when HLFB asserts (indicating the motor has reached the commanded
171 * position)
172 *
173 * Parameters:
174 * int distance - The distance, in step pulses, to move
175 *
176 * Returns: True/False depending on whether the move was successfully triggered.
177 */
178bool MoveDistance(int32_t distance) {
179 // Check if a motor alert is currently preventing motion
180 // Clear alert if configured to do so
181 if (motor.StatusReg().bit.AlertsPresent) {
182 SerialPort.SendLine("Motor alert detected.");
183 PrintAlerts();
184 if(HANDLE_ALERTS){
185 HandleAlerts();
186 } else {
187 SerialPort.SendLine("Enable automatic alert handling by setting HANDLE_ALERTS to 1.");
188 }
189 SerialPort.SendLine("Move canceled.");
190 SerialPort.SendLine();
191 return false;
192 }
193
194 SerialPort.Send("Commanding ");
195 SerialPort.Send(distance);
196 SerialPort.SendLine(" pulses");
197
198 // Command the move of incremental distance
199 motor.Move(distance);
200
201 // Add a short delay to allow HLFB to update
202 Delay_ms(2);
203
204 // Waits for HLFB to assert (signaling the move has successfully completed)
205 SerialPort.SendLine("Moving.. Waiting for HLFB");
206 while ( (!motor.StepsComplete() || motor.HlfbState() != MotorDriver::HLFB_ASSERTED) &&
207 !motor.StatusReg().bit.AlertsPresent) {
208 continue;
209 }
210 // Check if motor alert occurred during move
211 // Clear alert if configured to do so
212 if (motor.StatusReg().bit.AlertsPresent) {
213 SerialPort.SendLine("Motor alert detected.");
214 PrintAlerts();
215 if(HANDLE_ALERTS){
216 HandleAlerts();
217 } else {
218 SerialPort.SendLine("Enable automatic fault handling by setting HANDLE_ALERTS to 1.");
219 }
220 SerialPort.SendLine("Motion may not have completed as expected. Proceed with caution.");
221 SerialPort.SendLine();
222 return false;
223 } else {
224 SerialPort.SendLine("Move Done");
225 return true;
226 }
227}
228//------------------------------------------------------------------------------
229
230
231/*------------------------------------------------------------------------------
232 * PrintAlerts
233 *
234 * Prints active alerts.
235 *
236 * Parameters:
237 * requires "motor" to be defined as a ClearCore motor connector
238 *
239 * Returns:
240 * none
241 */
242 void PrintAlerts(){
243 // report status of alerts
244 SerialPort.SendLine("Alerts present: ");
245 if(motor.AlertReg().bit.MotionCanceledInAlert){
246 SerialPort.SendLine(" MotionCanceledInAlert "); }
247 if(motor.AlertReg().bit.MotionCanceledPositiveLimit){
248 SerialPort.SendLine(" MotionCanceledPositiveLimit "); }
249 if(motor.AlertReg().bit.MotionCanceledNegativeLimit){
250 SerialPort.SendLine(" MotionCanceledNegativeLimit "); }
251 if(motor.AlertReg().bit.MotionCanceledSensorEStop){
252 SerialPort.SendLine(" MotionCanceledSensorEStop "); }
253 if(motor.AlertReg().bit.MotionCanceledMotorDisabled){
254 SerialPort.SendLine(" MotionCanceledMotorDisabled "); }
255 if(motor.AlertReg().bit.MotorFaulted){
256 SerialPort.SendLine(" MotorFaulted ");
257 }
258 }
259//------------------------------------------------------------------------------
260
261
262/*------------------------------------------------------------------------------
263 * HandleAlerts
264 *
265 * Clears alerts, including motor faults.
266 * Faults are cleared by cycling enable to the motor.
267 * Alerts are cleared by clearing the ClearCore alert register directly.
268 *
269 * Parameters:
270 * requires "motor" to be defined as a ClearCore motor connector
271 *
272 * Returns:
273 * none
274 */
275 void HandleAlerts(){
276 if(motor.AlertReg().bit.MotorFaulted){
277 // if a motor fault is present, clear it by cycling enable
278 SerialPort.SendLine("Faults present. Cycling enable signal to motor to clear faults.");
279 motor.EnableRequest(false);
280 Delay_ms(3*TRIGGER_PULSE_TIME);
281 motor.EnableRequest(true);
282 }
283 // clear alerts
284 SerialPort.SendLine("Clearing alerts.");
285 motor.ClearAlerts();
286 }
287//------------------------------------------------------------------------------
288
289
void Delay_ms(uint32_t ms)
Blocks operations for ms milliseconds.
Definition SysTiming.h:287
uint32_t Milliseconds(void)
Number of milliseconds since the ClearCore was initialized.
bool MotorModeSet(MotorPair motorPair, Connector::ConnectorModes newMode)
Sets the operational mode for the specified MotorDriver connectors.