The ROS2RPI HAT is a powerful add-on board designed specifically for Raspberry Pi 4/5 models. It enhances the capabilities of your Raspberry Pi by providing a range of features, including:
The image depicts the physical connection between the ROS2RPi HAT and ROSRider cards using a standard QWIC cable. The ROSRider card’s additional QWIC port facilitates cascading configurations, enabling the expansion of the system with multiple ROSRider units or other compatible QWIC devices.
Qwiic cables are a popular choice for connecting various sensors and actuators to microcontrollers and other devices. They feature a 4-wire JST-SH connector on each end. One unique aspect of Qwiic cables is their asymmetrical orientation. One connector will typically be top-facing
while the other is bottom-facing.
This deliberate design choice helps with cable routing and prevents accidental misconnections, making it easier to create clean and organized setups.
⚠️ Prerequisites
In order to send I2C commands from your host with Python, you need to install the python3-smbus2
library.
For Ubuntu:
sudo apt install python3-smbus2
If your Ubuntu version does not have the python3-smbus2
package, use pip3 to install package locally:
pip3 install smbus2
Sending one byte to I2C address 0x20
we can control all the peripherals on the device.
bit | function | mask | description |
---|---|---|---|
0 | PSEL_3V3_A | 0x01 | Powers on I2C Bus Voltage-Level Translator A |
1 | PSEL_3V3_B | 0x02 | Powers on I2C Bus Voltage-Level Translator B |
2 | SERIAL_RX_ON | 0x04 | Connects the RPIs RX to debug port RX |
3 | SERIAL_TX_ON | 0x08 | Connects the RPIs TX to debug port TX |
4 | PSEL_LIDAR | 0x10 | LIDAR Power ON |
5 | LIDAR_TX_ON | 0x20 | Connects the RPIs RX to Lidars TX |
6 | LIDAR_PWM_ON | 0x40 | Connects RPIs GPIO19 to Lidars PWM input |
✅ Checkpoint
To ensure you’re in the i2c
group,
check the /etc/group
file or run the following command:
groups
If you're not listed, you'll need to add yourself to the group using the following command:
sudo usermod -aG i2c $USER
Remember to log out and log back in for the group membership change to take effect.
Create a file named haton.py
under $HOME\bin
and put the code below inside it
#!/usr/bin/env python
import string
import struct
import sys
import time
from smbus2 import SMBus
with SMBus(1) as bus:
TCA6408_OUTPUT = 0x01
TCA6408_CONFIGURATION = 0x03
TCA6406_ADDRESS = 0x20
# PSEL_3V3_A P0 0x01
# PSEL_3V3_B P1 0x02
# SERIAL_RX_ON P2 0x04
# SERIAL_TX_ON P3 0x08
# PSEL_LIDAR P4 0x10
# LIDAR_TX_ON P5 0x20
# LIDAR_PWM_ON P6 0x40
try:
bus.write_byte_data(TCA6406_ADDRESS, TCA6408_CONFIGURATION, 0x0)
bus.write_byte_data(TCA6406_ADDRESS, TCA6408_OUTPUT, 0x73)
except IOError as e:
print('IOError: %s' % e)
#!/usr/bin/env python
import string
import struct
import sys
import time
from smbus2 import SMBus
with SMBus(1) as bus:
TCA6408_OUTPUT = 0x01
TCA6408_CONFIGURATION = 0x03
TCA6406_ADDRESS = 0x20
# PSEL_3V3_A P0 0x01
# PSEL_3V3_B P1 0x02
# SERIAL_RX_ON P2 0x04
# SERIAL_TX_ON P3 0x08
# PSEL_LIDAR P4 0x10
# LIDAR_TX_ON P5 0x20
# LIDAR_PWM_ON P6 0x40
try:
bus.write_byte_data(TCA6406_ADDRESS, TCA6408_CONFIGURATION, 0x0)
bus.write_byte_data(TCA6406_ADDRESS, TCA6408_OUTPUT, 0x0F)
except IOError as e:
print('IOError: %s' % e)
Create a file named hatoff.py
under $HOME\bin
and put the code below inside it
#!/usr/bin/env python
import string
import struct
import sys
import time
from smbus2 import SMBus
with SMBus(1) as bus:
# send hibernate command to ROSRider
try:
# 0x04 is sys_ctl address
bus.write_i2c_block_data(0x3C, 0x04, [0,0,0,0x05])
except IOError as e:
print('IOError: %s' % e)
TCA6408_OUTPUT = 0x01
TCA6408_CONFIGURATION = 0x03
TCA6406_ADDRESS = 0x20
# turn the ROS2RPI board off
try:
bus.write_byte_data(TCA6406_ADDRESS, TCA6408_CONFIGURATION, 0x00)
bus.write_byte_data(TCA6406_ADDRESS, TCA6408_OUTPUT, 0x0)
except IOError as e:
print('IOError: %s' % e)
uint8_t send_hat_command(int fd, uint8_t output) {
int rv_hat = ioctl(fd, I2C_SLAVE, 0x20);
if(rv_hat<0) { return rv_hat; }
unsigned char hat_command[1] = {0};
int rw_hat = I2C_RW_Block(fd, 0x03, I2C_SMBUS_WRITE, 1, hat_command);
hat_command[0] = output;
rw_hat = I2C_RW_Block(fd, 0x01, I2C_SMBUS_WRITE, 1, hat_command);
return rw_hat;
}
uint8_t send_sysctl(int fd, uint8_t command) {
unsigned char sysctl_buffer[5] = {0};
sysctl_buffer[3] = command;
uint8_t rw = I2C_RW_Block(fd, 0x04, I2C_SMBUS_WRITE, 5, sysctl_buffer);
if(rw == 0) {
return 0;
} else {
RCLCPP_INFO(this->get_logger(), "I2C Error: %s", strerror(rw));
return rw;
}
}
Change directory to /lib/systemd/system
and create haton.service
file by typing the following commands:
cd /lib/systemd/system
sudo nano haton.service
Inside this file insert the following input:
[Unit]
Description=Turns ROS2RPI on
After=multi-user.target
[Service]
Type=oneshot
RemainAfterExit=false
ExecStart=/usr/bin/python /home/ubuntu/bin/haton.py
[Install]
WantedBy=multi-user.target
Enable haton service by:
sudo systemctl enable haton
If successful, you should see output similar to:
Created symlink /etc/systemd/system/multi-user.target.wants/haton.service → /usr/lib/systemd/system/haton.service.
The system will execute haton.py
at boottime.
Change directory to /lib/systemd/system
and create hatoff.service
file by typing the following commands:
cd /lib/systemd/system
sudo nano hatoff.service
Inside this file insert the following input:
[Unit]
Description=Turns ROS2RPI off
After=multi-user.target
[Service]
Type=oneshot
RemainAfterExit=true
ExecStop=/usr/bin/python /home/ubuntu/bin/hatoff.py
[Install]
WantedBy=multi-user.target
Enable hatoff service by:
sudo systemctl enable hatoff
If successful, you should see output similar to:
Created symlink /etc/systemd/system/multi-user.target.wants/hatoff.service → /usr/lib/systemd/system/hatoff.service.
The system will execute hatoff.py
at shutdown.
Important Node
While we can leverage Python scripts to manage peripheral control at boot and shutdown, the ROSRiders driver offers a software-based approach to dynamically activate and deactivate peripherals in response to ROS node lifecycle events.
The ROSRiders driver leverages the I2C bus to communicate with the ROSRider card. By powering the I2C port on the ROS2RPi, a wake-up signal is generated, awakening the ROSRider card from a low-power state. This allows for efficient power management and quick activation when needed.
ROS2RPI mounted a top RPI5, as seen in the picture all the ports including display ports can be reached.
TODO