API for a STEPPERONLINE Nema 17 Bipolar Linear Stepper Motor. Provides speed, direction, and revolution control.

Dependencies:   mbed

lin_step_mtr.cpp

Committer:
mikermarza
Date:
2020-04-29
Revision:
11:2507965c1bec
Parent:
8:f1d869d9b8df

File content as of revision 11:2507965c1bec:

// Code for the lin_step_mtr driver

#include "lin_step_mtr.h"

//Construtors
LinStepMtr::LinStepMtr(PinName A_f, PinName A_r, PinName B_f, PinName B_r, int m_rpm=MAX_RPM)
        :mtr_ctrl(B_r, A_r, B_f,A_f), max_speed((m_rpm > MAX_RPM) ? floor((float)MAX_RPM * 10/3):floor((float)m_rpm * 10/3)),
        max_rpm(m_rpm)
{
    mtr_ctrl = 0x0;
    speed = floor((float)DEFAULT_RPM * 10 / 3);
    dir = CW;
    cur_step = ONE;
    
    min_rev_cnt = MIN_DOUBLE_VAL;
    max_rev_cnt = MAX_DOUBLE_VAL;
}

LinStepMtr::LinStepMtr(PinName A_f, PinName A_r, PinName B_f, PinName B_r)
    :mtr_ctrl(B_r,A_r,B_f,A_f), max_speed(floor((float)MAX_RPM * 10/3)), max_rpm(MAX_RPM)
{
    mtr_ctrl = 0x0;
    speed = floor((double)DEFAULT_RPM * 10 / 3);
    dir = CW;
    cur_step = ONE;
}

// Destructor
LinStepMtr::~LinStepMtr()
{
}

// Member Functions
float LinStepMtr::get_speed()
{
    return (float) speed * 3 / 10;
}

void LinStepMtr::set_speed(float rpm) {
    speed = floor((float)rpm * 10/3);
}

double LinStepMtr::get_rev()
{
    return rev_cnt;
}

void LinStepMtr::set_min_rev_cnt(double rc)
{
    if(rc < MIN_DOUBLE_VAL || rc > MAX_DOUBLE_VAL)
        min_rev_cnt = MIN_DOUBLE_VAL;
    else
        min_rev_cnt = rc;   
}

void LinStepMtr::set_max_rev_cnt(double rc)
{
    if(rc < MIN_DOUBLE_VAL || rc > MAX_DOUBLE_VAL)
        max_rev_cnt = MAX_DOUBLE_VAL;
    else
        max_rev_cnt = rc; 
}

double LinStepMtr::get_min_rev_cnt()
{
    return min_rev_cnt;
}

double LinStepMtr::get_max_rev_cnt()
{
    return max_rev_cnt;
}

void LinStepMtr::RESET_rev_cnts()
{
    max_rev_cnt = MAX_DOUBLE_VAL;
    min_rev_cnt = MIN_DOUBLE_VAL;
}

LinStepMtr::Direction LinStepMtr::get_dir()
{
    return dir;   
}

/* NOT SUPPORTED
LinStepMtr::set_dir(Direction d)
{
    if(dir !=d)
        dir = d;   
}
*/

// NOTE: uses wait() instead of Thread::wait() because depending on speed, can be
// waiting for under a millisecond, and Thread::wait() only supports ms
double LinStepMtr::rotate(Direction d, float rev=1)
{ 
    int steps = floor(200 * rev);
    float w = 1/(float)speed;
    switch(d){
        case CW:
            for (int i = 0; i < steps; ++i) {
                if(rev_cnt > max_rev_cnt -.005){
                    break;
                }
                    mtr_ctrl = ++cur_step;
                    rev_cnt += .005;
                    wait(w);
            }
            break;
        case CCW:
            for (int i = 0; i < steps; ++i) {
                if (rev_cnt < min_rev_cnt + .005){
                    break;
                }
                    mtr_ctrl = --cur_step;
                    rev_cnt -= .005;
                    wait(w);   
            }
            break;   
        
    }   
    mtr_ctrl = STOP;
    return rev_cnt;
}

/*
#define SPIN_INCR 83 // steps
#define SPIN_WAIT 10 // ms
void LinStepMtr::spin_up(float rpm) {
    int end_speed;
    
    if(rpm == -1) {
        end_speed = speed;
    } else {
        end_speed = (rpm > max_rpm) ? max_speed:floor(rpm * 10 / 3);
    }
    for(int i = min_speed; i < end_speed-SPIN_INCR; i+=SPIN_INCR){
        speed = i;
        Thread::wait(SPIN_WAIT);
    }
    speed = end_speed;
   
}

int LinStepMtr::spin_down(float rpm) {

    int end_speed;
    int s = speed;
    
    if(rpm == -1) {
        end_speed = min_speed;
    } else {
        end_speed = (rpm < min_rpm) ? min_speed:floor(rpm * 10 / 3);
    }
    
    for(int i = speed; i > end_speed+SPIN_INCR; i-=SPIN_INCR){
        speed = i;
        Thread::wait(SPIN_WAIT);
    }
    speed = end_speed;
    return s;


    return -1;
}
*/

// Private Class: Step Functions

LinStepMtr::Step_Num LinStepMtr::Step::get_cur_step()
{
        return cur_step;
}
        
LinStepMtr::Step_Num LinStepMtr::Step::operator++()
{    
    switch(cur_step){
        case ONE:
            cur_step=TWO;
            break;
        case TWO:
            cur_step = THREE;
            break;
        case THREE:
            cur_step = FOUR;
            break;
        case FOUR:
            cur_step = ONE; 
            break;      
    }
    return cur_step;
}

LinStepMtr::Step_Num LinStepMtr::Step::operator--()
{
    switch(cur_step){
        case ONE:
            cur_step=FOUR;
            break;
        case TWO:
            cur_step = ONE;
            break;
        case THREE:
            cur_step = TWO;
            break;
        case FOUR:
            cur_step = THREE; 
            break;      
    }
    return cur_step;
}

void LinStepMtr::Step::operator=(LinStepMtr::Step_Num s)
{
    cur_step = s;   
}