sl-jetson 3755e235aa feat: Orin Nano Super platform update + 4x IMX219 CSI cameras
Task A — Orin Nano Super platform update:
- docker-compose.yml: update header/comments, switch all service image tags
  to jetson-orin, update devices to udev symlinks (/dev/rplidar,
  /dev/stm32-bridge, i2c-7), add NVMe volume mounts (/mnt/nvme/saltybot),
  update stm32-bridge to saltybot_bridge launch, add csi-cameras service
- docs/pinout.md: full rewrite for Orin Nano Super — i2c-7, ttyTHS0,
  CSI-A/B connectors, M.2 NVMe slot, IMX219 15-pin FFC pinout, V4L2 nodes,
  GStreamer test commands, updated udev rules
- docs/power-budget.md: full rewrite — 25W TDP, 8GB LPDDR5, 67 TOPS,
  4-camera CSI bandwidth analysis, nvpmodel modes, Nano vs Orin comparison,
  5V 6A PSU recommendation, 4S LiPo architecture
- scripts/setup-jetson.sh: full rewrite — JetPack 6 / Ubuntu 22.04,
  nvidia-container-toolkit new keyring method, NVMe partition/format/fstab,
  CSI driver check (imx219 modprobe), video group, jtop install, 8GB swap

Task B — saltybot_cameras ROS2 package:
- launch/csi_cameras.launch.py: 4x v4l2_camera nodes, namespace per camera
  (front/left/rear/right), 640x480x30fps, includes TF launch automatically
- launch/camera_tf.launch.py: static TF for 4 cameras at 90deg intervals
  on sensor_head_link (r=5cm offset), yaw 0/90/180/-90 deg
- package.xml, setup.py, setup.cfg, __init__.py, resource marker
- config/cameras_params.yaml: per-camera device/frame/offset configuration

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-28 22:59:13 -05:00

9.4 KiB
Raw Permalink Blame History

Jetson Orin Nano Super — GPIO / I2C / UART / CSI Pinout Reference

Self-Balancing Robot: STM32F722 Bridge + RealSense D435i + RPLIDAR A1M8 + 4× IMX219

Last updated: 2026-02-28 JetPack version: 6.x (L4T R36.x / Ubuntu 22.04)


40-Pin Header Overview

The Jetson Orin Nano Super 40-pin header is physically compatible with Raspberry Pi HATs. Pin numbering follows physical board pin (140).

 3.3V  [ 1] [ 2] 5V
SDA1  [ 3] [ 4] 5V         ← I2C SDA (i2c-7 on Orin Nano)
SCL1  [ 5] [ 6] GND        ← I2C SCL (i2c-7 on Orin Nano)
 GPIO [ 7] [ 8] TXD0       ← UART TX (ttyTHS0)
  GND [ 9] [10] RXD0       ← UART RX (ttyTHS0)
 GPIO [11] [12] GPIO
 GPIO [13] [14] GND
 GPIO [15] [16] GPIO
 3.3V [17] [18] GPIO
 MOSI [19] [20] GND        ← SPI1 MOSI
 MISO [21] [22] GPIO       ← SPI1 MISO
 SCLK [23] [24] CE0        ← SPI1 CLK / CS0
  GND [25] [26] CE1        ← SPI1 CS1
 ID_SD[27] [28] ID_SC     ← I2C ID EEPROM (reserved)
 GPIO [29] [30] GND
 GPIO [31] [32] GPIO
 GPIO [33] [34] GND
 GPIO [35] [36] GPIO
 GPIO [37] [38] GPIO
  GND [39] [40] GPIO

Note on Orin Nano I2C bus numbering: The 40-pin header I2C pins (3/5) map to /dev/i2c-7 on Orin Nano (not i2c-1 as on the older Nano). Verify with:

ls /dev/i2c-*
i2cdetect -l

1. STM32F722 Bridge (USB CDC — Primary)

The STM32 acts as a real-time motor + IMU controller. Communication is via USB CDC serial.

USB CDC Connection

Connection Detail
Interface USB Micro-B on STM32 dev board → USB-A on Jetson
Device node /dev/ttyACM0 → symlink /dev/stm32-bridge (via udev)
Baud rate 921600 (configured in STM32 firmware)
Protocol JSON telemetry RX + ASCII command TX (see bridge docs)
Power Powered via robot 5V bus (data-only via USB)

Hardware UART (Fallback — 40-pin header)

Jetson Pin Signal STM32 Pin Notes
Pin 8 (TXD0) TX → PA10 (UART1 RX) Cross-connect TX→RX
Pin 10 (RXD0) RX ← PA9 (UART1 TX) Cross-connect RX→TX
Pin 6 (GND) GND GND Common ground required

Jetson device node: /dev/ttyTHS0 Baud rate: 921600, 8N1 Voltage level: 3.3V — both Jetson Orin and STM32F722 are 3.3V GPIO

# Verify UART
ls /dev/ttyTHS0
sudo usermod -aG dialout $USER
# Quick test
picocom -b 921600 /dev/ttyTHS0

ROS2 topics (STM32 bridge node):

ROS2 Topic Direction Content
/saltybot/imu STM32→Jetson IMU data (accel, gyro) at 50Hz
/saltybot/balance_state STM32→Jetson Motor cmd, pitch, state
/cmd_vel Jetson→STM32 Velocity commands → C<spd>,<str>\n
/saltybot/estop Jetson→STM32 Emergency stop

2. RealSense D435i (USB 3.1)

Connection

Parameter Value
Interface USB 3.1 Gen 1 (USB-A on Jetson — use blue port)
Device node /dev/bus/usb/... (udev-managed)
USB PID:VID 0x8086:0x0b3a (D435i)
Power draw ~1.5W active, 3.5W peak during init
Cable USB 3.1 — use short cable ≤1m for stability

Note: Orin Nano Developer Kit has 2× USB-A + 1× USB-C. Use USB-A (blue = USB 3.1) for D435i.

lsusb | grep Intel
# Expected: Bus 002 Device 003: ID 8086:0b3a Intel Corp. Intel RealSense D435i

ROS2 topics:

Topic Type Rate
/camera/color/image_raw sensor_msgs/Image 30Hz
/camera/depth/image_rect_raw sensor_msgs/Image 30Hz
/camera/aligned_depth_to_color/image_raw sensor_msgs/Image 30Hz
/camera/imu sensor_msgs/Imu 400Hz

3. RPLIDAR A1M8 (UART via USB adapter)

Connection

Parameter Value
Interface USB Micro-B (via included CP2102 USB-UART adapter)
Device node /dev/ttyUSB0 → symlink /dev/rplidar (via udev)
Baud rate 115200
Power draw ~2.6W motor on, 0.4W idle
Motor control DTR line (handled by rplidar_ros driver)
ls /dev/rplidar      # should exist after udev rule applied
ros2 launch rplidar_ros rplidar_a1_launch.py serial_port:=/dev/rplidar

ROS2 topics:

Topic Type Rate
/scan sensor_msgs/LaserScan 10Hz

4. 4× IMX219 CSI Cameras (MIPI CSI-2)

The IMX219 (Sony 8MP) cameras connect via MIPI CSI-2 FFC cables to the Jetson Orin Nano.

CSI Connector Layout (Orin Nano Developer Kit)

The Orin Nano Developer Kit has two MIPI CSI-2 connectors:

  • CSI-A (J5): 15-pin FFC — connects to ArduCam adapter A
  • CSI-B (J8): 15-pin FFC — connects to ArduCam adapter B

Each ArduCam multi-camera adapter multiplexes 2× IMX219 cameras onto one CSI lane.

ArduCam Multi-Camera Adapter Wiring

Adapter Cameras CSI Connector V4L2 Devices
Adapter A (CSI-A) front + left J5 /dev/video0, /dev/video2
Adapter B (CSI-B) rear + right J8 /dev/video4, /dev/video6

IMX219 15-pin FFC Pinout (each camera module)

Pin Signal Notes
1 GND
2 CSI D0- MIPI data lane 0 negative
3 CSI D0+ MIPI data lane 0 positive
4 GND
5 CSI D1- MIPI data lane 1 negative
6 CSI D1+ MIPI data lane 1 positive
7 GND
8 CSI CLK- MIPI clock negative
9 CSI CLK+ MIPI clock positive
10 GND
11 CAM_GPIO Camera enable (active high)
12 CAM_CLK I2C / control clock
13 CAM_SDA I2C data
14 GND
15 3.3V Power

V4L2 Device Nodes

# List all video devices
v4l2-ctl --list-devices

# Expected output:
# vi-output, imx219 2-0010 (platform:tegra-capture-vi:0):
#         /dev/video0
# vi-output, imx219 2-0010 (platform:tegra-capture-vi:1):
#         /dev/video2
# vi-output, imx219 4-0010 (platform:tegra-capture-vi:2):
#         /dev/video4
# vi-output, imx219 4-0010 (platform:tegra-capture-vi:3):
#         /dev/video6

# Capture test (GStreamer)
gst-launch-1.0 nvarguscamerasrc sensor-id=0 ! \
  'video/x-raw(memory:NVMM),width=640,height=480,framerate=30/1' ! \
  nvvidconv ! xvimagesink

# Capture via V4L2
v4l2-ctl --device=/dev/video0 --stream-mmap --stream-count=1 \
  --set-fmt-video=width=640,height=480,pixelformat=RG10

ROS2 Topics (saltybot_cameras package)

Topic Camera Type Rate
/camera/front/image_raw front (video0) sensor_msgs/Image 30Hz
/camera/left/image_raw left (video2) sensor_msgs/Image 30Hz
/camera/rear/image_raw rear (video4) sensor_msgs/Image 30Hz
/camera/right/image_raw right (video6) sensor_msgs/Image 30Hz

TF Frames

Camera Frame ID Offset from sensor_head_link
front camera_front_link x=+0.05m, yaw=0°
left camera_left_link y=+0.05m, yaw=+90°
rear camera_rear_link x=-0.05m, yaw=180°
right camera_right_link y=-0.05m, yaw=-90°

5. I2C Bus (i2c-7) — Pin 3 / Pin 5

Available for future peripherals (IMU breakout, OLED display, etc.).

Parameter Value
Jetson I2C bus i2c-7 (pins 3 = SDA, 5 = SCL) on Orin Nano
Voltage 3.3V pull-up
Max clock 400kHz (Fast Mode)
# Scan i2c-7 bus
i2cdetect -y -r 7

Note: i2c-0 (pins 27/28) is reserved for EEPROM ID — do not use.


6. M.2 NVMe Storage

The Orin Nano Developer Kit includes an M.2 Key M slot.

Parameter Value
Interface PCIe Gen 3 ×4
Form factor M.2 2230 / 2242 / 2280
Recommended 256GB+ NVMe SSD (e.g., WD SN530, Samsung PM991)
Mount point /mnt/nvme
# Verify NVMe detected
lsblk | grep nvme
nvme list

# Partition + format (one-time setup — see setup-jetson.sh)
sudo parted /dev/nvme0n1 mklabel gpt
sudo parted /dev/nvme0n1 mkpart primary ext4 0% 100%
sudo mkfs.ext4 /dev/nvme0n1p1
sudo mkdir -p /mnt/nvme

7. USB Ports Summary

Port Type Used For
USB-A (top, blue) USB 3.1 Gen 1 RealSense D435i
USB-A (bottom) USB 2.0 RPLIDAR (via USB-UART adapter)
USB-C USB 3.1 Gen 1 (+ DP) STM32 CDC or host flash
Micro-USB Debug/flash JetPack flash only

8. GPIO Summary Table

Physical Pin Function Voltage Used For
3 SDA1 3.3V I2C data (i2c-7)
5 SCL1 3.3V I2C clock (i2c-7)
8 TXD0 3.3V UART TX → STM32 (fallback)
10 RXD0 3.3V UART RX ← STM32 (fallback)
USB-A ×2 5V D435i, RPLIDAR
USB-C 5V STM32 CDC
CSI-A (J5) MIPI CSI-2 Cameras front + left
CSI-B (J8) MIPI CSI-2 Cameras rear + right
M.2 Key M PCIe Gen3 ×4 NVMe SSD

9. udev Rules

Apply stable device names:

# /etc/udev/rules.d/99-saltybot.rules

# RPLIDAR A1M8 (SiliconLabs CP2102)
KERNEL=="ttyUSB*", ATTRS{idVendor}=="10c4", ATTRS{idProduct}=="ea60", \
  SYMLINK+="rplidar", MODE="0666"

# STM32 USB CDC (STMicroelectronics)
KERNEL=="ttyACM*", ATTRS{idVendor}=="0483", ATTRS{idProduct}=="5740", \
  SYMLINK+="stm32-bridge", MODE="0666"

# Intel RealSense D435i
SUBSYSTEM=="usb", ATTRS{idVendor}=="8086", ATTRS{idProduct}=="0b3a", \
  MODE="0666"

# IMX219 CSI cameras (V4L2)
KERNEL=="video[0246]", SUBSYSTEM=="video4linux", MODE="0666"
sudo cp docs/99-saltybot.rules /etc/udev/rules.d/
sudo udevadm control --reload-rules && sudo udevadm trigger