Drive a stepper motor using A4988 with asynchronous. No wait() function.
AsyncStepper.cpp@1:0f8209567b7d, 2018-07-28 (annotated)
- Committer:
- babylonica
- Date:
- Sat Jul 28 18:22:05 2018 +0000
- Revision:
- 1:0f8209567b7d
- Parent:
- 0:26fa30c35f74
minor changes
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
babylonica | 0:26fa30c35f74 | 1 | // -*- coding:utf-8-unix -*- |
babylonica | 0:26fa30c35f74 | 2 | /*! |
babylonica | 0:26fa30c35f74 | 3 | @file AsyncStepper.cpp |
babylonica | 0:26fa30c35f74 | 4 | |
babylonica | 0:26fa30c35f74 | 5 | @brief Drive a stepper motor using A4988 with asynchronous. |
babylonica | 0:26fa30c35f74 | 6 | |
babylonica | 0:26fa30c35f74 | 7 | @author T.Kawamura |
babylonica | 0:26fa30c35f74 | 8 | @version 1.0 |
babylonica | 0:26fa30c35f74 | 9 | @date 2018-07-12 T.Kawamura Written for C++/mbed. |
babylonica | 0:26fa30c35f74 | 10 | @see |
babylonica | 0:26fa30c35f74 | 11 | Copyright (C) 2018 Takuma Kawamura. |
babylonica | 0:26fa30c35f74 | 12 | Released under the MIT license. |
babylonica | 0:26fa30c35f74 | 13 | http://opensource.org/licenses/mit-license.php |
babylonica | 0:26fa30c35f74 | 14 | */ |
babylonica | 0:26fa30c35f74 | 15 | #include "AsyncStepper.hpp" |
babylonica | 0:26fa30c35f74 | 16 | |
babylonica | 0:26fa30c35f74 | 17 | AsyncStepper::AsyncStepper( PinName enablePin, PinName stepPin, PinName dirPin, uint32_t rpm, stepMode_e stepMode, PinName ms1Pin, PinName ms2Pin, PinName ms3Pin, uint32_t oneRotationFullSteps, stopMode_e stopMode ) : stepMode( stepMode ), ms1Pin( ms1Pin ), ms2Pin( ms2Pin ), ms3Pin( ms3Pin ), oneRotationFullSteps( oneRotationFullSteps ), stopMode( stopMode ), halfPulseCount( 0 ), currentMaxStepCount( 0 ), stopPulseOut( true ) |
babylonica | 0:26fa30c35f74 | 18 | { |
babylonica | 0:26fa30c35f74 | 19 | ticker = new Ticker(); |
babylonica | 0:26fa30c35f74 | 20 | enableOut = new DigitalOut( enablePin ); |
babylonica | 0:26fa30c35f74 | 21 | stepOut = new DigitalOut( stepPin ); |
babylonica | 0:26fa30c35f74 | 22 | dirOut = new DigitalOut( dirPin ); |
babylonica | 0:26fa30c35f74 | 23 | if ( ms1Pin != NC && ms2Pin != NC && ms3Pin != NC ) { |
babylonica | 0:26fa30c35f74 | 24 | stepModeBus = new BusOut( ms1Pin, ms2Pin, ms3Pin ); |
babylonica | 0:26fa30c35f74 | 25 | stepModeBus->write( stepMode ); |
babylonica | 0:26fa30c35f74 | 26 | } |
babylonica | 0:26fa30c35f74 | 27 | enableOut->write( 1 ); |
babylonica | 0:26fa30c35f74 | 28 | stepOut->write( 0 ); |
babylonica | 0:26fa30c35f74 | 29 | dirOut->write( 0 ); |
babylonica | 0:26fa30c35f74 | 30 | |
babylonica | 0:26fa30c35f74 | 31 | oneRotationSteps = oneRotationFullSteps * ( stepMode + 1 ); |
babylonica | 0:26fa30c35f74 | 32 | pulseWidth_us = (uint64_t)( 30000000 / ( rpm * oneRotationSteps ) ); |
babylonica | 0:26fa30c35f74 | 33 | ticker->attach_us( callback(this, &AsyncStepper::ISR_PULSEOUT), pulseWidth_us ); |
babylonica | 0:26fa30c35f74 | 34 | } |
babylonica | 0:26fa30c35f74 | 35 | |
babylonica | 0:26fa30c35f74 | 36 | AsyncStepper::~AsyncStepper() |
babylonica | 0:26fa30c35f74 | 37 | { |
babylonica | 0:26fa30c35f74 | 38 | delete ticker; |
babylonica | 0:26fa30c35f74 | 39 | delete enableOut; |
babylonica | 0:26fa30c35f74 | 40 | delete stepOut; |
babylonica | 0:26fa30c35f74 | 41 | delete dirOut; |
babylonica | 0:26fa30c35f74 | 42 | if ( ms1Pin != NC && ms2Pin != NC && ms3Pin != NC ) { |
babylonica | 0:26fa30c35f74 | 43 | delete stepModeBus; |
babylonica | 0:26fa30c35f74 | 44 | } |
babylonica | 0:26fa30c35f74 | 45 | } |
babylonica | 0:26fa30c35f74 | 46 | |
babylonica | 0:26fa30c35f74 | 47 | void AsyncStepper::ISR_PULSEOUT( void ) |
babylonica | 0:26fa30c35f74 | 48 | { |
babylonica | 1:0f8209567b7d | 49 | DISABLE_INTERRUPTS; |
babylonica | 1:0f8209567b7d | 50 | |
babylonica | 0:26fa30c35f74 | 51 | if ( !stopPulseOut ) { |
babylonica | 0:26fa30c35f74 | 52 | stepOut->write( !stepOut->read() ); |
babylonica | 0:26fa30c35f74 | 53 | |
babylonica | 0:26fa30c35f74 | 54 | if ( ++halfPulseCount / 2 > currentMaxStepCount ) { |
babylonica | 0:26fa30c35f74 | 55 | if ( stopMode == FREE ) { |
babylonica | 0:26fa30c35f74 | 56 | AsyncStepper::Disable(); |
babylonica | 0:26fa30c35f74 | 57 | } |
babylonica | 0:26fa30c35f74 | 58 | halfPulseCount = 0; |
babylonica | 0:26fa30c35f74 | 59 | stopPulseOut = true; |
babylonica | 0:26fa30c35f74 | 60 | } |
babylonica | 0:26fa30c35f74 | 61 | } |
babylonica | 0:26fa30c35f74 | 62 | |
babylonica | 1:0f8209567b7d | 63 | RESTORE_INTERRUPTS; |
babylonica | 0:26fa30c35f74 | 64 | return; |
babylonica | 0:26fa30c35f74 | 65 | } |
babylonica | 0:26fa30c35f74 | 66 | |
babylonica | 0:26fa30c35f74 | 67 | void AsyncStepper::SetRPM( uint32_t rpm ) |
babylonica | 0:26fa30c35f74 | 68 | { |
babylonica | 1:0f8209567b7d | 69 | DISABLE_INTERRUPTS; |
babylonica | 1:0f8209567b7d | 70 | |
babylonica | 0:26fa30c35f74 | 71 | ticker->detach(); |
babylonica | 0:26fa30c35f74 | 72 | oneRotationSteps = oneRotationFullSteps * ( stepMode + 1 ); |
babylonica | 0:26fa30c35f74 | 73 | pulseWidth_us = (uint64_t)( 30000000 / ( rpm * oneRotationSteps ) ); |
babylonica | 0:26fa30c35f74 | 74 | ticker->attach_us( callback(this, &AsyncStepper::ISR_PULSEOUT), pulseWidth_us ); |
babylonica | 0:26fa30c35f74 | 75 | |
babylonica | 1:0f8209567b7d | 76 | RESTORE_INTERRUPTS; |
babylonica | 0:26fa30c35f74 | 77 | return; |
babylonica | 0:26fa30c35f74 | 78 | } |
babylonica | 0:26fa30c35f74 | 79 | |
babylonica | 0:26fa30c35f74 | 80 | void AsyncStepper::SetStepMode( stepMode_e stepMode ) |
babylonica | 0:26fa30c35f74 | 81 | { |
babylonica | 0:26fa30c35f74 | 82 | if ( ms1Pin != NC && ms2Pin != NC && ms3Pin != NC ) { |
babylonica | 0:26fa30c35f74 | 83 | stepModeBus->write( stepMode ); |
babylonica | 0:26fa30c35f74 | 84 | } |
babylonica | 0:26fa30c35f74 | 85 | |
babylonica | 0:26fa30c35f74 | 86 | return; |
babylonica | 0:26fa30c35f74 | 87 | } |
babylonica | 0:26fa30c35f74 | 88 | |
babylonica | 0:26fa30c35f74 | 89 | void AsyncStepper::Enable( void ) |
babylonica | 0:26fa30c35f74 | 90 | { |
babylonica | 0:26fa30c35f74 | 91 | enableOut->write( 0 ); |
babylonica | 0:26fa30c35f74 | 92 | |
babylonica | 0:26fa30c35f74 | 93 | return; |
babylonica | 0:26fa30c35f74 | 94 | } |
babylonica | 0:26fa30c35f74 | 95 | |
babylonica | 0:26fa30c35f74 | 96 | void AsyncStepper::Disable( void ) |
babylonica | 0:26fa30c35f74 | 97 | { |
babylonica | 0:26fa30c35f74 | 98 | enableOut->write( 1 ); |
babylonica | 0:26fa30c35f74 | 99 | |
babylonica | 0:26fa30c35f74 | 100 | return; |
babylonica | 0:26fa30c35f74 | 101 | } |
babylonica | 0:26fa30c35f74 | 102 | |
babylonica | 0:26fa30c35f74 | 103 | bool AsyncStepper::IsStopping( void ) |
babylonica | 0:26fa30c35f74 | 104 | { |
babylonica | 0:26fa30c35f74 | 105 | return stopPulseOut; |
babylonica | 0:26fa30c35f74 | 106 | } |
babylonica | 0:26fa30c35f74 | 107 | |
babylonica | 0:26fa30c35f74 | 108 | void AsyncStepper::Rotate( direction_e direction, uint32_t steps ) |
babylonica | 0:26fa30c35f74 | 109 | { |
babylonica | 1:0f8209567b7d | 110 | DISABLE_INTERRUPTS; |
babylonica | 1:0f8209567b7d | 111 | |
babylonica | 0:26fa30c35f74 | 112 | dirOut->write( direction ); |
babylonica | 0:26fa30c35f74 | 113 | |
babylonica | 0:26fa30c35f74 | 114 | AsyncStepper::Enable(); |
babylonica | 0:26fa30c35f74 | 115 | currentMaxStepCount = steps; |
babylonica | 0:26fa30c35f74 | 116 | stopPulseOut = false; |
babylonica | 0:26fa30c35f74 | 117 | |
babylonica | 1:0f8209567b7d | 118 | RESTORE_INTERRUPTS; |
babylonica | 0:26fa30c35f74 | 119 | return; |
babylonica | 0:26fa30c35f74 | 120 | } |