Drive a stepper motor using A4988 with asynchronous. No wait() function.
Diff: AsyncStepper.cpp
- Revision:
- 0:26fa30c35f74
- Child:
- 1:0f8209567b7d
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/AsyncStepper.cpp Thu Jul 12 01:27:04 2018 +0000 @@ -0,0 +1,111 @@ +// -*- coding:utf-8-unix -*- +/*! + @file AsyncStepper.cpp + + @brief Drive a stepper motor using A4988 with asynchronous. + + @author T.Kawamura + @version 1.0 + @date 2018-07-12 T.Kawamura Written for C++/mbed. + @see + Copyright (C) 2018 Takuma Kawamura. + Released under the MIT license. + http://opensource.org/licenses/mit-license.php +*/ +#include "AsyncStepper.hpp" + +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 ) +{ + ticker = new Ticker(); + enableOut = new DigitalOut( enablePin ); + stepOut = new DigitalOut( stepPin ); + dirOut = new DigitalOut( dirPin ); + if ( ms1Pin != NC && ms2Pin != NC && ms3Pin != NC ) { + stepModeBus = new BusOut( ms1Pin, ms2Pin, ms3Pin ); + stepModeBus->write( stepMode ); + } + enableOut->write( 1 ); + stepOut->write( 0 ); + dirOut->write( 0 ); + + oneRotationSteps = oneRotationFullSteps * ( stepMode + 1 ); + pulseWidth_us = (uint64_t)( 30000000 / ( rpm * oneRotationSteps ) ); + ticker->attach_us( callback(this, &AsyncStepper::ISR_PULSEOUT), pulseWidth_us ); +} + +AsyncStepper::~AsyncStepper() +{ + delete ticker; + delete enableOut; + delete stepOut; + delete dirOut; + if ( ms1Pin != NC && ms2Pin != NC && ms3Pin != NC ) { + delete stepModeBus; + } +} + +void AsyncStepper::ISR_PULSEOUT( void ) +{ + if ( !stopPulseOut ) { + stepOut->write( !stepOut->read() ); + + if ( ++halfPulseCount / 2 > currentMaxStepCount ) { + if ( stopMode == FREE ) { + AsyncStepper::Disable(); + } + halfPulseCount = 0; + stopPulseOut = true; + } + } + + return; +} + +void AsyncStepper::SetRPM( uint32_t rpm ) +{ + ticker->detach(); + oneRotationSteps = oneRotationFullSteps * ( stepMode + 1 ); + pulseWidth_us = (uint64_t)( 30000000 / ( rpm * oneRotationSteps ) ); + ticker->attach_us( callback(this, &AsyncStepper::ISR_PULSEOUT), pulseWidth_us ); + + return; +} + +void AsyncStepper::SetStepMode( stepMode_e stepMode ) +{ + if ( ms1Pin != NC && ms2Pin != NC && ms3Pin != NC ) { + stepModeBus->write( stepMode ); + } + + return; +} + +void AsyncStepper::Enable( void ) +{ + enableOut->write( 0 ); + + return; +} + +void AsyncStepper::Disable( void ) +{ + enableOut->write( 1 ); + + return; +} + +bool AsyncStepper::IsStopping( void ) +{ + return stopPulseOut; +} + +void AsyncStepper::Rotate( direction_e direction, uint32_t steps ) +{ + dirOut->write( direction ); + + AsyncStepper::Enable(); + currentMaxStepCount = steps; + stopPulseOut = false; + + return; +}