Compiling Code Using CMake and Uploading it to Arduino

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.

Table of Contents

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 <ros.h>
#include <std_msgs/String.h>
#include <Arduino.h>
ros::NodeHandle nh;
std_msgs::String str_msg;
ros::Publisher chatter("chatter", &str_msg);
char hello[13] = "hello world!";
void setup() {
void loop() { = hello;


#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, 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
# Generate information for the rosserial client library
  PACKAGE rosserial_arduino
# Configure the rosserial client
  DIRECTORY firmware
# 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 “” 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)
  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.

Run prompt log

Step 6: Test

					# Start the ROS core
# Run the rosserial serial node
rosrun rosserial_python _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 _port:=/dev/ttyUSB0: This command runs the 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.

Open a new terminal and run

More content you may be interested in

How to Enable Multi-Core on ESP32 Microcontroller
How to Enable Multi-Core on ESP32 Microcontroller

This comprehensive guide elucidates the process of enabling multi-core functionality on the ESP32 microcontroller, leveraging its dual-core architecture for enhanced parallel processing capabilities. Through detailed

Arduino MQ-3 Alcohol Sensor Project
Arduino MQ-3 Alcohol Sensor Project

Creating an alcohol sensing project with an MQ-3 sensor and Arduino allows for accurate alcohol concentration monitoring in environments like bars and factories. The MQ-3

Arduino Temperature Alarm Project
Arduino Temperature Alarm Project

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

Arduino Breathing LED Project
Arduino Breathing LED Project

A breathing light is an LED lighting effect that simulates the human breathing process, gradually increasing or decreasing in brightness within a specific cycle. This

Scroll to Top