Stepper motor with 5 states. State machine is used for switching between states.

Dependencies:   mbed

Fork of NucleoF103-stepper_motor_with_button by Vasek Moravcik

main.cpp

Committer:
sh3ppard
Date:
2015-03-22
Revision:
0:a8de23e49ba2
Child:
1:d30c9dbba3f2

File content as of revision 0:a8de23e49ba2:

/**********************************************************************************
* @file    main.cpp
* @author  Vaclav Moravcik
* @version V0.1
* @date    22-March-2015
* @brief   Controling of stepper motor with state machine. Presing the button changes direction, speed or stops the motor.
***********************************************************************************/

/* Includes ----------------------------------------------------------------------*/
#include "mbed.h"

/* Defines -----------------------------------------------------------------------*/

/* Function prototypes -----------------------------------------------------------*/
void goForward();
void goBackward();
void accelerate();
void decelerate();
void stop();
void pressed();

/* Variables ---------------------------------------------------------------------*/
int direction = 0;
bool running = true;
int state = 1;
float stepFreq = 5;
int accelerationMode = 0;  //0 - no acceleration, 1 - accelerating, 2 - decelerating
int position = 1;

//mbed - initialization of peripherals
DigitalOut  my_led(LED1);
DigitalOut  out1(PB_10);
DigitalOut  out2(PB_4);
DigitalOut  out3(PB_5);
DigitalOut  out4(PB_3);
InterruptIn my_button(USER_BUTTON);

/* Functions----------------------------------------------------------------------*/

/*******************************************************************************
* Function Name  : goForward.
* Description    : Sets variables so the motor revolves forward.
* Input          : none.
* Output         : none.
* Return         : none.
*******************************************************************************/
void goForward() {
    accelerationMode = 0;
    running = true;
    direction = 0;  
}

/*******************************************************************************
* Function Name  : goBackward.
* Description    : Sets variables so the motor revolves backward.
* Input          : none.
* Output         : none.
* Return         : none.
*******************************************************************************/
void goBackward() {
    accelerationMode = 0;
    running = true;
    direction = 1;  
}

/*******************************************************************************
* Function Name  : stop.
* Description    : Stops the rotation of the motor.
* Input          : none.
* Output         : none.
* Return         : none.
*******************************************************************************/
void stop() {
    running = false;    
}  

/*******************************************************************************
* Function Name  : accelerate.
* Description    : Sets accelerationMode so the stepFrequency increases over time.
* Input          : none.
* Output         : none.
* Return         : none.
*******************************************************************************/
void accelerate() {
    accelerationMode = 1;
    running = true;
}

/*******************************************************************************
* Function Name  : decelerate.
* Description    : Sets accelerationMode so the stepFrequency decreases over time.
* Input          : none.
* Output         : none.
* Return         : none.
*******************************************************************************/
void decelerate() {
    accelerationMode = 2;
    running = true;
}

/*******************************************************************************
* Function Name  : pressed.
* Description    : When button is pushed the state is switched.
* Input          : none.
* Output         : none.
* Return         : none.
*******************************************************************************/ 
void pressed() {
    if(state < 5) { //Program goes through the states in circle
        state++;
    }
    else {
        state = 1;
    }
    switch(state){  //Depending on the state the appropriate action is done
        case 1 :    //Stopped
            goForward();
            break;
        case 2 :    //Running forward
            goBackward();
            break;
        case 3 :    //Running backward
            stop();
            break;
        case 4 :    //Accelerating
            accelerate();
            break;
        case 5 :    //Accelerating
            decelerate();
            break;
    }
}

/*******************************************************************************
* Function Name  : increment.
* Description    : Increments step position and when reaches limit, circles back to start value.
* Input          : position: current position of motor. direction: decides if function counts up or down.
*                : upperLimit: limit stated by resolution of stepping (for half-stepping its 8).
* Output         : position: new incremented position.
* Return         : 
*******************************************************************************/
int increment(int position ,int direction, int upperLimit) {
    if(direction == 0) {    //Counting up
        if(position > upperLimit - 1) {    //Check limits
            position = 1;     //If position is equal to upperLimit then come back to 1
        }
        else {
            position++;   
        }
    }
    else {                  //Counting down
        if(position < 2) {    //Check limits
            position = upperLimit;     //If position is equal to 1 then come back to upperLimit
        }
        else {
            position--;   
        }
    }
    return position;        
}

/*******************************************************************************
* Function Name  : halfStep.
* Description    : Depending on current position function activates corresponding outputs.
* Input          : position: current position of motor. 
* Output         : none.
* Return         : none.
*******************************************************************************/
void halfStep(int position) {  //Alternating between one powered coil and two adjacent powered coils.
     switch(position){
        case 1 :
            out1.write(1);
            out2.write(0);
            out3.write(0);
            out4.write(0);
            break;
        case 2 :
            out1.write(1);
            out2.write(1);
            out3.write(0);
            out4.write(0);
            break;
        case 3 :
            out1.write(0);
            out2.write(1);
            out3.write(0);
            out4.write(0);
            break;
        case 4 :
            out1.write(0);
            out2.write(1);
            out3.write(1);
            out4.write(0);
            break;
        case 5 :
            out1.write(0);
            out2.write(0);
            out3.write(1);
            out4.write(0);
            break;
        case 6 :
            out1.write(0);
            out2.write(0);
            out3.write(1);
            out4.write(1);
            break;
        case 7 :
            out1.write(0);
            out2.write(0);
            out3.write(0);
            out4.write(1);
            break;
        case 8 :
            out1.write(1);
            out2.write(0);
            out3.write(0);
            out4.write(1);
            break;       
    }   
}

/*******************************************************************************
* Function Name  : main.
* Description    : Main routine.
* Input          : None.
* Output         : None.
* Return         : None.
*******************************************************************************/
int main() {

    // Set button action
    my_button.fall(&pressed);   //On falling edge function pressed is called 
    
    while (1) {     //Infinite while loop
        if(running == true) {
            halfStep(position);
            position = increment(position , direction, 8);
            my_led = !my_led;
        }
        if(accelerationMode == 1 && stepFreq < 500) {
            wait(0.05); //For better control over acceleration
            stepFreq = stepFreq + 1;    //Increases stepFreq causing faster rotation of the motor
        }
        if(accelerationMode == 2 && stepFreq > 1) {
            wait(0.05); //For better control over deceleration
            stepFreq = stepFreq - 1;    //Decreases stepFreq causing slower rotation of the motor
        }
        wait(1/stepFreq); // 1/stepFreq ms wait    
    }
}