Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: mbed tinyshell X_NUCLEO_IHM02A1
Diff: main.cpp
- Revision:
- 30:a23204ee2be2
- Parent:
- 29:a510e875936d
- Child:
- 31:ebd464b0d0d8
--- a/main.cpp Thu Apr 01 18:03:26 2021 +0000 +++ b/main.cpp Thu Apr 01 22:20:55 2021 +0000 @@ -1,45 +1,3 @@ -/** - ****************************************************************************** - * @file main.cpp - * @author Davide Aliprandi, STMicroelectronics - * @version V1.0.0 - * @date November 4th, 2015 - * @brief mbed test application for the STMicroelectronics X-NUCLEO-IHM02A1 - * Motor Control Expansion Board: control of 2 motors. - ****************************************************************************** - * @attention - * - * <h2><center>© COPYRIGHT(c) 2015 STMicroelectronics</center></h2> - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. Neither the name of STMicroelectronics nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - ****************************************************************************** - */ - - -/* Includes ------------------------------------------------------------------*/ - -/* mbed specific header files. */ #include "mbed.h" /* Helper header files. */ @@ -51,6 +9,9 @@ /* Tinyshell: https://os.mbed.com/users/murilopontes/code/tinyshell/ */ #include "tinysh.h" +#include <cstdlib> +#include <string> + /* Definitions ---------------------------------------------------------------*/ /* Motor specs */ @@ -59,7 +20,7 @@ #define MAX_PHASE_CURRENT_A 0.67 #define PHASE_RES_OHMS 12.0 #define MOTOR_INITIAL_SPEED_SPS 1000.0 -#define MOTOR_ACCEL_SPS2 200.0 +#define MOTOR_ACCEL_SPS2 1000.0 #define MOTOR_MAX_SPEED_SPS 2000.0 #define FULL_STEP_TH_SPS 602.7 #define DUMMY_KVAL_V 3.06 @@ -74,23 +35,6 @@ #define MIN_LOOP_TIME_MS 1 #define HARD_STOP_WAIT_MS 100 -#define CMD_BUFFER_SIZE 256 -#define OUTPUT_BUFFER_SIZE 1024 - -/* Number of steps. */ -#define STEPS_1 (20000 * 1) /* 1 revolution given a 200 step motor and 100:1 gearbox, with full stepping */ -#define STEPS_2 (STEPS_1 * 2) -#define SPEED_SPS 10000 // steps per second - -/* Number of movements per revolution. */ -#define MPR_1 4 - -/* Delay in milliseconds. */ -#define DELAY_1 1000 -#define DELAY_2 2000 -#define DELAY_3 5000 - - /* Variables -----------------------------------------------------------------*/ /* Motor Control Expansion Board. */ @@ -163,6 +107,11 @@ bool status_flag = false; bool run_flag = false; bool stop_flag = false; +bool cmd_both = false; +int which_axis = 0; +int speed_sps = 0; +int go_steps = 0; +int dir_fwd = true; /* Tinyshell command handler functions */ void set_status_flag(int argc, char **argv) @@ -170,21 +119,88 @@ status_flag = true; } +// gosteps dir steps (axis) +void set_gosteps_flag(int argc, char **argv) +{ + if (argc < 3 || argc > 4) { + printf("\r\nIncorrect number of arguments for: gosteps dir steps (axis).\r\n"); + return; + } + + dir_fwd = true; + if (argv[1] == std::string("bwd")) dir_fwd = false; + go_steps = atoi(argv[2]); + + if (argc == 3) { + // both axes + cmd_both = true; + } else { + cmd_both = false; + which_axis = 0; + if (argv[3] == std::string("y")) which_axis = 1; + } +} + +// run dir speed (axis) void set_run_flag(int argc, char **argv) { + if (argc < 3 || argc > 4) { + printf("\r\nIncorrect number of arguments for: run dir steps (axis).\r\n"); + return; + } + run_flag = true; + dir_fwd = true; + if (argv[1] == std::string("bwd")) dir_fwd = false; + speed_sps = atoi(argv[2]); + + //printf("\r\nParsing 'run'[%d], %s %s %s", argc, argv[1], argv[2], argv[3]); + if (argc == 3) { + // both axes + cmd_both = true; + //printf("\r\nUsing both axes\r\n"); + } else { + cmd_both = false; + which_axis = 0; + if (argv[3] == std::string("y")) which_axis = 1; + //printf("\r\nUsing axis %s (%d)\r\n", argv[3], which_axis); + } } +// stop (axis) void set_stop_flag(int argc, char **argv) { + if (argc > 2) { + printf("\r\nIncorrect number of arguments for: stop (axis).\r\n"); + return; + } + stop_flag = true; + + if (argc == 1) { + // both axes + cmd_both = true; + } else { + cmd_both = false; + which_axis = 0; + if (argv[1] == std::string("y")) which_axis = 1; + } } // parent cmd (0 for top) cmd input name, help string, usage string, // function to launch, arg when called, next (0 at init), child (0 at init) -tinysh_cmd_t print_status_cmd = {0, "status", "status command", "[args]", set_status_flag,0,0,0}; -tinysh_cmd_t run_cmd = {0, "run", "run command", "[args]", set_run_flag,0,0,0}; -tinysh_cmd_t stop_cmd = {0, "stop", "stop command", "[args]", set_stop_flag,0,0,0}; +tinysh_cmd_t print_status_cmd = {0, "status", + "\r\nPrint content of status registers.\r\n", + "[no args]", set_status_flag,0,0,0}; +tinysh_cmd_t go_steps_cmd = {0, "gosteps", + "\r\n'Go n steps', dir = 'fwd' for CW or 'bwd' for CCW, steps = n steps, axis = 'x' or 'y' (omit for both).\r\n", + "[dir, steps, (axis)]", set_gosteps_flag,0,0,0}; +tinysh_cmd_t run_cmd = {0, "run", + "\r\nRun motor, dir = 'fwd' for CW or 'bwd' for CCW, speed in steps per second, axis = 'x' or 'y' (omit for both).\r\n", + "[dir, speed, (axis)]", set_run_flag,0,0,0}; +tinysh_cmd_t stop_cmd = {0, "stop", + "\r\nStop motor, optional axis = 'x' or 'y'; both stopped if omitted.\r\n", + "[(axis)]", set_stop_flag,0,0,0}; /* mandatory tiny shell output function */ void tinysh_char_out(unsigned char c) @@ -201,12 +217,13 @@ /* Set up tinyshell */ pc.baud(115200); - pc.printf("Motor controller ready\r\n"); - tinysh_set_prompt("$ "); + pc.printf("\r\nMotor controller ready\r\n"); + tinysh_set_prompt("> "); // Add all tinyshell commands here tinysh_add_command(&print_status_cmd); tinysh_add_command(&run_cmd); + tinysh_add_command(&go_steps_cmd); tinysh_add_command(&stop_cmd); /* Initializing SPI bus. */ @@ -224,7 +241,7 @@ // Main loop while(1) { - /* 1: Check for hardware flags ----------------------------------------*/ + /* 1: Check for hardware flags ---------------------------------------*/ if (limit_flag) { // clear flag limit_flag = false; @@ -243,49 +260,111 @@ } x_nucleo_ihm02a1->perform_prepared_actions(); - printf("Reached limit.\r\n"); + printf("\r\nReached limit.\r\n"); } /* 2: Fetch new chars for Tinyshell ----------------------------------*/ tinysh_char_in(pc.getc()); /* 3: Handle Commands ------------------------------------------------*/ + if (go_steps) { + // Stop first + if (cmd_both) { + for (int m = 0; m < L6470DAISYCHAINSIZE; m++) { + motors[m]->prepare_hard_stop(); + } + x_nucleo_ihm02a1->perform_prepared_actions(); + } else { + motors[which_axis]->hard_stop(); + } + wait_ms(HARD_STOP_WAIT_MS); + + if (cmd_both) { + for (int m = 0; m < L6470DAISYCHAINSIZE; m++) { + if (dir_fwd) motors[m]->prepare_move(StepperMotor::FWD, go_steps); + else motors[m]->prepare_move(StepperMotor::BWD, go_steps); + } + x_nucleo_ihm02a1->perform_prepared_actions(); + } else { + if (dir_fwd) motors[which_axis]->move(StepperMotor::FWD, go_steps); + else motors[which_axis]->move(StepperMotor::BWD, go_steps); + } + + printf("\r\nGoing %s %d steps.\r\n", dir_fwd ? "Forward" : "Backward", go_steps); + + // Clear flags + go_steps = 0; + cmd_both = false; + } + if (run_flag) { + // Stop first + if (cmd_both) { + // stop both at same time + for (int m = 0; m < L6470DAISYCHAINSIZE; m++) { + motors[m]->prepare_hard_stop(); + } + x_nucleo_ihm02a1->perform_prepared_actions(); + } else { + motors[which_axis]->hard_stop(); + } + wait_ms(HARD_STOP_WAIT_MS); + + if (cmd_both) { + for (int m = 0; m < L6470DAISYCHAINSIZE; m++) { + if (dir_fwd) motors[m]->prepare_run(StepperMotor::FWD, speed_sps); + else motors[m]->prepare_run(StepperMotor::BWD, speed_sps); + } + x_nucleo_ihm02a1->perform_prepared_actions(); + } else { + if (dir_fwd) motors[which_axis]->run(StepperMotor::FWD, speed_sps); + else motors[which_axis]->run(StepperMotor::BWD, speed_sps); + } + + printf("\r\nRunning.\r\n"); + + // Clear flags run_flag = false; - // Hello world: just run the damn motor forever - printf("Running.\r\n"); - for (int m = 0; m < L6470DAISYCHAINSIZE; m++) { - motors[m]->prepare_run(StepperMotor::BWD, SPEED_SPS); - } - x_nucleo_ihm02a1->perform_prepared_actions(); + cmd_both = false; } if (stop_flag) { - stop_flag = false; + + printf("\r\nStopping.\r\n"); + // Hard stop - printf("Stopping.\r\n"); - for (int m = 0; m < L6470DAISYCHAINSIZE; m++) { - motors[m]->prepare_hard_stop(); + if (cmd_both) { + // stop both at same time + for (int m = 0; m < L6470DAISYCHAINSIZE; m++) { + motors[m]->prepare_hard_stop(); + } + x_nucleo_ihm02a1->perform_prepared_actions(); + } else { + motors[which_axis]->hard_stop(); } - x_nucleo_ihm02a1->perform_prepared_actions(); - wait_ms(HARD_STOP_WAIT_MS); // High Z - for (int m = 0; m < L6470DAISYCHAINSIZE; m++) { - motors[m]->prepare_hard_hiz(); + if (cmd_both) { + for (int m = 0; m < L6470DAISYCHAINSIZE; m++) { + motors[m]->prepare_hard_hiz(); + } + x_nucleo_ihm02a1->perform_prepared_actions(); + } else { + motors[which_axis]->hard_hiz(); } - x_nucleo_ihm02a1->perform_prepared_actions(); + + // clear flags + stop_flag = false; + cmd_both = false; } + if (status_flag) { - // clear flag - status_flag = false; - // Fetch and parse the status register for each motor for (int m = 0; m < L6470DAISYCHAINSIZE; m++) { status_bytes[m] = motors[m]->get_status(); - printf("Status reg %d: 0x%02X\r\n", m, status_bytes[m]); + printf("\r\nStatus reg %d: 0x%02X\r\n", m, status_bytes[m]); printf(" STEP-CLOCK MODE: "); printf(status_bytes[m] & 0x8000 ? "SET\r\n" : "NOT SET\r\n"); printf(" STEP_LOSS_B: "); @@ -319,256 +398,11 @@ printf(status_bytes[m] & 0x0002 ? "SET\r\n" : "NOT SET\r\n"); printf(" HI_Z: "); printf(status_bytes[m] & 0x0001 ? "SET\r\n" : "NOT SET\r\n"); - printf("\n\n"); + printf("\r\n\n"); } + // clear flag + status_flag = false; } } // end main loop -} - - -// /* Printing to the console. */ -// printf("--> Setting home position.\r\n"); -// -// /* Setting the home position. */ -// motors[0]->set_home(); - -// /* Waiting. */ -// wait_ms(DELAY_1); -// -// /* Getting the current position. */ -// int position = motors[0]->get_position(); -// -// /* Printing to the console. */ -// printf("--> Getting the current position: %d\r\n", position); - -// /* Waiting. */ -// wait_ms(DELAY_1); -// -// /* Printing to the console. */ -// printf("--> Moving forward %d steps.\r\n", STEPS_1); -// -// /* Moving. */ -// motors[0]->move(StepperMotor::FWD, STEPS_1); -// -// /* Waiting while active. */ -// motors[0]->wait_while_active(); -// -// /* Getting the current position. */ -// position = motors[0]->get_position(); -// -// /* Printing to the console. */ -// printf("--> Getting the current position: %d\r\n", position); -// -// /* Printing to the console. */ -// printf("--> Marking the current position.\r\n"); -// -// /* Marking the current position. */ -// motors[0]->set_mark(); -// -// /* Waiting. */ -// wait_ms(DELAY_1); -// -// /* Printing to the console. */ -// printf("--> Moving backward %d steps.\r\n", STEPS_2); -// -// /* Moving. */ -// motors[0]->move(StepperMotor::BWD, STEPS_2); -// -// /* Waiting while active. */ -// motors[0]->wait_while_active(); -// -// /* Waiting. */ -// wait_ms(DELAY_1); -// -// /* Getting the current position. */ -// position = motors[0]->get_position(); -// -// /* Printing to the console. */ -// printf("--> Getting the current position: %d\r\n", position); -// -// /* Waiting. */ -// wait_ms(DELAY_1); -// -// /* Printing to the console. */ -// printf("--> Going to marked position.\r\n"); -// -// /* Going to marked position. */ -// motors[0]->go_mark(); -// -// /* Waiting while active. */ -// motors[0]->wait_while_active(); -// -// /* Waiting. */ -// wait_ms(DELAY_1); -// -// /* Getting the current position. */ -// position = motors[0]->get_position(); -// -// /* Printing to the console. */ -// printf("--> Getting the current position: %d\r\n", position); -// -// /* Waiting. */ -// wait_ms(DELAY_1); -// -// /* Printing to the console. */ -// printf("--> Going to home position.\r\n"); -// -// /* Going to home position. */ -// motors[0]->go_home(); -// -// /* Waiting while active. */ -// motors[0]->wait_while_active(); -// -// /* Waiting. */ -// wait_ms(DELAY_1); -// -// /* Getting the current position. */ -// position = motors[0]->get_position(); -// -// /* Printing to the console. */ -// printf("--> Getting the current position: %d\r\n", position); -// -// /* Waiting. */ -// wait_ms(DELAY_1); -// -// /* Printing to the console. */ -// printf("--> Halving the microsteps.\r\n"); -// -// /* Halving the microsteps. */ -// init[0].step_sel = (init[0].step_sel > 0 ? init[0].step_sel - 1 : init[0].step_sel); -// if (!motors[0]->set_step_mode((StepperMotor::step_mode_t) init[0].step_sel)) { -// printf(" Step Mode not allowed.\r\n"); -// } -// -// /* Waiting. */ -// wait_ms(DELAY_1); -// -// /* Printing to the console. */ -// printf("--> Setting home position.\r\n"); -// -// /* Setting the home position. */ -// motors[0]->set_home(); -// -// /* Waiting. */ -// wait_ms(DELAY_1); -// -// /* Getting the current position. */ -// position = motors[0]->get_position(); -// -// /* Printing to the console. */ -// printf("--> Getting the current position: %d\r\n", position); -// -// /* Waiting. */ -// wait_ms(DELAY_1); -// -// /* Printing to the console. */ -// printf("--> Moving forward %d steps.\r\n", STEPS_1); -// -// /* Moving. */ -// motors[0]->move(StepperMotor::FWD, STEPS_1); -// -// /* Waiting while active. */ -// motors[0]->wait_while_active(); -// -// /* Getting the current position. */ -// position = motors[0]->get_position(); -// -// /* Printing to the console. */ -// printf("--> Getting the current position: %d\r\n", position); -// -// /* Printing to the console. */ -// printf("--> Marking the current position.\r\n"); -// -// /* Marking the current position. */ -// motors[0]->set_mark(); -// -// /* Waiting. */ -// wait_ms(DELAY_2); -// -// -// /*----- Running together for a certain amount of time. -----*/ -// -// /* Printing to the console. */ -// printf("--> Running together for %d seconds.\r\n", DELAY_3 / 1000); -// -// /* Preparing each motor to perform a run at a specified speed. */ -// for (int m = 0; m < L6470DAISYCHAINSIZE; m++) { -// motors[m]->prepare_run(StepperMotor::BWD, 400); -// } -// -// /* Performing the action on each motor at the same time. */ -// x_nucleo_ihm02a1->perform_prepared_actions(); -// -// /* Waiting. */ -// wait_ms(DELAY_3); -// -// -// /*----- Increasing the speed while running. -----*/ -// -// /* Preparing each motor to perform a run at a specified speed. */ -// for (int m = 0; m < L6470DAISYCHAINSIZE; m++) { -// motors[m]->prepare_get_speed(); -// } -// -// /* Performing the action on each motor at the same time. */ -// uint32_t* results = x_nucleo_ihm02a1->perform_prepared_actions(); -// -// /* Printing to the console. */ -// printf(" Speed: M1 %d, M2 %d.\r\n", results[0], results[1]); -// -// /* Printing to the console. */ -// printf("--> Doublig the speed while running again for %d seconds.\r\n", DELAY_3 / 1000); -// -// /* Preparing each motor to perform a run at a specified speed. */ -// for (int m = 0; m < L6470DAISYCHAINSIZE; m++) { -// motors[m]->prepare_run(StepperMotor::BWD, results[m] << 1); -// } -// -// /* Performing the action on each motor at the same time. */ -// results = x_nucleo_ihm02a1->perform_prepared_actions(); -// -// /* Waiting. */ -// wait_ms(DELAY_3); -// -// /* Preparing each motor to perform a run at a specified speed. */ -// for (int m = 0; m < L6470DAISYCHAINSIZE; m++) { -// motors[m]->prepare_get_speed(); -// } -// -// /* Performing the action on each motor at the same time. */ -// results = x_nucleo_ihm02a1->perform_prepared_actions(); -// -// /* Printing to the console. */ -// printf(" Speed: M1 %d, M2 %d.\r\n", results[0], results[1]); -// -// /* Waiting. */ -// wait_ms(DELAY_1); -// -// -// /*----- Doing a full revolution on each motor, one after the other. -----*/ -// -// /* Printing to the console. */ -// printf("--> Doing a full revolution on each motor, one after the other.\r\n"); -// -// /* Doing a full revolution on each motor, one after the other. */ -// for (int m = 0; m < L6470DAISYCHAINSIZE; m++) { -// for (int i = 0; i < MPR_1; i++) { -// /* Computing the number of steps. */ -// int steps = (int) (((int) init[m].fullstepsperrevolution * pow(2.0f, init[m].step_sel)) / MPR_1); -// -// /* Moving. */ -// motors[m]->move(StepperMotor::FWD, steps); -// -// /* Waiting while active. */ -// motors[m]->wait_while_active(); -// -// /* Waiting. */ -// wait_ms(DELAY_1); -// } -// } -// -// /* Waiting. */ -// wait_ms(DELAY_2); -// -//} +} \ No newline at end of file