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.
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
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())
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"))
python brainco_revo_agent.py --mock --session test --self-test to exercise all API methods and piano press sequences without any physical device.
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)
- All fingers open to 0% closure
- Wait 300 ms for mechanical settle
- For each finger (thumb → index → middle → ring → pinky):
- Close to 90% closure — wait 120 ms
- Open to 0% closure — wait 120 ms
- All fingers settle at hover position (15% closure)
- 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())
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())