Simple program featuring a few API functions usage of the X_NUCLEO_IHM04A1 library.

Dependencies:   X_NUCLEO_IHM04A1 mbed

Dependents:   SimplePIDBot

Fork of HelloWorld_IHM04A1 by ST Expansion SW Team

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.

Committer:
davide.aliprandi@st.com
Date:
Fri Mar 24 11:00:26 2017 +0100
Revision:
6:b9b32d6c2b40
Parent:
5:4c1e581bbb8b
Child:
7:20ff5668f5fe
Aligning to ARM mbed coding style.

Who changed what in which revision?

UserRevisionLine numberNew 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>&copy; 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. */
brdirais 0:dcc35ef6effc 166 motor = new L6206( D2, A4, D5, D4, A0, A1);
brdirais 0:dcc35ef6effc 167
davide.aliprandi@st.com 6:b9b32d6c2b40 168 /* When init method is called with NULL pointer, the L6206 parameters are set */
brdirais 0:dcc35ef6effc 169 /* with the predefined values from file l6206_target_config.h, otherwise the */
davide.aliprandi@st.com 6:b9b32d6c2b40 170 /* parameters are set using the init structure values. */
davide.aliprandi@st.com 6:b9b32d6c2b40 171 if (motor->init(&init) != COMPONENT_OK) {
brdirais 0:dcc35ef6effc 172 exit(EXIT_FAILURE);
davide.aliprandi@st.com 6:b9b32d6c2b40 173 }
brdirais 0:dcc35ef6effc 174
davide.aliprandi@st.com 6:b9b32d6c2b40 175 /* Attach the function my_flag_irq_handler (defined below) to the flag interrupt */
davide.aliprandi@st.com 6:b9b32d6c2b40 176 motor->attach_flag_interrupt(my_flag_irq_handler);
brdirais 0:dcc35ef6effc 177
davide.aliprandi@st.com 6:b9b32d6c2b40 178 /* Attach the function my_error_handler (defined below) to the error Handler*/
davide.aliprandi@st.com 6:b9b32d6c2b40 179 motor->attach_error_handler(my_error_handler);
brdirais 0:dcc35ef6effc 180
brdirais 0:dcc35ef6effc 181 /* Printing to the console. */
brdirais 1:4d9b9123d9e1 182 printf("Motor Control Application Example for 4 Motor\r\n\n");
brdirais 0:dcc35ef6effc 183
brdirais 0:dcc35ef6effc 184 /* Select the configuration with no bridge paralleling, two unidirectionnal motors on bridge A
brdirais 0:dcc35ef6effc 185 and two unidirectionnal motors on bridge B */
davide.aliprandi@st.com 6:b9b32d6c2b40 186 motor->set_dual_full_bridge_config(PARALLELING_NONE___2_UNDIR_MOTOR_BRIDGE_A__2_UNDIR_MOTOR_BRIDGE_B);
brdirais 0:dcc35ef6effc 187
brdirais 1:4d9b9123d9e1 188 /* Set PWM Frequency of bridge A inputs to 1000 Hz */
davide.aliprandi@st.com 6:b9b32d6c2b40 189 motor->set_bridge_input_pwm_freq(0,1000);
brdirais 0:dcc35ef6effc 190
brdirais 1:4d9b9123d9e1 191 /* Set PWM Frequency of bridge B inputs to 2000 Hz */
davide.aliprandi@st.com 6:b9b32d6c2b40 192 motor->set_bridge_input_pwm_freq(1,2000);
brdirais 0:dcc35ef6effc 193
davide.aliprandi@st.com 6:b9b32d6c2b40 194 // Attach my_button_pressed function to Irq
davide.aliprandi@st.com 6:b9b32d6c2b40 195 my_button_irq.fall(&my_button_pressed);
brdirais 0:dcc35ef6effc 196
brdirais 0:dcc35ef6effc 197 /* Infinite loop */
davide.aliprandi@st.com 6:b9b32d6c2b40 198 while (true) {
brdirais 0:dcc35ef6effc 199
davide.aliprandi@st.com 6:b9b32d6c2b40 200 if (gStep > 0) {
davide.aliprandi@st.com 6:b9b32d6c2b40 201 printf("run motor 0 at 20%% of the maximum speed\n");
brdirais 1:4d9b9123d9e1 202 /* Set speed of motor 0 to 20% */
davide.aliprandi@st.com 6:b9b32d6c2b40 203 motor->set_speed(0,20);
brdirais 0:dcc35ef6effc 204 /* start motor 0 */
davide.aliprandi@st.com 6:b9b32d6c2b40 205 motor->run(0, BDCMotor::FWD);
brdirais 0:dcc35ef6effc 206 }
brdirais 0:dcc35ef6effc 207
davide.aliprandi@st.com 6:b9b32d6c2b40 208 if (gStep > 1) {
davide.aliprandi@st.com 6:b9b32d6c2b40 209 printf("run motor 1 at 30%% of the maximum speed\n");
brdirais 0:dcc35ef6effc 210 /* Set speed of motor 1 to 30 % */
davide.aliprandi@st.com 6:b9b32d6c2b40 211 motor->set_speed(1,30);
brdirais 0:dcc35ef6effc 212 /* start motor 1 */
davide.aliprandi@st.com 6:b9b32d6c2b40 213 motor->run(1, BDCMotor::FWD);
brdirais 0:dcc35ef6effc 214 }
brdirais 0:dcc35ef6effc 215
davide.aliprandi@st.com 6:b9b32d6c2b40 216 if (gStep > 2) {
davide.aliprandi@st.com 6:b9b32d6c2b40 217 printf("run motor 2 at 40%% of the maximum speed\n");
brdirais 0:dcc35ef6effc 218 /* Set speed of motor 2 to 40 % */
davide.aliprandi@st.com 6:b9b32d6c2b40 219 motor->set_speed(2,40);
brdirais 0:dcc35ef6effc 220 /* start motor 2 */
davide.aliprandi@st.com 6:b9b32d6c2b40 221 motor->run(2, BDCMotor::FWD);
brdirais 0:dcc35ef6effc 222 }
brdirais 0:dcc35ef6effc 223
davide.aliprandi@st.com 6:b9b32d6c2b40 224 if (gStep > 3) {
davide.aliprandi@st.com 6:b9b32d6c2b40 225 printf("run motor 3 at 50%% of the maximum speed\n");
brdirais 0:dcc35ef6effc 226 /* Set speed of motor 3 to 50 % */
davide.aliprandi@st.com 6:b9b32d6c2b40 227 motor->set_speed(3,50);
brdirais 0:dcc35ef6effc 228 /* start motor 3 */
davide.aliprandi@st.com 6:b9b32d6c2b40 229 motor->run(3, BDCMotor::FWD);
brdirais 0:dcc35ef6effc 230 }
brdirais 0:dcc35ef6effc 231
davide.aliprandi@st.com 6:b9b32d6c2b40 232 if (gStep > 0) {
brdirais 0:dcc35ef6effc 233 wait_ms(1000);
brdirais 0:dcc35ef6effc 234
davide.aliprandi@st.com 6:b9b32d6c2b40 235 motor->hard_hiz(0);
davide.aliprandi@st.com 6:b9b32d6c2b40 236 motor->hard_hiz(1);
davide.aliprandi@st.com 6:b9b32d6c2b40 237 motor->hard_hiz(2);
davide.aliprandi@st.com 6:b9b32d6c2b40 238 motor->hard_hiz(3);
brdirais 0:dcc35ef6effc 239
brdirais 0:dcc35ef6effc 240 wait_ms(1000);
brdirais 0:dcc35ef6effc 241 }
brdirais 0:dcc35ef6effc 242 }
brdirais 0:dcc35ef6effc 243 }
brdirais 0:dcc35ef6effc 244
brdirais 0:dcc35ef6effc 245 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/