rosnode example using STM32.
rosserial_arduino_lib allows you to communicate with Arduino environments such as ATMega328(UNO,Nano,ProMini) and ATMega2560(MEGA) via serial.
Data from various sensors can be imported into ROS using Arduino.
However, ATMega328 is not suitable as rosnode because memory is too small.
ATMega2560 is fine, but the board is too big.
We can use compact and powerful STM32 Development Board as rosnode.
STM32 has enough memory to run rosnode and is much faster than ATMega.
Arduino environment has many libraries that we can use.
- ROS Melodic
- PlatformIO Core
- Arduino_Core_STM32
-
STM32 Development Board like Bluepill/Blackpill
Supported boards is here. -
Inexpensive Chinese ST-LINK adapter
Available on eBay and AliExpress for $2.
-
UART-USB converter module
$ sudo apt install python3-pip python3-setuptools
$ python3 -m pip install -U platformio
$ pio --version
PlatformIO Core, version 6.1.6
$ sudo apt install ros-melodic-rosserial-arduino ros-melodic-rosserial
$ sudo usermod -a -G dialout {login_user_name}
$ sudo apt install curl
$ curl -fsSL https://raw.githubusercontent.com/platformio/platformio-core/develop/platformio/assets/system/99-platformio-udev.rules | sudo tee /etc/udev/rules.d/99-platformio-udev.rules
$ ls /etc/udev/rules.d/99-platformio-udev.rules
/etc/udev/rules.d/99-platformio-udev.rules
$ sudo reboot
Connect ST-LINK adapter and STM32.
+----------+ +----------+ +----------+
| STM32 | | ST-LINK | USB | Host |
| 3.3V|---------|3.3V |=========| |
| GND |---------|GND | | |
| PA13|---------|SWDIO | | |
| PA14|---------|SWCLK | | |
+----------+ +----------+ +----------+
/dev/stlinkv2* device files are generated.
$ ls /dev/stlinkv2*
/dev/stlinkv2_4
Build rosserial_arduino Library
$ git clone https://github.com/nopnop2002/Arduino-STM32-rosnode
$ cd Arduino-STM32-rosnode/HelloWorld
$ cd lib
$ rosrun rosserial_arduino make_libraries.py .
$ ls
README ros_lib
Build Firmware for pill board
$ cd ..
$ pio run -e blackpill_f103c8 -t upload
Build Firmware for generic board
$ cd ..
$ pio run -e genericSTM32F103C8 -t upload
Connect STM32 and ROS HOST using UART-USB converter.
Build with pill board
+----------+ +----------+ +----------+
| STM32 | UART | UART-USB | USB | ROS HOST |
| PA9 |---------|RX |=========| |
| PA10|---------|TX | | |
| GND |---------|GND | | |
+----------+ +----------+ +----------+
Build with generic board
+----------+ +----------+ +----------+
| STM32 | UART | UART-UART| USB | ROS HOST |
| PA2 |---------|RX |=========| |
| PA3 |---------|TX | | |
| GND |---------|GND | | |
+----------+ +----------+ +----------+
When the PlatformIO host and ROS host are the same, it will be as follows:
Do not supply power from both ST-LINK and UART-USB.
+----------+ +----------+ +----------+
| STM32 | | ST-LINK | USB | ROS Host |
| 3.3V|---------|3.3V |=========| |
| GND |---------|GND | | |
| PA13|---------|SWDIO | | |
| PA14|---------|SWCLK | | |
| | +----------+ | |
| | | |
| | +----------+ | |
| | UART | UART-USB | USB | |
| PA9 |---------|RX |=========| |
| PA10|---------|TX | | |
| 5V |xxxxxxxxx|5V | | |
| GND |---------|GND | | |
+----------+ +----------+ +----------+
If the quality of the UART wire is poor, you will get an error like this.
[ERROR] [1677403411.453212]: Mismatched protocol version in packet ('\x12'): lost sync or rosserial_python is from different ros release than the rosserial client
[INFO] [1677403411.456146]: Protocol version of client is unrecognized, expected Rev 1 (rosserial 0.5+)
[ERROR] [1677403411.950751]: Mismatched protocol version in packet ('\xff'): lost sync or rosserial_python is from different ros release than the rosserial client
[INFO] [1677403411.953727]: Protocol version of client is Rev 0 (rosserial 0.4 and earlier), expected Rev 1 (rosserial 0.5+)
$ roscore
$ rosrun rosserial_python serial_node.py _port:=/dev/ttyUSB0 _baud:=115200
[INFO] [1677197464.818522]: ROS Serial Python Node
[INFO] [1677197464.827333]: Connecting to /dev/ttyUSB0 at 115200 baud
[INFO] [1677197466.935209]: Requesting topics...
[INFO] [1677197467.339121]: Note: publish buffer size is 512 bytes
[INFO] [1677197467.341800]: Setup publisher on chatter [std_msgs/String]
[INFO] [1677197467.348600]: Note: subscribe buffer size is 512 bytes
[INFO] [1677197467.350585]: Setup subscriber on led [std_msgs/Bool]
$ rostopic echo /chatter
data: "hello world! 2131011"
---
data: "hello world! 2131511"
---
data: "hello world! 2132011"
---
# Onboard led gose LOW
$ rostopic pub -1 /led std_msgs/Bool "data: false"
# Onboard led gose HOGH
$ rostopic pub -1 /led std_msgs/Bool "data: true"
There are boards that turn off when it goes LOW and boards that turn off when it goes HIGH.
This is hardware implementation dependent.
GPIO of onboard LED is set in platform.ini.
Settings for boards other than BluePill and BlackPill are provisional.
build_flags = '-D LED_BUILTIN=PC13'
rosserial_arduino_lib uses Serial object for ROS communication.
The hardware serial of STM32 is complicated, and the pin assignment of the Serial object has different GPIO for each valiant.
For example, blackpill_f103c8/bluepill_f103c8 Serial objects are assigned TX=PA9 RX=PA10, but genericSTM32F103C8 Serial objects are assigned TX=PA2 RX=PA3.
In other words, even with the same STM32F103C8, the GPIO of Sirial changes depending on the build conditions.
Additionally, the serial GPIO can be remapped to a alternate pins by code in your application.
STM32F4 is especially complicated.
This is a sample of some boards.
Bord valiant | TX of Serial | RX of Serial | MCU |
---|---|---|---|
blackpill_f103c8 | PA9 | PA10 | STM32F103C8 |
bluepill_f103c8 | PA9 | PA10 | STM32F103C8 |
genericSTM32F103C8 | PA2 | PA3 | STM32F103C8 |
blackpill_f401cc | PA9 | PA10 | STM32F401CC |
genericSTM32F401CC | PA2 | PA3 | STM32F401CC |
blackpill_f411ce | PA9 | PA10 | STM32F411CE |
genericSTM32F411CE | PA2 | PA3 | STM32F411CE |
genericSTM32F405RG | PA0 | PA1 | STM32F405RG |
diymore_f407vgt | PA9 | PA10 | STM32F407VGT |
black_f407vg | PA2 | PA3 | STM32F407VGT |
genericSTM32F407VGT6 | PA0 | PA1 | STM32F407VGT |
disco_f407vg | PA2 | PA3 | STM32F407VGT |
The UART definition of each board cannot be understood without looking at the variant_generic.h of each board published here.
Some definitions are intended only for specific boards, such as variant_DIYMORE_F407VGT.h and variant_BLACK_F407VX.h.
It is necessary to confirm the mapping of the Serial object in advance.
There are variants where the default upload protocol is not ST-LINK.
Here is the documentation for the generic STM32F405RG but the default upload protocol is serial.
It would be a mistake to think that all STM32 have ST-LINK as the default protocol.
If you look closely at the messages when writing, you can see that the upload protocol is serial.
Configuring upload protocol...
AVAILABLE: blackmagic, dfu, jlink, serial, stlink
CURRENT: upload_protocol = serial
Looking for upload port...
Warning! Please install `99-platformio-udev.rules`.
More details: https://docs.platformio.org/page/faq.html#platformio-udev-rules
Error: Please specify `upload_port` for environment or use global `--upload-port` option.
For some development platforms it can b
If ST-LINK is not the default protocol, you need to specify the protocol as follows.
[env:genericSTM32F405RG]
platform = ststm32
board = genericSTM32F405RG
framework = arduino
upload_protocol = stlink