Difference between revisions of "Nucleo Boards for Control Systems"

From RobolaboWiki
Jump to: navigation, search
(Created page with "__TOC__ <!-- <h1> Configuring environment </h1> <h2> Linux </h2> <h3> Installing dependencies </h3> <h4>Dependencies for compilling </h4> In a command line, execute: <pre>...")
 
 
(32 intermediate revisions by 4 users not shown)
Line 1: Line 1:
 
__TOC__
 
__TOC__
  
<!--
 
<h1> Configuring environment </h1>
 
<h2> Linux </h2>
 
<h3> Installing dependencies </h3>
 
  
<h4>Dependencies for compilling </h4>
+
To install STM32CubeIDE and to run a Hello World example, please check it here: http://wiki.robolabo.etsit.upm.es/index.php/Nucleo_Boards
In a command line, execute:
+
<pre>
+
sudo apt-get install build-essential gcc-arm-none-eabi libnewlib-arm-none-eabi libstdc++-arm-none-eabi-newlib
+
</pre>
+
  
<h4> Dependencies for flashing the microcontroller </h4>
+
<h1> GPIO read and write </h1>
In a command line, execute:
+
 
 +
<h2> Read from a GPIO</h2>
 
<pre>
 
<pre>
sudo apt-get install git cmake libusb-1.0-0-dev dfu-util
+
HAL_GPIO_ReadPin (GPIOA, GPIO_PIN_9);
 
</pre>
 
</pre>
 
+
<h2> Write to a GPIO</h2>
<h4> Dependencies for debugging the microcontroller </h4>
+
- High level:
In a command line, execute:
+
 
<pre>
 
<pre>
sudo apt-get install gdb
+
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_8, GPIO_PIN_SET);
 
</pre>
 
</pre>
  
Moreover, stlink utility is mandatory to debug in a nucleo board.
+
- Low level:
In a command line, execute:
+
 
<pre>
 
<pre>
git clone https://github.com/texane/stlink.git
+
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_8, GPIO_PIN_RESET);
cd stlink
+
make
+
cd build/Release
+
sudo make install
+
 
</pre>
 
</pre>
  
<h3> References </h3>
 
https://nebkelectronics.wordpress.com/2016/12/19/the-stm32cube-library-part-1-toolchain/ <br>
 
https://nebkelectronics.wordpress.com/2016/12/24/stm32cube-library-part-2-hello-world/ <br>
 
https://nebkelectronics.wordpress.com/2017/10/08/stm32cube-library-part-3-compiling/
 
  
 +
<h1> Encoder </h1>
 +
<h2> Theory </h2>
  
-->
+
The encoder used in the laboratory is a position sensor that uses a two-channels hall effect sensor. It is a quadrature encoder that is attached to the motor shaft and which provides a resolution of <b>48 counts per revolution</b>. This means that, for a complete turn of the motor shaft, the encoder provides a value of 48 counts. The hall sensor requires an input voltage, Vcc. Additionally, the output of the encoder comes from reading the output of the two channels, channel A and channel B, of the hall sensor. These two channels are square waves which are 90º out of phase.
  
<h1> STM32CubeIDE </h1>
+
<h2> Encoder Configuration in STM32CubeIDE</h2>
<h2> Installation </h2>
+
This section explains how to easily configure an STM32 timer as an encoder with STM32CubeIDE.
 +
The first step is to select one of the available timers that can be
 +
The main timers that can be set as PWM are: TIM2, TIM3, TIM4 and TIM5.
  
<h3> Linux </h3>
+
<b>Advice:</b> It is recommended to use the timer that matches directly with the pins connected to the encoder of the motor through the H-bridge.
  
Last release of STM32CubeIDE can be obtained here: https://www.st.com/en/development-tools/stm32cubeide.html. <br>
+
It is very important to configure this timer using the Encoder Mode in the Combined Channels (Channels 1 and 2) of the selected timer.
For Debian like distributions (e.g. ubuntu), download the STM32CubeIDE-DEB file. To download it, you will need to provide name and a valid email address.
+
Once the timer has been configured as an encoder, we must activate corresponding global interrupt in the NVIC Interrupt Table.
 +
Other relevant parameters are:
 +
<ul>
 +
<li><b>Counter Period:</b> Parameter to set the value of the ARR register. It represents the max. value of the timer's counter before reset. </li>
 +
<li><b>Encoder Mode:</b>Should be set to "Encoder Mode TI1 and TI2" for handling both encoder channels.</li>
 +
</ul>
  
Unzip the file (e.g. <FILE> = en.st-stm32cubeide_1.0.1_3139_20190612_1256_amd64.deb_bundle)
+
Once configured, we should start the timer as follows:
 +
<pre>HAL_TIM_Encoder_Start_IT(&htimx, TIM_CHANNEL_ALL);</pre>
  
 +
<!--
 +
Additionally, we have to code a callback function that is executed every time the interrupt is activated.
 
<pre>
 
<pre>
unzip <FILE>.sh.zip
+
void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim){
 +
// Rellenar
 +
}
 
</pre>
 
</pre>
 +
-->
  
It will generate a .sh file.
+
The current value of the counter can be accessed though the following function:
Give it permits for execution.
+
 
+
 
<pre>
 
<pre>
chmod 777 <FILE>.sh
+
__HAL_TIM_GET_COUNTER(htim)
 
</pre>
 
</pre>
 +
where htimX is the instance of the timer X used as encoder (e.g. htim2 or htim3).
  
Finally, execute the installation
 
<pre>
 
sudo ./<FILE>.sh
 
</pre>
 
  
You must accept all license agreements.
+
<h1> PWM </h1>
  
 +
<h2> Theory </h2>
 +
One method that is often used to control the speed of a DC motor is the Pulse Width Modulation (PWM) method. The speed of the electric motor depends on the modulator voltage. The greater the voltage, the faster the rotation of an electric motor. The use of this PWM can be used to control motor rotation through changes in PWM duty cycle or PWM pulse width. When the duty cycle is 0%, the motor will stop completely. When the duty cycle is 50%, the motor will rotate at half the speed of the maximum speed and when the PWM is 100%, the motor rotates with maximum speed.
  
<h3> Windows </h3>
+
<h2> Main registers </h2>
 +
<h3> Prescaler (PSC) </h3>
  
Last release of STM32CubeIDE can be obtained here: https://www.st.com/en/development-tools/stm32cubeide.html. <br>
+
The prescaler is a register that divides the timer clock frequency to obtain a specific frequency.
For Windows like distributions, download the STM32CubeIDE-Win file. To download it, you will need to provide name and a valid email address.
+
Specifically, the frequency reduction is applied using the following formula: 
  
Unzip the file and execute the binary. Follow all steps and accept all conditions.
+
f_TMR = f_CLK / (PSC + 1)
  
<h3> MAC </h3>
+
Therefore, if the frequency to set is the same as the frequency of the clock, the PSC register must be set at PSC=0.
Last release of STM32CubeIDE can be obtained here: https://www.st.com/en/development-tools/stm32cubeide.html. <br>
+
The STM32 timers allow a prescaler value up to 65535, through 16 bits registers.  
For MAC like distributions, download the STM32CubeIDE-MAC file. To download it, you will need to provide name and a valid email address.
+
  
Unzip the file and execute the binary. Follow all steps and accept all conditions.
 
  
<b> IMPORTANT </b> Some problems have been reported related to lasts versions of STM32CubeIDE-MAC, where the code generator does not include macro definitions for the peripheral of nucleo-boards. Last version correctly tested is 1.0.0.
+
<h3> Auto Reload Register (ARR) and Capture Compare Register (CCR) </h3>
 +
The ARR register storages the maximum value that the counter can reach before going back to zero.
 +
Moreover, the CCR registers the value of the corresponding timer counter after which the output PWM signal goes from high to low level.  
 +
Every channel of the timer used to generate the PWM will have a different CCR register (for example, CCR1 and CCR2 for channels 1 and 2).
 +
In this way, the value of the CCR together with the value of the ARR define the width of the pulses and, therefore, the duty cycle of the PWM signal:
  
<h2> Hello World </h2>
+
Duty_Cycle (%) = 100 * (CCR / ARR)
In this Section a Hellow World (led blinking) example will be programmed on a NUCLEO-F446RE board:
+
  
<ul>
+
<h3> CNT </h3>
<li> Open STM32CubeIDE </li>
+
This is the register that storages the value of the counter used to generate the PWM.  
<li> Select where to store the workspace. This will be the folder where different projects could be stored. </li>
+
<li> Select <b> Start new STM32 project </b> </li>
+
<li> A microcontroller or board should be selected. In our case, a NUCLEO-F446RE will be used.
+
Then, select <b> board selector </b>  and search part number <b> Nucleo-F446RE </b>. Once chosen, press <b> Next </b> </li>
+
<li> Chose a Project name (e.g. ledp) and keep the rest of parameters as they are. Press <b> Finish </b></li>
+
<li> The STM32CubeIDE will ask if you want  Initialize all peripherals with their default Mode. Answer <b> Yes </b> </li>
+
<li> The STM32CubeIDE will inform that yhis kind of projects is associated with the STM32CubeMx prespective and will ask if you want to open this perspective now. Answer <b> Yes </b>. <br>
+
Download of required libraries will start. It could take long for the first time depending on your connection settings. </li>
+
<li> Once the project is open, on the left side on the "Project Explorer", look for <i> Src -> main.c </i>. <br>
+
Inside the code, look for the <i> while(1) </i> sentence in the <i> main(void) </i> function, and fill it as follows:
+
<pre>
+
while (1)
+
{
+
  HAL_GPIO_TogglePin(LD2_GPIO_Port, LD2_Pin);
+
  HAL_Delay(100);
+
/* USER CODE END WHILE */
+
  
/* USER CODE BEGIN 3 */
+
<h2>PWM Configuration in STM32CubeIDE</h2>
}
+
/* USER CODE END 3 */
+
  
</pre> </li>
+
To configure a timer as PWM, the first thing to do is to select one of the timers that could be configured as a PWM generator.
 +
Additionally, also the channels that will be used as PWM output must be decided.
  
<li> In order to compile, Go to <i> Project -> Build All (Ctrl+B or Hammer) </i>. It should compile the code without errors. <br>
+
<b>Advice:</b> As different PWM outputs are needed, it is recommended to use different channels of the same timer to the extent possible.
If any error appears, previous steps should be reviewed. </li>
+
<li> In order to start the debugger, Go to <i> Run -> Debug (F11 or bug) </i> <br>
+
Select STM32 MCU C/C++ Application and Press <b> OK </b> </li>
+
<li> Leave all configuration propeties as they are and Press <b> OK </b> </li>
+
<li> The STM32CubeIDE will ask if you want to switch to the debug perspective say <b> Switch </b> </li>
+
<li> In order to execute the code, Go to <i> Run -> Resume (F8 or Green Arrow) </i>. <br>
+
The led should be blinking at 100 ms. </li>
+
  
</ul>
+
The main timers that can be set as PWM are: TIM2, TIM3, TIM4 and TIM5, with 4 different channels each of them.
  
<h2> Problems with STM32CUBEIDE </h2>
+
<b>Advice:</b> It is recommended to use the timer and the corresponding channels that match directly with the pins that feed the H-bridge to modulate the speed of the motor. Otherwise, the PWM output signals must be bridged with the H-bridge input signals.
<h3> sprintf %f </h3>
+
  
All the information on this page is obtained from: http://www.nadler.com/embedded/newlibAndFreeRTOS.html
+
Therefore, the pins that the channels of the timer are using need to be checked in the "Pinout" section of the STM32CubeIDE.
There is some errors on the implementation of malloc on STM32CubeMX, so if using some newlib fuctions (e.g. sprintf %f), the following steps must be implemented:
+
  
 +
Once the channels of the timer have been activated, some parameters and the configuration of the timer must be changed.
 +
 +
Main parameters:
 
<ul>
 
<ul>
<li> Remove heapX.c form Middlewares->Thirs_Party->FreeRTOS->Source->CMSIS_RTOS_V2->portable->MemMang->heap_X.c </li>
+
<li><b>Clock Source:</b> Clock of the timer. The Internal clock option must be selected. Moreover, it must be checked that the frequency of the clock that is being used is the one desired. This could be checked within the clock configuration tab of the STM32CubeIDE. </li>
<li> Add this file to the Src directory: [[media:heap_useNewlib.txt | heap_useNewlib]] and rename it as heap_useNewlib.c</li>
+
<li><b>Channel x:</b> Configuration for the channel x of the timer. The option “PWM Generation CHx” must be selected, in which x will be the number of the channel to configure.</li>
<li> Comment _sbrk function on sysmem.c file; it is already implemented on heap_useNewlib.c </li>
+
<li><b>Prescaler (PSC):</b> Parameter to introduce the value of the PSC register.</li>
<li> Include in FreeRTOSConfig.h the folowing directive: </li>
+
<li><b>Counter Period:</b> Parameter to set the value of the ARR register.</li>
<pre>
+
<li><b>Pulse (16 bits):</b> Parameter to mofidy the CCR register.</li>
#define configUSE_NEWLIB_REENTRANT 1
+
<li><b>Mode: </b> The PWM mode 1 must be selected.</li>
</pre>
+
<li> Go to Project -> Porperties -> MCU Settings -> Tool Settings and select float for printf and scanf from newlib-nano </li>
+
 
</ul>
 
</ul>
  
<h3> IDE Flickering </h3>
+
Additionally, within the code, the timer to use must be initialized following the structure below:
 
+
First check the value of GTK_IM_MODULE in your environment by executing
+
  
 
<pre>
 
<pre>
echo $GTK_IM_MODULE
+
HAL_TIM_PWM_Start(&htim3, TIM_CHANNEL_1);
 
</pre>
 
</pre>
  
If the output is "xim", Eclipse expects it to be “ibus”.
 
So enter the following command in a terminal session to set it to the value.
 
  
 +
The CCR value can be modified by introducing the following instruction:
 
<pre>
 
<pre>
export GTK_IM_MODULE="ibus"
+
htimx.Instance->CCR1 = new_ccr;
 
</pre>
 
</pre>
  
Now if you launch Eclipse from the same terminal session, you should not experience any flickering issue.
+
in which CCR1 indicates that we are accessing to the channel 1 register, new_ccr is the new to set and htimx refers to the timer x (for example, htim2 or htim3).
If you launch eclipse from a desktop menu entry, then edit the .desktop file (e.g.  /usr/share/applications/st-stm32cubeide-1.6.1.desktop) and put the following string in the beginning of the Exec command:
+
  
 +
In the same way, to modify the register of the channel 2:
 
<pre>
 
<pre>
env GTK_IM_MODULE=ibus
+
htimx.Instance->CCR2 = new_ccr;
 
</pre>
 
</pre>
  
E.g. Exec=env GTK_IM_MODULE=ibus /opt/st/stm32cubeide_1.6.1/stm32cubeide %F
+
<h1> Serial Port </h1>
 +
In STM32CubeIDE we can enable the UART serial port communication of the STM32 by activating the corresponding USART_TX and USART_RX pins in the Pinout View.  
 +
Then, we can transmit data as follows:
 +
<pre>
 +
uint8_t msg[] = "Hello World !!!\r\n";
 +
HAL_UART_Transmit(&huart1,msg,sizeof(msg),10);
 +
</pre>
 +
 
 +
During the execution, in order to read the sent data in our computer, we have to configure a console terminal as Serial Port. We recommend to set up the native console in STM32CubeIDE, selecting the correct USB serial port and fixing the desired baud rate and data size.
 +
Command Shell Console". In the console configuration we create a new connection.
 +
 
 +
In order to enable the transmission of float data, the setting "use float" must be enabled in the config route "Project/Properties/C/C++Build/Settings/MCU Settings".

Latest revision as of 13:23, 1 March 2023


To install STM32CubeIDE and to run a Hello World example, please check it here: http://wiki.robolabo.etsit.upm.es/index.php/Nucleo_Boards

GPIO read and write

Read from a GPIO

HAL_GPIO_ReadPin (GPIOA, GPIO_PIN_9);

Write to a GPIO

- High level:

HAL_GPIO_WritePin(GPIOA, GPIO_PIN_8, GPIO_PIN_SET);

- Low level:

HAL_GPIO_WritePin(GPIOA, GPIO_PIN_8, GPIO_PIN_RESET);


Encoder

Theory

The encoder used in the laboratory is a position sensor that uses a two-channels hall effect sensor. It is a quadrature encoder that is attached to the motor shaft and which provides a resolution of 48 counts per revolution. This means that, for a complete turn of the motor shaft, the encoder provides a value of 48 counts. The hall sensor requires an input voltage, Vcc. Additionally, the output of the encoder comes from reading the output of the two channels, channel A and channel B, of the hall sensor. These two channels are square waves which are 90º out of phase.

Encoder Configuration in STM32CubeIDE

This section explains how to easily configure an STM32 timer as an encoder with STM32CubeIDE. The first step is to select one of the available timers that can be The main timers that can be set as PWM are: TIM2, TIM3, TIM4 and TIM5.

Advice: It is recommended to use the timer that matches directly with the pins connected to the encoder of the motor through the H-bridge.

It is very important to configure this timer using the Encoder Mode in the Combined Channels (Channels 1 and 2) of the selected timer. Once the timer has been configured as an encoder, we must activate corresponding global interrupt in the NVIC Interrupt Table. Other relevant parameters are:

  • Counter Period: Parameter to set the value of the ARR register. It represents the max. value of the timer's counter before reset.
  • Encoder Mode:Should be set to "Encoder Mode TI1 and TI2" for handling both encoder channels.

Once configured, we should start the timer as follows:

HAL_TIM_Encoder_Start_IT(&htimx, TIM_CHANNEL_ALL);


The current value of the counter can be accessed though the following function:

__HAL_TIM_GET_COUNTER(htim)

where htimX is the instance of the timer X used as encoder (e.g. htim2 or htim3).


PWM

Theory

One method that is often used to control the speed of a DC motor is the Pulse Width Modulation (PWM) method. The speed of the electric motor depends on the modulator voltage. The greater the voltage, the faster the rotation of an electric motor. The use of this PWM can be used to control motor rotation through changes in PWM duty cycle or PWM pulse width. When the duty cycle is 0%, the motor will stop completely. When the duty cycle is 50%, the motor will rotate at half the speed of the maximum speed and when the PWM is 100%, the motor rotates with maximum speed.

Main registers

Prescaler (PSC)

The prescaler is a register that divides the timer clock frequency to obtain a specific frequency. Specifically, the frequency reduction is applied using the following formula:

f_TMR = f_CLK / (PSC + 1)

Therefore, if the frequency to set is the same as the frequency of the clock, the PSC register must be set at PSC=0. The STM32 timers allow a prescaler value up to 65535, through 16 bits registers.


Auto Reload Register (ARR) and Capture Compare Register (CCR)

The ARR register storages the maximum value that the counter can reach before going back to zero. Moreover, the CCR registers the value of the corresponding timer counter after which the output PWM signal goes from high to low level. Every channel of the timer used to generate the PWM will have a different CCR register (for example, CCR1 and CCR2 for channels 1 and 2). In this way, the value of the CCR together with the value of the ARR define the width of the pulses and, therefore, the duty cycle of the PWM signal:

Duty_Cycle (%) = 100 * (CCR / ARR)

CNT

This is the register that storages the value of the counter used to generate the PWM.

PWM Configuration in STM32CubeIDE

To configure a timer as PWM, the first thing to do is to select one of the timers that could be configured as a PWM generator. Additionally, also the channels that will be used as PWM output must be decided.

Advice: As different PWM outputs are needed, it is recommended to use different channels of the same timer to the extent possible.

The main timers that can be set as PWM are: TIM2, TIM3, TIM4 and TIM5, with 4 different channels each of them.

Advice: It is recommended to use the timer and the corresponding channels that match directly with the pins that feed the H-bridge to modulate the speed of the motor. Otherwise, the PWM output signals must be bridged with the H-bridge input signals.

Therefore, the pins that the channels of the timer are using need to be checked in the "Pinout" section of the STM32CubeIDE.

Once the channels of the timer have been activated, some parameters and the configuration of the timer must be changed.

Main parameters:

  • Clock Source: Clock of the timer. The Internal clock option must be selected. Moreover, it must be checked that the frequency of the clock that is being used is the one desired. This could be checked within the clock configuration tab of the STM32CubeIDE.
  • Channel x: Configuration for the channel x of the timer. The option “PWM Generation CHx” must be selected, in which x will be the number of the channel to configure.
  • Prescaler (PSC): Parameter to introduce the value of the PSC register.
  • Counter Period: Parameter to set the value of the ARR register.
  • Pulse (16 bits): Parameter to mofidy the CCR register.
  • Mode: The PWM mode 1 must be selected.

Additionally, within the code, the timer to use must be initialized following the structure below:

HAL_TIM_PWM_Start(&htim3, TIM_CHANNEL_1);


The CCR value can be modified by introducing the following instruction:

htimx.Instance->CCR1 = new_ccr;

in which CCR1 indicates that we are accessing to the channel 1 register, new_ccr is the new to set and htimx refers to the timer x (for example, htim2 or htim3).

In the same way, to modify the register of the channel 2:

htimx.Instance->CCR2 = new_ccr;

Serial Port

In STM32CubeIDE we can enable the UART serial port communication of the STM32 by activating the corresponding USART_TX and USART_RX pins in the Pinout View. Then, we can transmit data as follows:

uint8_t msg[] = "Hello World !!!\r\n";
HAL_UART_Transmit(&huart1,msg,sizeof(msg),10);

During the execution, in order to read the sent data in our computer, we have to configure a console terminal as Serial Port. We recommend to set up the native console in STM32CubeIDE, selecting the correct USB serial port and fixing the desired baud rate and data size. Command Shell Console". In the console configuration we create a new connection.

In order to enable the transmission of float data, the setting "use float" must be enabled in the config route "Project/Properties/C/C++Build/Settings/MCU Settings".