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.

main.cpp

Committer:
Davidroid
Date:
2017-08-03
Revision:
9:be4faa697346
Parent:
8:05340e740644

File content as of revision 9:be4faa697346:

/**
  ******************************************************************************
  * @file    main.cpp
  * @author  IPC Rennes
  * @version V1.0.0
  * @date    May 16, 2016
  * @brief   This example shows how to use 1 IHM04A1 expansion board with 
  * 4 unidirectionnal Brush DC motors.
  * Each motor has one lead connected to one of the bridge output, 
  * the other lead to the ground. The input bridges are not parallelised.
  * The demo sequence starts when the user button is pressed.
  * Each time, the user button is pressed, one new motor is activated
  ******************************************************************************
  * @attention
  *
  * <h2><center>&copy; 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"

/* Component specific header files. */
#include "L6206.h"


/* Definitions ---------------------------------------------------------------*/

#define MAX_MOTOR (4)


/* Variables -----------------------------------------------------------------*/

static volatile uint16_t gLastError;
static volatile uint8_t gStep = 0;


/* Variables -----------------------------------------------------------------*/

/* Initialization parameters. */
L6206_init_t init =
{
    L6206_CONF_PARAM_PARALLE_BRIDGES,
    {L6206_CONF_PARAM_FREQ_PWM1A, L6206_CONF_PARAM_FREQ_PWM2A, L6206_CONF_PARAM_FREQ_PWM1B, L6206_CONF_PARAM_FREQ_PWM2B},
    {100,100,100,100},
    {FORWARD,FORWARD,BACKWARD,FORWARD},
    {INACTIVE,INACTIVE,INACTIVE,INACTIVE},
    {FALSE,FALSE}
};

/* Motor Control Component. */
L6206 *motor;

/* User button on Nucleo board */
InterruptIn my_button_irq(USER_BUTTON);


/* Functions -----------------------------------------------------------------*/

/**
  * @brief  This function is executed in case of error occurrence.
  * @param  error number of the error
  * @retval None
  */
void my_error_handler(uint16_t error)
{
  /* Backup error number */
  gLastError = error;
  
  /* Enter your own code here */
}

/**
* @brief  This function is the User handler for the flag interrupt
* @param  None
* @retval None
* @note   If needed, implement it, and then attach and enable it:
*           + motor->attach_flag_interrupt(my_flag_irq_handler);
*/
void my_flag_irq_handler(void)
{
  /* Code to be customised */
  /************************/
  /* Get the state of bridge A */
  uint16_t bridgeState  = motor->get_bridge_status(0);
  
  if (bridgeState == 0) {
    if ((motor->get_device_state(0) != INACTIVE)||
        (motor->get_device_state(1) != INACTIVE)) {
      /* Bridge A was disabling due to overcurrent or over temperature */
      /* When at least on of its  motor was running */
        my_error_handler(0XBAD0);
    }
  }
  
  /* Get the state of bridge B */
  bridgeState  = motor->get_bridge_status(1);
  
  if (bridgeState == 0)  {
    if ((motor->get_device_state(2) != INACTIVE)||
        (motor->get_device_state(3) != INACTIVE)) {
      /* Bridge A was disabling due to overcurrent or over temperature */
      /* When at least on of its  motor was running */
        my_error_handler(0XBAD1);
    }
  }  
}


/* Private functions ---------------------------------------------------------*/

/**
  * @brief  Button Irq
  * @param  None
  * @retval None
  */

void my_button_pressed(void)
{
    my_button_irq.disable_irq();
    gStep++;
    if (gStep > MAX_MOTOR) {
        gStep = 0;
    }
    wait_ms(200);
    my_button_irq.enable_irq();
}


/**
  * @brief  Main program
  * @param  None
  * @retval None
  */
int main(void)
{
    /*----- Initialization. -----*/

    /* Initializing Motor Control Component. */
#ifdef TARGET_STM32F429
    motor = new L6206(D2, A4, PB_4, PC_7, PA_15, PB_3);
#else
    motor = new L6206(D2, A4, D5, D4, A0, A1);
#endif

    /* When init method is called with NULL pointer, the L6206 parameters are set   */
    /* with the predefined values from file l6206_target_config.h, otherwise the    */
    /* parameters are set using the init structure values.          */
    if (motor->init(&init) != COMPONENT_OK) {
        exit(EXIT_FAILURE);
    }

    /* Attach the function my_flag_irq_handler (defined below) to the flag interrupt */
    motor->attach_flag_interrupt(my_flag_irq_handler);

    /* Attach the function my_error_handler (defined below) to the error Handler*/
    motor->attach_error_handler(my_error_handler);

    /* Printing to the console. */
    printf("Motor Control Application Example for 4 Motors\r\n\n");

    /* Select the configuration with no bridge paralleling, two unidirectionnal motors on bridge A 
       and two unidirectionnal motors on bridge B */
    motor->set_dual_full_bridge_config(PARALLELING_NONE___2_UNDIR_MOTOR_BRIDGE_A__2_UNDIR_MOTOR_BRIDGE_B);
 
    /* Set PWM Frequency of bridge A inputs to 1000 Hz */ 
    motor->set_bridge_input_pwm_freq(0,1000);
  
    /* Set PWM Frequency of bridge B inputs to 2000 Hz */ 
    motor->set_bridge_input_pwm_freq(1,2000);
  
    // Attach my_button_pressed function to Irq
    my_button_irq.fall(&my_button_pressed);

    /* Infinite loop */
    while (true) {

        if (gStep > 0) {
            printf("Running motor 0 at 5%% of the maximum speed\r\n");
            /* Set speed of motor 0 to 5% */
            motor->set_speed(0,5);
            /* start motor 0 */
            motor->run(0, BDCMotor::FWD);
        }

        if (gStep > 1) {
            printf("Running motor 1 at 10%% of the maximum speed\r\n");
            /* Set speed of motor 1 to 10 % */
            motor->set_speed(1,10);
            /* start motor 1 */
            motor->run(1, BDCMotor::FWD);
        }

        if (gStep > 2) {
            printf("Running motor 2 at 15%% of the maximum speed\r\n");
            /* Set speed of motor 2 to 15 % */
            motor->set_speed(2,15);
            /* start motor 2 */
            motor->run(2, BDCMotor::FWD);
        }

        if (gStep > 3)  {
            printf("Running motor 3 at 20%% of the maximum speed\r\n");
            /* Set speed of motor 3 to 20 % */
            motor->set_speed(3,20);
            /* start motor 3 */
            motor->run(3, BDCMotor::FWD);      
        }

        if (gStep > 0) {
            wait_ms(1000);
        
            motor->hard_hiz(0);   
            motor->hard_hiz(1);   
            motor->hard_hiz(2);   
            motor->hard_hiz(3);
            
            wait_ms(1000);
        }
    }
}

/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/