Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependents: LAB04_Oppgave1 test_stepper Stepper_Motor_Demo StepperMotorUni_Hello ... more
StepperMotorUni.cpp@6:007d0570ba4f, 2017-09-13 (annotated)
- Committer:
- okano
- Date:
- Wed Sep 13 03:55:30 2017 +0000
- Revision:
- 6:007d0570ba4f
- Parent:
- 5:93f9ce526f38
- Child:
- 7:7e6fb609780a
fix for keeping stop position
Who changed what in which revision?
| User | Revision | Line number | New contents of line |
|---|---|---|---|
| okano | 0:5d0abdf92786 | 1 | /** Stepper Motor (Unipolar) control library |
| okano | 0:5d0abdf92786 | 2 | * |
| okano | 0:5d0abdf92786 | 3 | * @class StepperMotorUni |
| okano | 0:5d0abdf92786 | 4 | * @author Tedd OKANO |
| okano | 5:93f9ce526f38 | 5 | * @version 1.1.2 |
| okano | 5:93f9ce526f38 | 6 | * @date 27-Apr-2015 |
| okano | 0:5d0abdf92786 | 7 | * |
| okano | 3:0eec6148e739 | 8 | * Copyright: 2010, 2014, 2015 Tedd OKANO |
| okano | 0:5d0abdf92786 | 9 | * Released under the Apache 2 license License |
| okano | 0:5d0abdf92786 | 10 | * |
| okano | 0:5d0abdf92786 | 11 | * The library that controls stepper motor via motor driver chip |
| okano | 0:5d0abdf92786 | 12 | * This is a driver for a unipolar stepper motor. |
| okano | 0:5d0abdf92786 | 13 | * |
| okano | 0:5d0abdf92786 | 14 | * Example: |
| okano | 0:5d0abdf92786 | 15 | * @code |
| okano | 0:5d0abdf92786 | 16 | * #include "mbed.h" |
| okano | 0:5d0abdf92786 | 17 | * #include "StepperMotorUni.h" |
| okano | 4:6909efe4c8ac | 18 | * |
| okano | 0:5d0abdf92786 | 19 | * StepperMotorUni motor( p26, p25, p24, p23 ); |
| okano | 4:6909efe4c8ac | 20 | * |
| okano | 0:5d0abdf92786 | 21 | * int main() |
| okano | 0:5d0abdf92786 | 22 | * { |
| okano | 0:5d0abdf92786 | 23 | * motor.set_pps( 50 ); |
| okano | 4:6909efe4c8ac | 24 | * |
| okano | 0:5d0abdf92786 | 25 | * while ( 1 ) { |
| okano | 0:5d0abdf92786 | 26 | * motor.move_steps( 24 ); |
| okano | 0:5d0abdf92786 | 27 | * wait( 1 ); |
| okano | 4:6909efe4c8ac | 28 | * |
| okano | 0:5d0abdf92786 | 29 | * motor.move_steps( -24 ); |
| okano | 0:5d0abdf92786 | 30 | * wait( 1 ); |
| okano | 0:5d0abdf92786 | 31 | * } |
| okano | 0:5d0abdf92786 | 32 | * } |
| okano | 0:5d0abdf92786 | 33 | * @endcode |
| okano | 4:6909efe4c8ac | 34 | * |
| okano | 4:6909efe4c8ac | 35 | * version 0.51 (27-Nov-2010) // initial version (un-published) |
| okano | 4:6909efe4c8ac | 36 | * version 0.6 (15-Jan-2014) // compatible to LPC1768, LPC11U24 and LPC1114 targets |
| okano | 4:6909efe4c8ac | 37 | * version 1.0 (19-Jun-2014) // version 1.0 release |
| okano | 3:0eec6148e739 | 38 | * version 1.0.1 (14-Apr-2015) // API document correction |
| okano | 4:6909efe4c8ac | 39 | * version 1.1 (21-Apr-2015) // ramp control function enabled |
| okano | 4:6909efe4c8ac | 40 | * version 1.1.1 (22-Apr-2015) // fixed: find_home_position compatibility with ramp control feature |
| okano | 5:93f9ce526f38 | 41 | * version 1.1.2 (27-Apr-2015) // fixed: init_done behavior |
| okano | 0:5d0abdf92786 | 42 | */ |
| okano | 0:5d0abdf92786 | 43 | |
| okano | 0:5d0abdf92786 | 44 | #include "mbed.h" |
| okano | 0:5d0abdf92786 | 45 | #include "StepperMotorUni.h" |
| okano | 0:5d0abdf92786 | 46 | |
| okano | 0:5d0abdf92786 | 47 | StepperMotorUni::StepperMotorUni( |
| okano | 0:5d0abdf92786 | 48 | PinName out_A, |
| okano | 0:5d0abdf92786 | 49 | PinName out_B, |
| okano | 0:5d0abdf92786 | 50 | PinName out_C, |
| okano | 0:5d0abdf92786 | 51 | PinName out_D, |
| okano | 0:5d0abdf92786 | 52 | PinName position_detect |
| okano | 0:5d0abdf92786 | 53 | ) : |
| okano | 5:93f9ce526f38 | 54 | init_done( false ), |
| okano | 4:6909efe4c8ac | 55 | motor_out( out_A, out_B, out_C, out_D ), |
| okano | 4:6909efe4c8ac | 56 | position_detect_pin( position_detect ), |
| okano | 4:6909efe4c8ac | 57 | rot_mode( SHORTEST ), |
| okano | 4:6909efe4c8ac | 58 | sync_mode( ASYNCHRONOUS ), |
| okano | 4:6909efe4c8ac | 59 | max_pos( 480 ), |
| okano | 4:6909efe4c8ac | 60 | current_pos( 0 ), |
| okano | 4:6909efe4c8ac | 61 | pos_offset( 0 ), |
| okano | 4:6909efe4c8ac | 62 | target_pos( 0 ), |
| okano | 4:6909efe4c8ac | 63 | max_pps( MAX_PPS ), |
| okano | 4:6909efe4c8ac | 64 | pause( false ), |
| okano | 4:6909efe4c8ac | 65 | power_ctrl( false ), |
| okano | 4:6909efe4c8ac | 66 | ramp_init_speed_rate( 1.0 ), |
| okano | 4:6909efe4c8ac | 67 | ramp_control_steps( 0 ), |
| okano | 4:6909efe4c8ac | 68 | ramp_rate( 1.0 ) |
| okano | 4:6909efe4c8ac | 69 | { |
| okano | 0:5d0abdf92786 | 70 | |
| okano | 0:5d0abdf92786 | 71 | pps = max_pps; |
| okano | 0:5d0abdf92786 | 72 | pattern = (unsigned char *)pattern_one_phase; |
| okano | 0:5d0abdf92786 | 73 | pat_index_mask = 0x3; |
| okano | 0:5d0abdf92786 | 74 | t.attach( this, &StepperMotorUni::motor_maintain, 1.0 / (float)pps ); |
| okano | 0:5d0abdf92786 | 75 | } |
| okano | 0:5d0abdf92786 | 76 | |
| okano | 4:6909efe4c8ac | 77 | float StepperMotorUni::set_pps( float v ) |
| okano | 4:6909efe4c8ac | 78 | { |
| okano | 0:5d0abdf92786 | 79 | float p; |
| okano | 0:5d0abdf92786 | 80 | |
| okano | 0:5d0abdf92786 | 81 | p = pps; |
| okano | 0:5d0abdf92786 | 82 | pps = v; |
| okano | 0:5d0abdf92786 | 83 | t.detach(); |
| okano | 0:5d0abdf92786 | 84 | t.attach( this, &StepperMotorUni::motor_maintain, 1.0 / (float)pps ); |
| okano | 0:5d0abdf92786 | 85 | return ( p ); |
| okano | 0:5d0abdf92786 | 86 | } |
| okano | 0:5d0abdf92786 | 87 | |
| okano | 4:6909efe4c8ac | 88 | void StepperMotorUni::set_max_pps( float v ) |
| okano | 4:6909efe4c8ac | 89 | { |
| okano | 0:5d0abdf92786 | 90 | max_pps = v; |
| okano | 0:5d0abdf92786 | 91 | } |
| okano | 0:5d0abdf92786 | 92 | |
| okano | 4:6909efe4c8ac | 93 | int StepperMotorUni::find_home_position( PositionDetectPorarity edge ) |
| okano | 4:6909efe4c8ac | 94 | { |
| okano | 0:5d0abdf92786 | 95 | RotMode prev_rot; |
| okano | 0:5d0abdf92786 | 96 | SyncMode prev_sync; |
| okano | 0:5d0abdf92786 | 97 | float prev_pps; |
| okano | 4:6909efe4c8ac | 98 | float prev_i_rate; |
| okano | 4:6909efe4c8ac | 99 | int prev_rcs; |
| okano | 0:5d0abdf92786 | 100 | int prev_det_pin; |
| okano | 0:5d0abdf92786 | 101 | int direction; |
| okano | 0:5d0abdf92786 | 102 | |
| okano | 0:5d0abdf92786 | 103 | if ( position_detect_pin == NC ) |
| okano | 0:5d0abdf92786 | 104 | return 0; |
| okano | 0:5d0abdf92786 | 105 | |
| okano | 0:5d0abdf92786 | 106 | prev_pps = set_pps( max_pps ); |
| okano | 4:6909efe4c8ac | 107 | prev_i_rate = ramp_init_speed_rate; |
| okano | 4:6909efe4c8ac | 108 | prev_rcs = ramp_control_steps; |
| okano | 0:5d0abdf92786 | 109 | prev_rot = rot_mode; |
| okano | 0:5d0abdf92786 | 110 | prev_sync = sync_mode; |
| okano | 0:5d0abdf92786 | 111 | set_sync_mode( SYNCHRONOUS ); |
| okano | 0:5d0abdf92786 | 112 | set_rot_mode( SHORTEST ); |
| okano | 0:5d0abdf92786 | 113 | |
| okano | 4:6909efe4c8ac | 114 | prev_det_pin = position_detect_pin; |
| okano | 4:6909efe4c8ac | 115 | set_ramp_control( 1.0, 0 ); |
| okano | 0:5d0abdf92786 | 116 | |
| okano | 0:5d0abdf92786 | 117 | if ( prev_rot == COUNTER_CLOCKWISE_ONLY ) |
| okano | 0:5d0abdf92786 | 118 | direction = -1; |
| okano | 0:5d0abdf92786 | 119 | else |
| okano | 0:5d0abdf92786 | 120 | direction = 1; |
| okano | 0:5d0abdf92786 | 121 | |
| okano | 5:93f9ce526f38 | 122 | init_done = false; |
| okano | 5:93f9ce526f38 | 123 | |
| okano | 0:5d0abdf92786 | 124 | if ( prev_rot == NO_WRAPAROUND ) { |
| okano | 0:5d0abdf92786 | 125 | |
| okano | 0:5d0abdf92786 | 126 | for ( int i = 0; i < (max_pos >> 1); i++ ) { |
| okano | 0:5d0abdf92786 | 127 | move_steps( -1 ); |
| okano | 0:5d0abdf92786 | 128 | if ( ((edge == RISING_EDGE) && !prev_det_pin && position_detect_pin) |
| okano | 0:5d0abdf92786 | 129 | || ((edge == FALLING_EDGE) && prev_det_pin && !position_detect_pin) ) { |
| okano | 0:5d0abdf92786 | 130 | set_home_position(); |
| okano | 0:5d0abdf92786 | 131 | init_done = true; |
| okano | 0:5d0abdf92786 | 132 | break; |
| okano | 0:5d0abdf92786 | 133 | } |
| okano | 0:5d0abdf92786 | 134 | prev_det_pin = position_detect_pin; |
| okano | 0:5d0abdf92786 | 135 | } |
| okano | 0:5d0abdf92786 | 136 | } |
| okano | 0:5d0abdf92786 | 137 | |
| okano | 0:5d0abdf92786 | 138 | for ( int i = 0; i < ((prev_rot == NO_WRAPAROUND) ? (max_pos - 1) : (max_pos + 10)); i++ ) { |
| okano | 0:5d0abdf92786 | 139 | move_steps( direction ); |
| okano | 0:5d0abdf92786 | 140 | if ( ((edge == RISING_EDGE) && !prev_det_pin && position_detect_pin) |
| okano | 0:5d0abdf92786 | 141 | || ((edge == FALLING_EDGE) && prev_det_pin && !position_detect_pin) ) { |
| okano | 0:5d0abdf92786 | 142 | set_home_position(); |
| okano | 0:5d0abdf92786 | 143 | init_done = true; |
| okano | 0:5d0abdf92786 | 144 | break; |
| okano | 0:5d0abdf92786 | 145 | } |
| okano | 0:5d0abdf92786 | 146 | prev_det_pin = position_detect_pin; |
| okano | 0:5d0abdf92786 | 147 | } |
| okano | 0:5d0abdf92786 | 148 | |
| okano | 0:5d0abdf92786 | 149 | go_position( 0 ); |
| okano | 0:5d0abdf92786 | 150 | set_pps( prev_pps ); |
| okano | 0:5d0abdf92786 | 151 | set_rot_mode( prev_rot ); |
| okano | 0:5d0abdf92786 | 152 | set_sync_mode( prev_sync ); |
| okano | 4:6909efe4c8ac | 153 | set_ramp_control( prev_i_rate, prev_rcs ); |
| okano | 0:5d0abdf92786 | 154 | |
| okano | 0:5d0abdf92786 | 155 | return ( init_done ); |
| okano | 0:5d0abdf92786 | 156 | } |
| okano | 0:5d0abdf92786 | 157 | |
| okano | 4:6909efe4c8ac | 158 | void StepperMotorUni::set_home_position( void ) |
| okano | 4:6909efe4c8ac | 159 | { |
| okano | 0:5d0abdf92786 | 160 | set_pause( true ); |
| okano | 0:5d0abdf92786 | 161 | pos_offset = current_pos & 0x3; |
| okano | 0:5d0abdf92786 | 162 | current_pos = 0; |
| okano | 0:5d0abdf92786 | 163 | set_target_pos( 0 ); |
| okano | 0:5d0abdf92786 | 164 | set_pause( false ); |
| okano | 0:5d0abdf92786 | 165 | } |
| okano | 0:5d0abdf92786 | 166 | |
| okano | 0:5d0abdf92786 | 167 | |
| okano | 4:6909efe4c8ac | 168 | void StepperMotorUni::go_angle( float angle ) |
| okano | 4:6909efe4c8ac | 169 | { |
| okano | 0:5d0abdf92786 | 170 | go_position( (int)((angle / 360.0) * (float)max_pos) ); |
| okano | 0:5d0abdf92786 | 171 | } |
| okano | 0:5d0abdf92786 | 172 | |
| okano | 4:6909efe4c8ac | 173 | int StepperMotorUni::move_steps( int s ) |
| okano | 4:6909efe4c8ac | 174 | { |
| okano | 0:5d0abdf92786 | 175 | set_target_pos( current_pos + s ); |
| okano | 0:5d0abdf92786 | 176 | return ( current_pos ); |
| okano | 0:5d0abdf92786 | 177 | } |
| okano | 0:5d0abdf92786 | 178 | |
| okano | 4:6909efe4c8ac | 179 | int StepperMotorUni::move_rotates( float r ) |
| okano | 4:6909efe4c8ac | 180 | { |
| okano | 0:5d0abdf92786 | 181 | set_target_pos( current_pos + (int)(r * (float)max_pos) ); |
| okano | 0:5d0abdf92786 | 182 | return ( current_pos ); |
| okano | 0:5d0abdf92786 | 183 | } |
| okano | 0:5d0abdf92786 | 184 | |
| okano | 4:6909efe4c8ac | 185 | void StepperMotorUni::set_operation_phase_mode( OperationPhaseMode v ) |
| okano | 4:6909efe4c8ac | 186 | { |
| okano | 0:5d0abdf92786 | 187 | |
| okano | 0:5d0abdf92786 | 188 | switch ( v ) { |
| okano | 0:5d0abdf92786 | 189 | case StepperMotorUni::ONE_PHASE : |
| okano | 0:5d0abdf92786 | 190 | pattern = pattern_one_phase; |
| okano | 0:5d0abdf92786 | 191 | pat_index_mask = 0x3; |
| okano | 0:5d0abdf92786 | 192 | break; |
| okano | 0:5d0abdf92786 | 193 | case StepperMotorUni::TWO_PHASE : |
| okano | 0:5d0abdf92786 | 194 | pattern = pattern_two_phase; |
| okano | 0:5d0abdf92786 | 195 | pat_index_mask = 0x3; |
| okano | 0:5d0abdf92786 | 196 | break; |
| okano | 0:5d0abdf92786 | 197 | case StepperMotorUni::HALFSTEP : |
| okano | 0:5d0abdf92786 | 198 | pattern = pattern_halfstep; |
| okano | 0:5d0abdf92786 | 199 | pat_index_mask = 0x7; |
| okano | 0:5d0abdf92786 | 200 | break; |
| okano | 0:5d0abdf92786 | 201 | } |
| okano | 0:5d0abdf92786 | 202 | |
| okano | 0:5d0abdf92786 | 203 | phase_mode = v; |
| okano | 0:5d0abdf92786 | 204 | } |
| okano | 0:5d0abdf92786 | 205 | |
| okano | 4:6909efe4c8ac | 206 | void StepperMotorUni::set_rot_mode( RotMode m ) |
| okano | 4:6909efe4c8ac | 207 | { |
| okano | 0:5d0abdf92786 | 208 | rot_mode = m; |
| okano | 0:5d0abdf92786 | 209 | } |
| okano | 0:5d0abdf92786 | 210 | |
| okano | 4:6909efe4c8ac | 211 | void StepperMotorUni::set_sync_mode( SyncMode m ) |
| okano | 4:6909efe4c8ac | 212 | { |
| okano | 0:5d0abdf92786 | 213 | sync_mode = m; |
| okano | 0:5d0abdf92786 | 214 | } |
| okano | 0:5d0abdf92786 | 215 | |
| okano | 4:6909efe4c8ac | 216 | int StepperMotorUni::distance( void ) |
| okano | 4:6909efe4c8ac | 217 | { |
| okano | 0:5d0abdf92786 | 218 | return( target_pos - current_pos ); |
| okano | 0:5d0abdf92786 | 219 | } |
| okano | 0:5d0abdf92786 | 220 | |
| okano | 4:6909efe4c8ac | 221 | void StepperMotorUni::set_pause( int sw ) |
| okano | 4:6909efe4c8ac | 222 | { |
| okano | 0:5d0abdf92786 | 223 | pause = sw; |
| okano | 0:5d0abdf92786 | 224 | } |
| okano | 0:5d0abdf92786 | 225 | |
| okano | 4:6909efe4c8ac | 226 | void StepperMotorUni::brake( void ) |
| okano | 4:6909efe4c8ac | 227 | { |
| okano | 0:5d0abdf92786 | 228 | brake( SOFT_BRAKE ); |
| okano | 0:5d0abdf92786 | 229 | } |
| okano | 0:5d0abdf92786 | 230 | |
| okano | 4:6909efe4c8ac | 231 | void StepperMotorUni::brake( BrakeMode mode ) |
| okano | 4:6909efe4c8ac | 232 | { |
| okano | 0:5d0abdf92786 | 233 | int extra_steps; |
| okano | 0:5d0abdf92786 | 234 | |
| okano | 0:5d0abdf92786 | 235 | if ( mode == SOFT_BRAKE ) { |
| okano | 0:5d0abdf92786 | 236 | extra_steps = abs( target_pos - current_pos ); |
| okano | 0:5d0abdf92786 | 237 | extra_steps = extra_steps < ramp_control_steps ? extra_steps : ramp_control_steps; |
| okano | 0:5d0abdf92786 | 238 | extra_steps = target_pos < current_pos ? -extra_steps : extra_steps; |
| okano | 0:5d0abdf92786 | 239 | } else { |
| okano | 0:5d0abdf92786 | 240 | extra_steps = 0; |
| okano | 0:5d0abdf92786 | 241 | } |
| okano | 0:5d0abdf92786 | 242 | |
| okano | 0:5d0abdf92786 | 243 | target_pos = current_pos + extra_steps; |
| okano | 0:5d0abdf92786 | 244 | } |
| okano | 0:5d0abdf92786 | 245 | |
| okano | 4:6909efe4c8ac | 246 | void StepperMotorUni::set_target_pos( int p ) |
| okano | 4:6909efe4c8ac | 247 | { |
| okano | 0:5d0abdf92786 | 248 | target_pos = p; |
| okano | 0:5d0abdf92786 | 249 | |
| okano | 0:5d0abdf92786 | 250 | if (sync_mode == SYNCHRONOUS) |
| okano | 0:5d0abdf92786 | 251 | while ( distance() ) |
| okano | 0:5d0abdf92786 | 252 | wait( 0 ); |
| okano | 0:5d0abdf92786 | 253 | } |
| okano | 0:5d0abdf92786 | 254 | |
| okano | 4:6909efe4c8ac | 255 | void StepperMotorUni::set_power_ctrl( int sw ) |
| okano | 4:6909efe4c8ac | 256 | { |
| okano | 0:5d0abdf92786 | 257 | power_ctrl = sw; |
| okano | 0:5d0abdf92786 | 258 | } |
| okano | 0:5d0abdf92786 | 259 | |
| okano | 4:6909efe4c8ac | 260 | void StepperMotorUni::set_steps_per_rotate( int steps ) |
| okano | 4:6909efe4c8ac | 261 | { |
| okano | 0:5d0abdf92786 | 262 | max_pos = steps; |
| okano | 0:5d0abdf92786 | 263 | } |
| okano | 0:5d0abdf92786 | 264 | |
| okano | 4:6909efe4c8ac | 265 | void StepperMotorUni::set_ramp_control( float initial_speed_rate, int ramp_steps ) |
| okano | 4:6909efe4c8ac | 266 | { |
| okano | 0:5d0abdf92786 | 267 | ramp_init_speed_rate = initial_speed_rate; |
| okano | 0:5d0abdf92786 | 268 | ramp_control_steps = ramp_steps; |
| okano | 4:6909efe4c8ac | 269 | |
| okano | 4:6909efe4c8ac | 270 | if ( ramp_steps == 0 ) |
| okano | 4:6909efe4c8ac | 271 | ramp_rate = 1.0; |
| okano | 4:6909efe4c8ac | 272 | else { |
| okano | 4:6909efe4c8ac | 273 | ramp_rate = powf( ramp_init_speed_rate, 1.0 / (float)ramp_control_steps ); |
| okano | 4:6909efe4c8ac | 274 | } |
| okano | 0:5d0abdf92786 | 275 | } |
| okano | 0:5d0abdf92786 | 276 | |
| okano | 4:6909efe4c8ac | 277 | void StepperMotorUni::motor_maintain( void ) |
| okano | 4:6909efe4c8ac | 278 | { |
| okano | 0:5d0abdf92786 | 279 | int distance; |
| okano | 0:5d0abdf92786 | 280 | static int moved_steps = 0; |
| okano | 0:5d0abdf92786 | 281 | static int ramp_steps = 0; |
| okano | 0:5d0abdf92786 | 282 | static float speed_rate = 1.0; |
| okano | 0:5d0abdf92786 | 283 | |
| okano | 0:5d0abdf92786 | 284 | if ( pause ) |
| okano | 0:5d0abdf92786 | 285 | return; |
| okano | 0:5d0abdf92786 | 286 | |
| okano | 0:5d0abdf92786 | 287 | distance = target_pos - current_pos; |
| okano | 0:5d0abdf92786 | 288 | distance = (distance < 0)? -distance : distance; |
| okano | 0:5d0abdf92786 | 289 | |
| okano | 0:5d0abdf92786 | 290 | if ( !distance ) { |
| okano | 6:007d0570ba4f | 291 | if ( power_ctrl ) |
| okano | 6:007d0570ba4f | 292 | motor_out = 0; |
| okano | 6:007d0570ba4f | 293 | |
| okano | 0:5d0abdf92786 | 294 | moved_steps = 0; |
| okano | 0:5d0abdf92786 | 295 | return; |
| okano | 0:5d0abdf92786 | 296 | } |
| okano | 0:5d0abdf92786 | 297 | |
| okano | 0:5d0abdf92786 | 298 | if ( !moved_steps ) { // ramp control |
| okano | 0:5d0abdf92786 | 299 | speed_rate = ramp_init_speed_rate; |
| okano | 0:5d0abdf92786 | 300 | ramp_steps = ((ramp_control_steps * 2) - distance) / 2; |
| okano | 0:5d0abdf92786 | 301 | ramp_steps = (0 < ramp_steps) ? ramp_control_steps - ramp_steps : ramp_control_steps; |
| okano | 0:5d0abdf92786 | 302 | // printf( "ramp_steps=%d, speed_rate=%f\r\n", ramp_steps, speed_rate ); |
| okano | 0:5d0abdf92786 | 303 | // printf( "diff=%d, speed_rate=%f\r\n", diff, speed_rate ); |
| okano | 0:5d0abdf92786 | 304 | } else if ( moved_steps < ramp_steps ) { |
| okano | 0:5d0abdf92786 | 305 | speed_rate /= ramp_rate; |
| okano | 0:5d0abdf92786 | 306 | } else if ( distance <= ramp_steps ) { |
| okano | 0:5d0abdf92786 | 307 | speed_rate *= ramp_rate; |
| okano | 0:5d0abdf92786 | 308 | } else { |
| okano | 0:5d0abdf92786 | 309 | speed_rate = 1.0; |
| okano | 0:5d0abdf92786 | 310 | } |
| okano | 0:5d0abdf92786 | 311 | |
| okano | 0:5d0abdf92786 | 312 | moved_steps++; |
| okano | 0:5d0abdf92786 | 313 | current_pos = current_pos + ( (target_pos < current_pos) ? -1 : 1 ); |
| okano | 0:5d0abdf92786 | 314 | |
| okano | 0:5d0abdf92786 | 315 | motor_out = pattern[ (current_pos + pos_offset) & pat_index_mask ]; |
| okano | 0:5d0abdf92786 | 316 | |
| okano | 0:5d0abdf92786 | 317 | //printf( "%d>>>%d\r\n", current_pos, target_pos ); |
| okano | 0:5d0abdf92786 | 318 | |
| okano | 0:5d0abdf92786 | 319 | if ( speed_rate != 1.0 ) { |
| okano | 2:6835e719ff96 | 320 | t.detach(); |
| okano | 2:6835e719ff96 | 321 | t.attach( this, &StepperMotorUni::motor_maintain, ((1.0 / (float)pps)) / speed_rate ); |
| okano | 0:5d0abdf92786 | 322 | } |
| okano | 0:5d0abdf92786 | 323 | |
| okano | 0:5d0abdf92786 | 324 | if ( target_pos == current_pos ) { |
| okano | 0:5d0abdf92786 | 325 | current_pos = current_pos % max_pos; |
| okano | 0:5d0abdf92786 | 326 | target_pos = target_pos % max_pos; |
| okano | 0:5d0abdf92786 | 327 | moved_steps = 0; |
| okano | 0:5d0abdf92786 | 328 | } |
| okano | 0:5d0abdf92786 | 329 | }; |
| okano | 0:5d0abdf92786 | 330 | |
| okano | 4:6909efe4c8ac | 331 | int StepperMotorUni::go_position( int target_pos ) |
| okano | 4:6909efe4c8ac | 332 | { |
| okano | 0:5d0abdf92786 | 333 | |
| okano | 0:5d0abdf92786 | 334 | current_pos = current_pos % max_pos; |
| okano | 0:5d0abdf92786 | 335 | current_pos = (current_pos < 0) ? current_pos + max_pos : current_pos; |
| okano | 0:5d0abdf92786 | 336 | |
| okano | 0:5d0abdf92786 | 337 | target_pos = target_pos % max_pos; |
| okano | 0:5d0abdf92786 | 338 | target_pos = (target_pos < 0) ? target_pos + max_pos : target_pos; |
| okano | 0:5d0abdf92786 | 339 | |
| okano | 0:5d0abdf92786 | 340 | #define CW 0 |
| okano | 0:5d0abdf92786 | 341 | #define CCW 1 |
| okano | 0:5d0abdf92786 | 342 | |
| okano | 0:5d0abdf92786 | 343 | int direction; |
| okano | 0:5d0abdf92786 | 344 | |
| okano | 0:5d0abdf92786 | 345 | switch ( rot_mode ) { |
| okano | 0:5d0abdf92786 | 346 | case NO_WRAPAROUND : |
| okano | 0:5d0abdf92786 | 347 | direction = (current_pos < target_pos) ? CW : CCW; |
| okano | 0:5d0abdf92786 | 348 | break; |
| okano | 0:5d0abdf92786 | 349 | case CLOCKWISE_ONLY : |
| okano | 0:5d0abdf92786 | 350 | direction = CW; |
| okano | 0:5d0abdf92786 | 351 | break; |
| okano | 0:5d0abdf92786 | 352 | case COUNTER_CLOCKWISE_ONLY : |
| okano | 0:5d0abdf92786 | 353 | direction = CCW; |
| okano | 0:5d0abdf92786 | 354 | break; |
| okano | 0:5d0abdf92786 | 355 | default : // SHORTEST : |
| okano | 0:5d0abdf92786 | 356 | direction = ( (max_pos >> 1) < ((target_pos + max_pos - current_pos) % max_pos) ) ? CCW : CW; |
| okano | 0:5d0abdf92786 | 357 | break; |
| okano | 0:5d0abdf92786 | 358 | } |
| okano | 0:5d0abdf92786 | 359 | |
| okano | 0:5d0abdf92786 | 360 | switch ( direction ) { |
| okano | 0:5d0abdf92786 | 361 | case CW : |
| okano | 0:5d0abdf92786 | 362 | current_pos = (target_pos < current_pos) ? current_pos - max_pos : current_pos; |
| okano | 0:5d0abdf92786 | 363 | break; |
| okano | 0:5d0abdf92786 | 364 | case CCW : |
| okano | 0:5d0abdf92786 | 365 | target_pos = (current_pos < target_pos) ? target_pos - max_pos : target_pos; |
| okano | 0:5d0abdf92786 | 366 | break; |
| okano | 0:5d0abdf92786 | 367 | } |
| okano | 0:5d0abdf92786 | 368 | |
| okano | 0:5d0abdf92786 | 369 | set_target_pos( target_pos ); |
| okano | 0:5d0abdf92786 | 370 | return ( current_pos ); |
| okano | 0:5d0abdf92786 | 371 | } |
| okano | 0:5d0abdf92786 | 372 | |
| okano | 0:5d0abdf92786 | 373 | #if 0 |
| okano | 0:5d0abdf92786 | 374 | unsigned char StepperMotorUni::pattern_one_phase[ 4 ] = { 0x8, 0x4, 0x2, 0x1 }; |
| okano | 0:5d0abdf92786 | 375 | unsigned char StepperMotorUni::pattern_two_phase[ 4 ] = { 0x9, 0xC, 0x6, 0x3 }; |
| okano | 0:5d0abdf92786 | 376 | unsigned char StepperMotorUni::pattern_halfstep[ 8 ] = { 0x9, 0x8, 0xC, 0x4, 0x6, 0x2, 0x3, 0x1 }; |
| okano | 0:5d0abdf92786 | 377 | #else |
| okano | 0:5d0abdf92786 | 378 | unsigned char StepperMotorUni::pattern_one_phase[ 4 ] = { 0x1, 0x2, 0x4, 0x8 }; |
| okano | 0:5d0abdf92786 | 379 | unsigned char StepperMotorUni::pattern_two_phase[ 4 ] = { 0x3, 0x6, 0xC, 0x9 }; |
| okano | 0:5d0abdf92786 | 380 | unsigned char StepperMotorUni::pattern_halfstep[ 8 ] = { 0x1, 0x3, 0x2, 0x6, 0x4, 0xC, 0x8, 0x9 }; |
| okano | 0:5d0abdf92786 | 381 | #endif |