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

Return to SDK Examples for Microchip Studio

1/*
2 * Title: 4IncrementsHomeToHardStop
3 *
4 * Objective:
5 * This example demonstrates control of the ClearPath-MCPV operational mode
6 * Move Incremental Distance, 4 Increments (Home to Hard Stop).
7 *
8 * Description:
9 * This example enables a ClearPath motor and executes a repeating pattern of
10 * incremental moves. During operation, various move statuses are written to
11 * 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 Move Incremental Distance, 4 Increments (Home to Hard Stop) mode (In
17 * MSP select Mode>>Position>>Move Incremental Distance, then with "4
18 * Increments (Home to Hard Stop)" selected hit the OK button).
19 * 3. The ClearPath motor must be set to use the HLFB mode "ASG-Position
20 * w/Measured Torque" with a PWM carrier frequency of 482 Hz through the MSP
21 * software (select Advanced>>High Level Feedback [Mode]... then choose
22 * "ASG-Position w/Measured Torque" from the dropdown, make sure that 482 Hz
23 * is selected in the "PWM Carrier Frequency" dropdown, and hit the OK
24 * button).
25 * 4. The ClearPath must have defined Position Increments through the MSP
26 * software which match the #define values below (On the main MSP window
27 * check the "Position Increment Setup (cnts)" box and fill in the four text
28 * boxes labeled "A off B off", "A on B off", "A off B on", and "A on B on").
29 * 5. Ensure the Trigger Pulse Time in MSP is set to 20ms. To configure, click
30 * the "Setup..." button found under the "Trigger Pulse" label on the MSP's
31 * main window, fill in the text box, and hit the OK button. Setting this to
32 * 20ms allows trigger pulses to be as long as 60ms, which will accommodate
33 * our 25ms pulses used later.
34 * 6. Ensure the Input A & B filters in MSP are both set to 20ms (In MSP
35 * select Advanced>>Input A, B Filtering... then in the Settings box fill in
36 * the textboxes labeled "Input A Filter Time Constant (msec)" and "Input B
37 * Filter Time Constant (msec)" then hit the OK button).
38 *
39 * ** Note: Homing is optional, and not required in this operational mode or in
40 * this example. This example makes its first move in the positive direction,
41 * assuming any homing move occurs in the negative direction
42 *
43 * Links:
44 * ** ClearCore Documentation: https://teknic-inc.github.io/ClearCore-library/
45 * ** ClearCore Manual: https://www.teknic.com/files/downloads/clearcore_user_manual.pdf
46 * ** ClearPath Manual (DC Power): https://www.teknic.com/files/downloads/clearpath_user_manual.pdf
47 * ** ClearPath Manual (AC Power): https://www.teknic.com/files/downloads/ac_clearpath-mc-sd_manual.pdf
48 * ** ClearPath Mode Informational Video: https://www.teknic.com/watch-video/#OpMode4
49 *
50 *
51 * Copyright (c) 2020 Teknic Inc. This work is free to use, copy and distribute under the terms of
52 * the standard MIT permissive software license which can be found at https://opensource.org/licenses/MIT
53 */
54
55#include "ClearCore.h"
56
57// Define the motor's connector as ConnectorM0
58#define motor ConnectorM0
59
60// The TRIGGER_PULSE_TIME is set to 25ms to ensure it is within the
61// Trigger Pulse Range defined in the MSP software (Default is 20-60ms)
62#define TRIGGER_PULSE_TIME 25
63
64// The INPUT_A_B_FILTER must match the Input A, B filter setting in
65// MSP (Advanced >> Input A, B Filtering...)
66#define INPUT_A_B_FILTER 20
67
68// Increments defined below must be set identically to the position increments
69// set in MSP
70#define POSITION_INCREMENT_1 750 // Inputs A off / B off, 750 counts (CCW)
71#define POSITION_INCREMENT_2 -750 // Inputs A on / B off, -750 counts (CW)
72#define POSITION_INCREMENT_3 1666 // Inputs A off / B on, 1666 counts (CCW)
73#define POSITION_INCREMENT_4 -1666 // Inputs A on / B on, -1666 counts (CW)
74
75// Select the baud rate to match the target device.
76#define baudRate 9600
77
78// Specify which serial to use: ConnectorUsb, ConnectorCOM0, or ConnectorCOM1.
79#define SerialPort ConnectorUsb
80
81// This example has built-in functionality to automatically clear motor faults.
82// Any uncleared fault will cancel and disallow motion.
83// WARNING: enabling automatic fault handling will clear faults immediately when
84// encountered and return a motor to a state in which motion is allowed. Before
85// enabling this functionality, be sure to understand this behavior and ensure
86// your system will not enter an unsafe state.
87// To enable automatic fault handling, #define HANDLE_MOTOR_FAULTS (1)
88// To disable automatic fault handling, #define HANDLE_MOTOR_FAULTS (0)
89#define HANDLE_MOTOR_FAULTS (0)
90
91// Declares user-defined helper functions.
92// The definition/implementations of these functions are at the bottom of the sketch.
93bool MoveIncrements(uint32_t NumberOfIncrements, int32_t PositionIncrement);
94void HandleMotorFaults();
95
96int main()
97{
98 // Sets all motor connectors to the correct mode for Incremental Distance
99 // mode.
100 MotorMgr.MotorModeSet(MotorManager::MOTOR_ALL,
101 Connector::CPM_MODE_A_DIRECT_B_DIRECT);
102
103 // Set the motor's HLFB mode to bipolar PWM
104 motor.HlfbMode(MotorDriver::HLFB_MODE_HAS_BIPOLAR_PWM);
105 // Set the HFLB carrier frequency to 482 Hz
106 motor.HlfbCarrier(MotorDriver::HLFB_CARRIER_482_HZ);
107
108 // Enforces the state of the motor's A and B inputs before enabling
109 // the motor.
110 motor.MotorInAState(false);
111 motor.MotorInBState(false);
112
113 // Sets up serial communication and waits up to 5 seconds for a port to open.
114 // Serial communication is not required for this example to run.
115 SerialPort.Mode(Connector::USB_CDC);
116 SerialPort.Speed(baudRate);
117 uint32_t timeout = 5000;
118 uint32_t startTime = Milliseconds();
119 SerialPort.PortOpen();
120 while (!SerialPort && Milliseconds() - startTime < timeout)
121 {
122 continue;
123 }
124
125 // Enables the motor; homing will begin automatically if homing is enabled
126 // in MSP.
127 motor.EnableRequest(true);
128 SerialPort.SendLine("Motor Enabled");
129
130 // Waits for HLFB to assert (waits for homing to complete if applicable)
131 SerialPort.SendLine("Waiting for HLFB...");
132 while (motor.HlfbState() != MotorDriver::HLFB_ASSERTED &&
133 !motor.StatusReg().bit.MotorInFault)
134 {
135 continue;
136 }
137 // Check if a motor faulted during enabling
138 // Clear fault if configured to do so
139 if (motor.StatusReg().bit.MotorInFault)
140 {
141 SerialPort.SendLine("Motor fault detected.");
142 if (HANDLE_MOTOR_FAULTS)
143 {
144 HandleMotorFaults();
145 }
146 else
147 {
148 SerialPort.SendLine("Enable automatic fault handling by setting HANDLE_MOTOR_FAULTS to 1.");
149 }
150 SerialPort.SendLine("Enabling may not have completed as expected. Proceed with caution.");
151 SerialPort.SendLine();
152 }
153 else
154 {
155 SerialPort.SendLine("Motor Ready");
156 }
157
158 while (true)
159 {
160 // Move a distance equal to 1 * POSITION_INCREMENT_1 = 750 counts
161 MoveIncrements(1, POSITION_INCREMENT_1); // See below for the detailed
162 // function definition
163 // Stay settled for 1 second before moving again.
164 Delay_ms(1000);
165
166 // Move a distance equal to 1 * POSITION_INCREMENT_2 = -750 counts
167 MoveIncrements(1, POSITION_INCREMENT_2);
168 Delay_ms(1000);
169
170 // Note: If another incremental move is triggered in the same direction as
171 // an active move before deceleration begins, then the moves will be
172 // seamlessly combined into one continuous move.
173
174 // Move a distance equal to 2 * POSITION_INCREMENT_3 = 3332 counts
175 MoveIncrements(2, POSITION_INCREMENT_3);
176 Delay_ms(1000);
177
178 // Move a distance equal to 2 * POSITION_INCREMENT_4 = -3332 counts
179 MoveIncrements(2, POSITION_INCREMENT_4);
180 Delay_ms(1000);
181 }
182}
183
184/*------------------------------------------------------------------------------
185 * MoveIncrements
186 *
187 * Triggers an incremental move of length numberOfIncrements *
188 * positionIncrement.
189 * Prints the distance and move status to the USB serial port.
190 * Returns when HLFB asserts (indicating move has successfully completed).
191 *
192 * Parameters:
193 * int numberOfIncrements - The number of increments to command
194 * int positionIncrement - The position increment commanded
195 *
196 * Returns: True/False depending on whether the move was successfully triggered.
197 */
198bool MoveIncrements(uint32_t numberOfIncrements, int32_t positionIncrement)
199{
200 // Check if a motor fault is currently preventing motion
201 // Clear fault if configured to do so
202 if (motor.StatusReg().bit.MotorInFault)
203 {
204 if (HANDLE_MOTOR_FAULTS)
205 {
206 SerialPort.SendLine("Motor fault detected. Move canceled.");
207 HandleMotorFaults();
208 }
209 else
210 {
211 SerialPort.SendLine("Motor fault detected. Move canceled. Enable automatic fault handling by setting HANDLE_MOTOR_FAULTS to 1.");
212 }
213 return false;
214 }
215
216 SerialPort.Send("Moving ");
217 SerialPort.Send(numberOfIncrements);
218 SerialPort.Send(" * ");
219
220 switch (positionIncrement)
221 {
222 case POSITION_INCREMENT_1:
223 // Sets Input A and B to position increment 1
224 SerialPort.SendLine(POSITION_INCREMENT_1);
225 motor.MotorInAState(false);
226 motor.MotorInBState(false);
227 break;
228 case POSITION_INCREMENT_2:
229 // Sets Input A and B to position increment 2
230 SerialPort.SendLine(POSITION_INCREMENT_2);
231 motor.MotorInAState(true);
232 motor.MotorInBState(false);
233 break;
234 case POSITION_INCREMENT_3:
235 // Sets Input A and B to position increment 3
236 SerialPort.SendLine(POSITION_INCREMENT_3);
237 motor.MotorInAState(false);
238 motor.MotorInBState(true);
239 break;
240 case POSITION_INCREMENT_4:
241 // Sets Input A and B to position increment 4
242 SerialPort.SendLine(POSITION_INCREMENT_4);
243 motor.MotorInAState(true);
244 motor.MotorInBState(true);
245 break;
246 default:
247 // If this case is reached then an incorrect positionIncrement was
248 // entered
249 return false;
250 }
251
252 // Delays 20ms longer than the Input A, B filter setting in MSP
253 Delay_ms(20 + INPUT_A_B_FILTER);
254
255 // Sends trigger pulses to the motor
256 motor.EnableTriggerPulse(numberOfIncrements, TRIGGER_PULSE_TIME, true);
257
258 // Waits for HLFB to assert (signaling the move has successfully completed)
259 SerialPort.SendLine("Moving.. Waiting for HLFB");
260 while (motor.HlfbState() != MotorDriver::HLFB_ASSERTED &&
261 !motor.StatusReg().bit.MotorInFault)
262 {
263 continue;
264 }
265 // Check if a motor faulted during move
266 // Clear fault if configured to do so
267 if (motor.StatusReg().bit.MotorInFault)
268 {
269 SerialPort.SendLine("Motor fault detected.");
270 if (HANDLE_MOTOR_FAULTS)
271 {
272 HandleMotorFaults();
273 }
274 else
275 {
276 SerialPort.SendLine("Enable automatic fault handling by setting HANDLE_MOTOR_FAULTS to 1.");
277 }
278 SerialPort.SendLine("Motion may not have completed as expected. Proceed with caution.");
279 SerialPort.SendLine();
280 return false;
281 }
282 else
283 {
284 SerialPort.SendLine("Move Done");
285 return true;
286 }
287}
288//------------------------------------------------------------------------------
289
290/*------------------------------------------------------------------------------
291 * HandleMotorFaults
292 *
293 * Clears motor faults by cycling enable to the motor.
294 * Assumes motor is in fault
295 * (this function is called when motor.StatusReg.MotorInFault == true)
296 *
297 * Parameters:
298 * requires "motor" to be defined as a ClearCore motor connector
299 *
300 * Returns:
301 * none
302 */
303void HandleMotorFaults()
304{
305 SerialPort.SendLine("Handling fault: clearing faults by cycling enable signal to motor.");
306 motor.EnableRequest(false);
307 Delay_ms(3 * TRIGGER_PULSE_TIME);
308 motor.EnableRequest(true);
309 Delay_ms(100);
310}
311//------------------------------------------------------------------------------
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.