Test application for the STMicroelectronics X-NUCLEO-IHM01A1 Stepper Motor Control Expansion Board.

Dependencies:   X_NUCLEO_IHM01A1

Fork of MotorControl_IHM01A1 by ST

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers main.cpp Source File

main.cpp

Go to the documentation of this file.
00001 /**
00002  ******************************************************************************
00003  * @file    main.cpp
00004  * @author  Davide Aliprandi, STMicrolectronics
00005  * @version V1.0.0
00006  * @date    October 14th, 2015
00007  * @brief   mbed test application for the STMicroelectronics X-NUCLEO-IHM01A1
00008  *          Motor Control Expansion Board: control of 1 motor showing the usage
00009  *          of all the related APIs.
00010  ******************************************************************************
00011  * @attention
00012  *
00013  * <h2><center>&copy; COPYRIGHT(c) 2015 STMicroelectronics</center></h2>
00014  *
00015  * Redistribution and use in source and binary forms, with or without modification,
00016  * are permitted provided that the following conditions are met:
00017  *   1. Redistributions of source code must retain the above copyright notice,
00018  *      this list of conditions and the following disclaimer.
00019  *   2. Redistributions in binary form must reproduce the above copyright notice,
00020  *      this list of conditions and the following disclaimer in the documentation
00021  *      and/or other materials provided with the distribution.
00022  *   3. Neither the name of STMicroelectronics nor the names of its contributors
00023  *      may be used to endorse or promote products derived from this software
00024  *      without specific prior written permission.
00025  *
00026  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
00027  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00028  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
00029  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
00030  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00031  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
00032  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
00033  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
00034  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
00035  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00036  *
00037  ******************************************************************************
00038  */
00039 
00040 
00041 /* Includes ------------------------------------------------------------------*/
00042 
00043 /* mbed specific header files. */
00044 #include "mbed.h"
00045 
00046 /* Helper header files. */
00047 #include "DevSPI.h"
00048 
00049 /* Component specific header files. */
00050 #include "L6474.h"
00051 
00052 
00053 /* Variables -----------------------------------------------------------------*/
00054 
00055 /* Initialization parameters. */
00056 L6474_init_t init = {
00057     160,                              /* Acceleration rate in pps^2. Range: (0..+inf). */
00058     160,                              /* Deceleration rate in pps^2. Range: (0..+inf). */
00059     1600,                             /* Maximum speed in pps. Range: (30..10000]. */
00060     800,                              /* Minimum speed in pps. Range: [30..10000). */
00061     250,                              /* Torque regulation current in mA. Range: 31.25mA to 4000mA. */
00062     L6474_OCD_TH_750mA,               /* Overcurrent threshold (OCD_TH register). */
00063     L6474_CONFIG_OC_SD_ENABLE,        /* Overcurrent shutwdown (OC_SD field of CONFIG register). */
00064     L6474_CONFIG_EN_TQREG_TVAL_USED,  /* Torque regulation method (EN_TQREG field of CONFIG register). */
00065     L6474_STEP_SEL_1_16,              /* Step selection (STEP_SEL field of STEP_MODE register). */
00066     L6474_SYNC_SEL_1_2,               /* Sync selection (SYNC_SEL field of STEP_MODE register). */
00067     L6474_FAST_STEP_12us,             /* Fall time value (T_FAST field of T_FAST register). Range: 2us to 32us. */
00068     L6474_TOFF_FAST_8us,              /* Maximum fast decay time (T_OFF field of T_FAST register). Range: 2us to 32us. */
00069     3,                                /* Minimum ON time in us (TON_MIN register). Range: 0.5us to 64us. */
00070     21,                               /* Minimum OFF time in us (TOFF_MIN register). Range: 0.5us to 64us. */
00071     L6474_CONFIG_TOFF_044us,          /* Target Swicthing Period (field TOFF of CONFIG register). */
00072     L6474_CONFIG_SR_320V_us,          /* Slew rate (POW_SR field of CONFIG register). */
00073     L6474_CONFIG_INT_16MHZ,           /* Clock setting (OSC_CLK_SEL field of CONFIG register). */
00074     L6474_ALARM_EN_OVERCURRENT |
00075     L6474_ALARM_EN_THERMAL_SHUTDOWN |
00076     L6474_ALARM_EN_THERMAL_WARNING |
00077     L6474_ALARM_EN_UNDERVOLTAGE |
00078     L6474_ALARM_EN_SW_TURN_ON |
00079     L6474_ALARM_EN_WRONG_NPERF_CMD    /* Alarm (ALARM_EN register). */
00080 };
00081 
00082 /* Motor Control Component. */
00083 L6474 *motor;
00084 
00085 
00086 /* Functions -----------------------------------------------------------------*/
00087 
00088 /**
00089   * @brief  This is an example of user handler for the flag interrupt.
00090   *         Empty parts can be implemented by the user upon needs.
00091   * @param  None.
00092   * @retval None.
00093   * @note   If needed, implement it, and then attach and enable it:
00094   *           + motor->AttachFlagIRQ(&FlagIRQHandler);
00095   *           + motor->EnableFlagIRQ();
00096   *         To disable it:
00097   *           + motor->DisbleFlagIRQ();
00098   */
00099 void FlagIRQHandler(void)
00100 {
00101     /* Set ISR flag. */
00102     motor->isr_flag = TRUE;
00103 
00104     /* Get the value of the status register. */
00105     unsigned int status = motor->get_status();
00106     
00107     /* Check HIZ flag: if set, power brigdes are disabled. */
00108     if ((status & L6474_STATUS_HIZ) == L6474_STATUS_HIZ)
00109     { /* HIZ state. Action to be customized. */ }
00110     
00111     /* Check direction. */
00112     if ((status & L6474_STATUS_DIR) == L6474_STATUS_DIR)
00113     { /* Forward direction is set. Action to be customized. */ }
00114     else
00115     { /* Backward direction is set. Action to be customized. */ }
00116     
00117     /* Check NOTPERF_CMD flag: if set, the command received by SPI can't be performed. */
00118     /* This often occures when a command is sent to the L6474 while it is not in HiZ state. */
00119     if ((status & L6474_STATUS_NOTPERF_CMD) == L6474_STATUS_NOTPERF_CMD)
00120     { /* Command received by SPI can't be performed. Action to be customized. */ }
00121      
00122     /* Check WRONG_CMD flag: if set, the command does not exist. */
00123     if ((status & L6474_STATUS_WRONG_CMD) == L6474_STATUS_WRONG_CMD)
00124     { /* The command received by SPI does not exist. Action to be customized. */ }
00125     
00126     /* Check UVLO flag: if not set, there is an undervoltage lock-out. */
00127     if ((status & L6474_STATUS_UVLO) == 0)
00128     { /* Undervoltage lock-out. Action to be customized. */ }
00129     
00130     /* Check TH_WRN flag: if not set, the thermal warning threshold is reached. */
00131     if ((status & L6474_STATUS_TH_WRN) == 0)
00132     { /* Thermal warning threshold is reached. Action to be customized. */ }
00133     
00134     /* Check TH_SHD flag: if not set, the thermal shut down threshold is reached. */
00135     if ((status & L6474_STATUS_TH_SD) == 0)
00136     { /* Thermal shut down threshold is reached. Action to be customized. */ }
00137     
00138     /* Check OCD  flag: if not set, there is an overcurrent detection. */
00139     if ((status & L6474_STATUS_OCD) == 0)
00140     { /* Overcurrent detection. Action to be customized. */ }
00141 
00142     /* Reset ISR flag. */
00143     motor->isr_flag = FALSE;
00144 }
00145 
00146 /**
00147   * @brief  This is an example of user handler for the errors.
00148   * @param  error error-code.
00149   * @retval None
00150   * @note   If needed, implement it, and then attach it:
00151   *           + motor->AttachErrorHandler(&ErrorHandler);
00152   */
00153 void ErrorHandler(uint16_t error)
00154 {
00155     /* Printing to the console. */
00156     printf("Error: %d.\r\n", error);
00157     
00158     /* Aborting the program. */
00159     exit(EXIT_FAILURE);
00160 }
00161 
00162 
00163 /* Main ----------------------------------------------------------------------*/
00164 
00165 int main()
00166 {
00167     /*----- Initialization. -----*/
00168 
00169     /* Initializing SPI bus. */
00170     DevSPI dev_spi(D11, D12, D13);
00171 
00172     /* Initializing Motor Control Component. */
00173     motor = new L6474(D2, D8, D7, D9, D10, dev_spi);
00174     if (motor->init(&init) != COMPONENT_OK) {
00175         exit(EXIT_FAILURE);
00176     }
00177 
00178     /* Attaching and enabling the user handler for the flag interrupt. */
00179     motor->attach_flag_irq(&FlagIRQHandler);
00180     motor->enable_flag_irq();
00181 
00182     /* Printing to the console. */
00183     printf("Motor Control Application Example for 1 Motor\r\n\n");
00184 
00185 
00186     /*----- Moving forward 16000 steps. -----*/
00187 
00188     /* Printing to the console. */
00189     printf("--> Moving forward 16000 steps.\r\n");
00190 
00191     /* Moving 16000 steps in the forward direction. */
00192     motor->move(StepperMotor::FWD, 16000);
00193     
00194     /* Waiting while the motor is active. */
00195     motor->wait_while_active();
00196 
00197     /* Waiting 2 seconds. */
00198     wait_ms(2000);
00199 
00200     
00201     /*----- Moving backward 16000 steps. -----*/
00202     
00203     /* Printing to the console. */
00204     printf("--> Moving backward 16000 steps.\r\n");
00205     
00206     /* Moving 16000 steps in the backward direction. */
00207     motor->move(StepperMotor::BWD, 16000);
00208 
00209     /* Waiting while the motor is active. */
00210     motor->wait_while_active();
00211 
00212     /* Printing to the console. */
00213     printf("--> Setting Home.\r\n");
00214 
00215     /* Setting the current position to be the home position. */
00216     motor->set_home();
00217 
00218     /* Waiting 2 seconds. */
00219     wait_ms(2000);
00220 
00221 
00222     /*----- Going to a specified position. -----*/
00223 
00224     /* Printing to the console. */
00225     printf("--> Going to position -6400.\r\n");
00226     
00227     /* Requesting to go to a specified position. */
00228     motor->go_to(-6400);
00229     
00230     /* Waiting while the motor is active. */
00231     motor->wait_while_active();
00232 
00233     /* Getting current position. */
00234     int position = motor->get_position();
00235     
00236     /* Printing to the console. */
00237     printf("    Position: %d.\r\n", position);
00238     
00239     /* Printing to the console. */
00240     printf("--> Setting a mark.\r\n");
00241 
00242     /* Setting the current position to be the mark position. */
00243     motor->set_mark();
00244 
00245     /* Waiting 2 seconds. */
00246     wait_ms(2000);
00247 
00248     
00249     /*----- Going Home. -----*/
00250 
00251     /* Printing to the console. */
00252     printf("--> Going Home.\r\n");
00253     
00254     /* Requesting to go to home */
00255     motor->go_home();  
00256     
00257     /* Waiting while the motor is active. */
00258     motor->wait_while_active();
00259 
00260     /* Getting current position. */
00261     position = motor->get_position();
00262 
00263     /* Printing to the console. */
00264     printf("    Position: %d.\r\n", position);
00265 
00266     /* Waiting 2 seconds. */
00267     wait_ms(2000);
00268 
00269 
00270     /*----- Going to a specified position. -----*/
00271 
00272     /* Printing to the console. */
00273     printf("--> Going to position 6400.\r\n");
00274     
00275     /* Requesting to go to a specified position. */
00276     motor->go_to(6400);
00277     
00278     /* Waiting while the motor is active. */
00279     motor->wait_while_active();
00280 
00281     /* Getting current position. */
00282     position = motor->get_position();
00283 
00284     /* Printing to the console. */
00285     printf("    Position: %d.\r\n", position);
00286 
00287     /* Waiting 2 seconds. */
00288     wait_ms(2000);
00289 
00290 
00291     /*----- Going to mark which was set previously after going to -6400. -----*/
00292 
00293     /* Printing to the console. */
00294     printf("--> Going to the mark set previously.\r\n");
00295     
00296     /* Requesting to go to mark position. */
00297     motor->go_mark();  
00298     
00299     /* Waiting while the motor is active. */
00300     motor->wait_while_active();
00301 
00302     /* Getting current position. */
00303     position = motor->get_position();
00304 
00305     /* Printing to the console. */
00306     printf("    Position: %d.\r\n", position);
00307 
00308     /* Waiting 2 seconds. */
00309     wait_ms(2000);
00310 
00311 
00312     /*----- Running backward. -----*/
00313 
00314     /* Printing to the console. */
00315     printf("--> Running backward.\r\n");
00316 
00317     /* Requesting to run backward. */
00318     motor->run(StepperMotor::BWD);
00319 
00320     /* Waiting until delay has expired. */
00321     wait_ms(5000);
00322 
00323     /* Getting current speed. */
00324     int speed = motor->get_speed();
00325 
00326     /* Printing to the console. */
00327     printf("    Speed: %d.\r\n", speed);
00328 
00329 
00330     /*----- Increasing the speed while running. -----*/
00331 
00332     /* Printing to the console. */
00333     printf("--> Increasing the speed while running.\r\n");
00334 
00335     /* Increasing the speed. */
00336     motor->set_max_speed(2400);
00337 
00338     /* Waiting until delay has expired. */
00339     wait_ms(5000);
00340 
00341     /* Getting current speed. */
00342     speed = motor->get_speed();
00343 
00344     /* Printing to the console. */
00345     printf("    Speed: %d.\r\n", speed);
00346 
00347 
00348     /*----- Decreasing the speed while running. -----*/
00349 
00350     /* Printing to the console. */
00351     printf("--> Decreasing the speed while running.\r\n");
00352 
00353     /* Decreasing the speed. */
00354     motor->set_max_speed(1200);
00355 
00356     /* Waiting until delay has expired. */
00357     wait_ms(5000);
00358 
00359     /* Getting current speed. */
00360     speed = motor->get_speed();
00361 
00362     /* Printing to the console. */
00363     printf("    Speed: %d.\r\n", speed);
00364 
00365 
00366     /*----- Increasing acceleration while running. -----*/
00367 
00368     /* Printing to the console. */
00369     printf("--> Increasing acceleration while running.\r\n");
00370 
00371     /* Increasing the acceleration. */
00372     motor->set_acceleration(480);
00373 
00374     /* Waiting until delay has expired. */
00375     wait_ms(5000);
00376 
00377     /* Increasing the speed. */
00378     motor->set_max_speed(2400);
00379 
00380     /* Waiting until delay has expired. */
00381     wait_ms(5000);
00382 
00383     /* Getting current speed. */
00384     speed = motor->get_speed();
00385 
00386     /* Printing to the console. */
00387     printf("    Speed: %d.\r\n", speed);
00388 
00389 
00390     /*----- Increasing deceleration while running. -----*/
00391 
00392     /* Printing to the console. */
00393     printf("--> Increasing deceleration while running.\r\n");
00394 
00395     /* Increasing the deceleration. */
00396     motor->set_deceleration(480);
00397 
00398     /* Waiting until delay has expired. */
00399     wait_ms(5000);
00400 
00401     /* Decreasing the speed. */
00402     motor->set_max_speed(1200);
00403 
00404     /* Waiting until delay has expired. */
00405     wait_ms(5000);
00406 
00407     /* Getting current speed. */
00408     speed = motor->get_speed();
00409 
00410     /* Printing to the console. */
00411     printf("    Speed: %d.\r\n", speed);
00412 
00413 
00414     /*----- Requesting soft-stop while running. -----*/
00415 
00416     /* Printing to the console. */
00417     printf("--> Requesting soft-stop while running.\r\n");
00418 
00419     /* Requesting soft stop. */
00420     motor->soft_stop();
00421 
00422     /* Waiting while the motor is active. */
00423     motor->wait_while_active();
00424 
00425     /* Waiting 2 seconds. */
00426     wait_ms(2000);
00427 
00428 
00429     /*----- Requesting hard-stop while running. -----*/
00430 
00431     /* Printing to the console. */
00432     printf("--> Running forward.\r\n");
00433     
00434     /* Requesting to run in forward direction. */
00435     motor->run(StepperMotor::FWD);
00436 
00437     /* Waiting until delay has expired. */
00438     wait_ms(5000);
00439 
00440     /* Printing to the console. */
00441     printf("--> Requesting hard-stop while running.\r\n");
00442 
00443     /* Requesting to immediatly stop. */
00444     motor->hard_stop();
00445 
00446     /* Waiting while the motor is active. */
00447     motor->wait_while_active();
00448 
00449     /* Waiting 2 seconds. */
00450     wait_ms(2000);
00451 
00452 
00453     /*----- GOTO stopped by soft-stop. -----*/
00454 
00455     /* Printing to the console. */
00456     printf("--> Going to position 20000.\r\n");
00457     
00458     /* Requesting to go to a specified position. */
00459     motor->go_to(20000);  
00460     
00461     /* Waiting while the motor is active. */
00462     wait_ms(5000);
00463 
00464     /* Printing to the console. */
00465     printf("--> Requiring soft-stop while running.\r\n");
00466 
00467     /* Requesting to perform a soft stop */
00468     motor->soft_stop();
00469 
00470     /* Waiting while the motor is active. */
00471     motor->wait_while_active();
00472 
00473     /* Waiting 2 seconds. */
00474     wait_ms(2000);
00475 
00476 
00477     /*----- Reading inexistent register to test "MyFlagInterruptHandler". -----*/
00478 
00479     /* Printing to the console. */
00480     printf("--> Reading inexistent register to test \"MyFlagInterruptHandler\".\r\n");
00481 
00482     /*
00483      * Trying to read an inexistent register.
00484      * The flag interrupt should be raised and the "MyFlagInterruptHandler"
00485      * function called.
00486      */
00487     motor->get_parameter(0x1F);
00488 
00489     /* Waiting 0.5 seconds. */
00490     wait_ms(500);
00491 
00492 
00493     /*----- Changing step mode to full step mode. -----*/
00494 
00495     /* Printing to the console. */
00496     printf("--> Changing step mode to full step mode.\r\n");
00497 
00498     /* Selecting full step mode. */
00499     if (!motor->set_step_mode((StepperMotor::step_mode_t) STEP_MODE_FULL)) {
00500         printf("    Step Mode not allowed.\r\n");
00501     }
00502 
00503     /* Setting speed and acceleration to be consistent with full step mode. */
00504     motor->set_max_speed(100);
00505     motor->set_min_speed(50);
00506     motor->set_acceleration(10);
00507     motor->set_deceleration(10);
00508 
00509     /* Requesting to go to a specified position. */
00510     motor->go_to(200);
00511 
00512     /* Waiting while the motor is active. */
00513     motor->wait_while_active();
00514 
00515     /* Getting current position */
00516     position = motor->get_position();
00517 
00518     /* Printing to the console. */
00519     printf("    Position: %d.\r\n", position);
00520 
00521     /* Waiting 2 seconds. */
00522     wait_ms(2000);
00523     
00524 
00525     /*----- Restoring 1/16 microstepping mode. -----*/
00526 
00527     /* Printing to the console. */
00528     printf("--> Restoring 1/16 microstepping mode.\r\n");
00529 
00530     /* Resetting to 1/16 microstepping mode */
00531     if (!motor->set_step_mode((StepperMotor::step_mode_t) STEP_MODE_1_16)) {
00532         printf("    Step Mode not allowed.\r\n");
00533     }
00534 
00535     /* Update speed, acceleration, deceleration for 1/16 microstepping mode*/
00536     motor->set_max_speed(1600);
00537     motor->set_min_speed(800);
00538     motor->set_acceleration(160);
00539     motor->set_deceleration(160);  
00540 
00541 
00542     /*----- Infinite Loop. -----*/
00543 
00544     /* Printing to the console. */
00545     printf("--> Infinite Loop...\r\n");
00546 
00547     /* Infinite Loop. */
00548     while (true) {
00549         /* Requesting to go to a specified position. */
00550         motor->go_to(-6400);
00551 
00552         /* Waiting while the motor is active. */
00553         motor->wait_while_active();
00554 
00555         /* Requesting to go to a specified position. */
00556         motor->go_to(6400);
00557 
00558         /* Waiting while the motor is active. */
00559         motor->wait_while_active();
00560     }
00561 }