![](/media/cache/group/ST_logo_2020_blue_V_cmyk.jpg.50x50_q85.jpg)
Simple program featuring a few API functions usage of the X_NUCLEO_IHM04A1 library.
Dependencies: X_NUCLEO_IHM04A1 mbed
Fork of HelloWorld_IHM04A1 by
This application provides a simple example of usage of the X-NUCLEO-IHM04A1 Brush DC Motor Control Expansion Board.
It shows how to use four unidirectional brush DC motors connected to the board by running the four motor in parallel. At the beginning, no motor is running. Each time the user presses the user button, a new brush DC motor is activated. Motors run during one second, stop during one second and run again.
- motor 1 runs at 20% of maximum speed.
- motor 2 runs at 30% of maximum speed.
- motor 3 runs at 40% of maximum speed.
- motor 4 runs at 50% of maximum speed.
For the hardware configuration of the expansion board, please refer to the X_NUCLEO_IHM04A1 library web page.
main.cpp@9:be4faa697346, 2017-08-03 (annotated)
- Committer:
- Davidroid
- Date:
- Thu Aug 03 16:33:35 2017 +0000
- Revision:
- 9:be4faa697346
- Parent:
- 8:05340e740644
Updating with new version of the libraries.
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
brdirais | 0:dcc35ef6effc | 1 | /** |
brdirais | 0:dcc35ef6effc | 2 | ****************************************************************************** |
davide.aliprandi@st.com | 6:b9b32d6c2b40 | 3 | * @file main.cpp |
brdirais | 0:dcc35ef6effc | 4 | * @author IPC Rennes |
brdirais | 0:dcc35ef6effc | 5 | * @version V1.0.0 |
brdirais | 1:4d9b9123d9e1 | 6 | * @date May 16, 2016 |
brdirais | 0:dcc35ef6effc | 7 | * @brief This example shows how to use 1 IHM04A1 expansion board with |
brdirais | 0:dcc35ef6effc | 8 | * 4 unidirectionnal Brush DC motors. |
brdirais | 0:dcc35ef6effc | 9 | * Each motor has one lead connected to one of the bridge output, |
brdirais | 0:dcc35ef6effc | 10 | * the other lead to the ground. The input bridges are not parallelised. |
brdirais | 0:dcc35ef6effc | 11 | * The demo sequence starts when the user button is pressed. |
brdirais | 1:4d9b9123d9e1 | 12 | * Each time, the user button is pressed, one new motor is activated |
brdirais | 0:dcc35ef6effc | 13 | ****************************************************************************** |
brdirais | 0:dcc35ef6effc | 14 | * @attention |
brdirais | 0:dcc35ef6effc | 15 | * |
brdirais | 0:dcc35ef6effc | 16 | * <h2><center>© COPYRIGHT(c) 2015 STMicroelectronics</center></h2> |
brdirais | 0:dcc35ef6effc | 17 | * |
brdirais | 0:dcc35ef6effc | 18 | * Redistribution and use in source and binary forms, with or without modification, |
brdirais | 0:dcc35ef6effc | 19 | * are permitted provided that the following conditions are met: |
brdirais | 0:dcc35ef6effc | 20 | * 1. Redistributions of source code must retain the above copyright notice, |
brdirais | 0:dcc35ef6effc | 21 | * this list of conditions and the following disclaimer. |
brdirais | 0:dcc35ef6effc | 22 | * 2. Redistributions in binary form must reproduce the above copyright notice, |
brdirais | 0:dcc35ef6effc | 23 | * this list of conditions and the following disclaimer in the documentation |
brdirais | 0:dcc35ef6effc | 24 | * and/or other materials provided with the distribution. |
brdirais | 0:dcc35ef6effc | 25 | * 3. Neither the name of STMicroelectronics nor the names of its contributors |
brdirais | 0:dcc35ef6effc | 26 | * may be used to endorse or promote products derived from this software |
brdirais | 0:dcc35ef6effc | 27 | * without specific prior written permission. |
brdirais | 0:dcc35ef6effc | 28 | * |
brdirais | 0:dcc35ef6effc | 29 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" |
brdirais | 0:dcc35ef6effc | 30 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
brdirais | 0:dcc35ef6effc | 31 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE |
brdirais | 0:dcc35ef6effc | 32 | * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE |
brdirais | 0:dcc35ef6effc | 33 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
brdirais | 0:dcc35ef6effc | 34 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR |
brdirais | 0:dcc35ef6effc | 35 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER |
brdirais | 0:dcc35ef6effc | 36 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, |
brdirais | 0:dcc35ef6effc | 37 | * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
brdirais | 0:dcc35ef6effc | 38 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
brdirais | 0:dcc35ef6effc | 39 | * |
brdirais | 0:dcc35ef6effc | 40 | ****************************************************************************** |
brdirais | 0:dcc35ef6effc | 41 | */ |
brdirais | 0:dcc35ef6effc | 42 | |
davide.aliprandi@st.com | 6:b9b32d6c2b40 | 43 | |
brdirais | 0:dcc35ef6effc | 44 | /* Includes ------------------------------------------------------------------*/ |
brdirais | 0:dcc35ef6effc | 45 | |
brdirais | 0:dcc35ef6effc | 46 | /* mbed specific header files. */ |
brdirais | 0:dcc35ef6effc | 47 | #include "mbed.h" |
brdirais | 0:dcc35ef6effc | 48 | |
brdirais | 0:dcc35ef6effc | 49 | /* Component specific header files. */ |
davide.aliprandi@st.com | 6:b9b32d6c2b40 | 50 | #include "L6206.h" |
brdirais | 0:dcc35ef6effc | 51 | |
brdirais | 0:dcc35ef6effc | 52 | |
brdirais | 0:dcc35ef6effc | 53 | /* Definitions ---------------------------------------------------------------*/ |
brdirais | 0:dcc35ef6effc | 54 | |
brdirais | 0:dcc35ef6effc | 55 | #define MAX_MOTOR (4) |
brdirais | 0:dcc35ef6effc | 56 | |
brdirais | 0:dcc35ef6effc | 57 | |
brdirais | 0:dcc35ef6effc | 58 | /* Variables -----------------------------------------------------------------*/ |
brdirais | 0:dcc35ef6effc | 59 | |
brdirais | 0:dcc35ef6effc | 60 | static volatile uint16_t gLastError; |
brdirais | 0:dcc35ef6effc | 61 | static volatile uint8_t gStep = 0; |
brdirais | 0:dcc35ef6effc | 62 | |
brdirais | 0:dcc35ef6effc | 63 | |
brdirais | 0:dcc35ef6effc | 64 | /* Variables -----------------------------------------------------------------*/ |
brdirais | 0:dcc35ef6effc | 65 | |
brdirais | 0:dcc35ef6effc | 66 | /* Initialization parameters. */ |
davide.aliprandi@st.com | 6:b9b32d6c2b40 | 67 | L6206_init_t init = |
brdirais | 0:dcc35ef6effc | 68 | { |
brdirais | 0:dcc35ef6effc | 69 | L6206_CONF_PARAM_PARALLE_BRIDGES, |
brdirais | 0:dcc35ef6effc | 70 | {L6206_CONF_PARAM_FREQ_PWM1A, L6206_CONF_PARAM_FREQ_PWM2A, L6206_CONF_PARAM_FREQ_PWM1B, L6206_CONF_PARAM_FREQ_PWM2B}, |
brdirais | 0:dcc35ef6effc | 71 | {100,100,100,100}, |
brdirais | 0:dcc35ef6effc | 72 | {FORWARD,FORWARD,BACKWARD,FORWARD}, |
brdirais | 0:dcc35ef6effc | 73 | {INACTIVE,INACTIVE,INACTIVE,INACTIVE}, |
brdirais | 0:dcc35ef6effc | 74 | {FALSE,FALSE} |
brdirais | 0:dcc35ef6effc | 75 | }; |
brdirais | 0:dcc35ef6effc | 76 | |
brdirais | 0:dcc35ef6effc | 77 | /* Motor Control Component. */ |
brdirais | 0:dcc35ef6effc | 78 | L6206 *motor; |
brdirais | 0:dcc35ef6effc | 79 | |
brdirais | 0:dcc35ef6effc | 80 | /* User button on Nucleo board */ |
davide.aliprandi@st.com | 6:b9b32d6c2b40 | 81 | InterruptIn my_button_irq(USER_BUTTON); |
brdirais | 0:dcc35ef6effc | 82 | |
brdirais | 0:dcc35ef6effc | 83 | |
brdirais | 0:dcc35ef6effc | 84 | /* Functions -----------------------------------------------------------------*/ |
brdirais | 0:dcc35ef6effc | 85 | |
brdirais | 0:dcc35ef6effc | 86 | /** |
brdirais | 0:dcc35ef6effc | 87 | * @brief This function is executed in case of error occurrence. |
brdirais | 0:dcc35ef6effc | 88 | * @param error number of the error |
brdirais | 0:dcc35ef6effc | 89 | * @retval None |
brdirais | 0:dcc35ef6effc | 90 | */ |
davide.aliprandi@st.com | 6:b9b32d6c2b40 | 91 | void my_error_handler(uint16_t error) |
brdirais | 0:dcc35ef6effc | 92 | { |
brdirais | 0:dcc35ef6effc | 93 | /* Backup error number */ |
brdirais | 0:dcc35ef6effc | 94 | gLastError = error; |
brdirais | 0:dcc35ef6effc | 95 | |
brdirais | 0:dcc35ef6effc | 96 | /* Enter your own code here */ |
brdirais | 0:dcc35ef6effc | 97 | } |
brdirais | 0:dcc35ef6effc | 98 | |
brdirais | 0:dcc35ef6effc | 99 | /** |
brdirais | 0:dcc35ef6effc | 100 | * @brief This function is the User handler for the flag interrupt |
brdirais | 0:dcc35ef6effc | 101 | * @param None |
brdirais | 0:dcc35ef6effc | 102 | * @retval None |
brdirais | 0:dcc35ef6effc | 103 | * @note If needed, implement it, and then attach and enable it: |
davide.aliprandi@st.com | 6:b9b32d6c2b40 | 104 | * + motor->attach_flag_interrupt(my_flag_irq_handler); |
brdirais | 0:dcc35ef6effc | 105 | */ |
davide.aliprandi@st.com | 6:b9b32d6c2b40 | 106 | void my_flag_irq_handler(void) |
brdirais | 0:dcc35ef6effc | 107 | { |
brdirais | 0:dcc35ef6effc | 108 | /* Code to be customised */ |
brdirais | 0:dcc35ef6effc | 109 | /************************/ |
brdirais | 0:dcc35ef6effc | 110 | /* Get the state of bridge A */ |
davide.aliprandi@st.com | 6:b9b32d6c2b40 | 111 | uint16_t bridgeState = motor->get_bridge_status(0); |
brdirais | 0:dcc35ef6effc | 112 | |
davide.aliprandi@st.com | 6:b9b32d6c2b40 | 113 | if (bridgeState == 0) { |
davide.aliprandi@st.com | 6:b9b32d6c2b40 | 114 | if ((motor->get_device_state(0) != INACTIVE)|| |
davide.aliprandi@st.com | 6:b9b32d6c2b40 | 115 | (motor->get_device_state(1) != INACTIVE)) { |
brdirais | 0:dcc35ef6effc | 116 | /* Bridge A was disabling due to overcurrent or over temperature */ |
brdirais | 0:dcc35ef6effc | 117 | /* When at least on of its motor was running */ |
davide.aliprandi@st.com | 6:b9b32d6c2b40 | 118 | my_error_handler(0XBAD0); |
brdirais | 0:dcc35ef6effc | 119 | } |
brdirais | 0:dcc35ef6effc | 120 | } |
brdirais | 0:dcc35ef6effc | 121 | |
brdirais | 0:dcc35ef6effc | 122 | /* Get the state of bridge B */ |
davide.aliprandi@st.com | 6:b9b32d6c2b40 | 123 | bridgeState = motor->get_bridge_status(1); |
brdirais | 0:dcc35ef6effc | 124 | |
davide.aliprandi@st.com | 6:b9b32d6c2b40 | 125 | if (bridgeState == 0) { |
davide.aliprandi@st.com | 6:b9b32d6c2b40 | 126 | if ((motor->get_device_state(2) != INACTIVE)|| |
davide.aliprandi@st.com | 6:b9b32d6c2b40 | 127 | (motor->get_device_state(3) != INACTIVE)) { |
brdirais | 0:dcc35ef6effc | 128 | /* Bridge A was disabling due to overcurrent or over temperature */ |
brdirais | 0:dcc35ef6effc | 129 | /* When at least on of its motor was running */ |
davide.aliprandi@st.com | 6:b9b32d6c2b40 | 130 | my_error_handler(0XBAD1); |
brdirais | 0:dcc35ef6effc | 131 | } |
brdirais | 0:dcc35ef6effc | 132 | } |
davide.aliprandi@st.com | 6:b9b32d6c2b40 | 133 | } |
brdirais | 0:dcc35ef6effc | 134 | |
brdirais | 0:dcc35ef6effc | 135 | |
brdirais | 0:dcc35ef6effc | 136 | /* Private functions ---------------------------------------------------------*/ |
brdirais | 0:dcc35ef6effc | 137 | |
brdirais | 0:dcc35ef6effc | 138 | /** |
brdirais | 0:dcc35ef6effc | 139 | * @brief Button Irq |
brdirais | 0:dcc35ef6effc | 140 | * @param None |
brdirais | 0:dcc35ef6effc | 141 | * @retval None |
brdirais | 0:dcc35ef6effc | 142 | */ |
brdirais | 0:dcc35ef6effc | 143 | |
davide.aliprandi@st.com | 6:b9b32d6c2b40 | 144 | void my_button_pressed(void) |
brdirais | 0:dcc35ef6effc | 145 | { |
davide.aliprandi@st.com | 6:b9b32d6c2b40 | 146 | my_button_irq.disable_irq(); |
brdirais | 0:dcc35ef6effc | 147 | gStep++; |
davide.aliprandi@st.com | 6:b9b32d6c2b40 | 148 | if (gStep > MAX_MOTOR) { |
brdirais | 0:dcc35ef6effc | 149 | gStep = 0; |
brdirais | 0:dcc35ef6effc | 150 | } |
brdirais | 0:dcc35ef6effc | 151 | wait_ms(200); |
davide.aliprandi@st.com | 6:b9b32d6c2b40 | 152 | my_button_irq.enable_irq(); |
brdirais | 0:dcc35ef6effc | 153 | } |
brdirais | 0:dcc35ef6effc | 154 | |
brdirais | 0:dcc35ef6effc | 155 | |
brdirais | 0:dcc35ef6effc | 156 | /** |
brdirais | 0:dcc35ef6effc | 157 | * @brief Main program |
brdirais | 0:dcc35ef6effc | 158 | * @param None |
brdirais | 0:dcc35ef6effc | 159 | * @retval None |
brdirais | 0:dcc35ef6effc | 160 | */ |
brdirais | 0:dcc35ef6effc | 161 | int main(void) |
brdirais | 0:dcc35ef6effc | 162 | { |
brdirais | 0:dcc35ef6effc | 163 | /*----- Initialization. -----*/ |
brdirais | 0:dcc35ef6effc | 164 | |
brdirais | 0:dcc35ef6effc | 165 | /* Initializing Motor Control Component. */ |
Davidroid | 9:be4faa697346 | 166 | #ifdef TARGET_STM32F429 |
Davidroid | 9:be4faa697346 | 167 | motor = new L6206(D2, A4, PB_4, PC_7, PA_15, PB_3); |
Davidroid | 9:be4faa697346 | 168 | #else |
Davidroid | 9:be4faa697346 | 169 | motor = new L6206(D2, A4, D5, D4, A0, A1); |
Davidroid | 9:be4faa697346 | 170 | #endif |
brdirais | 0:dcc35ef6effc | 171 | |
davide.aliprandi@st.com | 6:b9b32d6c2b40 | 172 | /* When init method is called with NULL pointer, the L6206 parameters are set */ |
brdirais | 0:dcc35ef6effc | 173 | /* with the predefined values from file l6206_target_config.h, otherwise the */ |
davide.aliprandi@st.com | 6:b9b32d6c2b40 | 174 | /* parameters are set using the init structure values. */ |
davide.aliprandi@st.com | 6:b9b32d6c2b40 | 175 | if (motor->init(&init) != COMPONENT_OK) { |
brdirais | 0:dcc35ef6effc | 176 | exit(EXIT_FAILURE); |
davide.aliprandi@st.com | 6:b9b32d6c2b40 | 177 | } |
brdirais | 0:dcc35ef6effc | 178 | |
davide.aliprandi@st.com | 6:b9b32d6c2b40 | 179 | /* Attach the function my_flag_irq_handler (defined below) to the flag interrupt */ |
davide.aliprandi@st.com | 6:b9b32d6c2b40 | 180 | motor->attach_flag_interrupt(my_flag_irq_handler); |
brdirais | 0:dcc35ef6effc | 181 | |
davide.aliprandi@st.com | 6:b9b32d6c2b40 | 182 | /* Attach the function my_error_handler (defined below) to the error Handler*/ |
davide.aliprandi@st.com | 6:b9b32d6c2b40 | 183 | motor->attach_error_handler(my_error_handler); |
brdirais | 0:dcc35ef6effc | 184 | |
brdirais | 0:dcc35ef6effc | 185 | /* Printing to the console. */ |
Davidroid | 7:20ff5668f5fe | 186 | printf("Motor Control Application Example for 4 Motors\r\n\n"); |
brdirais | 0:dcc35ef6effc | 187 | |
brdirais | 0:dcc35ef6effc | 188 | /* Select the configuration with no bridge paralleling, two unidirectionnal motors on bridge A |
brdirais | 0:dcc35ef6effc | 189 | and two unidirectionnal motors on bridge B */ |
davide.aliprandi@st.com | 6:b9b32d6c2b40 | 190 | motor->set_dual_full_bridge_config(PARALLELING_NONE___2_UNDIR_MOTOR_BRIDGE_A__2_UNDIR_MOTOR_BRIDGE_B); |
brdirais | 0:dcc35ef6effc | 191 | |
brdirais | 1:4d9b9123d9e1 | 192 | /* Set PWM Frequency of bridge A inputs to 1000 Hz */ |
davide.aliprandi@st.com | 6:b9b32d6c2b40 | 193 | motor->set_bridge_input_pwm_freq(0,1000); |
brdirais | 0:dcc35ef6effc | 194 | |
brdirais | 1:4d9b9123d9e1 | 195 | /* Set PWM Frequency of bridge B inputs to 2000 Hz */ |
davide.aliprandi@st.com | 6:b9b32d6c2b40 | 196 | motor->set_bridge_input_pwm_freq(1,2000); |
brdirais | 0:dcc35ef6effc | 197 | |
davide.aliprandi@st.com | 6:b9b32d6c2b40 | 198 | // Attach my_button_pressed function to Irq |
davide.aliprandi@st.com | 6:b9b32d6c2b40 | 199 | my_button_irq.fall(&my_button_pressed); |
brdirais | 0:dcc35ef6effc | 200 | |
brdirais | 0:dcc35ef6effc | 201 | /* Infinite loop */ |
davide.aliprandi@st.com | 6:b9b32d6c2b40 | 202 | while (true) { |
brdirais | 0:dcc35ef6effc | 203 | |
davide.aliprandi@st.com | 6:b9b32d6c2b40 | 204 | if (gStep > 0) { |
Davidroid | 8:05340e740644 | 205 | printf("Running motor 0 at 5%% of the maximum speed\r\n"); |
Davidroid | 8:05340e740644 | 206 | /* Set speed of motor 0 to 5% */ |
Davidroid | 8:05340e740644 | 207 | motor->set_speed(0,5); |
brdirais | 0:dcc35ef6effc | 208 | /* start motor 0 */ |
davide.aliprandi@st.com | 6:b9b32d6c2b40 | 209 | motor->run(0, BDCMotor::FWD); |
brdirais | 0:dcc35ef6effc | 210 | } |
brdirais | 0:dcc35ef6effc | 211 | |
davide.aliprandi@st.com | 6:b9b32d6c2b40 | 212 | if (gStep > 1) { |
Davidroid | 8:05340e740644 | 213 | printf("Running motor 1 at 10%% of the maximum speed\r\n"); |
Davidroid | 8:05340e740644 | 214 | /* Set speed of motor 1 to 10 % */ |
Davidroid | 8:05340e740644 | 215 | motor->set_speed(1,10); |
brdirais | 0:dcc35ef6effc | 216 | /* start motor 1 */ |
davide.aliprandi@st.com | 6:b9b32d6c2b40 | 217 | motor->run(1, BDCMotor::FWD); |
brdirais | 0:dcc35ef6effc | 218 | } |
brdirais | 0:dcc35ef6effc | 219 | |
davide.aliprandi@st.com | 6:b9b32d6c2b40 | 220 | if (gStep > 2) { |
Davidroid | 8:05340e740644 | 221 | printf("Running motor 2 at 15%% of the maximum speed\r\n"); |
Davidroid | 8:05340e740644 | 222 | /* Set speed of motor 2 to 15 % */ |
Davidroid | 8:05340e740644 | 223 | motor->set_speed(2,15); |
brdirais | 0:dcc35ef6effc | 224 | /* start motor 2 */ |
davide.aliprandi@st.com | 6:b9b32d6c2b40 | 225 | motor->run(2, BDCMotor::FWD); |
brdirais | 0:dcc35ef6effc | 226 | } |
brdirais | 0:dcc35ef6effc | 227 | |
davide.aliprandi@st.com | 6:b9b32d6c2b40 | 228 | if (gStep > 3) { |
Davidroid | 8:05340e740644 | 229 | printf("Running motor 3 at 20%% of the maximum speed\r\n"); |
Davidroid | 8:05340e740644 | 230 | /* Set speed of motor 3 to 20 % */ |
Davidroid | 8:05340e740644 | 231 | motor->set_speed(3,20); |
brdirais | 0:dcc35ef6effc | 232 | /* start motor 3 */ |
davide.aliprandi@st.com | 6:b9b32d6c2b40 | 233 | motor->run(3, BDCMotor::FWD); |
brdirais | 0:dcc35ef6effc | 234 | } |
brdirais | 0:dcc35ef6effc | 235 | |
davide.aliprandi@st.com | 6:b9b32d6c2b40 | 236 | if (gStep > 0) { |
brdirais | 0:dcc35ef6effc | 237 | wait_ms(1000); |
brdirais | 0:dcc35ef6effc | 238 | |
davide.aliprandi@st.com | 6:b9b32d6c2b40 | 239 | motor->hard_hiz(0); |
davide.aliprandi@st.com | 6:b9b32d6c2b40 | 240 | motor->hard_hiz(1); |
davide.aliprandi@st.com | 6:b9b32d6c2b40 | 241 | motor->hard_hiz(2); |
davide.aliprandi@st.com | 6:b9b32d6c2b40 | 242 | motor->hard_hiz(3); |
brdirais | 0:dcc35ef6effc | 243 | |
brdirais | 0:dcc35ef6effc | 244 | wait_ms(1000); |
brdirais | 0:dcc35ef6effc | 245 | } |
brdirais | 0:dcc35ef6effc | 246 | } |
brdirais | 0:dcc35ef6effc | 247 | } |
brdirais | 0:dcc35ef6effc | 248 | |
brdirais | 0:dcc35ef6effc | 249 | /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ |