This repository contains a ROS2 package for controlling the PCA9685 PWM driver using both:
- A ROS2 native service-based interface (legacy control)
- A ROS2 Control hardware interface (recommended for modern robot systems)
It is designed primarily for servo motor control.
Tested setup:
- Raspberry Pi 4B (4GB RAM)
- OS: ros-realtime-rpi4-image
- ROS2: Humble
- PCA9685 16-channel PWM driver (I2C)
- Servo: TowerPro SG90
Reference: - https://www.nxp.com/products/pca9685 - https://www.towerpro.com.tw/product/sg90-7/
This package supports two operation modes:
- Node:
ros2_pca9685 - Control method: ROS2 Service (
/pca9685/set_pwm) - Suitable for simple direct control or testing
- Integrates with
ros2_control - Exposes:
- Command interfaces (position)
- State interfaces (position feedback = commanded value)
- Works with
controller_managerand standard ROS2 controllers
Clone into your ROS2 workspace:
cd ~/ros2_ws/src
git clone <your-repo-url>Build:
cd ~/ros2_ws
colcon build --packages-select ros2_pca9685Source:
source install/setup.bashLaunch driver node:
ros2 launch ros2_pca9685 ros2_pca9685.launch.pyCheck service:
ros2 service listCall service:
ros2 service call /pca9685/set_pwm ros2_pca9685/srv/SetPwm "channel_num: 1
target_position: 170"The hardware interface does NOT start controller_manager automatically.
User is responsible for:
- Starting
controller_manager - Loading controllers (e.g.
joint_trajectory_controller,forward_command_controller) - Providing URDF + ros2_control tags
Example snippet:
<ros2_control name="PCA9685System" type="system">
<hardware>
<plugin>ros2_pca9685/PCA9685Hardware</plugin>
</hardware>
<joint name="servo_joint_1">
<command_interface name="position" />
<state_interface name="position" />
</joint>
</ros2_control>ros2 run controller_manager ros2_control_node --ros-args --params-file config/controllers.yamlros2 control load_controller joint_state_broadcaster
ros2 control load_controller forward_command_controllerActivate:
ros2 control switch_controller --activate forward_command_controller --activate joint_state_broadcasterros2 topic pub /forward_command_controller/commands std_msgs/msg/Float64MultiArray "data: [1.57, 0.78]"- write(): converts rad to PWM duty cycle
- read(): echoes command (no encoder feedback)
MoveIt / User Node
|
controller_manager
|
ros2_control hardware interface
|
PCA9685 PWM Driver
|
Servo Motor
BSD 3-Clause License
Copyright (c) 2026 Mezael Docoy