Sometimes, when working on larger Arduino projects, you may find that the Arduino IDE lacks support for code management and automation, making it less suitable for the task at hand. In such cases, it’s advisable to use CMake for code compilation, especially when you need to compile your code from the command line or within automated integrated development environments. By leveraging the infrastructure of CMake and rosserial_client, you can build and distribute firmware using ROS.
Step 1: Create a Workspace and ROS Package
$ cd ~/catkin_ws_cmake/src/
$ catkin_create_pkg helloworld rosserial_arduino rosserial_client std_msgs
$ cd ~/catkin_ws_cmake/src/: This command changes your current working directory in the terminal to “~/catkin_ws_cmake/src/.” Typically, source code files for ROS projects are stored in the “src” directory.
$ catkin_create_pkg helloworld rosserial_arduino rosserial_client std_msgs: This command is used to create a new ROS package. Specifically, it creates a package named “helloworld” that will have dependencies on three other ROS software packages: “rosserial_arduino,” “rosserial_client,” and “std_msgs.” Dependencies mean that your package will use the functionality and message definitions provided by these packages.
Step 2: Create Arduino Firmware
#include
#include
#include
ros::NodeHandle nh;
std_msgs::String str_msg;
ros::Publisher chatter("chatter", &str_msg);
char hello[13] = "hello world!";
void setup() {
nh.initNode();
nh.advertise(chatter);
}
void loop() {
str_msg.data = hello;
chatter.publish(&str_msg);
nh.spinOnce();
delay(1000);
}
#include Statements: These lines include the necessary library files, such as ROS and Arduino libraries, to enable the use of related functions in the program.
ros::NodeHandle nh;: It creates a ROS node handle used to communicate with the ROS system.
std_msgs::String str_msg;: This line defines a ROS string message object used to publish string messages on a ROS topic.
ros::Publisher chatter(“chatter”, &str_msg);: It creates a ROS publisher object that publishes messages to a topic named “chatter,” which will contain string messages.
void setup(): This function is the Arduino initialization function, typically executed when the program starts.
void loop(): This function is the main loop of the Arduino program, repeatedly executed. Inside the loop, the code assigns the “hello world!” string to the ROS message str_msg.data, publishes this message to the “chatter” topic, processes ROS communication events with nh.spinOnce(), and then introduces a 1-second delay with delay(1000) before the loop repeats.
Step 3: Edit the CMakeLists.txt File for the Package
find_package(catkin REQUIRED COMPONENTS
rosserial_arduino
rosserial_client
)
catkin_package()
# Generate information for the rosserial client library
rosserial_generate_ros_lib(
PACKAGE rosserial_arduino
SCRIPT make_libraries.py
)
# Configure the rosserial client
rosserial_configure_client(
DIRECTORY firmware
TOOLCHAIN_FILE ${ROSSERIAL_ARDUINO_TOOLCHAIN}
)
# Add rosserial client targets
rosserial_add_client_target(firmware hello ALL)
rosserial_add_client_target(firmware hello-upload)
find_package(catkin REQUIRED COMPONENTS …: This line is used to find and specify the required Catkin packages for this particular ROS project. In this case, it’s specifying that the project depends on the “rosserial_arduino” and “rosserial_client” packages.
catkin_package(): This command specifies the package dependencies and other details, making this package suitable for Catkin, which is the build system for ROS.
rosserial_generate_ros_lib(…): This command generates information for the rosserial client library, which is a library that allows communication between Arduino boards and ROS. It uses the “rosserial_arduino” package and the “make_libraries.py” script to generate this library.
rosserial_configure_client(…): Here, the rosserial client is configured. It specifies the directory where the firmware for Arduino boards will be built, and it also references a toolchain file for the Arduino build process.
rosserial_add_client_target(…): These lines add rosserial client targets for the firmware. Specifically, it adds two targets: “hello” and “hello-upload.”
Step 4: Create the CMakeLists.txt File for the Firmware Subproject
cmake_minimum_required(VERSION 2.8.3)
include_directories(${ROS_LIB_DIR})
add_definitions(-DUSB_CON)
generate_arduino_firmware(hello
SRCS chatter.cpp ${ROS_LIB_DIR}/time.cpp
BOARD uno
PORT /dev/ttyUSB0
)
cmake_minimum_required(VERSION 2.8.3): This line specifies the minimum required CMake version for this configuration.
include_directories(${ROS_LIB_DIR}): It includes directories related to ROS libraries to ensure that the firmware can communicate with ROS correctly.
add_definitions(-DUSB_CON): This command adds a compilation definition, “-DUSB_CON,” which is typically used when your Arduino board has native USB support. It’s a conditional definition that is included when building the firmware.
generate_arduino_firmware(hello … ): Used to generate Arduino firmware.
SRCS chatter.cpp ${ROS_LIB_DIR}/time.cpp: specifies the source files to include in the firmware. In this case, it includes “chatter.cpp” and “time.cpp” from the ROS library directory.
PORT /dev/ttyUSB0: defines the serial port where the firmware will be uploaded. It usually points to the specific USB port connected to the Arduino board.
Step 5: Compile and Upload the Firmware
catkin_make helloworld_firmware_hello
catkin_make helloworld_firmware_hello: This command instructs the Catkin build system to compile and build the firmware target named “hello” for the “helloworld” package. Essentially, it compiles the Arduino firmware defined in the package, making it ready to be uploaded to an Arduino board.
catkin_make helloworld_firmware_hello-upload
catkin_make helloworld_firmware_hello-upload: This command is similar to the previous one, but it goes a step further. It not only builds the “hello” firmware but also prepares it for uploading to an Arduino board. It might involve actions like compiling, generating the binary file, and preparing the upload process so that you can flash the firmware onto the connected Arduino board.

Step 6: Test
# Start the ROS core
roscore
# Run the rosserial serial node
rosrun rosserial_python serial_node.py _port:=/dev/ttyUSB0
# Monitor the "chatter" topic
rostopic echo chatter
roscore: This command starts the ROS Master, which is the core of the ROS communication system. It initializes the ROS parameter server and allows various ROS nodes to communicate with each other.
rosrun rosserial_python serial_node.py _port:=/dev/ttyUSB0: This command runs the serial_node.py script from the rosserial_python package. It configures and initializes a serial node that connects to a device located at the specified port.
rostopic echo chatter: This command uses the rostopic tool to subscribe to the “chatter” topic in ROS and displays the messages being published on that topic. In this context, “chatter” is a topic where data is exchanged between ROS nodes, and you are monitoring the data stream published on that topic.



You Might Be Interested


Unlock your computer with a touch using Arduino! Transform your keyboard by adding a fingerprint module for seamless login. Discover our step-by-step guide to upgrade your setup with biometric security


This article introduces six beginner-friendly projects for Arduino UNO, a popular microcontroller board. These projects cover a range of applications, from marquee lights and stepper motor control to ultrasonic ranging,


In this project, TechSparks will use Arduino to create a smart car project that can achieve Bluetooth remote control, obstacle avoidance, and line tracking functions. We will showcase the required


Unlock the power of Arduino UNO! This versatile development board lets you build everything from automated systems to robots. Explore its features and discover how it can turn your creative


In this article, we’ll start with the basics of ultrasonic sensors, walk you through using Arduino for distance measurement, and explore practical applications of this technology in projects like smart


Loops are a key concept in Arduino, enabling repeated execution of code without redundancy. This includes for, while, and do-while loops. Click the link to learn more about their concepts,


This Arduino temperature alarm project effectively demonstrates how to create a practical temperature monitoring system. By utilizing the LM35 temperature sensor and a buzzer, it warns users with an audible


This DIY project introduces an Arduino-based smart tea maker that combines mechanical and electronic control for automated tea brewing. It uses multiple Arduinos, servos, and sensors to handle tasks like