Overview

Custom wireless gimbal control system built around ESP32 controllers over CAN bus, enabling joystick PTZ, HTTP presets, and Stream Deck operation across multiple Ronin RS2 units in a portable broadcast rig.

Problem

DJI Ronin RS2 gimbals rely on the Ronin app and basic handle controls, which are not at all useful for live, multi-camera productions. However, due to their excellent stabilization, zoom/focus control, and the ability to handle the weight of most camera and lens combinations, they have the potential to become unobtrusive low-cost PTZ cameras. The goal was to create a deterministic, tactile control system that could scale across multiple gimbals, support diverse camera bodies, and integrate with a centralized control surface. Pair this with a compact video switcher like a Blackmagic Atem Mini Pro ISO and low-latency wireless transmitters, and you have a small and portable broadcast setup for any venue.

Hardware

Protocol

Implements DJI R SDK v2.5 over CAN at 1 Mbit/s. Frames are reassembled from 8-byte CAN packets and validated with reverse-engineered CRC-16/CRC-32 parameters based on DJI demo code.

Common CAN Command Frames

Focus Motor Calibration (CmdSubID 0x02)

Field Type Values
Command sub ID uint8 0x02 (focus motor calibration)
Motor type uint8 0x00 (focus motor)
Calibration command uint8 0x00 no control · 0x01 auto cal · 0x02 manual cal · 0x03 reserved · 0x04 set min · 0x05 set max · 0x06 stop
Return uint8 0x00 success · 0x01 failed

Focus Motor Position (CmdSubID 0x15)

Field Type Values
Command sub ID uint8 0x15 (current position)
Motor type uint8 0x00 (focus motor)
Endpoints status uint8 0x01 no calibration · 0x02 calibrating · 0x03 calibration complete
Current position uint32 0–4095

Third‑Party Camera Motion (CmdSet 0x0D, CmdID 0x00)

Command Value
Shutter0x0001
Stop shuttering0x0002
Start recording0x0003
Stop recording0x0004
Center focus0x0005
End center focus0x000B

Third‑Party Camera Status (CmdSet 0x0D, CmdID 0x01)

Field Type Values
Camera status obtain uint8 0x01 (query recording status)
Camera status uint8 0x00 not recording · 0x02 recording

Summarized from the official DJI SDK documentation.

SDK Reference

DJI RS2 accessory port pinout table and connector diagram from the SDK
Accessory port pinout (from the DJI RS2 SDK documentation).

RS2 Control Block Diagram

flowchart LR SD[Stream Deck] --> PI[Raspberry Pi] PI --> ESP[ESP32] JOY[Analog Joystick] --> ESP WIFI[WiFi Network] --- ESP WIFI --- PI ESP --> LORA[LoRa Link] LORA --> N1[ESP32 LoRa Node A] LORA --> N2[ESP32 LoRa Node B] LORA --> N3[ESP32 LoRa Node C] N1 --> CAN1[CAN Transceiver A] CAN1 --> RS2A[DJI Ronin RS2 A] RS2A <--> FM1[DJI Focus Motor A] N2 --> CAN2[CAN Transceiver B] CAN2 --> RS2B[DJI Ronin RS2 B] RS2B <--> FM2[DJI Focus Motor B] N3 --> CAN3[CAN Transceiver C] CAN3 --> RS2C[DJI Ronin RS2 C] RS2C <--> FM3[DJI Focus Motor C]

Firmware Architecture

Key Features

Challenges

Stack

ESP32, Arduino + ESP-IDF TWAI, C++, Bitfocus Companion, Stream Deck.

Outcome

Delivered a truly portable, broadcast‑grade PTZ system that replaces app‑based control with tactile operation, reliable presets, and centralized Stream Deck automation. It remains highly customizable because it supports the full DJI Ronin gimbal family and most camera/lens combinations, offering a clear advantage over typical PTZ systems that rely on smaller sensors, lower‑quality optics, or 1080p caps.

The closest comparable option is the Sony FR7, which offers similar capabilities but at a much higher cost and with a fixed‑sensor body.

Next Steps

Continue debugging the encrypted BLE connection to unlock deeper gimbal control (e.g., real‑time motor parameter changes), which currently live only inside the gimbal system rather than the CAN interface.