- Dockerfile: L4T R32.6.1 (JetPack 4.6) base + ROS2 Humble + SLAM stack (slam_toolbox, Nav2, rplidar_ros, realsense2_camera, robot_localization) - docker-compose.yml: multi-service stack (ROS2, RPLIDAR A1M8, D435i, STM32 bridge) with device passthrough, host networking for DDS, persistent map volume - docs/pinout.md: full GPIO/I2C/UART pinout for STM32F722 bridge (USB CDC + UART fallback), RealSense D435i (USB3), RPLIDAR A1M8, udev rules - docs/power-budget.md: 10W envelope analysis with per-component breakdown, mitigation strategies (RPLIDAR gating, D435i 640p, nvpmodel modes) - scripts/setup-jetson.sh: host one-shot setup (Docker, nvidia-container-runtime, udev rules, MAXN power mode, swap) - scripts/build-and-run.sh: build/up/down/shell/slam/status helper Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
214 lines
6.3 KiB
Markdown
214 lines
6.3 KiB
Markdown
# Jetson Nano — GPIO / I2C / UART Pinout Reference
|
||
## Self-Balancing Robot: STM32F722 Bridge + RealSense D435i + RPLIDAR A1M8
|
||
|
||
Last updated: 2026-02-28
|
||
JetPack version: 4.6 (L4T R32.6.1)
|
||
|
||
---
|
||
|
||
## 40-Pin Header Overview
|
||
|
||
The Jetson Nano 40-pin header is physically compatible with Raspberry Pi HATs.
|
||
Pin numbering below follows **physical board pin** (1–40) and the Jetson GPIO BCM-equivalent name.
|
||
|
||
```
|
||
3.3V [ 1] [ 2] 5V
|
||
SDA1 [ 3] [ 4] 5V ← I2C SDA (i2c-1)
|
||
SCL1 [ 5] [ 6] GND ← I2C SCL (i2c-1)
|
||
GPIO [ 7] [ 8] TXD0 ← UART TX (ttyTHS1)
|
||
GND [ 9] [10] RXD0 ← UART RX (ttyTHS1)
|
||
GPIO [11] [12] GPIO
|
||
GPIO [13] [14] GND
|
||
GPIO [15] [16] GPIO
|
||
3.3V [17] [18] GPIO
|
||
MOSI [19] [20] GND ← SPI0 MOSI
|
||
MISO [21] [22] GPIO ← SPI0 MISO
|
||
SCLK [23] [24] CE0 ← SPI0 CLK / CS0
|
||
GND [25] [26] CE1 ← SPI0 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
|
||
```
|
||
|
||
---
|
||
|
||
## 1. STM32F722 Bridge (UART)
|
||
|
||
The STM32 acts as a real-time motor + IMU controller. Communication to Jetson is via **USB CDC serial** (primary) with hardware UART as fallback.
|
||
|
||
### USB CDC (Primary — Recommended)
|
||
| Connection | Detail |
|
||
|-----------|--------|
|
||
| Interface | USB Micro-B on STM32 dev board → USB-A on Jetson |
|
||
| Device node | `/dev/ttyACM0` or `/dev/ttyUSB1` |
|
||
| Baud rate | 921600 (configured in STM32 firmware) |
|
||
| Protocol | Custom binary framing (see `src/comm/`) |
|
||
| Power | Powered via Jetson USB 5V (500mA max from host) |
|
||
|
||
### Hardware UART (Fallback)
|
||
| 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/ttyTHS1`
|
||
**Baud rate:** 921600, 8N1
|
||
**Voltage level:** 3.3V — STM32F722 is 3.3V tolerant; Jetson GPIO is 3.3V
|
||
**Do NOT use 5V** — Jetson GPIO max is 3.3V
|
||
|
||
```bash
|
||
# Verify UART on Jetson
|
||
ls /dev/ttyTHS1
|
||
# Check permissions (add user to dialout group)
|
||
sudo usermod -aG dialout $USER
|
||
# Quick loopback test (connect TX→RX)
|
||
picocom -b 921600 /dev/ttyTHS1
|
||
```
|
||
|
||
**ROS2 topic mapping (STM32 bridge node):**
|
||
| ROS2 Topic | Direction | Content |
|
||
|-----------|-----------|---------|
|
||
| `/stm32/imu_raw` | STM32→Jetson | IMU data (accel, gyro) at 500Hz |
|
||
| `/stm32/motor_state` | STM32→Jetson | Motor RPM, current, temperature |
|
||
| `/cmd_vel` | Jetson→STM32 | Velocity commands (m/s, rad/s) |
|
||
| `/stm32/estop` | Jetson→STM32 | Emergency stop signal |
|
||
|
||
---
|
||
|
||
## 2. RealSense D435i (USB3)
|
||
|
||
The D435i provides RGB-D (depth + color) and IMU (accelerometer + gyroscope).
|
||
|
||
### Connection
|
||
| Parameter | Value |
|
||
|-----------|-------|
|
||
| Interface | USB 3.1 Gen 1 (USB-A on Jetson) |
|
||
| 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:** The Jetson Nano has **4× USB-A ports** — use a USB3 port (blue) for D435i.
|
||
|
||
```bash
|
||
# Verify detection
|
||
lsusb | grep Intel
|
||
# Expected: Bus 002 Device 003: ID 8086:0b3a Intel Corp. Intel RealSense D435i
|
||
|
||
# Install udev rules (required for non-root access)
|
||
sudo cp /etc/udev/rules.d/99-realsense-libusb.rules /etc/udev/rules.d/
|
||
sudo udevadm control --reload-rules && sudo udevadm trigger
|
||
|
||
# Test with realsense-viewer (if installed)
|
||
realsense-viewer
|
||
```
|
||
|
||
**ROS2 topics published:**
|
||
| 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 |
|
||
| `/camera/color/camera_info` | `sensor_msgs/CameraInfo` | 30Hz |
|
||
|
||
---
|
||
|
||
## 3. RPLIDAR A1M8 (UART via USB adapter)
|
||
|
||
The A1M8 uses a CP2102/CH340 USB-UART adapter (included in kit).
|
||
|
||
### Connection
|
||
| Parameter | Value |
|
||
|-----------|-------|
|
||
| Interface | USB Micro-B (via included USB-UART adapter) |
|
||
| Device node | `/dev/ttyUSB0` (first USB-UART device) |
|
||
| Baud rate | 115200 |
|
||
| Power draw | ~2.6W motor on, 0.4W idle |
|
||
| Motor control | DTR line (handled by rplidar_ros driver) |
|
||
|
||
```bash
|
||
# Verify detection
|
||
ls /dev/ttyUSB*
|
||
# Expected: /dev/ttyUSB0
|
||
|
||
# Set permissions
|
||
sudo usermod -aG dialout $USER
|
||
|
||
# Test — should output scan data
|
||
ros2 launch rplidar_ros rplidar_a1_launch.py serial_port:=/dev/ttyUSB0
|
||
```
|
||
|
||
**ROS2 topics published:**
|
||
| Topic | Type | Rate |
|
||
|-------|------|------|
|
||
| `/scan` | `sensor_msgs/LaserScan` | 10Hz |
|
||
|
||
**udev rule (set consistent device name):**
|
||
```bash
|
||
# /etc/udev/rules.d/99-rplidar.rules
|
||
KERNEL=="ttyUSB*", ATTRS{idVendor}=="10c4", ATTRS{idProduct}=="ea60", \
|
||
SYMLINK+="rplidar", MODE="0666"
|
||
```
|
||
|
||
---
|
||
|
||
## 4. I2C Bus (i2c-1) — Pin 3 / Pin 5
|
||
|
||
Available for future peripherals (IMU breakout, OLED display, etc.).
|
||
|
||
| Parameter | Value |
|
||
|-----------|-------|
|
||
| Jetson I2C bus | i2c-1 (pins 3 = SDA, 5 = SCL) |
|
||
| Voltage | 3.3V pull-up |
|
||
| Max clock | 400kHz (Fast Mode) |
|
||
| Current source | Jetson 3.3V rail (max ~500mA shared) |
|
||
|
||
```bash
|
||
# Scan i2c-1 bus
|
||
i2cdetect -y -r 1
|
||
```
|
||
|
||
**Note:** i2c-0 (pins 27/28) is reserved for EEPROM ID — do not use.
|
||
|
||
---
|
||
|
||
## 5. GPIO Summary Table
|
||
|
||
| Physical Pin | Jetson GPIO | Voltage | Current Used For |
|
||
|-------------|-------------|---------|-----------------|
|
||
| 3 | SDA1 | 3.3V | I2C data (i2c-1) |
|
||
| 5 | SCL1 | 3.3V | I2C clock (i2c-1) |
|
||
| 8 | TXD0 | 3.3V | UART TX → STM32 (fallback) |
|
||
| 10 | RXD0 | 3.3V | UART RX ← STM32 (fallback) |
|
||
| USB-A (×4) | — | 5V | D435i, RPLIDAR adapter, STM32 USB |
|
||
|
||
---
|
||
|
||
## 6. Device Enumeration Notes
|
||
|
||
USB devices may enumerate differently across reboots. Use udev rules for stable names:
|
||
|
||
```bash
|
||
# /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"
|
||
```
|
||
|
||
Apply rules:
|
||
```bash
|
||
sudo cp docs/99-saltybot.rules /etc/udev/rules.d/
|
||
sudo udevadm control --reload-rules && sudo udevadm trigger
|
||
```
|