Skip to content

Commit 7c93b4f

Browse files
authored
Merge pull request #1 from Edi-Codutti/main
X-NUCLEO-IHM04A1
2 parents 73c0018 + e340afd commit 7c93b4f

File tree

16 files changed

+3539
-1
lines changed

16 files changed

+3539
-1
lines changed
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
name: X-NUCLEO-IHM04A1 Continuous Integration
2+
on:
3+
push:
4+
branches:
5+
- main
6+
paths-ignore:
7+
- '*'
8+
- '**.md'
9+
- '**.txt'
10+
pull_request:
11+
paths-ignore:
12+
- '*'
13+
- '**.md'
14+
- '**.txt'
15+
jobs:
16+
astyle_check:
17+
runs-on: ubuntu-latest
18+
name: AStyle check
19+
steps:
20+
# First of all, clone the repo using the checkout action.
21+
- name: Checkout
22+
uses: actions/checkout@main
23+
24+
- name: Astyle check
25+
id: Astyle
26+
uses: stm32duino/actions/astyle-check@main
27+
28+
# Use the output from the `Astyle` step
29+
- name: Astyle Errors
30+
if: failure()
31+
run: |
32+
cat ${{ steps.Astyle.outputs.astyle-result }}
33+
exit 1
34+
codespell:
35+
name: Check for spelling errors
36+
runs-on: ubuntu-latest
37+
steps:
38+
- name: Checkout
39+
uses: actions/checkout@main
40+
41+
# See: https://github.com/codespell-project/actions-codespell/blob/master/README.md
42+
- name: Spell check
43+
uses: codespell-project/actions-codespell@master
44+
with:
45+
check_filenames: true
46+
check_hidden: true
47+
# In the event of a false positive, add the word in all lower case to this file:
48+
ignore_words_file: ./extras/codespell-ignore-words-list.txt
49+
lib_build:
50+
runs-on: ubuntu-latest
51+
name: Library compilation
52+
steps:
53+
# First of all, clone the repo using the checkout action.
54+
- name: Checkout
55+
uses: actions/checkout@main
56+
57+
- name: Compilation
58+
id: compile
59+
uses: stm32duino/actions/compile-examples@main
60+
with:
61+
board-pattern: "NUCLEO_L476RG"
62+
63+
# Use the output from the `Compilation` step
64+
- name: Compilation Errors
65+
if: failure()
66+
run: |
67+
cat ${{ steps.compile.outputs.compile-result }}
68+
exit 1

README.md

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,31 @@
11
# X-NUCLEO-IHM04A1
2-
Arduino library to support dual brush DC motor driver based on L6206 component
2+
3+
The X-NUCLEO-IHM04A1 is a dual brush DC motor drive expansion board based on the L6206
4+
(DMOS dual full bridge driver) to drive dual bipolar DC or quad unipolar DC motors.
5+
It provides an affordable and easy-to-use solution for driving DC motors in your STM32 Nucleo project.
6+
The X-NUCLEO-IHM04A1 is compatible with the Arduino UNO R3 connector,
7+
and supports the addition of other expansion boards with a single STM32 Nucleo board.
8+
The user can also mount the ST Morpho connector.
9+
10+
## Examples
11+
12+
There are 3 examples with the X-NUCLEO-IHM04A1 library.
13+
Each one provides a simple example of usage of the X-NUCLEO-IHM04A1 board.
14+
* X_NUCLEO_IHM04A1_2BiDir: This application shows how to use two brush DC motors connected to the board,
15+
moving the rotors with several speed values, direction of rotations, etc.
16+
* X_NUCLEO_IHM04A1_1BiDir: This application is similar to the previous one, but, at every bridge,
17+
the two half-bridges are connected in parallel so that the dissipation in the device
18+
will be reduced, but the peak current rating is not increased.
19+
This example uses 1 brush DC motor in bidirectional mode.
20+
* X_NUCLEO_IHM04A1_4UniDir: This application shows how use the board to control 4 brush DC motors in unidirectional mode.
21+
22+
## Documentation
23+
24+
You can find the source files at
25+
https://github.com/stm32duino/X-NUCLEO-IHM04A1
26+
27+
The L6206 datasheet is available at
28+
https://www.st.com/en/motor-drivers/l6206.html
29+
30+
Information about the IHM04A1 can be found at
31+
https://www.st.com/en/evaluation-tools/x-nucleo-ihm04a1.html

astyle.out

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Formatted C:\Users\coduttie\X-NUCLEO-IHM04A1\examples\X_NUCLEO_IHM04A1_4UniDir\X_NUCLEO_IHM04A1_4UniDir.cpp
Lines changed: 280 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,280 @@
1+
/**
2+
******************************************************************************
3+
* @file X_NUCLEO_IHM15A1_HelloWorld.ino
4+
* @author STMicroelectronics
5+
* @version V1.0.0
6+
* @date 12 January 2022
7+
* @brief Arduino test application for the STMicroelectronics X-NUCLEO-IHM15A1
8+
* Motor Control Expansion Board: control of 2 DC Brush motors.
9+
******************************************************************************
10+
* @attention
11+
*
12+
* <h2><center>&copy; COPYRIGHT(c) 2022 STMicroelectronics</center></h2>
13+
*
14+
* Redistribution and use in source and binary forms, with or without modification,
15+
* are permitted provided that the following conditions are met:
16+
* 1. Redistributions of source code must retain the above copyright notice,
17+
* this list of conditions and the following disclaimer.
18+
* 2. Redistributions in binary form must reproduce the above copyright notice,
19+
* this list of conditions and the following disclaimer in the documentation
20+
* and/or other materials provided with the distribution.
21+
* 3. Neither the name of STMicroelectronics nor the names of its contributors
22+
* may be used to endorse or promote products derived from this software
23+
* without specific prior written permission.
24+
*
25+
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
26+
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27+
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
28+
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
29+
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
30+
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
31+
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
32+
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
33+
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
34+
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
35+
*
36+
******************************************************************************
37+
*/
38+
39+
/* Includes ------------------------------------------------------------------*/
40+
41+
/* Arduino specific header files. */
42+
#include "Arduino.h"
43+
44+
/* Component specific header files. */
45+
#include "l6206.h"
46+
47+
/* Definitions ---------------------------------------------------------------*/
48+
49+
#define SerialPort Serial
50+
51+
/* Variables -----------------------------------------------------------------*/
52+
L6206_Init_t gMotorInitStruct = {
53+
.config = L6206_CONF_PARAM_PARALLE_BRIDGES,
54+
.pwmFreq = {L6206_CONF_PARAM_FREQ_PWM1A, L6206_CONF_PARAM_FREQ_PWM2A, L6206_CONF_PARAM_FREQ_PWM1B, L6206_CONF_PARAM_FREQ_PWM2B}
55+
};
56+
57+
/* Motor Control Component. */
58+
L6206 *motor;
59+
60+
static volatile uint16_t gLastError;
61+
62+
/* Functions -----------------------------------------------------------------*/
63+
64+
/**
65+
* @brief This is an example of error handler.
66+
* @param[in] error Number of the error
67+
* @retval None
68+
* @note If needed, implement it, and then attach it:
69+
* + motor->attach_error_handler(&my_error_handler);
70+
*/
71+
void my_error_handler(uint16_t error)
72+
{
73+
/* Printing to the console. */
74+
char report[256];
75+
sprintf(report, "Error 0x%x detected\r\n\n", error);
76+
SerialPort.print(report);
77+
78+
uint32_t blinkDelay = 0;
79+
80+
/* Backup error number */
81+
gLastError = error;
82+
switch (gLastError) {
83+
case 0XBAD0: blinkDelay = 100;
84+
// fail on Bridge A: fast LED blinking -> 100ms
85+
motor->disable_bridge(0);
86+
motor->hard_stop(1);
87+
break;
88+
case 0XBAD1: blinkDelay = 500;
89+
// fail on Bridge B: LED blinking -> 500ms
90+
motor->disable_bridge(1);
91+
motor->hard_stop(0);
92+
break;
93+
case 0XBADB: blinkDelay = 2000;
94+
// fail on Bridge A: slow LED blinking -> 2s
95+
motor->disable_bridge(0);
96+
motor->disable_bridge(1);
97+
break;
98+
default:
99+
blinkDelay = 10;
100+
}
101+
102+
/* Infinite loop */
103+
while (1) {
104+
delay(blinkDelay);
105+
digitalWrite(LED_BUILTIN, HIGH);
106+
delay(blinkDelay);
107+
digitalWrite(LED_BUILTIN, LOW);
108+
}
109+
}
110+
111+
/**
112+
* @brief This is an example of user handler for the flag interrupt.
113+
* @param None
114+
* @retval None
115+
*/
116+
void my_flag_irq_handler(void)
117+
{
118+
/* Code to be customised */
119+
/************************/
120+
/****** Code to be customised... *******/
121+
122+
/**
123+
*********************************************************************
124+
* In this example the code checks on which bridge the FAULT occurred.
125+
* Then an error code is generated according to the FAULT detected and
126+
* the error handler is called.
127+
*********************************************************************
128+
*/
129+
130+
SerialPort.print(" WARNING: \"FLAG\" interrupt triggered.\r\n");
131+
132+
/* Get the state of bridge A */
133+
uint16_t bridgeStateA = 1;
134+
uint16_t bridgeStateB = 1;
135+
136+
if (motor->get_device_state(0) != INACTIVE) {
137+
bridgeStateA = motor->get_bridge_status(BRIDGE_A);
138+
}
139+
140+
if (motor->get_device_state(1) != INACTIVE) {
141+
bridgeStateB = motor->get_bridge_status(BRIDGE_B);
142+
}
143+
144+
if (bridgeStateA == 0 && bridgeStateB != 0) {
145+
/* Bridge A was disabled due to overcurrent */
146+
/* When motor was running */
147+
my_error_handler(0XBAD0);
148+
} else if (bridgeStateA != 0 && bridgeStateB == 0) {
149+
/* Bridges B was disabled due to overcurrent */
150+
/* When motor was running */
151+
my_error_handler(0XBAD1);
152+
} else if (bridgeStateA == 0 && bridgeStateB == 0) {
153+
/* Both Bridges B was disabled due to overcurrent */
154+
/* over temperature or UVLO when motor was running */
155+
my_error_handler(0XBADB);
156+
}
157+
}
158+
159+
/* setup ----------------------------------------------------------------------*/
160+
161+
void setup()
162+
{
163+
// Led.
164+
pinMode(LED_BUILTIN, OUTPUT);
165+
166+
/* Initialize Serial Port */
167+
SerialPort.begin(115200);
168+
169+
/* Printing to the console. */
170+
SerialPort.println("STARTING DEMO PROGRAM");
171+
172+
/* Initialization of the motor driver*/
173+
/* Please, be careful that pins can change if you change the Nucleo board */
174+
/* Give a look at the DataSheet of the Nucleo to find a correct configuration */
175+
motor = new L6206(D2, A4, D5, D4, A0, A1);
176+
177+
if (motor->init(&gMotorInitStruct) != COMPONENT_OK) {
178+
exit(EXIT_FAILURE);
179+
}
180+
181+
/* Attaching and enabling an interrupt handler. */
182+
motor->attach_flag_irq(&my_flag_irq_handler);
183+
184+
/* Attaching an error handler */
185+
motor->attach_error_handler(&my_error_handler);
186+
187+
/* Printing to the console. */
188+
SerialPort.print("Motor Control Application Example for 1 bidirectional brush DC motors\r\n");
189+
190+
motor->set_dual_full_bridge_config(PARALLELING_IN1A_IN2A__IN1B_IN2B__1_BIDIR_MOTOR);
191+
192+
/* Set PWM Frequency of bridge A inputs to 10000 Hz */
193+
motor->set_bridge_input_pwm_freq(BRIDGE_A, 10000);
194+
195+
/* Set PWM Frequency of bridge B inputs to 10000 Hz */
196+
motor->set_bridge_input_pwm_freq(BRIDGE_B, 10000);
197+
}
198+
199+
/* loop ----------------------------------------------------------------------*/
200+
201+
void loop()
202+
{
203+
static uint8_t demoStep = 0;
204+
205+
switch (demoStep) {
206+
case 0: {
207+
SerialPort.print("STEP 0: Motor(0) FWD Speed=100%%\r\n");
208+
/* Set speed of motor 0 to 100 % */
209+
motor->set_speed(0, 100);
210+
/* start motor 0 to run forward*/
211+
/* if chip is in standby mode */
212+
/* it is automatically awakened */
213+
motor->run(0, BDCMotor::FWD);
214+
break;
215+
}
216+
case 1: {
217+
SerialPort.print("STEP 1: Motor(0) FWD Speed=75%%\r\n");
218+
/* Set speed of motor 0 to 75 % */
219+
motor->set_speed(0, 75);
220+
break;
221+
}
222+
case 2: {
223+
SerialPort.print("STEP 2: Motor(0) FWD Speed=50%%\r\n");
224+
/* Set speed of motor 0 to 50 % */
225+
motor->set_speed(0, 50);
226+
break;
227+
}
228+
case 3: {
229+
SerialPort.print("STEP 3: Motor(0) FWD Speed=25%% \r\n");
230+
/* Set speed of motor 0 to 25 % */
231+
motor->set_speed(0, 25);
232+
break;
233+
}
234+
case 4: {
235+
SerialPort.print("STEP 4: Motor(0) Stopped\r\n");
236+
/* Stop Motor 0 */
237+
motor->hard_stop(0);
238+
break;
239+
}
240+
case 5: {
241+
SerialPort.print("STEP 5: Motor(0) BWD Speed=25%%\r\n");
242+
/* Set speed of motor 0 to 25 % */
243+
motor->set_speed(0, 25);
244+
/* start motor 0 to run backward */
245+
motor->run(0, BDCMotor::BWD);
246+
break;
247+
}
248+
case 6: {
249+
SerialPort.print("STEP 6: Motor(0) BWD Speed=50%%\r\n");
250+
/* Set speed of motor 0 to 50 % */
251+
motor->set_speed(0, 50);
252+
break;
253+
}
254+
case 7: {
255+
SerialPort.print("STEP 7: Motor(0) BWD Speed=75%%\r\n");
256+
/* Set speed of motor 0 to 75 % */
257+
motor->set_speed(0, 75);
258+
break;
259+
}
260+
case 8: {
261+
SerialPort.print("STEP 8: Motor(0) BWD Speed=100%%\r\n");
262+
/* Set speed of motor 0 to 100 % */
263+
motor->set_speed(0, 100);
264+
break;
265+
}
266+
case 9:
267+
default: {
268+
SerialPort.print("STEP 9: Stop motor and disable bridge\r\n");
269+
/* Stop both motors and disable bridge */
270+
motor->hard_hiz(0);
271+
break;
272+
}
273+
}
274+
275+
/* Wait for 2 seconds */
276+
delay(2000);
277+
278+
/* Increment demostep*/
279+
demoStep = (demoStep + 1) % 10;
280+
}

0 commit comments

Comments
 (0)