Drive a stepper motor using A4988 with asynchronous. No wait() function.

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?

UserRevisionLine numberNew 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 }