Skip to main content

F-Machine BLE Protocol

Introduction

Several F-Machine products are available in Bluetooth LE-enabled variants. These devices share a common BLE protocol using an 18-byte message with a CRC-8 checksum. Commands map to button presses on the physical device UI.

Covered devices:

DeviceBLE NameSecondary Function
Tremblr BT-RFM-TSuction
Gigolo BT-RFM-GNone
AlphaFM-AThrust Depth

BLE Profile

ble_names:
- "FM-T"
- "FM-G"
- "FM-A"
services:
- uuid: "0xfff0"
characteristics:
- uuid: "0xfff1"
properties: [read, write]
role: tx
description: "Command endpoint"
- uuid: "0xfff4"
properties: [notify, read]
role: rx
description: "Response/notification endpoint"

Device Configuration

Pairing

No special pairing procedure required.

Command Message Format

CMD 64 00 00 00 00 31 32 33 34 00 00 00 00 00 00 00 CRC
PositionValueDescription
Byte 0Command byteSee command table below
Byte 10x64Constant
Bytes 2–50x00Constant
Bytes 6–90x31 0x32 0x33 0x34Password placeholder (not implemented)
Bytes 10–160x00Constant
Byte 17CRC byteCRC-8 checksum

Notification Response Format

CMD 64 00 BITMASK 00 00 00 00 00 00 00 00 00 00 00 00 00 CRC
PositionValueDescription
Byte 0Command byteSee command table below
Byte 10x64Constant
Byte 20x00Constant
Byte 3Bitmask byteSee response bitmask below
Bytes 4–160x00Constant
Byte 17CRC byteCRC-8 checksum

Commands

Each command represents a button event. Button-held events are followed by a button-released event when released.

CommandByteDescription
On/Off hold0x01On/Off button held down
On/Off release0x02On/Off button released
Speed buttons release0x03Speed buttons released
Reserved0x04Unknown / Reserved
Speed Up hold0x05Speed Up button held down
Speed Down hold0x06Speed Down button held down
Secondary Function Up hold0x07Secondary Function Up button held down
Secondary Function Down hold0x08Secondary Function Down button held down
Secondary Function buttons release0x09Secondary Function buttons released

The secondary function (0x07/0x08/0x09) controls different physical mechanisms depending on the device: Suction on the Tremblr BT-R, and Thrust Depth on the Alpha. The Gigolo BT-R has no secondary function and does not use these commands.

CRC-8 Checksum

The checksum is computed over the first 17 bytes of the message:

function calcCRC8 (data) {
let bitCount = 0
let crc = 0

for (let i = 0; i < 17; i++) {
let byte = data[i]
for (let b = 0; b < 8; b++) {
if ((byte & (1 << b)) !== 0 ) {
bitCount++
}
}
}

const remainder = bitCount % 3
if (remainder === 0) {
crc = 222 - bitCount
} else if (remainder === 1) {
crc = Math.floor(bitCount / 2) + 111
} else {
crc = Math.floor(bitCount / 3) + 177
}

return crc
}

Response bitmask

Although multiple buttons may be held simultaneously, the device only ever reports the highest value bit at any one time.

000xxxxx
||||\_ Is On/Off Held (`0x01`)
|||\__ Is Speed Up Held (`0x02`)
||\___ Is Speed Down Held (`0x04`)
|\____ Is Secondary Function Up Held (`0x08`)
\_____ Is Secondary Function Down Held (`0x10`)

An example, if Speed Up and Secondary Function Up are both held, only 0x08 will be returned until Secondary Function Release is sent, then it will reply 0x02 as Speed Up is still held. Once nothing is held it will go back to 0x00.

Notes

  • All three BLE devices (Tremblr BT-R FM-T, Gigolo BT-R FM-G, Alpha FM-A) share this protocol. The secondary function commands (0x07/0x08/0x09) are only applicable to the Tremblr BT-R (suction) and the Alpha (thrust depth); the Gigolo BT-R has no secondary function.
  • Password bytes (0x31 0x32 0x33 0x34) are intended for authentication but not implemented in current firmware. It's unknown whether firmware can be upgraded.
  • CRC formula: based on bitCount mod 3, applies one of three linear transformations to the total bit count.

Sources