Control Stepper Motor using Matlab via Serial port

Dependencies:   BufferedSerial X_NUCLEO_IHM01A1 mbed

main.cpp

Committer:
Arkadi
Date:
2016-01-26
Revision:
1:fd0fbabd0c8f
Parent:
0:ad32f7e53ed6

File content as of revision 1:fd0fbabd0c8f:

////////////////////////////////////////
// Control Stepper motor using matlab //
// Arkadiraf@gmail.com - 24/1/2016    //
////////////////////////////////////////
/*
   Parts:
    Nucleo STM32F401RE
    X-Nucleo-IHM01A1 Stepper Driver shield     
    
*/

// Libraries:
#include "mbed.h"
#include "BufferedSerial.h"  // solves issues of loosing data. alternative doing it yourself
#include "l6474_class.h" // stepper library

/////////////
// Objects //
////////////

// create serial object
//Serial pc(SERIAL_TX, SERIAL_RX);
BufferedSerial pc(USBTX, USBRX);

// Pinouts:
DigitalOut myled(LED1);

// Stepper Pins
DigitalOut StepDir(D7);
DigitalOut StepPWM(D9);

// Define Stepper Ticker
Ticker StepperTicker;

// Define Ticker
Ticker SensorSampleTicker;

// define millis ticker
volatile uint32_t MillisValue = 0;
Ticker MillisTicket;

///////////////
// variables //
///////////////
char BufferCMD[64]={0};
uint16_t BufferIndex=0;
volatile bool Sensor_Sample_Flag=0;
#define Sample_Interval 5000 // interval in us, (5ms, 200Hz)
float CMDValue=0; // CMD at which speed to run
char inbyte=' ';

// Stepper Variables:
#define STEPS2ROTATION 3200.0f // 200 steps rotation 16 microsteps
/* Initialization parameters. */
// not sure if it acctually uses it
L6474_InitTypeDef init =
{
    50,                              /* Acceleration rate in step/s2. Range: (0..+inf). */
    50,                              /* Deceleration rate in step/s2. Range: (0..+inf). */
    3500,                             /* Maximum speed in step/s. Range: (30..10000]. */
    30,                              /* Minimum speed in step/s. Range: [30..10000). */
    500,                              /* Torque regulation current in mA. Range: 31.25mA to 4000mA. */
    L6474_OCD_TH_1500mA,              /* Overcurrent threshold (OCD_TH register). */
    L6474_CONFIG_OC_SD_ENABLE,        /* Overcurrent shutwdown (OC_SD field of CONFIG register). */
    L6474_CONFIG_EN_TQREG_TVAL_USED,  /* Torque regulation method (EN_TQREG field of CONFIG register). */
    L6474_STEP_SEL_1_16,              /* Step selection (STEP_SEL field of STEP_MODE register). */
    L6474_SYNC_SEL_1_2,               /* Sync selection (SYNC_SEL field of STEP_MODE register). */
    L6474_FAST_STEP_12us,             /* Fall time value (T_FAST field of T_FAST register). Range: 2us to 32us. */
    L6474_TOFF_FAST_8us,              /* Maximum fast decay time (T_OFF field of T_FAST register). Range: 2us to 32us. */
    3,                                /* Minimum ON time in us (TON_MIN register). Range: 0.5us to 64us. */
    21,                               /* Minimum OFF time in us (TOFF_MIN register). Range: 0.5us to 64us. */
    L6474_CONFIG_TOFF_044us,          /* Target Swicthing Period (field TOFF of CONFIG register). */
    L6474_CONFIG_SR_320V_us,          /* Slew rate (POW_SR field of CONFIG register). */
    L6474_CONFIG_INT_16MHZ,           /* Clock setting (OSC_CLK_SEL field of CONFIG register). */
    L6474_ALARM_EN_OVERCURRENT |
    L6474_ALARM_EN_THERMAL_SHUTDOWN |
    L6474_ALARM_EN_THERMAL_WARNING |
    L6474_ALARM_EN_UNDERVOLTAGE |
    L6474_ALARM_EN_SW_TURN_ON |
    L6474_ALARM_EN_WRONG_NPERF_CMD    /* Alarm (ALARM_EN register). */
};


/* Motor Control Component. */
L6474 *StepperMotor;

// variable to store stepper position
volatile int32_t StepperPos=0;


////////////////
// Functions: //
////////////////
// Ticker function for stepper speed control, not very eficient.
void Stepper_PWM() {
    StepPWM=!StepPWM;
    if (StepPWM==1){ //If change to high, step performed Update Stepper Position
     if (StepDir==1){ 
         StepperPos++;
     }else{
        StepperPos--;
     }
    }
}

// Ticker function
void Sensor_Sample() {
    Sensor_Sample_Flag=1;
}

// millis ticker // its roughly gets the job done, so hell why not... (Better solution is to use SysTick)
void MillisCounter ()
{
    MillisValue++;
}

// Main Code:
int main() {
    // Setup:
    pc.baud(921600); 
    
    //Attach ticker object:   
    SensorSampleTicker.attach_us(&Sensor_Sample, Sample_Interval); // create Sample Ticker
    
    // Attach millis ticker:
    MillisTicket.attach_us(&MillisCounter, 1000); // create 1Khz Ticker (1ms increment) 
    
    // Initialize Stepper:
        /* Initializing SPI bus. */
    DevSPI dev_spi(D11, D12, D13);

    /* Initializing Motor Control Component. */
    //StepperMotor = new L6474(D2, D8, D7, D9, D10, dev_spi);
    StepperMotor = new L6474(D2, D8, D3, D4, D10, dev_spi); // initialization with different Step pin and Dir Pin, Interference with external control
    if (StepperMotor->Init() != COMPONENT_OK)
        exit(EXIT_FAILURE);
    
    /*----- Changing motor setting. -----*/
    
    /* Setting High Impedance State to update L6474's registers. */
    StepperMotor->SoftHiZ();
    // Disabling motor
    StepperMotor->Disable();
    /* Changing step mode. */
    StepperMotor->SetStepMode(STEP_MODE_1_16);
    /* Increasing the torque regulation current to 500mA. */
    StepperMotor->SetParameter(L6474_TVAL, 500);
    
    // Enabling motor
    StepperMotor->Enable();
    
    /* Waiting 1 second. */
    wait_ms(1000);
    
    ////////////
    // Loop : //
    ////////////
    while(1){ 
    
        // receive Motor Command
        while (pc.readable()) {
            inbyte=pc.getc();
            //pc.printf("%c" ,inbyte); // debug check/
            BufferCMD[BufferIndex]=inbyte;
            BufferIndex++;
            // parse incoming message format: "$<value>\r\n"    
            if (inbyte=='$'){ // start of message
                BufferIndex=0; // initialize to start of parser   
            }else if(inbyte=='\r'){ // end of message
               CMDValue=atof(BufferCMD);
               BufferIndex=0;   
               //pc.printf("CMD: %f \r\n" ,CMDValue); // debug check/ 
               //pc.printf("CMD: %s \r\n" ,BufferCMD); // debug check/
               
               /* Update Stepper Commad */
               if (CMDValue>0){
                    StepDir=1;
                }else{
                    StepDir=0;
                    CMDValue=-CMDValue;
                }
               if (CMDValue<1.0f){ // Stops
                  StepperTicker.detach(); 
               }else{
                   StepperTicker.attach(&Stepper_PWM,0.5f/CMDValue); // Set Stepper Freq, 2.0f/Freq : 2 calls to ticker object performs a step
               }
     
            }//end parser  
        }//end serial
        
        if(Sensor_Sample_Flag){ // sample data and stream out.
            Sensor_Sample_Flag=0;
            /* Stream Data */
            pc.printf("VAL:%d,%d\r\n" ,MillisValue,StepperPos); // Stream data
        }// End sampling and stream data
    }// end loop
}// end main