My Version of the Crealab MotorLib.

Fork of MotorLib by CreaLab

Committer:
sepp_nepp
Date:
Thu Apr 18 12:12:48 2019 +0000
Revision:
24:932ea7bdc850
Compiles

Who changed what in which revision?

UserRevisionLine numberNew contents of line
sepp_nepp 24:932ea7bdc850 1 /**
sepp_nepp 24:932ea7bdc850 2 * @file CreaMot.h
sepp_nepp 24:932ea7bdc850 3 * \brief File contains Crealab CreaMot Library.
sepp_nepp 24:932ea7bdc850 4
sepp_nepp 24:932ea7bdc850 5 * CreaMot.h contains the class CreaMot, and related enums and structs.
sepp_nepp 24:932ea7bdc850 6 * Includes only "mbed.h".
sepp_nepp 24:932ea7bdc850 7 *
sepp_nepp 24:932ea7bdc850 8 * MotStatus structure is dissolved into the CreaMot Class
sepp_nepp 24:932ea7bdc850 9 *
sepp_nepp 24:932ea7bdc850 10 * Rotation directions are now consistently called Clockwise, and Counterclockwise (CCW),
sepp_nepp 24:932ea7bdc850 11 * instead of mix them with Left and Right.
sepp_nepp 24:932ea7bdc850 12 * Doxygens Tags are preceeded by either a backslash @\ or by an at symbol @@.
sepp_nepp 24:932ea7bdc850 13
sepp_nepp 24:932ea7bdc850 14 * @author Tarek Lule, Francois Druilhe, et al.
sepp_nepp 24:932ea7bdc850 15 * @date 01. Nov. 2018.
sepp_nepp 24:932ea7bdc850 16 * @see https://os.mbed.com/users/sepp_nepp/code/MotorLib/ */
sepp_nepp 24:932ea7bdc850 17
sepp_nepp 24:932ea7bdc850 18 // -------------------- CreaMot ---------------------------
sepp_nepp 24:932ea7bdc850 19
sepp_nepp 24:932ea7bdc850 20 #ifndef CREAMOT_H
sepp_nepp 24:932ea7bdc850 21 #define CREAMOT_H
sepp_nepp 24:932ea7bdc850 22
sepp_nepp 24:932ea7bdc850 23 #include "mbed.h"
sepp_nepp 24:932ea7bdc850 24
sepp_nepp 24:932ea7bdc850 25 #define MOTOR_STEP_TIME_MIN_US 700 /**< Shortest Time between two CreaMot steps = 0.7ms, was MOTOR_STEP_TIME_MIN*/
sepp_nepp 24:932ea7bdc850 26 #define MOTOR_STEP_TIME_DEFAULT_US 5000 /**< Default Time between two CreaMot steps = 5ms, was MOTOR_STEP_TIME_DEFAULT*/
sepp_nepp 24:932ea7bdc850 27 #define MOTOR_STEPS_FOR_A_TURN 4096 /**< Default number of CreaMot steps to complete a turn = 4096 steps */
sepp_nepp 24:932ea7bdc850 28 #define CLOCKWISE true /**< Constant for Clockwise direction */
sepp_nepp 24:932ea7bdc850 29 #define COUNTERCLOCKWISE false /**< Constant for Counter-Clockwise direction */
sepp_nepp 24:932ea7bdc850 30 #define MAX_SPEED_CM_SEC 30.0f /**< Clamp maximum advancement speed = 30cm/sec, was MAX_SPEED */
sepp_nepp 24:932ea7bdc850 31 #define MIN_SPEED_CM_SEC 0.001f /**< Clamp minimum advancement speed = 10um/sec */
sepp_nepp 24:932ea7bdc850 32 #define PI 3.141592f /** PI needed to calcuate from angle to distances */
sepp_nepp 24:932ea7bdc850 33 #define PI_OVER_180 (PI/180.0f) /** needed to translate from angle to circumference */
sepp_nepp 24:932ea7bdc850 34
sepp_nepp 24:932ea7bdc850 35 /** \enum motStates
sepp_nepp 24:932ea7bdc850 36 * \brief Possible States of CreaMot state machine
sepp_nepp 24:932ea7bdc850 37 *
sepp_nepp 24:932ea7bdc850 38 * Motor_CALIB is deprecated, was removed from the enum structure */
sepp_nepp 24:932ea7bdc850 39 typedef enum {
sepp_nepp 24:932ea7bdc850 40 Motor_OFF = 0, /**< All phase currents is off, replaces Motor_STOP. */
sepp_nepp 24:932ea7bdc850 41 Motor_ZERO, /**< CreaMot at phase position 0 and ON, only reached by call of Zero() procedure. */
sepp_nepp 24:932ea7bdc850 42 Motor_ON, /**< Phases are engaged, but CreaMot state machine stopped, replaces Motor_PAUSE. */
sepp_nepp 24:932ea7bdc850 43 Motor_RUN /**< Phases are engaged, and CreaMot state machine runs*/
sepp_nepp 24:932ea7bdc850 44 } motStates;
sepp_nepp 24:932ea7bdc850 45
sepp_nepp 24:932ea7bdc850 46 /** \enum motCmands
sepp_nepp 24:932ea7bdc850 47 * \brief Commands that are handled by the CreaMot state machine
sepp_nepp 24:932ea7bdc850 48 *
sepp_nepp 24:932ea7bdc850 49 * These Commands are issued asynchonously by calling CreaMot class methods.
sepp_nepp 24:932ea7bdc850 50 * They are executed in the state machine called by the ticker handler.
sepp_nepp 24:932ea7bdc850 51 *
sepp_nepp 24:932ea7bdc850 52 * OFF and STOP commands do not go through the state machine.
sepp_nepp 24:932ea7bdc850 53 *
sepp_nepp 24:932ea7bdc850 54 * MOTOR_restart is equivalent to and replaced by MOTOR_run.
sepp_nepp 24:932ea7bdc850 55 */
sepp_nepp 24:932ea7bdc850 56 typedef enum {
sepp_nepp 24:932ea7bdc850 57 MOTOR_nop = 0, /**< No active command to execute. */
sepp_nepp 24:932ea7bdc850 58 MOTOR_run, /**< Run CreaMot until Nsteps are achieved. */
sepp_nepp 24:932ea7bdc850 59 MOTOR_stop, /**< Stop immediately all activity, turn off CreaMot. */
sepp_nepp 24:932ea7bdc850 60 MOTOR_pause /**< CreaMot is temporarily paused from the state run. */
sepp_nepp 24:932ea7bdc850 61 } motCmands;
sepp_nepp 24:932ea7bdc850 62
sepp_nepp 24:932ea7bdc850 63 /** ATTENTION UNDER CONSTRUCTION, DO NOT YET USE.
sepp_nepp 24:932ea7bdc850 64 *
sepp_nepp 24:932ea7bdc850 65 * Class of a Four Phase Stepper CreaMot.
sepp_nepp 24:932ea7bdc850 66 *
sepp_nepp 24:932ea7bdc850 67 * Perform Runs for number of steps, or given amount angle, but also Low-Level steps.
sepp_nepp 24:932ea7bdc850 68 *
sepp_nepp 24:932ea7bdc850 69 * High-Level Run functions have 'Run' in their name.
sepp_nepp 24:932ea7bdc850 70 * They rely on tickers and return immediately after ticker is set up.
sepp_nepp 24:932ea7bdc850 71 * A state-machine evaluates the one ongoing command versus the CreaMot state at every tick.
sepp_nepp 24:932ea7bdc850 72 * When End of Run is detected tickers stop, and CreaMot turns off.
sepp_nepp 24:932ea7bdc850 73 *
sepp_nepp 24:932ea7bdc850 74 * To define the speed of the CreaMot set the variable StepTime_us, either by
sepp_nepp 24:932ea7bdc850 75 * a) Using the createor CreaMot(...., uint32_t AStepTime_us);
sepp_nepp 24:932ea7bdc850 76 * b) Calling function setStepTime_us(uint32_t AStepTime_us); any time
sepp_nepp 24:932ea7bdc850 77 * c) or leave it to the default value MOTOR_STEP_TIME_DEFAULT_US = 5000
sepp_nepp 24:932ea7bdc850 78 *
sepp_nepp 24:932ea7bdc850 79 * To be able to run the CreaMot for a given angle, set the number of steps per full turn
sepp_nepp 24:932ea7bdc850 80 * with the function "setStepsFullTurn"
sepp_nepp 24:932ea7bdc850 81 * That value defaults to MOTOR_STEPS_FOR_A_TURN = 4096
sepp_nepp 24:932ea7bdc850 82 *
sepp_nepp 24:932ea7bdc850 83 * To be able to run the CreaMot for a given perimeter distance in centimeters,
sepp_nepp 24:932ea7bdc850 84 * set the wheel diameter with the function setDiamCM( float Adiam_cm);
sepp_nepp 24:932ea7bdc850 85 *
sepp_nepp 24:932ea7bdc850 86 * Callbacks can be attached to react to 'end of run' events.
sepp_nepp 24:932ea7bdc850 87 *
sepp_nepp 24:932ea7bdc850 88 *Attention: the attached Callback is called within a Ticker Callback.
sepp_nepp 24:932ea7bdc850 89 * Your code you execute in the Callback should be short, must not use waits, or any long routines.
sepp_nepp 24:932ea7bdc850 90 * Do not call any CreaMot run commands in the callback, as it creates conflict situations.
sepp_nepp 24:932ea7bdc850 91 * Long Callback code may impair this and any other Ticker functions that run in your application.
sepp_nepp 24:932ea7bdc850 92 *
sepp_nepp 24:932ea7bdc850 93 *Low-Level functions directly talk to the hardware without ticker.
sepp_nepp 24:932ea7bdc850 94 * Use of Low-Level functions while tickers still run may lead to unexpected behavior.
sepp_nepp 24:932ea7bdc850 95 *
sepp_nepp 24:932ea7bdc850 96 * NB: all times are uint32_t, step numbers are int32_t
sepp_nepp 24:932ea7bdc850 97 */
sepp_nepp 24:932ea7bdc850 98 class CreaMot
sepp_nepp 24:932ea7bdc850 99 {
sepp_nepp 24:932ea7bdc850 100 public:
sepp_nepp 24:932ea7bdc850 101 /** CreaMot Class Creator
sepp_nepp 24:932ea7bdc850 102 *
sepp_nepp 24:932ea7bdc850 103 * Creates the class, initiallizes all fields, creates Phase Pins.
sepp_nepp 24:932ea7bdc850 104 * Time between two steps defaults here to MOTOR_STEP_TIME_DEFAULT_US = 5000usec.
sepp_nepp 24:932ea7bdc850 105 * Pin names are used to create digital outputs: Pin0 = new DigitalOut(_MPh0)
sepp_nepp 24:932ea7bdc850 106 *
sepp_nepp 24:932ea7bdc850 107 @code
sepp_nepp 24:932ea7bdc850 108 PinName MotPhases[] = {PB_1, PB_15, PB_14, PB_13};
sepp_nepp 24:932ea7bdc850 109 CreaMot MotorName(MotPhases); // Call this creator for example like this:
sepp_nepp 24:932ea7bdc850 110 @endcode
sepp_nepp 24:932ea7bdc850 111 *
sepp_nepp 24:932ea7bdc850 112 * @param _MPh Array of Names of the 4 Digital Pins of type PinNames
sepp_nepp 24:932ea7bdc850 113 */
sepp_nepp 24:932ea7bdc850 114 CreaMot(PinName _MPh[4] );
sepp_nepp 24:932ea7bdc850 115
sepp_nepp 24:932ea7bdc850 116 /** CreaMot Class Creator
sepp_nepp 24:932ea7bdc850 117 *
sepp_nepp 24:932ea7bdc850 118 * Creates the class, initiallizes all fields, creates Phase Pins.
sepp_nepp 24:932ea7bdc850 119 * Time between two steps defaults here to MOTOR_STEP_TIME_DEFAULT_US=5000usec.
sepp_nepp 24:932ea7bdc850 120 * Pin names are used to create digital outputs: Pin0 = new DigitalOut(_MPh0)
sepp_nepp 24:932ea7bdc850 121 *
sepp_nepp 24:932ea7bdc850 122 @code
sepp_nepp 24:932ea7bdc850 123 // Call this creator for example like this:
sepp_nepp 24:932ea7bdc850 124 CreaMot MotorName(PB_1, PB_15, PB_14, PB_13);
sepp_nepp 24:932ea7bdc850 125 @endcode
sepp_nepp 24:932ea7bdc850 126 *
sepp_nepp 24:932ea7bdc850 127 * @param <_MPh0, _MPh1, _MPh2, _MPh3> List of Names of the 4 Digital Pins of type PinNames
sepp_nepp 24:932ea7bdc850 128 */
sepp_nepp 24:932ea7bdc850 129 CreaMot(PinName _MPh0, PinName _MPh1, PinName _MPh2, PinName _MPh3);
sepp_nepp 24:932ea7bdc850 130
sepp_nepp 24:932ea7bdc850 131 /** CreaMot Class Creator
sepp_nepp 24:932ea7bdc850 132 *
sepp_nepp 24:932ea7bdc850 133 * Creates the class, initiallizes all fields, creates Phase Pins.
sepp_nepp 24:932ea7bdc850 134 * Time between two steps is passed as parameter.
sepp_nepp 24:932ea7bdc850 135 * Pin names are used to create digital outputs: Pin0 = new DigitalOut(_MPh0)
sepp_nepp 24:932ea7bdc850 136 *
sepp_nepp 24:932ea7bdc850 137 @code
sepp_nepp 24:932ea7bdc850 138 // Call this creator for example like this:
sepp_nepp 24:932ea7bdc850 139 CreaMot MotorName(PB_1, PB_15, PB_14, PB_13, 6000);
sepp_nepp 24:932ea7bdc850 140 @endcode
sepp_nepp 24:932ea7bdc850 141 *
sepp_nepp 24:932ea7bdc850 142 * @param <_MPh0, _MPh1, _MPh2, _MPh3> List of Names of the 4 Digital Pins of type PinNames
sepp_nepp 24:932ea7bdc850 143 * @param <AStepTime_us> the time in usec between two steps, thats used initially.
sepp_nepp 24:932ea7bdc850 144 */
sepp_nepp 24:932ea7bdc850 145 CreaMot(PinName _MPh0, PinName _MPh1, PinName _MPh2, PinName _MPh3, uint32_t AStepTime_us);
sepp_nepp 24:932ea7bdc850 146
sepp_nepp 24:932ea7bdc850 147 private:
sepp_nepp 24:932ea7bdc850 148 // deprecated: void initialization(PinName _MPh0, PinName _MPh1, PinName _MPh2, PinName _MPh3, uint32_t AStepTime_us);
sepp_nepp 24:932ea7bdc850 149 void initialization(PinName _MPh[4], uint32_t AStepTime_us);
sepp_nepp 24:932ea7bdc850 150
sepp_nepp 24:932ea7bdc850 151 public:
sepp_nepp 24:932ea7bdc850 152 /** Attach a basic Callback function.
sepp_nepp 24:932ea7bdc850 153 *
sepp_nepp 24:932ea7bdc850 154 * A callback is called when the current Command reaches it's requested end.
sepp_nepp 24:932ea7bdc850 155 * Not called when the CreaMot is stopped by a call of Stop Function, or any other events.
sepp_nepp 24:932ea7bdc850 156 * For use see precautions at Class description above.
sepp_nepp 24:932ea7bdc850 157 * Formerly called setMotorCallback()
sepp_nepp 24:932ea7bdc850 158 *
sepp_nepp 24:932ea7bdc850 159 @code
sepp_nepp 24:932ea7bdc850 160 // Simple callback function, state variable endMove can be polled elsewhere
sepp_nepp 24:932ea7bdc850 161 void CallBackFunction()
sepp_nepp 24:932ea7bdc850 162 { endMove=true; }
sepp_nepp 24:932ea7bdc850 163
sepp_nepp 24:932ea7bdc850 164 // main routine
sepp_nepp 24:932ea7bdc850 165 void main()
sepp_nepp 24:932ea7bdc850 166 { ...
sepp_nepp 24:932ea7bdc850 167 // Attach callback function:
sepp_nepp 24:932ea7bdc850 168 MotorInstance->callbackSet(CallBackFunction);
sepp_nepp 24:932ea7bdc850 169 ...
sepp_nepp 24:932ea7bdc850 170 while (true) {
sepp_nepp 24:932ea7bdc850 171 ....
sepp_nepp 24:932ea7bdc850 172 if (endMove) // poll the endMove flag
sepp_nepp 24:932ea7bdc850 173 { ... } // react to Movement End
sepp_nepp 24:932ea7bdc850 174
sepp_nepp 24:932ea7bdc850 175 ....
sepp_nepp 24:932ea7bdc850 176 }
sepp_nepp 24:932ea7bdc850 177 }
sepp_nepp 24:932ea7bdc850 178 @endcode
sepp_nepp 24:932ea7bdc850 179 * @param <*CBfunction> Callback function, must not be member of a class.
sepp_nepp 24:932ea7bdc850 180
sepp_nepp 24:932ea7bdc850 181 */
sepp_nepp 24:932ea7bdc850 182 void callbackSet(void (*CBfunction)(void)) {_callback = CBfunction;};
sepp_nepp 24:932ea7bdc850 183
sepp_nepp 24:932ea7bdc850 184
sepp_nepp 24:932ea7bdc850 185 /** Attach a Callback function, member of a class.
sepp_nepp 24:932ea7bdc850 186 * Only called when a Run Command reaches it's requested end.
sepp_nepp 24:932ea7bdc850 187 * Not called when the CreaMot is stopped by a call of Stop Function, or any other events.
sepp_nepp 24:932ea7bdc850 188 * For use see precautions at Class description above.
sepp_nepp 24:932ea7bdc850 189 * @param <*object> Class pointer which possesses callback member.
sepp_nepp 24:932ea7bdc850 190 * @param <*CBmember> Pointer to callback function, member of Class.
sepp_nepp 24:932ea7bdc850 191 *
sepp_nepp 24:932ea7bdc850 192 @code
sepp_nepp 24:932ea7bdc850 193 // Class Creator:
sepp_nepp 24:932ea7bdc850 194 AClass::AClass(Class Creation Parameters)
sepp_nepp 24:932ea7bdc850 195 { ...
sepp_nepp 24:932ea7bdc850 196 // Attach callback function:
sepp_nepp 24:932ea7bdc850 197 MotorInstance->setMotorCallback(this, &AClass::CallBackMemberFunction);
sepp_nepp 24:932ea7bdc850 198 ...
sepp_nepp 24:932ea7bdc850 199 }
sepp_nepp 24:932ea7bdc850 200
sepp_nepp 24:932ea7bdc850 201 // Simple callback function, state variable endMove can be polled by main thread
sepp_nepp 24:932ea7bdc850 202 void AClass::CallBackMemberFunction()
sepp_nepp 24:932ea7bdc850 203 { endMove=true; }
sepp_nepp 24:932ea7bdc850 204 @endcode
sepp_nepp 24:932ea7bdc850 205 */
sepp_nepp 24:932ea7bdc850 206 template<typename T>
sepp_nepp 24:932ea7bdc850 207 void callbackSet(T *object, void (T::*CBmember)(void)) {
sepp_nepp 24:932ea7bdc850 208 _callback = callback(object,CBmember);
sepp_nepp 24:932ea7bdc850 209 }
sepp_nepp 24:932ea7bdc850 210
sepp_nepp 24:932ea7bdc850 211 /** Remove the Callback function that may have been attached previously. */
sepp_nepp 24:932ea7bdc850 212 void callbackRemove() { _callback = NULL; };
sepp_nepp 24:932ea7bdc850 213
sepp_nepp 24:932ea7bdc850 214 public:
sepp_nepp 24:932ea7bdc850 215 // *********************************************************************
sepp_nepp 24:932ea7bdc850 216 // all following functions use wheel diameter to achieve cm distance
sepp_nepp 24:932ea7bdc850 217 // *********************************************************************
sepp_nepp 24:932ea7bdc850 218
sepp_nepp 24:932ea7bdc850 219 /** High Level: Run CreaMot for a given number of centimeters.
sepp_nepp 24:932ea7bdc850 220 *
sepp_nepp 24:932ea7bdc850 221 * Runs CreaMot for a given wheel circumference in cimeters in given direction.
sepp_nepp 24:932ea7bdc850 222 * You must setup the perimeter and diameter with setDiam(Adiam_cm) in advance, otherwise no reaction.
sepp_nepp 24:932ea7bdc850 223 * Call Pause() or Stop() to pause or end the CreaMot run prematurely.
sepp_nepp 24:932ea7bdc850 224 * While run: Uses ticker; State: first Motor_ON then Motor_RUN; cmd=MOTOR_run.
sepp_nepp 24:932ea7bdc850 225 * At end: calls attached Callback, stops ticker; State: Motor_OFF; cmd=MOTOR_stop then MOTOR_nop.
sepp_nepp 24:932ea7bdc850 226 * @param[in] <AClockWise> Given Direction, true for CLOCKWISE, false for COUNTERCLOCKWISE.
sepp_nepp 24:932ea7bdc850 227 * @param[in] <Dist_cm> Circumference to rotate for, in cm, Dist_cm<0 are run in opposite direction.
sepp_nepp 24:932ea7bdc850 228 */
sepp_nepp 24:932ea7bdc850 229 void RunDist_cm (bool AClockWise, float Dist_cm);
sepp_nepp 24:932ea7bdc850 230
sepp_nepp 24:932ea7bdc850 231 /** High Level: Run CreaMot for a given number of centimeters in default direction.
sepp_nepp 24:932ea7bdc850 232 * Same as RunDist_cm(AClockWise,Dist_cm) but uses Default diretion.*/
sepp_nepp 24:932ea7bdc850 233 void RunDist_cm (float Dist_cm);
sepp_nepp 24:932ea7bdc850 234
sepp_nepp 24:932ea7bdc850 235 /** High Level: Run CreaMot for a turn angle around a turn_radius_cm in default direction
sepp_nepp 24:932ea7bdc850 236 *
sepp_nepp 24:932ea7bdc850 237 * Runs CreaMot for a given turn angle in degrees with a given turn radius.
sepp_nepp 24:932ea7bdc850 238 * in default direction. Negative angles are rotated in opposite direction.
sepp_nepp 24:932ea7bdc850 239 * turn-radius must be positive. Zero or negative radius are not executed.
sepp_nepp 24:932ea7bdc850 240 * You must setup the perimeter and diameter with setDiam(Adiam_cm) in advance, otherwise no reaction.
sepp_nepp 24:932ea7bdc850 241 * Call Pause() or Stop() to pause or end the CreaMot run prematurely.
sepp_nepp 24:932ea7bdc850 242 * While run: Uses ticker; State: first Motor_ON then Motor_RUN; cmd=MOTOR_run.
sepp_nepp 24:932ea7bdc850 243 * At end: calls attached Callback, stops ticker; State: Motor_OFF; cmd=MOTOR_stop then MOTOR_nop.
sepp_nepp 24:932ea7bdc850 244 * @param[in] <turn_angle_deg> Given turn angle in degrees that should be run
sepp_nepp 24:932ea7bdc850 245 * @param[in] <turn_radius_cm> Given Trun radius that should be run */
sepp_nepp 24:932ea7bdc850 246 void RunTurnAngle(float turn_angle_deg, float turn_radius_cm);
sepp_nepp 24:932ea7bdc850 247
sepp_nepp 24:932ea7bdc850 248 /** Additional geometric information: set the wheel diameter, also sets perimeter and degrees per cm.*/
sepp_nepp 24:932ea7bdc850 249 void setDiamCM( float Adiam_cm);
sepp_nepp 24:932ea7bdc850 250
sepp_nepp 24:932ea7bdc850 251 /** Set CreaMot speed in centimeter/sec, based on perimeter in cm */
sepp_nepp 24:932ea7bdc850 252 void setSpeed_cm_sec(float speed_cm_sec);
sepp_nepp 24:932ea7bdc850 253
sepp_nepp 24:932ea7bdc850 254 /** Default rotation direction that serves as local storage, but not as actual direction */
sepp_nepp 24:932ea7bdc850 255 bool defaultDirection;
sepp_nepp 24:932ea7bdc850 256
sepp_nepp 24:932ea7bdc850 257 /** State value that is used and managed by the class owner.
sepp_nepp 24:932ea7bdc850 258 * Used for example by Creabot library to indicate if this is the left or right CreaMot. */
sepp_nepp 24:932ea7bdc850 259 char StateValue;
sepp_nepp 24:932ea7bdc850 260 private:
sepp_nepp 24:932ea7bdc850 261
sepp_nepp 24:932ea7bdc850 262 /** Additional geometric information: wheel diameter in centimeter */
sepp_nepp 24:932ea7bdc850 263 float diam_cm;
sepp_nepp 24:932ea7bdc850 264
sepp_nepp 24:932ea7bdc850 265 /** Additional geometric information: wheel perimeter in centimeter */
sepp_nepp 24:932ea7bdc850 266 float perim_cm;
sepp_nepp 24:932ea7bdc850 267
sepp_nepp 24:932ea7bdc850 268 /** Additional geometric information: rotation angle in degrees per cm circumference */
sepp_nepp 24:932ea7bdc850 269 float degree_per_cm;
sepp_nepp 24:932ea7bdc850 270
sepp_nepp 24:932ea7bdc850 271 public:
sepp_nepp 24:932ea7bdc850 272 // *****************************************************************
sepp_nepp 24:932ea7bdc850 273 // following functions are agnostic of wheel dimensions in centimeters
sepp_nepp 24:932ea7bdc850 274 // *****************************************************************
sepp_nepp 24:932ea7bdc850 275
sepp_nepp 24:932ea7bdc850 276 /** High Level: Run CreaMot for a given angle.
sepp_nepp 24:932ea7bdc850 277 *
sepp_nepp 24:932ea7bdc850 278 * Runs CreaMot for a given angle in given direction.
sepp_nepp 24:932ea7bdc850 279 * Angles<0 are run in opposite direction.
sepp_nepp 24:932ea7bdc850 280 * Call Pause() or Stop() to pause or end the CreaMot run prematurely.
sepp_nepp 24:932ea7bdc850 281 * While running: Uses ticker;
sepp_nepp 24:932ea7bdc850 282 * State: first Motor_ON then Motor_RUN; cmd=MOTOR_run.
sepp_nepp 24:932ea7bdc850 283 * At end: calls attached Callback, stops ticker; State: Motor_OFF; cmd=MOTOR_stop then MOTOR_nop.
sepp_nepp 24:932ea7bdc850 284 * @param[in] <AClockWise> Given Direction, true for CLOCKWISE, false for COUNTERCLOCKWISE.
sepp_nepp 24:932ea7bdc850 285 * @param[in] <angle_deg> Angle>0 to rotate for, in degrees, Angles<0 are run in opposite direction.
sepp_nepp 24:932ea7bdc850 286 */
sepp_nepp 24:932ea7bdc850 287 void RunDegrees (bool AClockWise, float angle_deg);
sepp_nepp 24:932ea7bdc850 288
sepp_nepp 24:932ea7bdc850 289 /** High Level: Run CreaMot for a given angle in default direction
sepp_nepp 24:932ea7bdc850 290 * for details see RunDegrees (bool AClockWise, float angle_deg);
sepp_nepp 24:932ea7bdc850 291 */
sepp_nepp 24:932ea7bdc850 292 void RunDegrees (float angle_deg);
sepp_nepp 24:932ea7bdc850 293
sepp_nepp 24:932ea7bdc850 294 /** High Level: Run CreaMot for a number of Steps.
sepp_nepp 24:932ea7bdc850 295 *
sepp_nepp 24:932ea7bdc850 296 * During Run: Uses ticker; State: first Motor_ON then Motor_RUN; cmd=MOTOR_run.
sepp_nepp 24:932ea7bdc850 297 * Call Pause() or Stop() to pause or end the run prematurely.
sepp_nepp 24:932ea7bdc850 298 * At the end: calls the Callback, stops ticker; State: Motor_OFF.
sepp_nepp 24:932ea7bdc850 299 * @param[in] <AClockWise> Given Direction, true for CLOCKWISE, false for COUNTERCLOCKWISE.
sepp_nepp 24:932ea7bdc850 300 * @param[in] <Nsteps> Number of steps to run for; Nsteps<0 are run in opposite direction!
sepp_nepp 24:932ea7bdc850 301 */
sepp_nepp 24:932ea7bdc850 302 void RunSteps (bool AClockWise, int32_t Nsteps);
sepp_nepp 24:932ea7bdc850 303
sepp_nepp 24:932ea7bdc850 304 /** High Level: Run CreaMot "unlimited"
sepp_nepp 24:932ea7bdc850 305 *
sepp_nepp 24:932ea7bdc850 306 * Runs CreaMot with out limit in given direction, precisely runs 4Billion Steps.
sepp_nepp 24:932ea7bdc850 307 * While run: Uses ticker; State: first Motor_ON then Motor_RUN; cmd=MOTOR_run.
sepp_nepp 24:932ea7bdc850 308 * Call Pause() or Stop() to pause or end the CreaMot run.
sepp_nepp 24:932ea7bdc850 309 * @param[in] <AClockWise> Given Direction, true for CLOCKWISE, false for COUNTERCLOCKWISE.
sepp_nepp 24:932ea7bdc850 310 */
sepp_nepp 24:932ea7bdc850 311 void RunInfinite (bool AClockWise);
sepp_nepp 24:932ea7bdc850 312
sepp_nepp 24:932ea7bdc850 313 /** High Level: Pause a CreaMot Run.
sepp_nepp 24:932ea7bdc850 314 * Put CreaMot into Pause state, Run is suspended, but only effective if Status.cmd=MOTOR_run.
sepp_nepp 24:932ea7bdc850 315 * Retains the number of steps that remain to be run if restarting run.
sepp_nepp 24:932ea7bdc850 316 * While paused: still uses ticker; State: Motor_RUN; cmd=MOTOR_pause.
sepp_nepp 24:932ea7bdc850 317 * Use RestartRun(); to continue. */
sepp_nepp 24:932ea7bdc850 318 void PauseRun();
sepp_nepp 24:932ea7bdc850 319
sepp_nepp 24:932ea7bdc850 320 /** High Level: Restart a Paused Run.
sepp_nepp 24:932ea7bdc850 321 * Restart the Run that was launched before calling PuaseRun.
sepp_nepp 24:932ea7bdc850 322 * Only effective if Status.cmd=MOTOR_pause, otherwise no re/action.
sepp_nepp 24:932ea7bdc850 323 * Status afterwards is same as afterRun commands. */
sepp_nepp 24:932ea7bdc850 324 void RestartRun();
sepp_nepp 24:932ea7bdc850 325
sepp_nepp 24:932ea7bdc850 326 /** High Level: End any Run.
sepp_nepp 24:932ea7bdc850 327 * Force stop of any ongoing run, but does not call the Callback function.
sepp_nepp 24:932ea7bdc850 328 * Only effective if Status.cmd=MOTOR_run, otherwise no re/action.
sepp_nepp 24:932ea7bdc850 329 * Emits first cmd=MOTOR_stop then cmd=MOTOR_nop.
sepp_nepp 24:932ea7bdc850 330 * Aftewards: ticker is detached; State: Motor_OFF; */
sepp_nepp 24:932ea7bdc850 331 void StopRun();
sepp_nepp 24:932ea7bdc850 332
sepp_nepp 24:932ea7bdc850 333 public: // All the ticker timing related parameters
sepp_nepp 24:932ea7bdc850 334
sepp_nepp 24:932ea7bdc850 335 /** MidLevel: Get number of Steps per Full turn
sepp_nepp 24:932ea7bdc850 336
sepp_nepp 24:932ea7bdc850 337 * Defaults to MOTOR_STEPS_FOR_A_TURN = 4096.
sepp_nepp 24:932ea7bdc850 338 * Used by RunDegrees() to translate from angle in degrees to number of steps.
sepp_nepp 24:932ea7bdc850 339 * Old Name was: getCalibration, but that was not a good explicit name.
sepp_nepp 24:932ea7bdc850 340 * @return uint32_t The number of motor steps needed for a full turn. */
sepp_nepp 24:932ea7bdc850 341 uint32_t getStepsFullTurn();
sepp_nepp 24:932ea7bdc850 342
sepp_nepp 24:932ea7bdc850 343 /** MidLevel: Set number of Steps per Full turn.
sepp_nepp 24:932ea7bdc850 344
sepp_nepp 24:932ea7bdc850 345 * Defaults is MOTOR_STEPS_FOR_A_TURN = 4096.
sepp_nepp 24:932ea7bdc850 346 * Used by RunDegrees() to translate from degrees to number of steps.
sepp_nepp 24:932ea7bdc850 347 * Old Name was: setCalibration, but not good explicit name.
sepp_nepp 24:932ea7bdc850 348 * @param <StepsFullTurn> Number of steps needed to complete a full CreaMot turn
sepp_nepp 24:932ea7bdc850 349 */
sepp_nepp 24:932ea7bdc850 350 void setStepsFullTurn(uint32_t StepsFullTurn);
sepp_nepp 24:932ea7bdc850 351
sepp_nepp 24:932ea7bdc850 352 /** Mid Level: Get the CreaMot step time.
sepp_nepp 24:932ea7bdc850 353
sepp_nepp 24:932ea7bdc850 354 * Step time is time between two CreaMot steps, and is given in microseconds
sepp_nepp 24:932ea7bdc850 355 * and is passed to the ticker as delay time.
sepp_nepp 24:932ea7bdc850 356 * So the larger the value the slower the CreaMot speed.
sepp_nepp 24:932ea7bdc850 357 * Defaults to MOTOR_STEP_TIME_DEFAULT_US = 5000.
sepp_nepp 24:932ea7bdc850 358 * @return uint32_t The structure of CreaMot status registers.
sepp_nepp 24:932ea7bdc850 359 */
sepp_nepp 24:932ea7bdc850 360 uint32_t getStepTime_us();
sepp_nepp 24:932ea7bdc850 361
sepp_nepp 24:932ea7bdc850 362 /** Set the time in microseconds between two CreaMot steps.
sepp_nepp 24:932ea7bdc850 363 * Defaults to MOTOR_STEP_TIME_DEFAULT_US = 5000usec.
sepp_nepp 24:932ea7bdc850 364 * Filters values below Minimum Value = 700.
sepp_nepp 24:932ea7bdc850 365 * Passed to the ticker as delay time.
sepp_nepp 24:932ea7bdc850 366 * Can be called while ticker is running, and takes immediate effect.
sepp_nepp 24:932ea7bdc850 367 * Was previously called setStepTime(), but was not clear which units.
sepp_nepp 24:932ea7bdc850 368 * @param <AStepTime_us> the time in microseconds between two CreaMot steps
sepp_nepp 24:932ea7bdc850 369 */
sepp_nepp 24:932ea7bdc850 370 void setStepTime_us(uint32_t AStepTime_us);
sepp_nepp 24:932ea7bdc850 371
sepp_nepp 24:932ea7bdc850 372 /** Set the time in seconds to get one full turn, rotation of 360°.
sepp_nepp 24:932ea7bdc850 373 * was previously called setSpeed().
sepp_nepp 24:932ea7bdc850 374 * @param <Seconds_Per_Turn> Period of Rotation, e.g. if =20.0 then CreaMot will do 360° in 20 seconds.
sepp_nepp 24:932ea7bdc850 375 */
sepp_nepp 24:932ea7bdc850 376 void setRotationPeriodSec(float Seconds_Per_Turn) ;
sepp_nepp 24:932ea7bdc850 377
sepp_nepp 24:932ea7bdc850 378
sepp_nepp 24:932ea7bdc850 379 motStates CurrState; /**< General state that the CreaMot state machine is in.*/
sepp_nepp 24:932ea7bdc850 380 motCmands CurrCmd; /**< Command asked to be executed currently by the state machine.*/
sepp_nepp 24:932ea7bdc850 381
sepp_nepp 24:932ea7bdc850 382 private:
sepp_nepp 24:932ea7bdc850 383 void setCommand(motCmands aCmd, bool aClockWise, int32_t aNSteps);
sepp_nepp 24:932ea7bdc850 384 /**< Helper; set Command, Direction and NSteps in one call. */
sepp_nepp 24:932ea7bdc850 385
sepp_nepp 24:932ea7bdc850 386 // all the Ticker and Timing procedures, used to run the CreaMot for a duration
sepp_nepp 24:932ea7bdc850 387 void StartTick();
sepp_nepp 24:932ea7bdc850 388 void ProcessMotorStateMachine();
sepp_nepp 24:932ea7bdc850 389 // The call back function pointer that is called when the Processor
sepp_nepp 24:932ea7bdc850 390 // State Machine reaches its end.
sepp_nepp 24:932ea7bdc850 391 Callback<void()> _callback;
sepp_nepp 24:932ea7bdc850 392 void StopTick();
sepp_nepp 24:932ea7bdc850 393 timestamp_t StepTime_us; // Time in µs for one CreaMot step
sepp_nepp 24:932ea7bdc850 394 Ticker MotorSysTick; // System Timer for CreaMot
sepp_nepp 24:932ea7bdc850 395 uint32_t Steps_FullTurn; // Number of step for a complete turn
sepp_nepp 24:932ea7bdc850 396 bool ClockWise; /**< Direction that the CreaMot is asked to run. True if Clockwise */
sepp_nepp 24:932ea7bdc850 397 int32_t NStepsToDo; /**< Number of steps remain for the CreaMot to run.
sepp_nepp 24:932ea7bdc850 398 NSteps=0: all steps finished; NSteps<0: indicates to run "forever" */
sepp_nepp 24:932ea7bdc850 399 bool TickIsAttached; /**< Indicates if Ticker is attached.
sepp_nepp 24:932ea7bdc850 400 Ticker is automatically attached while CreaMot runs, or paused;
sepp_nepp 24:932ea7bdc850 401 detaches when finished a run, or stopped. */
sepp_nepp 24:932ea7bdc850 402
sepp_nepp 24:932ea7bdc850 403 public: // all the low level direct CreaMot HW access, States are immediately reached
sepp_nepp 24:932ea7bdc850 404
sepp_nepp 24:932ea7bdc850 405 /** Low Level: Run one full turn clockwise then anticlockwise.
sepp_nepp 24:932ea7bdc850 406 * After: State: Motor_OFF.
sepp_nepp 24:932ea7bdc850 407 * Blocking function, returns back only after end of full movement.
sepp_nepp 24:932ea7bdc850 408 */
sepp_nepp 24:932ea7bdc850 409 void MotorTest();
sepp_nepp 24:932ea7bdc850 410
sepp_nepp 24:932ea7bdc850 411 /** Low Level: turn off all CreaMot Phases
sepp_nepp 24:932ea7bdc850 412 * No more current flows, reduces holding force.
sepp_nepp 24:932ea7bdc850 413 * After: State: Motor_OFF.
sepp_nepp 24:932ea7bdc850 414 * StepPhases memorizes the last used phase.
sepp_nepp 24:932ea7bdc850 415 * Equivalent what previously the function "void Stop();" did . */
sepp_nepp 24:932ea7bdc850 416 void MotorOFF();
sepp_nepp 24:932ea7bdc850 417
sepp_nepp 24:932ea7bdc850 418 /** Low Level: turn on the CreaMot Phases in the last used phase.
sepp_nepp 24:932ea7bdc850 419 * The last used phase is held in StepPhases.
sepp_nepp 24:932ea7bdc850 420 * After: State: Motor_ON, or Motor_ZERO if StepPhases==0
sepp_nepp 24:932ea7bdc850 421 * Equivalent to what previously the function "void Start();" did. */
sepp_nepp 24:932ea7bdc850 422 void MotorON();
sepp_nepp 24:932ea7bdc850 423
sepp_nepp 24:932ea7bdc850 424 /** Low Level: Advance CreaMot one step, rotates in direction of variable AClockWise. */
sepp_nepp 24:932ea7bdc850 425 void StepOnce();
sepp_nepp 24:932ea7bdc850 426
sepp_nepp 24:932ea7bdc850 427 /** Low Level: Advance CreaMot one step, rotates CounterClockwise. */
sepp_nepp 24:932ea7bdc850 428 void StepCCW();
sepp_nepp 24:932ea7bdc850 429
sepp_nepp 24:932ea7bdc850 430 /** Low Level: Advance CreaMot one step, rotates Clockwise. */
sepp_nepp 24:932ea7bdc850 431 void StepClkW();
sepp_nepp 24:932ea7bdc850 432
sepp_nepp 24:932ea7bdc850 433 /** Low Level: turn on the CreaMot Phases in Zero Position.
sepp_nepp 24:932ea7bdc850 434 * After: State: Motor_ZERO, StepPhases==0
sepp_nepp 24:932ea7bdc850 435 */
sepp_nepp 24:932ea7bdc850 436 void MotorZero();
sepp_nepp 24:932ea7bdc850 437
sepp_nepp 24:932ea7bdc850 438 private:
sepp_nepp 24:932ea7bdc850 439
sepp_nepp 24:932ea7bdc850 440 /** Low Level: Engage CreaMot Phases according to MotorIndex. */
sepp_nepp 24:932ea7bdc850 441 void SetPhases();
sepp_nepp 24:932ea7bdc850 442
sepp_nepp 24:932ea7bdc850 443 DigitalOut *MPh[4]; // Digital outputs, one per phase
sepp_nepp 24:932ea7bdc850 444 int StepPhase; // CreaMot Phase Variable, counts up and down with every step
sepp_nepp 24:932ea7bdc850 445 };
sepp_nepp 24:932ea7bdc850 446
sepp_nepp 24:932ea7bdc850 447 #endif