amr-ros-k4/src/as5600_node/README.md

2.9 KiB

as5600_node — AS5600 12-bit Magnetic Rotary Encoder (C++, I2C)

ROS2 node for reading AS5600 magnetic rotary position sensors via Linux I2C (ioctl). Publishes angle data periodically. Supports multiple encoders on separate I2C buses.

Platform: linux-aarch64 only (Raspberry Pi)

ROS2 Interface

Direction Topic Message Description
Publish /encoder/state EncoderRead Periodic angle readings per encoder
# EncoderRead.msg (as5600_node → executor)
uint8 encoder_id       # Encoder index (0, 1, 2, ...)
float32 angle          # Angle in degrees (0.0-360.0)
uint16 raw_angle       # Raw 12-bit value (0-4095)

Parameters

Parameter Type Default Description
i2c_devices string[] ["/dev/i2c-1"] List of I2C device paths, one per encoder
publish_rate double 10.0 Publish frequency Hz

File Structure

src/as5600_node/
├── CMakeLists.txt              # ament_cmake — NO external lib dependency
├── package.xml                 # depend: rclcpp, blockly_interfaces
├── include/as5600_node/
│   └── as5600_node.hpp         # As5600Node class + I2C helpers + register constants
└── src/
    ├── as5600_node.cpp          # I2C init, timer_callback, read_raw_angle
    └── main.cpp                 # rclcpp::spin(node)

Build & Run

pixi run build-as5600     # installs system deps (apt) + builds
pixi run as5600-node      # start node with default parameters (1 encoder)

# 3 encoders on separate buses, 20 Hz
source install/setup.bash
ros2 run as5600_node as5600_node --ros-args \
  -p i2c_devices:="['/dev/i2c-1', '/dev/i2c-3', '/dev/i2c-4']" \
  -p publish_rate:=20.0

AS5600 Register Map

Register Address Description
RAW_ANGLE 0x0C-0x0D 12-bit raw angle (0-4095)
STATUS 0x0B Magnet detect status
AGC 0x1A Automatic gain control

Implementation Notes

  • AS5600 has a fixed I2C address (0x36) — cannot be changed. For multiple encoders, each must be on a separate I2C bus
  • Uses Linux I2C via ioctl() + linux/i2c-dev.h — no external library dependency
  • I2C_SLAVE address is set once per fd at startup (each fd is dedicated to one bus/encoder)
  • Raw angle read: write register 0x0C, read 2 bytes → ((buf[0] & 0x0F) << 8) | buf[1] (12-bit)
  • Angle conversion: raw * 360.0 / 4096.0 degrees
  • Timer callback iterates all fds and publishes one EncoderRead per encoder with encoder_id matching the index in i2c_devices

Raspberry Pi I2C Setup

The Pi has one hardware I2C bus (/dev/i2c-1) by default. For multiple AS5600 encoders, enable extra I2C buses via GPIO bit-banging overlays in /boot/config.txt:

# Extra I2C buses using GPIO pins
dtoverlay=i2c-gpio,bus=3,i2c_gpio_sda=17,i2c_gpio_scl=27
dtoverlay=i2c-gpio,bus=4,i2c_gpio_sda=22,i2c_gpio_scl=23

After reboot, verify with ls /dev/i2c-* and i2cdetect -y <bus>.