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

Return to SDK Examples for Microchip Studio

1/*
2 * Title: FollowDigitalPosition
3 *
4 * Objective:
5 * This example demonstrates control of the ClearPath-MCPV operational mode
6 * Follow Digital Position Command, Unipolar PWM Command.
7 *
8 * Description:
9 * This example enables and then moves a ClearPath motor between various
10 * positions within a range defined in the MSP software based on the state
11 * of an analog input. During operation, various move statuses are written
12 * to the USB serial port.
13 * To achieve better positioning resolution (i.e. more commandable positions),
14 * consider using the ClearPath operational modes "Pulse Burst Positioning"
15 * or "Move Incremental Distance" instead.
16 *
17 * Requirements:
18 * 1. A ClearPath motor must be connected to Connector M-0.
19 * 2. The connected ClearPath motor must be configured through the MSP software
20 * for Follow Digital Position Command, Unipolar PWM Command mode (In MSP
21 * select Mode>>Position>>Follow Digital Position Command, then with
22 * "Unipolar PWM Command" selected hit the OK button).
23 * 3. The ClearPath motor must be set to use the HLFB mode "ASG-Position
24 * w/Measured Torque" with a PWM carrier frequency of 482 Hz through the MSP
25 * software (select Advanced>>High Level Feedback [Mode]... then choose
26 * "ASG-Position w/Measured Torque" from the dropdown, make sure that 482 Hz
27 * is selected in the "PWM Carrier Frequency" dropdown, and hit the OK
28 * button).
29 * 4. The ClearPath must have defined positions for 0% and 100% PWM (On the
30 * main MSP window check the "Position Range Setup (cnts)" box and fill in
31 * the two text boxes labeled "Posn at 0% PWM" and "Posn at 100% PWM").
32 * Change the "PositionZeroPWM" and "PositionMaxPWM" variables in the example
33 * below to match.
34 * 5. Homing must be configured in the MSP software for your mechanical
35 * system (e.g. homing direction, torque limit, etc.). This example does
36 * not use the ClearPath's Input A as a homing sensor, although that may
37 * be configured in this mode through MSP.
38 * 6. An analog input source (0-10V) connected to Connector A-9 to control motor
39 * position.
40 * 7. (Optional) An input source, such as a switch, connected to DI-6 to control
41 * the Command Lock or Home Sensor (configured in MSP).
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/#OpMode12
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// Defines the motor's connector
58#define motor ConnectorM0
59
60// Defines the command lock sensor connector
61#define LockSensor ConnectorDI6
62
63// Defines the analog input to control commanded position
64#define AnalogSensor ConnectorA9
65
66// Select the baud rate to match the target device.
67#define baudRate 9600
68
69// Specify which serial to use: ConnectorUsb, ConnectorCOM0, or ConnectorCOM1.
70#define SerialPort ConnectorUsb
71
72// This example has built-in functionality to automatically clear motor faults.
73// Any uncleared fault will cancel and disallow motion.
74// WARNING: enabling automatic fault handling will clear faults immediately when
75// encountered and return a motor to a state in which motion is allowed. Before
76// enabling this functionality, be sure to understand this behavior and ensure
77// your system will not enter an unsafe state.
78// To enable automatic fault handling, #define HANDLE_MOTOR_FAULTS (1)
79// To disable automatic fault handling, #define HANDLE_MOTOR_FAULTS (0)
80#define HANDLE_MOTOR_FAULTS (0)
81
82// Declares user-defined helper functions.
83// The definition/implementations of these functions are at the bottom of the sketch.
84double positionZeroPWM = 0;
85double positionMaxPWM = 10000;
86void HandleMotorFaults();
87
88// Declares our user-defined functions, which are used to pass the Command Lock
89// sensor state and send position commands to the motor. The implementations of
90// these functions are at the bottom of the sketch.
91void LockSensorCallback();
92bool CommandPosition(int32_t commandedPosition);
93
94int main() {
95 // Set up an analog sensor to control commanded position.
96 AnalogSensor.Mode(Connector::INPUT_ANALOG);
97
98 // Sets all motor connectors to the correct mode for Follow Digital
99 // Position mode.
100 MotorMgr.MotorModeSet(MotorManager::MOTOR_ALL,
101 Connector::CPM_MODE_A_DIRECT_B_PWM);
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 // This section attaches the interrupt callback to the locking sensor pin,
109 // set to trigger on any change of sensor state.
110 LockSensor.Mode(Connector::INPUT_DIGITAL);
111 LockSensor.InterruptHandlerSet(LockSensorCallback, InputManager::CHANGE, true);
112 // Set input A to match the initial state of the sensor.
113 motor.MotorInAState(LockSensor.State());
114
115 // Sets up serial communication and waits up to 5 seconds for a port to open.
116 // Serial communication is not required for this example to run.
117 SerialPort.Mode(Connector::USB_CDC);
118 SerialPort.Speed(baudRate);
119 uint32_t timeout = 5000;
120 uint32_t startTime = Milliseconds();
121 SerialPort.PortOpen();
122 while (!SerialPort && Milliseconds() - startTime < timeout) {
123 continue;
124 }
125
126 // Enables the motor; homing will begin automatically if applicable
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 continue;
135 }
136 // Check if a motor faulted during enabling
137 // Clear fault if configured to do so
138 if (motor.StatusReg().bit.MotorInFault) {
139 SerialPort.SendLine("Motor fault detected.");
140 if(HANDLE_MOTOR_FAULTS){
141 HandleMotorFaults();
142 } else {
143 SerialPort.SendLine("Enable automatic fault handling by setting HANDLE_MOTOR_FAULTS to 1.");
144 }
145 SerialPort.SendLine("Enabling may not have completed as expected. Proceed with caution.");
146 SerialPort.SendLine();
147 } else {
148 SerialPort.SendLine("Motor Ready");
149 }
150
151 while (true) {
152 // Read the voltage on the analog sensor (0-10V).
153 float analogVoltage = AnalogSensor.AnalogVoltage();
154 // Convert the voltage measured to a position within the valid range.
155 int32_t commandedPosition =
156 static_cast<int32_t>(round(analogVoltage / 10 * positionMaxPWM));
157 CommandPosition(commandedPosition); // See below for the detailed function definition.
158 }
159}
160
161/*------------------------------------------------------------------------------
162 * CommandPosition
163 *
164 * Move to position number commandedPosition (counts in MSP)
165 * Prints the move status to the USB serial port
166 * Returns whether the command has been updated.
167 *
168 * Parameters:
169 * int commandedPosition - The position, in counts, to command
170 *
171 */
172bool CommandPosition(int32_t commandedPosition) {
173 if (abs(commandedPosition) > abs(positionMaxPWM) ||
174 abs(commandedPosition) < abs(positionZeroPWM)) {
175 SerialPort.SendLine("Move rejected, invalid position requested");
176 return false;
177 }
178
179 // Check if a motor fault is currently preventing motion
180 // Clear fault if configured to do so
181 if (motor.StatusReg().bit.MotorInFault) {
182 if(HANDLE_MOTOR_FAULTS){
183 SerialPort.SendLine("Motor fault detected. Move canceled.");
184 HandleMotorFaults();
185 } else {
186 SerialPort.SendLine("Motor fault detected. Move canceled. Enable automatic fault handling by setting HANDLE_MOTOR_FAULTS to 1.");
187 }
188 return false;
189 }
190
191 SerialPort.Send("Moving to position: ");
192 SerialPort.SendLine(commandedPosition);
193
194 // Find the scaling factor of our position range mapped to the PWM duty
195 // cycle range (255 is the max duty cycle).
196 double scaleFactor = 255 / abs(positionMaxPWM - positionZeroPWM);
197
198 // Scale the position command to our duty cycle range.
199 uint8_t dutyRequest = abs(commandedPosition - positionZeroPWM) * scaleFactor;
200
201 // Command the move.
202 motor.MotorInBDuty(dutyRequest);
203
204 return true;
205}
206//------------------------------------------------------------------------------
207
208/*------------------------------------------------------------------------------
209 * LockSensorCallback
210 *
211 * Reads the state of the locking sensor and passes the state to the motor.
212 *
213 * Parameters:
214 * None
215 *
216 * Returns: None
217 */
218void LockSensorCallback() {
219 // A 1 ms delay is required in order to pass the correct filtered sensor
220 // state.
221 Delay_ms(1);
222 motor.MotorInAState(LockSensor.State());
223}
224//------------------------------------------------------------------------------
225
226/*------------------------------------------------------------------------------
227 * HandleMotorFaults
228 *
229 * Clears motor faults by cycling enable to the motor.
230 * Assumes motor is in fault
231 * (this function is called when motor.StatusReg.MotorInFault == true)
232 *
233 * Parameters:
234 * requires "motor" to be defined as a ClearCore motor connector
235 *
236 * Returns:
237 * none
238 */
239 void HandleMotorFaults(){
240 SerialPort.SendLine("Handling fault: clearing faults by cycling enable signal to motor.");
241 motor.EnableRequest(false);
242 Delay_ms(10);
243 motor.EnableRequest(true);
244 Delay_ms(100);
245 }
246//------------------------------------------------------------------------------
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.