Drive a stepper motor using A4988 with asynchronous. No wait() function.
AsyncStepper.cpp
- Committer:
- babylonica
- Date:
- 2018-07-28
- Revision:
- 1:0f8209567b7d
- Parent:
- 0:26fa30c35f74
File content as of revision 1:0f8209567b7d:
// -*- 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 ) { DISABLE_INTERRUPTS; if ( !stopPulseOut ) { stepOut->write( !stepOut->read() ); if ( ++halfPulseCount / 2 > currentMaxStepCount ) { if ( stopMode == FREE ) { AsyncStepper::Disable(); } halfPulseCount = 0; stopPulseOut = true; } } RESTORE_INTERRUPTS; return; } void AsyncStepper::SetRPM( uint32_t rpm ) { DISABLE_INTERRUPTS; ticker->detach(); oneRotationSteps = oneRotationFullSteps * ( stepMode + 1 ); pulseWidth_us = (uint64_t)( 30000000 / ( rpm * oneRotationSteps ) ); ticker->attach_us( callback(this, &AsyncStepper::ISR_PULSEOUT), pulseWidth_us ); RESTORE_INTERRUPTS; 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 ) { DISABLE_INTERRUPTS; dirOut->write( direction ); AsyncStepper::Enable(); currentMaxStepCount = steps; stopPulseOut = false; RESTORE_INTERRUPTS; return; }