noka @willow-micro / AsyncStepper
Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers AsyncStepper.cpp Source File

AsyncStepper.cpp

Go to the documentation of this file.
00001 // -*- coding:utf-8-unix -*-
00002 /*!
00003   @file   AsyncStepper.cpp
00004   
00005   @brief  Drive a stepper motor using A4988 with asynchronous.
00006   
00007   @author   T.Kawamura
00008   @version  1.0
00009   @date     2018-07-12  T.Kawamura  Written for C++/mbed.
00010   @see
00011   Copyright (C) 2018 Takuma Kawamura.
00012   Released under the MIT license.
00013   http://opensource.org/licenses/mit-license.php
00014 */
00015 #include "AsyncStepper.hpp"
00016 
00017 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 )
00018 {
00019   ticker = new Ticker();
00020   enableOut = new DigitalOut( enablePin );
00021   stepOut = new DigitalOut( stepPin );
00022   dirOut = new DigitalOut( dirPin );
00023   if ( ms1Pin != NC && ms2Pin != NC && ms3Pin != NC ) {
00024     stepModeBus = new BusOut( ms1Pin, ms2Pin, ms3Pin );
00025     stepModeBus->write( stepMode );
00026   }
00027   enableOut->write( 1 );
00028   stepOut->write( 0 );
00029   dirOut->write( 0 );
00030   
00031   oneRotationSteps = oneRotationFullSteps * ( stepMode + 1 );
00032   pulseWidth_us = (uint64_t)( 30000000 / ( rpm * oneRotationSteps ) );
00033   ticker->attach_us( callback(this, &AsyncStepper::ISR_PULSEOUT), pulseWidth_us );
00034 }
00035 
00036 AsyncStepper::~AsyncStepper()
00037 {
00038   delete ticker;
00039   delete enableOut;
00040   delete stepOut;
00041   delete dirOut;
00042   if ( ms1Pin != NC && ms2Pin != NC && ms3Pin != NC ) {
00043     delete stepModeBus;
00044   }
00045 }
00046 
00047 void AsyncStepper::ISR_PULSEOUT( void )
00048 {
00049   DISABLE_INTERRUPTS;
00050   
00051   if ( !stopPulseOut ) {
00052     stepOut->write( !stepOut->read() );
00053 
00054     if ( ++halfPulseCount / 2 > currentMaxStepCount ) {
00055       if ( stopMode == FREE ) {
00056         AsyncStepper::Disable();
00057       }
00058       halfPulseCount = 0;
00059       stopPulseOut = true;
00060     }
00061   }
00062   
00063   RESTORE_INTERRUPTS;
00064   return;
00065 }
00066 
00067 void AsyncStepper::SetRPM( uint32_t rpm )
00068 {
00069   DISABLE_INTERRUPTS;
00070   
00071   ticker->detach();
00072   oneRotationSteps = oneRotationFullSteps * ( stepMode + 1 );
00073   pulseWidth_us = (uint64_t)( 30000000 / ( rpm * oneRotationSteps ) );
00074   ticker->attach_us( callback(this, &AsyncStepper::ISR_PULSEOUT), pulseWidth_us );
00075   
00076   RESTORE_INTERRUPTS;
00077   return;
00078 }
00079 
00080 void AsyncStepper::SetStepMode( stepMode_e stepMode )
00081 {
00082   if ( ms1Pin != NC && ms2Pin != NC && ms3Pin != NC ) {
00083     stepModeBus->write( stepMode );
00084   }
00085   
00086   return;
00087 }
00088 
00089 void AsyncStepper::Enable( void )
00090 {
00091   enableOut->write( 0 );
00092   
00093   return;
00094 }
00095 
00096 void AsyncStepper::Disable( void )
00097 {
00098   enableOut->write( 1 );
00099   
00100   return;
00101 }
00102 
00103 bool AsyncStepper::IsStopping( void )
00104 {
00105   return stopPulseOut;
00106 }
00107 
00108 void AsyncStepper::Rotate( direction_e direction, uint32_t steps )
00109 {
00110   DISABLE_INTERRUPTS;
00111   
00112   dirOut->write( direction );
00113   
00114   AsyncStepper::Enable();
00115   currentMaxStepCount = steps;
00116   stopPulseOut = false;
00117   
00118   RESTORE_INTERRUPTS;
00119   return;
00120 }