STM32 F103 Blue Pill: How to use UART communication

I seem to be running the gamut of issues here! The focus now is on how to make use of the UART ports available on the STM32 F1. For those who haven’t been following the saga, I have my build scripts setup like so:

platform = ststm32
framework = arduino
board = genericSTM32F103C8
upload_protocol = dfu

I’m now trying to implement this library, which makes use of a UART port to communicate with the peripheral. In accordance with the example given, I’ve initialized the VescUART class like so:

VescUart vesc;          // VESC
// Init VESC
while (!Serial1) {}

However, upon compiling:

Processing genericSTM32F103C8 (platform: ststm32; board: genericSTM32F103C8; framework: arduino)
Verbose mode can be enabled via `-v, --verbose` option
PLATFORM: ST STM32 > STM32F103C8 (20k RAM. 64k Flash)
HARDWARE: STM32F103C8T6 72MHz 20KB RAM (64KB Flash)
DEBUG: CURRENT(blackmagic) EXTERNAL(blackmagic, jlink, stlink)
Library Dependency Finder ->
Collected 33 compatible libraries
Scanning dependencies...
Dependency Graph
|-- <SD> 1.2.3
|   |-- <SPI> 1.0
|-- <VescUart> 1.0.0
|-- <MPU6050_tockn> 1.4.0
|   |-- <Wire> 1.0
|-- <Wire> 1.0
Compiling .pioenvs\genericSTM32F103C8\src\main.cpp.o
Archiving .pioenvs\genericSTM32F103C8\lib6a5\libSPI.a
Archiving .pioenvs\genericSTM32F103C8\lib00d\libSD_ID868.a
Indexing .pioenvs\genericSTM32F103C8\lib6a5\libSPI.a
Compiling .pioenvs\genericSTM32F103C8\lib94d\VescUart_ID5830\buffer.cpp.o
Compiling .pioenvs\genericSTM32F103C8\lib94d\VescUart_ID5830\crc.cpp.o
Indexing .pioenvs\genericSTM32F103C8\lib00d\libSD_ID868.a
Compiling .pioenvs\genericSTM32F103C8\lib017\Wire\SoftWire.cpp.o
Compiling .pioenvs\genericSTM32F103C8\lib017\Wire\Wire.cpp.o
Compiling .pioenvs\genericSTM32F103C8\lib017\Wire\utility\WireBase.cpp.o
Compiling .pioenvs\genericSTM32F103C8\lib0d0\MPU6050_tockn_ID2824\MPU6050_tockn.cpp.o
Archiving .pioenvs\genericSTM32F103C8\lib94d\libVescUart_ID5830.a
C:\Users\neilb\.platformio\lib\MPU6050_tockn_ID2824\src\MPU6050_tockn.cpp: In member function 'void MPU6050::calcGyroOffsets(bool)':
C:\Users\neilb\.platformio\lib\MPU6050_tockn_ID2824\src\MPU6050_tockn.cpp:73:23: warning: value computed is not used [-Wunused-value]
wire->read() << 8 | wire->read();
Indexing .pioenvs\genericSTM32F103C8\lib94d\libVescUart_ID5830.aC:\Users\neilb\.platformio\lib\MPU6050_tockn_ID2824\src\MPU6050_tockn.cpp:74:23: warning: value computed is not used [-Wunused-value]

wire->read() << 8 | wire->read();
C:\Users\neilb\.platformio\lib\MPU6050_tockn_ID2824\src\MPU6050_tockn.cpp:75:23: warning: value computed is not used [-Wunused-value]
wire->read() << 8 | wire->read();
C:\Users\neilb\.platformio\lib\MPU6050_tockn_ID2824\src\MPU6050_tockn.cpp:76:23: warning: value computed is not used [-Wunused-value]
wire->read() << 8 | wire->read();
src\main.cpp: In function 'void setup()':
src\main.cpp:108:29: error: no matching function for call to 'VescUart::setSerialPort(USBSerial*)'
In file included from src\main.cpp:5:0:
C:\Users\neilb\.platformio\lib\VescUart_ID5830\src/VescUart.h:49:8: note: candidate: void VescUart::setSerialPort(HardwareSerial*)
void setSerialPort(HardwareSerial* port);
C:\Users\neilb\.platformio\lib\VescUart_ID5830\src/VescUart.h:49:8: note:   no known conversion for argument 1 from 'USBSerial*' to 'HardwareSerial*'
src\main.cpp: In function 'void loop()':
src\main.cpp:162:31: warning: second operand of conditional expression has no effect [-Wunused-value]
constrain(rpm, 0, MAX_RPM);  // Should be extranous, but just make sure
src\main.cpp:162:31: warning: third operand of conditional expression has no effect [-Wunused-value]
*** [.pioenvs\genericSTM32F103C8\src\main.cpp.o] Error 1

I’m not sure why Serial1 is of type USBSerial and not HardwareSerial, especially because Serial is the one that I call to make use of the USB port. Can anyone help explain why this is? Thanks!

This is interesting: When I use VSCode to inspect the source definition of Serial1, I get led to a certain iom32u4.h file, contained in the AVR folder structure. This seems odd…

Did you re-initialize the project (pio init --ide=vscode) and restart the IDE already?

I’ve restarted the idea multiple times over the course of the last couple days… Let’s try that command.

Okay so basically the problem is that Serial maps to a USBSerial object (i.e. the USB CDC emulation?) but the function needs a HardwareSerial object. Let me check that.

But is it intentional that you initialize Serial1 in your code but use Serial in the setSerialPort call?

I can’t get the terminal to work, even when launched from the button in the bottom bar.

neil@Neil-Laptop-10:/mnt/c/Users/neilb/Documents/GitHub/SVCE Ebike Controller$ pio init --ide=vscode

Command 'pio' not found, did you mean:

  command 'pico' from deb nano
  command 'pico' from deb alpine-pico
  command 'pico' from deb joe-jupp
  command 'fio' from deb fio
  command 'pig' from deb bsdgames
  command 'rio' from deb rio
  command 'pil' from deb picolisp
  command 'pi' from deb pi
  command 'plio' from deb gnustep-base-runtime
  command 'pip' from deb python-pip
  command 'pia' from deb pia
  command 'tio' from deb tio
  command 'gio' from deb libglib2.0-bin
  command 'pic' from deb groff-base
  command 'cpio' from deb cpio

Try: sudo apt install <deb name>

There’s also a project target for this. Press Ctrl + Shift + P and type “Rebuild…” and you should see a PlatformIO target “Rebuild Project C/C++ Index” or something

1 Like

Also yeah basically what I get is:


  • Serial means the USB serial that you get when you plug the Bluepills USB connector into the computer…
  • Serial1 is USART1.
  • Serial2 is USART2
  • Serial3 is USART3

See pinout for TX/RX / extra stuff (CTR, DTR) pins

So I guess you meant actually Serial1 all the time?

Sure? You want to use the USB-CDC serial as the input/output for the library? Or one of the hardware UART pins?

If USB “UART” -> the library doesn’t actually need HardwareSerial but only Stream… So you can re-write the types in the constructor so that it acceps a Stream* (which USBSerial implements) and the lib should still work.

OH DAMNIT. Yep. spelling error.

1 Like

I won’t say anything… other than I sympathise with you! :wink: Been there, done that… my latest folly? Using uint8_t as the datatype for a RF transmission struct when the floating point numbers that were being converted to integers included negative numbers… bad move! … Temperatures of 600+ degrees, here we come! :open_mouth: :man_facepalming: :laughing:

1 Like

Lol, that’s great… ya know, I actually do think that we’re on the surface of Venus…

1 Like