Example application for X-NUCLEO-IHM07M1 board connected to a 3-phase brushless motor with Hall sensors.

Dependencies:   BLDCmotorDriver RateLimiter mbed

Fork of HelloWorld_IHM07M1 by Antonio Vilei

Getting Started with X-NUCLEO-IHM07M1

This example demonstrates how to use the X-NUCLEO-IHM07M1 component with one of the STM32 Nucleo-64 platforms and a three-phase brushless DC (BLDC) motor with Hall sensors.

HW Prerequisites

  • X-NUCLEO-IHM07M1
  • STM32 Nucleo-64 board
  • external DC power supply
  • low voltage three-phase BLDC motor with Hall sensors

X-NUCLEO-IHM07M1 Jumpers Configuration

/media/uploads/avilei/x-nucleo-ihm07m1_jumpers.jpg
Configure the jumpers of your X-NUCLEO-IHM07M1 board as shown below:

  • JP1 open
  • JP2 open
  • JP3 closed
  • J9 closed
  • J5 closed on 2-3 (single shunt)
  • J6 closed on 2-3 (single shunt)
  • J7 open

For more details please refer to the X-NUCLEO-IHM07M1 user manual.

BLDCmotorDriver Library

This example is based on the BLDCmotorDriver motor control library by the TVZ Mechatronics Team, University of Applied Sciences Zagreb, Professional Study in Mechatronics. The BLDCmotorDriver library is a simple implementation of the six-step algorithm and needs Hall sensors to estimate the correct timing for commutation. If you want to use sensor-less BLDC motors with X-NUCLEO-IHM07M1 or if you want an optimized implementation, you must use a different software package like X-CUBE-SPN7, based on STM32Cube.

The HelloWorld_IHM07M1 application has been tested with the Nanotec DF45M024053-A2 motor, a 24V three-phase brushless motor with Hall sensors. This example implements a temperature check to prevent overheating.
If you use a different motor, please be advised that you may need to tweak the configuration parameters for the BLDCmotorDriver library.

Connecting the Motor

/media/uploads/avilei/wirings.jpg
In the picture above you can see an example setup with the Nanotec DF45M024053-A2 motor and a 24V power supply. If you use the same motor, please connect the brown, grey and yellow phases to the OUT1, OUT2 and OUT3 connectors of the X-NUCLEO-IHM07M1 board respectively. Then connect the blue, green, white, red and black wires for the Hall sensors to the A+/H1, B+/H2, Z+/H3, 5V, GND connectors as shown in the picture. If your motor is different, you must pay attention to connect the motor phases and Hall sensors pins in the correct order otherwise the motor won't spin.

Spinning the Motor

Open a terminal window (baudrate 9600, 8N1) to display the user interface of the HelloWorld_IHM07M1 application.
Press the 'w' character to start spinning the motor and speed it up; press the 's' character to slow it down and turn it off.
/media/uploads/avilei/terminal.png

Note

You need a terminal emulator installed on your PC to perform serial communications with your STM32 Nucleo platform. If you do not have it, please download and install one of the following terminal emulation programs:

Committer:
avilei
Date:
Mon Oct 17 15:17:28 2016 +0000
Revision:
6:0eec4b6e94ba
Parent:
5:3290e8857120
Child:
7:022c306baeb9
Add comments

Who changed what in which revision?

UserRevisionLine numberNew contents of line
avilei 2:4ae769d0b112 1 /* mbed Microcontroller Library
avilei 2:4ae769d0b112 2 * Copyright (c) 2006-2016 ARM Limited
avilei 2:4ae769d0b112 3 *
avilei 2:4ae769d0b112 4 * Licensed under the Apache License, Version 2.0 (the "License");
avilei 2:4ae769d0b112 5 * you may not use this file except in compliance with the License.
avilei 2:4ae769d0b112 6 * You may obtain a copy of the License at
avilei 2:4ae769d0b112 7 *
avilei 2:4ae769d0b112 8 * http://www.apache.org/licenses/LICENSE-2.0
avilei 2:4ae769d0b112 9 *
avilei 2:4ae769d0b112 10 * Unless required by applicable law or agreed to in writing, software
avilei 2:4ae769d0b112 11 * distributed under the License is distributed on an "AS IS" BASIS,
avilei 2:4ae769d0b112 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
avilei 2:4ae769d0b112 13 * See the License for the specific language governing permissions and
avilei 2:4ae769d0b112 14 * limitations under the License.
avilei 2:4ae769d0b112 15 */
avilei 2:4ae769d0b112 16
avilei 2:4ae769d0b112 17 /**
avilei 2:4ae769d0b112 18 ******************************************************************************
avilei 2:4ae769d0b112 19 * @file SPN7Driver.cpp
avilei 2:4ae769d0b112 20 * @author STMicroelectronics
avilei 2:4ae769d0b112 21 * @brief Implementation of SPN7Driver class
avilei 2:4ae769d0b112 22 ******************************************************************************
avilei 2:4ae769d0b112 23 * @copy
avilei 2:4ae769d0b112 24 *
avilei 2:4ae769d0b112 25 * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
avilei 2:4ae769d0b112 26 * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
avilei 2:4ae769d0b112 27 * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY
avilei 2:4ae769d0b112 28 * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
avilei 2:4ae769d0b112 29 * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
avilei 2:4ae769d0b112 30 * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
avilei 2:4ae769d0b112 31 *
avilei 2:4ae769d0b112 32 * <h2><center>&copy; COPYRIGHT 2016 STMicroelectronics</center></h2>
avilei 2:4ae769d0b112 33 */
avilei 2:4ae769d0b112 34
avilei 2:4ae769d0b112 35 #include "mbed.h"
avilei 2:4ae769d0b112 36 #include "SPN7Driver.h"
avilei 2:4ae769d0b112 37
avilei 3:4c71d3475814 38 typedef enum {
avilei 3:4c71d3475814 39 ST_BLDC_LOW = 0,
avilei 3:4c71d3475814 40 ST_BLDC_HIGH,
avilei 3:4c71d3475814 41 ST_BLDC_OFF
avilei 3:4c71d3475814 42 } st_bldc_status_t;
avilei 3:4c71d3475814 43
avilei 6:0eec4b6e94ba 44 /**************************************************************************/
avilei 6:0eec4b6e94ba 45 /**
avilei 6:0eec4b6e94ba 46 @brief Constructor
avilei 6:0eec4b6e94ba 47 * @param pIN1 Logic input pin IN1 of L6230 chip
avilei 6:0eec4b6e94ba 48 * @param pIN2 Logic input pin IN2 of L6230 chip
avilei 6:0eec4b6e94ba 49 * @param pIN3 Logic input pin IN3 of L6230 chip
avilei 6:0eec4b6e94ba 50 * @param pEN1 Enable channel pin EN1 of L6230 chip
avilei 6:0eec4b6e94ba 51 * @param pEN2 Enable channel pin EN2 of L6230 chip
avilei 6:0eec4b6e94ba 52 * @param pEN3 Enable channel pin EN3 of L6230 chip
avilei 6:0eec4b6e94ba 53 * @param pH1 Hall sensor pin for phase #1 (A) of X-NUCLEO-IHM07M1
avilei 6:0eec4b6e94ba 54 * @param pH2 Hall sensor pin for phase #2 (B) of X-NUCLEO-IHM07M1
avilei 6:0eec4b6e94ba 55 * @param pH3 Hall sensor pin for phase #3 (Z) of X-NUCLEO-IHM07M1
avilei 6:0eec4b6e94ba 56 * @param pFault Fault LED pin of X-NUCLEO-IHM07M1
avilei 6:0eec4b6e94ba 57 */
avilei 6:0eec4b6e94ba 58 /**************************************************************************/
avilei 2:4ae769d0b112 59 SPN7Driver::SPN7Driver(PinName pIN1, PinName pIN2, PinName pIN3,
avilei 2:4ae769d0b112 60 PinName pEN1, PinName pEN2, PinName pEN3,
avilei 2:4ae769d0b112 61 PinName pH1, PinName pH2, PinName pH3,
avilei 2:4ae769d0b112 62 PinName pFault) :
avilei 2:4ae769d0b112 63 BLDCmotorDriver(pIN1, pIN2, pIN3,
avilei 2:4ae769d0b112 64 pEN1, pEN2, pEN3,
avilei 2:4ae769d0b112 65 pH1, pH2, pH3,
avilei 2:4ae769d0b112 66 pFault)
avilei 2:4ae769d0b112 67 {
avilei 2:4ae769d0b112 68 // The BLDCmotorDriver class was implemented for half-bridge drivers
avilei 2:4ae769d0b112 69 // so the pin names may be misleading when referring to the L6230 chip.
avilei 3:4c71d3475814 70 // Get pointers to each input pin and call them IN[x] (logic input)
avilei 2:4ae769d0b112 71 // to be consistent with the terminology used in the L6230 documentation.
avilei 3:4c71d3475814 72 PwmOut* IN[3] = {&GH_A, &GH_B, &GH_C};
avilei 3:4c71d3475814 73
avilei 2:4ae769d0b112 74 // Set the switching period of the INx logic input pins (PWM driven)
avilei 3:4c71d3475814 75 for (int i = 0; i < 3; i++) {
avilei 3:4c71d3475814 76 IN[i]->period(switchingPeriod);
avilei 3:4c71d3475814 77 }
avilei 2:4ae769d0b112 78
avilei 2:4ae769d0b112 79 // Set the step commutation function (triggered by the Hall sensors)
avilei 2:4ae769d0b112 80 H1.rise(this, &SPN7Driver::commutation);
avilei 2:4ae769d0b112 81 H2.rise(this, &SPN7Driver::commutation);
avilei 2:4ae769d0b112 82 H3.rise(this, &SPN7Driver::commutation);
avilei 2:4ae769d0b112 83 H1.fall(this, &SPN7Driver::commutation);
avilei 2:4ae769d0b112 84 H2.fall(this, &SPN7Driver::commutation);
avilei 2:4ae769d0b112 85 H3.fall(this, &SPN7Driver::commutation);
avilei 2:4ae769d0b112 86 }
avilei 2:4ae769d0b112 87
avilei 6:0eec4b6e94ba 88 /**************************************************************************/
avilei 6:0eec4b6e94ba 89 /**
avilei 6:0eec4b6e94ba 90 @brief Set duty cycle for motor control
avilei 6:0eec4b6e94ba 91 * @param dc duty cycle value (positive for clockwise spin)
avilei 6:0eec4b6e94ba 92 */
avilei 6:0eec4b6e94ba 93 /**************************************************************************/
avilei 4:3f63eed73ad1 94 void SPN7Driver::setDutyCycle(float dc) {
avilei 4:3f63eed73ad1 95 if (dc >= -1 && dc <= 1) {
avilei 4:3f63eed73ad1 96 ticker.attach(this, &SPN7Driver::commutation, sampleTime);
avilei 4:3f63eed73ad1 97 tempDutyCycle = dc;
avilei 4:3f63eed73ad1 98 } else {
avilei 4:3f63eed73ad1 99 coast();
avilei 4:3f63eed73ad1 100 }
avilei 4:3f63eed73ad1 101 }
avilei 4:3f63eed73ad1 102
avilei 2:4ae769d0b112 103 // 6-step phase commutation
avilei 3:4c71d3475814 104 void SPN7Driver::commutation()
avilei 3:4c71d3475814 105 {
avilei 3:4c71d3475814 106 // The BLDCmotorDriver class was implemented for half-bridge drivers
avilei 3:4c71d3475814 107 // so the pin names may be misleading when referring to the L6230 chip.
avilei 3:4c71d3475814 108 // Get pointers to each input pin and call them IN[x] (logic input)
avilei 3:4c71d3475814 109 // to be consistent with the terminology used in the L6230 documentation.
avilei 3:4c71d3475814 110 PwmOut* IN[3] = {&GH_A, &GH_B, &GH_C};
avilei 3:4c71d3475814 111 // Get pointers to each enable pin and call them ENx (enable channel)
avilei 3:4c71d3475814 112 // to be consistent with the terminology used in the L6230 documentation.
avilei 3:4c71d3475814 113 DigitalOut* EN[3] = {&GL_A, &GL_B, &GL_C};
avilei 3:4c71d3475814 114
avilei 2:4ae769d0b112 115 // 1--X--0--0--X--1
avilei 2:4ae769d0b112 116 // X--1--1--X--0--0
avilei 3:4c71d3475814 117 // 0--0--X--1--1--X
avilei 3:4c71d3475814 118 st_bldc_status_t tab[6][3] = {
avilei 3:4c71d3475814 119 {ST_BLDC_HIGH, ST_BLDC_OFF, ST_BLDC_LOW},
avilei 3:4c71d3475814 120 {ST_BLDC_OFF, ST_BLDC_HIGH, ST_BLDC_LOW},
avilei 3:4c71d3475814 121 {ST_BLDC_LOW, ST_BLDC_HIGH, ST_BLDC_OFF},
avilei 3:4c71d3475814 122 {ST_BLDC_LOW, ST_BLDC_OFF, ST_BLDC_HIGH},
avilei 3:4c71d3475814 123 {ST_BLDC_OFF, ST_BLDC_LOW, ST_BLDC_HIGH},
avilei 3:4c71d3475814 124 {ST_BLDC_HIGH, ST_BLDC_LOW, ST_BLDC_OFF},
avilei 3:4c71d3475814 125 };
avilei 2:4ae769d0b112 126
avilei 2:4ae769d0b112 127 dutyCycle = rl.out(tempDutyCycle);
avilei 2:4ae769d0b112 128 currentSector = getSector();
avilei 2:4ae769d0b112 129
avilei 3:4c71d3475814 130 if (dutyCycle == 0) {
avilei 3:4c71d3475814 131 // Stop the motor
avilei 2:4ae769d0b112 132 coast();
avilei 3:4c71d3475814 133 return;
avilei 2:4ae769d0b112 134 }
avilei 2:4ae769d0b112 135
avilei 3:4c71d3475814 136 // Move to next sector (i.e. commute phase)
avilei 3:4c71d3475814 137 if (dutyCycle > 0 ) {
avilei 3:4c71d3475814 138 // Move forward
avilei 3:4c71d3475814 139 currentSector++;
avilei 3:4c71d3475814 140 if(currentSector > 5) currentSector = 0;
avilei 3:4c71d3475814 141 } else {
avilei 3:4c71d3475814 142 // Move backward
avilei 3:4c71d3475814 143 currentSector--;
avilei 3:4c71d3475814 144 if(currentSector < 0) currentSector = 5;
avilei 3:4c71d3475814 145 }
avilei 3:4c71d3475814 146
avilei 3:4c71d3475814 147 // Get the absolute value of the duty cycle for the PWM
avilei 3:4c71d3475814 148 float d = (dutyCycle > 0) ? dutyCycle : -dutyCycle;
avilei 3:4c71d3475814 149
avilei 3:4c71d3475814 150 // Update the logic inputs and the enable pins
avilei 3:4c71d3475814 151 for (int i = 0; i < 3; i++) {
avilei 3:4c71d3475814 152 *EN[i] = (tab[currentSector][i] == ST_BLDC_OFF) ? 0 : 1;
avilei 3:4c71d3475814 153 *IN[i] = (tab[currentSector][i] == ST_BLDC_HIGH) ? d : 0;
avilei 3:4c71d3475814 154 }
avilei 2:4ae769d0b112 155 }