BrainCo Revo II Setup Guide

Step-by-step setup for the BrainCo Revo II bionic hand — from USB or BLE connection through calibration, pose control, and platform integration.

1

USB-CDC Connection

Install Python dependencies

pip install pyserial websockets

Connect and identify the port

Connect the Revo II via USB. On Linux the device enumerates as /dev/ttyACM0 (or ttyACM1 if other ACM devices are present). On Windows, check Device Manager for the COM port.

ls /dev/ttyACM*          # Linux — find the device
# Windows: check Device Manager → Ports (COM & LPT)

Fix permissions on Linux

If you get a permission denied error, add your user to the dialout group, then log out and back in:

sudo usermod -aG dialout $USER
# Log out and back in for the change to take effect
Baud rate The Revo II communicates at exactly 115200 baud. Any other rate will produce unreadable output. Commands are newline-terminated UTF-8 JSON strings.
2

Bluetooth Low Energy (BLE) Connection

The same JSON command protocol works over BLE GATT. Use this path for wireless deployments.

Install the BLE library

pip install bleak

Scan for the Revo II

import asyncio
from bleak import BleakScanner

async def scan():
    devices = await BleakScanner.discover(timeout=5.0)
    for d in devices:
        print(d.address, d.name)

asyncio.run(scan())
# Look for a device named "BrainCo" or similar — note its address

BLE GATT UUIDs

  • Service: 0000ffe0-0000-1000-8000-00805f9b34fb
  • Write characteristic: 0000ffe1-0000-1000-8000-00805f9b34fb
  • Notify characteristic: 0000ffe2-0000-1000-8000-00805f9b34fb

Connect and send a command via BLE

import asyncio, json
from bleak import BleakClient

WRITE_CHAR = "0000ffe1-0000-1000-8000-00805f9b34fb"
ADDRESS = "AA:BB:CC:DD:EE:FF"   # replace with your device address

async def main():
    async with BleakClient(ADDRESS) as client:
        # Close all fingers to 50%
        cmd = json.dumps({"cmd": "set_pose", "positions": [50,50,50,50,50]})
        await client.write_gatt_char(WRITE_CHAR, cmd.encode("utf-8"), response=False)
        await asyncio.sleep(1.0)
        # Open all fingers
        cmd2 = json.dumps({"cmd": "set_pose", "positions": [0,0,0,0,0]})
        await client.write_gatt_char(WRITE_CHAR, cmd2.encode("utf-8"), response=False)

asyncio.run(main())
3

First Pose Commands (USB)

Position values in the JSON protocol are integers 0–100 (percent closure). The Python SDK uses normalized floats 0.0–1.0 and converts internally.

Raw serial commands

import serial, json, time

port = serial.Serial("/dev/ttyACM0", baudrate=115200, timeout=1.0)

def set_pose(positions):
    pcts = [int(p * 100) for p in positions]
    cmd = json.dumps({"cmd": "set_pose", "positions": pcts}) + "\n"
    port.write(cmd.encode("utf-8"))

# Open all fingers
set_pose([0.0, 0.0, 0.0, 0.0, 0.0])
time.sleep(1.0)

# Point with thumb extended, close others
set_pose([0.0, 0.8, 0.8, 0.8, 0.8])
time.sleep(1.0)

# Fist
set_pose([1.0, 1.0, 1.0, 1.0, 1.0])
time.sleep(1.0)

# Open again
set_pose([0.0] * 5)
port.close()

Finger index mapping

  • 0 — Thumb (2 DOF: flexion + rotation = flexion × 0.4)
  • 1 — Index (1 DOF flexion)
  • 2 — Middle (1 DOF flexion)
  • 3 — Ring (1 DOF flexion)
  • 4 — Pinky (1 DOF flexion)

Set single finger

# Set index finger to 75% closure
cmd = json.dumps({"cmd": "set_finger", "finger": 1, "position": 75}) + "\n"
port.write(cmd.encode("utf-8"))
No hardware? Use mock mode Run python brainco_revo_agent.py --mock --session test --self-test to exercise all API methods and piano press sequences without any physical device.
4

Calibration Wave Sequence

Calibration establishes per-finger travel limits in the firmware. Run this after first connection and after any mechanical adjustment.

Calibration sequence (automatic)

  1. All fingers open to 0% closure
  2. Wait 300 ms for mechanical settle
  3. For each finger (thumb → index → middle → ring → pinky):
    • Close to 90% closure — wait 120 ms
    • Open to 0% closure — wait 120 ms
  4. All fingers settle at hover position (15% closure)
  5. Send {"cmd": "calibrate"} to lock in firmware limits

Run calibration via SDK

import asyncio
from brainco_revo_agent import BrainCoReVoController

async def calibrate():
    ctrl = BrainCoReVoController(mock=False)
    await ctrl.connect("/dev/ttyACM0")
    await ctrl.calibrate()   # runs full wave then sends calibrate cmd
    print("Calibration complete")
    await ctrl.disconnect()

asyncio.run(calibrate())
5

Platform Teleop Integration

The brainco_revo_agent.py bridges the Revo II to the RoboticsCenter platform via WebSocket, enabling remote operation, finger position monitoring, and demonstration data collection from a browser.

Launch the agent

# Real hardware (USB)
python brainco_revo_agent.py \
  --backend wss://your-backend.run.app \
  --session YOUR_SESSION_ID \
  --device /dev/ttyACM0

# Real hardware (BLE)
python brainco_revo_agent.py \
  --backend wss://your-backend.run.app \
  --session YOUR_SESSION_ID \
  --ble AA:BB:CC:DD:EE:FF

# Mock mode — no hardware required
python brainco_revo_agent.py \
  --backend ws://localhost:8000 \
  --session test-session \
  --mock

Piano mode via platform

Trigger piano key presses from the browser teleop panel. Each press executes the 4-phase sequence: extend (20 ms) → drive (30 ms) → hold → retract (20 ms). Concurrent finger presses are supported.

High-level SDK API

import asyncio
from brainco_revo_agent import BrainCoReVoController

async def main():
    ctrl = BrainCoReVoController(mock=False)
    await ctrl.connect("/dev/ttyACM0")

    # Set all fingers to 60% closure
    await ctrl.set_hand_pose([0.6, 0.6, 0.6, 0.6, 0.6])
    await asyncio.sleep(0.5)

    # Read current state
    snap = await ctrl.snapshot()
    print(snap["positions_dict"])   # {"thumb":0.6, "index":0.6, ...}

    await ctrl.disconnect()

asyncio.run(main())
← Back to Overview Full Specifications →

Need Help with Setup?

Visit the community forum or contact SVRC support.