Attitude Estimation· Live
Home / Chapter 1 / 1.2

STM32: create the project and send text over the UART

Lesson 1.2 · STM32 · free

Video coming soon

We create an STM32 project for the NUCLEO-F401RE and turn on USART2, which reaches the computer over the same USB cable. Then we make printf send text to it and watch a counter in the serial plotter in the browser.

In this lesson · 9 steps
  1. Start a new project from the board
  2. Enable USART2
  3. Project Manager and code generation
  4. Include stdio.h
  5. Send printf to the UART
  6. Say hello once
  7. Print a counter every 100 ms
  8. Build and run
  9. Open the serial plotter

1Start a new project from the board

  1. STM32CubeMX → Board Selector
  2. Search NUCLEO-F401RE, select it, press Start Project
  3. "Initialize all peripherals with their default Mode?" → No (we enable only what we need)

2Enable USART2

  1. Pinout & Configuration → Connectivity → USART2: Mode = Asynchronous
  2. Keep the default Parameter Settings: 115200 baud, 8 bits, no parity, 1 stop bit
  3. Pins: PA2 = TX, PA3 = RX → wired to the ST-LINK on the Nucleo board (virtual COM port)
Why?
Why USART2, not 1 or 3? On the Nucleo board, its pins PA2 and PA3 are already wired to the ST-LINK. So the text goes to the computer over the same USB cable, and we don't need any adapter.

3Project Manager and code generation

  1. Project Name: CH1_UART
  2. Project Location: one folder for all the course projects
  3. Toolchain / IDE: STM32CubeIDE → Generate Code → Open Project
  4. CubeIDE starts and asks for a workspace (the folder where it keeps projects): choose the same folder as the Project Location → Launch
Why?
The toolchain must be STM32CubeIDE. That's the key, otherwise CubeIDE can't open the project. And the workspace must be the same folder as the Project Location.

4Include stdio.h

main.c · USER CODE BEGIN Includes

stdio.h gives us printf.

/* USER CODE BEGIN Includes */
#include <stdio.h>
/* USER CODE END Includes */
Why?
We always write our code between USER CODE BEGIN and END. Otherwise, it's erased when CubeMX generates the code again.

5Send printf to the UART

main.c · USER CODE BEGIN PV

Every time we call printf, the C library hands the text to _write, so the name must be exactly this.

/* USER CODE BEGIN PV */
int _write(int file, char *ptr, int len)
{
  HAL_UART_Transmit(&huart2, (uint8_t *)ptr, len, HAL_MAX_DELAY);
  return len;
}
/* USER CODE END PV */
Why?
Inside, HAL_UART_Transmit sends it: first &huart2, the USART2 handle CubeMX made at the top of main.c, then the pointer and the length. The last one is the timeout: HAL_MAX_DELAY means wait until it's all sent. Then we return the length.

6Say hello once

main.c · USER CODE BEGIN 2

This printf runs once, after the peripherals start. \r\n ends the line.

  /* USER CODE BEGIN 2 */
  printf("Hello from STM32!\r\n");
  int counter = 0;
  /* USER CODE END 2 */
Why?
And here is our counter, starting at zero, so the loop below can use it.

7Print a counter every 100 ms

main.c · inside while (1), before USER CODE END WHILE

We print a name, a colon and the value, like counter:12.

  /* USER CODE BEGIN WHILE */
  while (1)
  {
    printf("counter:%d\r\n", counter);
    counter++;
    HAL_Delay(100);
    /* USER CODE END WHILE */
Why?
The plotter needs exactly this format: the value goes on the plot, the name in the legend. HAL_Delay(100) waits 100 ms, so we get about 10 lines per second.

8Build and run

  1. Project Explorer → right-click the project → Build Project (0 errors)
  2. Debug (or Run): the first time, a launch dialog (Edit Configuration) opens → press OK
  3. In the debugger, the program stops at the start: press Resume (F8) and it runs

9Open the serial plotter

  1. steppeschool.com → Tools → Serial Plotter (or go straight to serial.steppeschool.com)
  2. Baud: 115200 (the same as USART2) → Connect
  3. In the browser window, pick the STM32 STLink port (ST-Link VCP) → Connect
  4. The counter line goes up on the plot, and the console on the right shows the lines
  5. Press the black reset button on the board to see the hello line again
Why?
Our serial plotter runs in the browser, so there is nothing to install. It needs Chrome or Edge, because it uses Web Serial. Only one program can use the port, so close any other serial monitor first.
Check & troubleshoot

What you should see

  • The console shows Hello from STM32 once, then lines like counter:12
  • The counter goes up about 10 times per second
  • The plot shows one line, counter, going up

If it doesn't work

  • Build does nothing: click the project name in the Project Explorer first, then press Build
  • No port in the plotter: choose the STLink Virtual COM Port, and close any other program that uses it
  • Nothing printed: check the _write function is inside USER CODE BEGIN PV, and the baud rate is 115200
  • Missed the hello line: it is sent only once at start; connect the plotter first, then press reset or Resume

Good to know

  • Several values fit in one line, with commas: ax:1,ay:2,az:3. The plotter draws each name as its own line. That's extremely helpful for sensors
  • The rate isn't exact. HAL_Delay waits 100 ms, but printf and the rest of the loop add time too. We fix that in lesson 1.3 with a timer

Next: Lesson 1.3: we replace HAL_Delay with a timer, so the loop runs at an exact rate.