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@4:6909efe4c8ac, 2015-04-22 (annotated)
- Committer:
- okano
- Date:
- Wed Apr 22 03:24:21 2015 +0000
- Revision:
- 4:6909efe4c8ac
- Parent:
- 3:0eec6148e739
- Child:
- 5:93f9ce526f38
fixed: find_home_position compatibility with ramp control feature
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 | 4:6909efe4c8ac | 5 | * @version 1.1.1 |
| okano | 4:6909efe4c8ac | 6 | * @date 22-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 | 0:5d0abdf92786 | 41 | */ |
| okano | 0:5d0abdf92786 | 42 | |
| okano | 0:5d0abdf92786 | 43 | #include "mbed.h" |
| okano | 0:5d0abdf92786 | 44 | #include "StepperMotorUni.h" |
| okano | 0:5d0abdf92786 | 45 | |
| okano | 0:5d0abdf92786 | 46 | StepperMotorUni::StepperMotorUni( |
| okano | 0:5d0abdf92786 | 47 | PinName out_A, |
| okano | 0:5d0abdf92786 | 48 | PinName out_B, |
| okano | 0:5d0abdf92786 | 49 | PinName out_C, |
| okano | 0:5d0abdf92786 | 50 | PinName out_D, |
| okano | 0:5d0abdf92786 | 51 | PinName position_detect |
| okano | 0:5d0abdf92786 | 52 | ) : |
| okano | 4:6909efe4c8ac | 53 | motor_out( out_A, out_B, out_C, out_D ), |
| okano | 4:6909efe4c8ac | 54 | position_detect_pin( position_detect ), |
| okano | 4:6909efe4c8ac | 55 | rot_mode( SHORTEST ), |
| okano | 4:6909efe4c8ac | 56 | sync_mode( ASYNCHRONOUS ), |
| okano | 4:6909efe4c8ac | 57 | max_pos( 480 ), |
| okano | 4:6909efe4c8ac | 58 | current_pos( 0 ), |
| okano | 4:6909efe4c8ac | 59 | pos_offset( 0 ), |
| okano | 4:6909efe4c8ac | 60 | target_pos( 0 ), |
| okano | 4:6909efe4c8ac | 61 | max_pps( MAX_PPS ), |
| okano | 4:6909efe4c8ac | 62 | init_done( false ), |
| okano | 4:6909efe4c8ac | 63 | pause( false ), |
| okano | 4:6909efe4c8ac | 64 | power_ctrl( false ), |
| okano | 4:6909efe4c8ac | 65 | ramp_init_speed_rate( 1.0 ), |
| okano | 4:6909efe4c8ac | 66 | ramp_control_steps( 0 ), |
| okano | 4:6909efe4c8ac | 67 | ramp_rate( 1.0 ) |
| okano | 4:6909efe4c8ac | 68 | { |
| okano | 0:5d0abdf92786 | 69 | |
| okano | 0:5d0abdf92786 | 70 | pps = max_pps; |
| okano | 0:5d0abdf92786 | 71 | pattern = (unsigned char *)pattern_one_phase; |
| okano | 0:5d0abdf92786 | 72 | pat_index_mask = 0x3; |
| okano | 0:5d0abdf92786 | 73 | t.attach( this, &StepperMotorUni::motor_maintain, 1.0 / (float)pps ); |
| okano | 0:5d0abdf92786 | 74 | } |
| okano | 0:5d0abdf92786 | 75 | |
| okano | 4:6909efe4c8ac | 76 | float StepperMotorUni::set_pps( float v ) |
| okano | 4:6909efe4c8ac | 77 | { |
| okano | 0:5d0abdf92786 | 78 | float p; |
| okano | 0:5d0abdf92786 | 79 | |
| okano | 0:5d0abdf92786 | 80 | p = pps; |
| okano | 0:5d0abdf92786 | 81 | pps = v; |
| okano | 0:5d0abdf92786 | 82 | t.detach(); |
| okano | 0:5d0abdf92786 | 83 | t.attach( this, &StepperMotorUni::motor_maintain, 1.0 / (float)pps ); |
| okano | 0:5d0abdf92786 | 84 | return ( p ); |
| okano | 0:5d0abdf92786 | 85 | } |
| okano | 0:5d0abdf92786 | 86 | |
| okano | 4:6909efe4c8ac | 87 | void StepperMotorUni::set_max_pps( float v ) |
| okano | 4:6909efe4c8ac | 88 | { |
| okano | 0:5d0abdf92786 | 89 | max_pps = v; |
| okano | 0:5d0abdf92786 | 90 | } |
| okano | 0:5d0abdf92786 | 91 | |
| okano | 4:6909efe4c8ac | 92 | int StepperMotorUni::find_home_position( PositionDetectPorarity edge ) |
| okano | 4:6909efe4c8ac | 93 | { |
| okano | 0:5d0abdf92786 | 94 | RotMode prev_rot; |
| okano | 0:5d0abdf92786 | 95 | SyncMode prev_sync; |
| okano | 0:5d0abdf92786 | 96 | float prev_pps; |
| okano | 4:6909efe4c8ac | 97 | float prev_i_rate; |
| okano | 4:6909efe4c8ac | 98 | int prev_rcs; |
| okano | 0:5d0abdf92786 | 99 | int prev_det_pin; |
| okano | 0:5d0abdf92786 | 100 | int direction; |
| okano | 0:5d0abdf92786 | 101 | |
| okano | 0:5d0abdf92786 | 102 | if ( position_detect_pin == NC ) |
| okano | 0:5d0abdf92786 | 103 | return 0; |
| okano | 0:5d0abdf92786 | 104 | |
| okano | 0:5d0abdf92786 | 105 | prev_pps = set_pps( max_pps ); |
| okano | 4:6909efe4c8ac | 106 | prev_i_rate = ramp_init_speed_rate; |
| okano | 4:6909efe4c8ac | 107 | prev_rcs = ramp_control_steps; |
| okano | 0:5d0abdf92786 | 108 | prev_rot = rot_mode; |
| okano | 0:5d0abdf92786 | 109 | prev_sync = sync_mode; |
| okano | 0:5d0abdf92786 | 110 | set_sync_mode( SYNCHRONOUS ); |
| okano | 0:5d0abdf92786 | 111 | set_rot_mode( SHORTEST ); |
| okano | 0:5d0abdf92786 | 112 | |
| okano | 4:6909efe4c8ac | 113 | prev_det_pin = position_detect_pin; |
| okano | 4:6909efe4c8ac | 114 | set_ramp_control( 1.0, 0 ); |
| okano | 0:5d0abdf92786 | 115 | |
| okano | 0:5d0abdf92786 | 116 | if ( prev_rot == COUNTER_CLOCKWISE_ONLY ) |
| okano | 0:5d0abdf92786 | 117 | direction = -1; |
| okano | 0:5d0abdf92786 | 118 | else |
| okano | 0:5d0abdf92786 | 119 | direction = 1; |
| okano | 0:5d0abdf92786 | 120 | |
| okano | 0:5d0abdf92786 | 121 | if ( prev_rot == NO_WRAPAROUND ) { |
| okano | 0:5d0abdf92786 | 122 | |
| okano | 0:5d0abdf92786 | 123 | for ( int i = 0; i < (max_pos >> 1); i++ ) { |
| okano | 0:5d0abdf92786 | 124 | move_steps( -1 ); |
| okano | 0:5d0abdf92786 | 125 | if ( ((edge == RISING_EDGE) && !prev_det_pin && position_detect_pin) |
| okano | 0:5d0abdf92786 | 126 | || ((edge == FALLING_EDGE) && prev_det_pin && !position_detect_pin) ) { |
| okano | 0:5d0abdf92786 | 127 | set_home_position(); |
| okano | 0:5d0abdf92786 | 128 | init_done = true; |
| okano | 0:5d0abdf92786 | 129 | break; |
| okano | 0:5d0abdf92786 | 130 | } |
| okano | 0:5d0abdf92786 | 131 | prev_det_pin = position_detect_pin; |
| okano | 0:5d0abdf92786 | 132 | } |
| okano | 0:5d0abdf92786 | 133 | } |
| okano | 0:5d0abdf92786 | 134 | |
| okano | 0:5d0abdf92786 | 135 | for ( int i = 0; i < ((prev_rot == NO_WRAPAROUND) ? (max_pos - 1) : (max_pos + 10)); i++ ) { |
| okano | 0:5d0abdf92786 | 136 | move_steps( direction ); |
| okano | 0:5d0abdf92786 | 137 | if ( ((edge == RISING_EDGE) && !prev_det_pin && position_detect_pin) |
| okano | 0:5d0abdf92786 | 138 | || ((edge == FALLING_EDGE) && prev_det_pin && !position_detect_pin) ) { |
| okano | 0:5d0abdf92786 | 139 | set_home_position(); |
| okano | 0:5d0abdf92786 | 140 | init_done = true; |
| okano | 0:5d0abdf92786 | 141 | break; |
| okano | 0:5d0abdf92786 | 142 | } |
| okano | 0:5d0abdf92786 | 143 | prev_det_pin = position_detect_pin; |
| okano | 0:5d0abdf92786 | 144 | } |
| okano | 0:5d0abdf92786 | 145 | |
| okano | 0:5d0abdf92786 | 146 | go_position( 0 ); |
| okano | 0:5d0abdf92786 | 147 | set_pps( prev_pps ); |
| okano | 0:5d0abdf92786 | 148 | set_rot_mode( prev_rot ); |
| okano | 0:5d0abdf92786 | 149 | set_sync_mode( prev_sync ); |
| okano | 4:6909efe4c8ac | 150 | set_ramp_control( prev_i_rate, prev_rcs ); |
| okano | 0:5d0abdf92786 | 151 | |
| okano | 0:5d0abdf92786 | 152 | return ( init_done ); |
| okano | 0:5d0abdf92786 | 153 | } |
| okano | 0:5d0abdf92786 | 154 | |
| okano | 4:6909efe4c8ac | 155 | void StepperMotorUni::set_home_position( void ) |
| okano | 4:6909efe4c8ac | 156 | { |
| okano | 0:5d0abdf92786 | 157 | set_pause( true ); |
| okano | 0:5d0abdf92786 | 158 | pos_offset = current_pos & 0x3; |
| okano | 0:5d0abdf92786 | 159 | current_pos = 0; |
| okano | 0:5d0abdf92786 | 160 | set_target_pos( 0 ); |
| okano | 0:5d0abdf92786 | 161 | set_pause( false ); |
| okano | 0:5d0abdf92786 | 162 | } |
| okano | 0:5d0abdf92786 | 163 | |
| okano | 0:5d0abdf92786 | 164 | |
| okano | 4:6909efe4c8ac | 165 | void StepperMotorUni::go_angle( float angle ) |
| okano | 4:6909efe4c8ac | 166 | { |
| okano | 0:5d0abdf92786 | 167 | go_position( (int)((angle / 360.0) * (float)max_pos) ); |
| okano | 0:5d0abdf92786 | 168 | } |
| okano | 0:5d0abdf92786 | 169 | |
| okano | 4:6909efe4c8ac | 170 | int StepperMotorUni::move_steps( int s ) |
| okano | 4:6909efe4c8ac | 171 | { |
| okano | 0:5d0abdf92786 | 172 | set_target_pos( current_pos + s ); |
| okano | 0:5d0abdf92786 | 173 | return ( current_pos ); |
| okano | 0:5d0abdf92786 | 174 | } |
| okano | 0:5d0abdf92786 | 175 | |
| okano | 4:6909efe4c8ac | 176 | int StepperMotorUni::move_rotates( float r ) |
| okano | 4:6909efe4c8ac | 177 | { |
| okano | 0:5d0abdf92786 | 178 | set_target_pos( current_pos + (int)(r * (float)max_pos) ); |
| okano | 0:5d0abdf92786 | 179 | return ( current_pos ); |
| okano | 0:5d0abdf92786 | 180 | } |
| okano | 0:5d0abdf92786 | 181 | |
| okano | 4:6909efe4c8ac | 182 | void StepperMotorUni::set_operation_phase_mode( OperationPhaseMode v ) |
| okano | 4:6909efe4c8ac | 183 | { |
| okano | 0:5d0abdf92786 | 184 | |
| okano | 0:5d0abdf92786 | 185 | switch ( v ) { |
| okano | 0:5d0abdf92786 | 186 | case StepperMotorUni::ONE_PHASE : |
| okano | 0:5d0abdf92786 | 187 | pattern = pattern_one_phase; |
| okano | 0:5d0abdf92786 | 188 | pat_index_mask = 0x3; |
| okano | 0:5d0abdf92786 | 189 | break; |
| okano | 0:5d0abdf92786 | 190 | case StepperMotorUni::TWO_PHASE : |
| okano | 0:5d0abdf92786 | 191 | pattern = pattern_two_phase; |
| okano | 0:5d0abdf92786 | 192 | pat_index_mask = 0x3; |
| okano | 0:5d0abdf92786 | 193 | break; |
| okano | 0:5d0abdf92786 | 194 | case StepperMotorUni::HALFSTEP : |
| okano | 0:5d0abdf92786 | 195 | pattern = pattern_halfstep; |
| okano | 0:5d0abdf92786 | 196 | pat_index_mask = 0x7; |
| okano | 0:5d0abdf92786 | 197 | break; |
| okano | 0:5d0abdf92786 | 198 | } |
| okano | 0:5d0abdf92786 | 199 | |
| okano | 0:5d0abdf92786 | 200 | phase_mode = v; |
| okano | 0:5d0abdf92786 | 201 | } |
| okano | 0:5d0abdf92786 | 202 | |
| okano | 4:6909efe4c8ac | 203 | void StepperMotorUni::set_rot_mode( RotMode m ) |
| okano | 4:6909efe4c8ac | 204 | { |
| okano | 0:5d0abdf92786 | 205 | rot_mode = m; |
| okano | 0:5d0abdf92786 | 206 | } |
| okano | 0:5d0abdf92786 | 207 | |
| okano | 4:6909efe4c8ac | 208 | void StepperMotorUni::set_sync_mode( SyncMode m ) |
| okano | 4:6909efe4c8ac | 209 | { |
| okano | 0:5d0abdf92786 | 210 | sync_mode = m; |
| okano | 0:5d0abdf92786 | 211 | } |
| okano | 0:5d0abdf92786 | 212 | |
| okano | 4:6909efe4c8ac | 213 | int StepperMotorUni::distance( void ) |
| okano | 4:6909efe4c8ac | 214 | { |
| okano | 0:5d0abdf92786 | 215 | return( target_pos - current_pos ); |
| okano | 0:5d0abdf92786 | 216 | } |
| okano | 0:5d0abdf92786 | 217 | |
| okano | 4:6909efe4c8ac | 218 | void StepperMotorUni::set_pause( int sw ) |
| okano | 4:6909efe4c8ac | 219 | { |
| okano | 0:5d0abdf92786 | 220 | pause = sw; |
| okano | 0:5d0abdf92786 | 221 | } |
| okano | 0:5d0abdf92786 | 222 | |
| okano | 4:6909efe4c8ac | 223 | void StepperMotorUni::brake( void ) |
| okano | 4:6909efe4c8ac | 224 | { |
| okano | 0:5d0abdf92786 | 225 | brake( SOFT_BRAKE ); |
| okano | 0:5d0abdf92786 | 226 | } |
| okano | 0:5d0abdf92786 | 227 | |
| okano | 4:6909efe4c8ac | 228 | void StepperMotorUni::brake( BrakeMode mode ) |
| okano | 4:6909efe4c8ac | 229 | { |
| okano | 0:5d0abdf92786 | 230 | int extra_steps; |
| okano | 0:5d0abdf92786 | 231 | |
| okano | 0:5d0abdf92786 | 232 | if ( mode == SOFT_BRAKE ) { |
| okano | 0:5d0abdf92786 | 233 | extra_steps = abs( target_pos - current_pos ); |
| okano | 0:5d0abdf92786 | 234 | extra_steps = extra_steps < ramp_control_steps ? extra_steps : ramp_control_steps; |
| okano | 0:5d0abdf92786 | 235 | extra_steps = target_pos < current_pos ? -extra_steps : extra_steps; |
| okano | 0:5d0abdf92786 | 236 | } else { |
| okano | 0:5d0abdf92786 | 237 | extra_steps = 0; |
| okano | 0:5d0abdf92786 | 238 | } |
| okano | 0:5d0abdf92786 | 239 | |
| okano | 0:5d0abdf92786 | 240 | target_pos = current_pos + extra_steps; |
| okano | 0:5d0abdf92786 | 241 | } |
| okano | 0:5d0abdf92786 | 242 | |
| okano | 4:6909efe4c8ac | 243 | void StepperMotorUni::set_target_pos( int p ) |
| okano | 4:6909efe4c8ac | 244 | { |
| okano | 0:5d0abdf92786 | 245 | target_pos = p; |
| okano | 0:5d0abdf92786 | 246 | |
| okano | 0:5d0abdf92786 | 247 | if (sync_mode == SYNCHRONOUS) |
| okano | 0:5d0abdf92786 | 248 | while ( distance() ) |
| okano | 0:5d0abdf92786 | 249 | wait( 0 ); |
| okano | 0:5d0abdf92786 | 250 | } |
| okano | 0:5d0abdf92786 | 251 | |
| okano | 4:6909efe4c8ac | 252 | void StepperMotorUni::set_power_ctrl( int sw ) |
| okano | 4:6909efe4c8ac | 253 | { |
| okano | 0:5d0abdf92786 | 254 | power_ctrl = sw; |
| okano | 0:5d0abdf92786 | 255 | } |
| okano | 0:5d0abdf92786 | 256 | |
| okano | 4:6909efe4c8ac | 257 | void StepperMotorUni::set_steps_per_rotate( int steps ) |
| okano | 4:6909efe4c8ac | 258 | { |
| okano | 0:5d0abdf92786 | 259 | max_pos = steps; |
| okano | 0:5d0abdf92786 | 260 | } |
| okano | 0:5d0abdf92786 | 261 | |
| okano | 4:6909efe4c8ac | 262 | void StepperMotorUni::set_ramp_control( float initial_speed_rate, int ramp_steps ) |
| okano | 4:6909efe4c8ac | 263 | { |
| okano | 0:5d0abdf92786 | 264 | ramp_init_speed_rate = initial_speed_rate; |
| okano | 0:5d0abdf92786 | 265 | ramp_control_steps = ramp_steps; |
| okano | 4:6909efe4c8ac | 266 | |
| okano | 4:6909efe4c8ac | 267 | if ( ramp_steps == 0 ) |
| okano | 4:6909efe4c8ac | 268 | ramp_rate = 1.0; |
| okano | 4:6909efe4c8ac | 269 | else { |
| okano | 4:6909efe4c8ac | 270 | ramp_rate = powf( ramp_init_speed_rate, 1.0 / (float)ramp_control_steps ); |
| okano | 4:6909efe4c8ac | 271 | } |
| okano | 0:5d0abdf92786 | 272 | } |
| okano | 0:5d0abdf92786 | 273 | |
| okano | 4:6909efe4c8ac | 274 | void StepperMotorUni::motor_maintain( void ) |
| okano | 4:6909efe4c8ac | 275 | { |
| okano | 0:5d0abdf92786 | 276 | int distance; |
| okano | 0:5d0abdf92786 | 277 | static int moved_steps = 0; |
| okano | 0:5d0abdf92786 | 278 | static int ramp_steps = 0; |
| okano | 0:5d0abdf92786 | 279 | static float speed_rate = 1.0; |
| okano | 0:5d0abdf92786 | 280 | |
| okano | 0:5d0abdf92786 | 281 | if ( pause ) |
| okano | 0:5d0abdf92786 | 282 | return; |
| okano | 0:5d0abdf92786 | 283 | |
| okano | 0:5d0abdf92786 | 284 | distance = target_pos - current_pos; |
| okano | 0:5d0abdf92786 | 285 | distance = (distance < 0)? -distance : distance; |
| okano | 0:5d0abdf92786 | 286 | |
| okano | 0:5d0abdf92786 | 287 | if ( !distance ) { |
| okano | 0:5d0abdf92786 | 288 | motor_out = power_ctrl ? 0 : 1; |
| okano | 0:5d0abdf92786 | 289 | moved_steps = 0; |
| okano | 0:5d0abdf92786 | 290 | return; |
| okano | 0:5d0abdf92786 | 291 | } |
| okano | 0:5d0abdf92786 | 292 | |
| okano | 0:5d0abdf92786 | 293 | if ( !moved_steps ) { // ramp control |
| okano | 0:5d0abdf92786 | 294 | speed_rate = ramp_init_speed_rate; |
| okano | 0:5d0abdf92786 | 295 | ramp_steps = ((ramp_control_steps * 2) - distance) / 2; |
| okano | 0:5d0abdf92786 | 296 | ramp_steps = (0 < ramp_steps) ? ramp_control_steps - ramp_steps : ramp_control_steps; |
| okano | 0:5d0abdf92786 | 297 | // printf( "ramp_steps=%d, speed_rate=%f\r\n", ramp_steps, speed_rate ); |
| okano | 0:5d0abdf92786 | 298 | // printf( "diff=%d, speed_rate=%f\r\n", diff, speed_rate ); |
| okano | 0:5d0abdf92786 | 299 | } else if ( moved_steps < ramp_steps ) { |
| okano | 0:5d0abdf92786 | 300 | speed_rate /= ramp_rate; |
| okano | 0:5d0abdf92786 | 301 | } else if ( distance <= ramp_steps ) { |
| okano | 0:5d0abdf92786 | 302 | speed_rate *= ramp_rate; |
| okano | 0:5d0abdf92786 | 303 | } else { |
| okano | 0:5d0abdf92786 | 304 | speed_rate = 1.0; |
| okano | 0:5d0abdf92786 | 305 | } |
| okano | 0:5d0abdf92786 | 306 | |
| okano | 0:5d0abdf92786 | 307 | moved_steps++; |
| okano | 0:5d0abdf92786 | 308 | current_pos = current_pos + ( (target_pos < current_pos) ? -1 : 1 ); |
| okano | 0:5d0abdf92786 | 309 | |
| okano | 0:5d0abdf92786 | 310 | motor_out = pattern[ (current_pos + pos_offset) & pat_index_mask ]; |
| okano | 0:5d0abdf92786 | 311 | |
| okano | 0:5d0abdf92786 | 312 | //printf( "%d>>>%d\r\n", current_pos, target_pos ); |
| okano | 0:5d0abdf92786 | 313 | |
| okano | 0:5d0abdf92786 | 314 | if ( speed_rate != 1.0 ) { |
| okano | 2:6835e719ff96 | 315 | t.detach(); |
| okano | 2:6835e719ff96 | 316 | t.attach( this, &StepperMotorUni::motor_maintain, ((1.0 / (float)pps)) / speed_rate ); |
| okano | 0:5d0abdf92786 | 317 | } |
| okano | 0:5d0abdf92786 | 318 | |
| okano | 0:5d0abdf92786 | 319 | if ( target_pos == current_pos ) { |
| okano | 0:5d0abdf92786 | 320 | current_pos = current_pos % max_pos; |
| okano | 0:5d0abdf92786 | 321 | target_pos = target_pos % max_pos; |
| okano | 0:5d0abdf92786 | 322 | moved_steps = 0; |
| okano | 0:5d0abdf92786 | 323 | } |
| okano | 0:5d0abdf92786 | 324 | }; |
| okano | 0:5d0abdf92786 | 325 | |
| okano | 4:6909efe4c8ac | 326 | int StepperMotorUni::go_position( int target_pos ) |
| okano | 4:6909efe4c8ac | 327 | { |
| okano | 0:5d0abdf92786 | 328 | |
| okano | 0:5d0abdf92786 | 329 | current_pos = current_pos % max_pos; |
| okano | 0:5d0abdf92786 | 330 | current_pos = (current_pos < 0) ? current_pos + max_pos : current_pos; |
| okano | 0:5d0abdf92786 | 331 | |
| okano | 0:5d0abdf92786 | 332 | target_pos = target_pos % max_pos; |
| okano | 0:5d0abdf92786 | 333 | target_pos = (target_pos < 0) ? target_pos + max_pos : target_pos; |
| okano | 0:5d0abdf92786 | 334 | |
| okano | 0:5d0abdf92786 | 335 | #define CW 0 |
| okano | 0:5d0abdf92786 | 336 | #define CCW 1 |
| okano | 0:5d0abdf92786 | 337 | |
| okano | 0:5d0abdf92786 | 338 | int direction; |
| okano | 0:5d0abdf92786 | 339 | |
| okano | 0:5d0abdf92786 | 340 | switch ( rot_mode ) { |
| okano | 0:5d0abdf92786 | 341 | case NO_WRAPAROUND : |
| okano | 0:5d0abdf92786 | 342 | direction = (current_pos < target_pos) ? CW : CCW; |
| okano | 0:5d0abdf92786 | 343 | break; |
| okano | 0:5d0abdf92786 | 344 | case CLOCKWISE_ONLY : |
| okano | 0:5d0abdf92786 | 345 | direction = CW; |
| okano | 0:5d0abdf92786 | 346 | break; |
| okano | 0:5d0abdf92786 | 347 | case COUNTER_CLOCKWISE_ONLY : |
| okano | 0:5d0abdf92786 | 348 | direction = CCW; |
| okano | 0:5d0abdf92786 | 349 | break; |
| okano | 0:5d0abdf92786 | 350 | default : // SHORTEST : |
| okano | 0:5d0abdf92786 | 351 | direction = ( (max_pos >> 1) < ((target_pos + max_pos - current_pos) % max_pos) ) ? CCW : CW; |
| okano | 0:5d0abdf92786 | 352 | break; |
| okano | 0:5d0abdf92786 | 353 | } |
| okano | 0:5d0abdf92786 | 354 | |
| okano | 0:5d0abdf92786 | 355 | switch ( direction ) { |
| okano | 0:5d0abdf92786 | 356 | case CW : |
| okano | 0:5d0abdf92786 | 357 | current_pos = (target_pos < current_pos) ? current_pos - max_pos : current_pos; |
| okano | 0:5d0abdf92786 | 358 | break; |
| okano | 0:5d0abdf92786 | 359 | case CCW : |
| okano | 0:5d0abdf92786 | 360 | target_pos = (current_pos < target_pos) ? target_pos - max_pos : target_pos; |
| okano | 0:5d0abdf92786 | 361 | break; |
| okano | 0:5d0abdf92786 | 362 | } |
| okano | 0:5d0abdf92786 | 363 | |
| okano | 0:5d0abdf92786 | 364 | set_target_pos( target_pos ); |
| okano | 0:5d0abdf92786 | 365 | return ( current_pos ); |
| okano | 0:5d0abdf92786 | 366 | } |
| okano | 0:5d0abdf92786 | 367 | |
| okano | 0:5d0abdf92786 | 368 | #if 0 |
| okano | 0:5d0abdf92786 | 369 | unsigned char StepperMotorUni::pattern_one_phase[ 4 ] = { 0x8, 0x4, 0x2, 0x1 }; |
| okano | 0:5d0abdf92786 | 370 | unsigned char StepperMotorUni::pattern_two_phase[ 4 ] = { 0x9, 0xC, 0x6, 0x3 }; |
| okano | 0:5d0abdf92786 | 371 | unsigned char StepperMotorUni::pattern_halfstep[ 8 ] = { 0x9, 0x8, 0xC, 0x4, 0x6, 0x2, 0x3, 0x1 }; |
| okano | 0:5d0abdf92786 | 372 | #else |
| okano | 0:5d0abdf92786 | 373 | unsigned char StepperMotorUni::pattern_one_phase[ 4 ] = { 0x1, 0x2, 0x4, 0x8 }; |
| okano | 0:5d0abdf92786 | 374 | unsigned char StepperMotorUni::pattern_two_phase[ 4 ] = { 0x3, 0x6, 0xC, 0x9 }; |
| okano | 0:5d0abdf92786 | 375 | unsigned char StepperMotorUni::pattern_halfstep[ 8 ] = { 0x1, 0x3, 0x2, 0x6, 0x4, 0xC, 0x8, 0x9 }; |
| okano | 0:5d0abdf92786 | 376 | #endif |