Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Document Tremblr BT-R Protocol #13

Open
denialtek opened this issue Sep 8, 2023 · 6 comments
Open

Document Tremblr BT-R Protocol #13

denialtek opened this issue Sep 8, 2023 · 6 comments

Comments

@denialtek
Copy link

denialtek commented Sep 8, 2023

Service: 0xfff0
TX: 0xfff1

Message format

{command} 0x64 0x00 0x00 0x00 0x00 0x31 0x32 0x33 0x34 0x00 0x00 0x00 0x00 0x00 0x00 0x00 {crc-8 checksum}

The 0x31 0x32 0x33 0x34 bytes are intended to be used for password functionality but it appears to not be implemented.

Commands

The commands all map to button presses or releases on the UI.

0x01 - On/Off button held down
0x02 - On/Off button released

0x05 - Speed Up button held down
0x06 - Speed Down button held down
0x03 - Speed buttons released

0x07 - Suction Up button held down
0x08 - Suction Down button held down
0x09 - Suction buttons released

ex.
Turn on device - Send 0x01 and then 0x02
Turn off device - Send 0x01 and then 0x02
Increase speed - Send 0x05 once. The device will continue slowly speeding up until 0x03 is sent.

There doesn't appear to be a way of reading what the current on/off state, speed, or suction level is of the device.

CRC-8

The CRC-8 checksum formula is non-standard. In JavaScript it looks like:

calcCrc8 (data) {
    let bitCount = 0
    let crc = 0

    for (let i = 0; i < data.length; i++) {
      const byte = data[i]
      for (let j = 0; j < 8; j++) {
        if ((byte & (1 << j)) !== 0) {
          bitCount++
        }
      }
    }

    const remainder = bitCount % 3

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

    return crc
}
@penaltybush
Copy link

penaltybush commented Oct 3, 2023

@denialtek Do you have the BLE Name it advertises under?

I'm looking to write a BLE to RF bridge for the Tremblr so that the older model can be used by the new BT-R smart app and any future services. Simular to LVS-Gateway.

My current attempts to emulate it using the information you have already provided doesn't allow for it to be detected by the smart app. If you have any additional information about the way this model presents itself via bluetooth I'd be greatful.

Thanks.

@denialtek
Copy link
Author

BLE Name: FM-T

@penaltybush
Copy link

penaltybush commented Oct 3, 2023

@denialtek Thanks that was what I was missing. I was able to grab some data from the iOS app.

From the iOS app I don't seem to receive button release messages, if I hold down a button on the app the message repeats around once per second.

BLE Messages

App

@penaltybush
Copy link

I noticed that in the App Store screenshots it also shows a remote marked as 'GIGOLO'. I checked the FCC ID filing for the Tremblr BT-R and the documents mention both the Tremblr and the Gigolo so I suspect there will be an announcement for a Gigolo BT-R at some point.

I tested setting the BLE Name to 'FM-G' and this makes the BLE device show up in the iOS App as GIGOLO and presents the same virtual remote minus the -/+ Suction buttons. I can also confirm that the buttons on the Gigolo remote send exactly the same codes as the Tremblr remote.

@penaltybush
Copy link

penaltybush commented Jan 1, 2024

@denialtek Thanks that was what I was missing. I was able to grab some data from the iOS app.

From the iOS app I don't seem to receive button release messages, if I hold down a button on the app the message repeats around once per second.

An updated version of the iOS app has been published and it no longer functions differently to the Android app. The iOS app now sends a single button press event followed by a button released event once the button is let go.


Also support for a new device has been added "F-machine Alpha" (BLE-Name: FM-A), this device uses the same remote codes as the Trumblr however Suction -/+ codes are used to change stroke depth.

Alpha Commands Capture

@penaltybush
Copy link

How F-Machine Connect implements Remote Play.

This information could be useful for adding support to the library.

The app only tracks the state of the device's speed, the suction level is not tracked.
The speed is tracked as a value between 0 (off) and 28 (full speed).
The speed down command can only reduce the speed to 1 (not zero).
When a button is held in the remote UI, Speed Pressed and Speed Release are sent continuously but the value is only considered to change by 1 every 200ms.

On Start

When a remote session is started in the app, the app sends the Speed Press Down, followed by the Speed Release commands 55 times (60ms apart, 110 total commands). This is probably done to ensure that if the machine was currently on level 28, there would be enough commands to bring it down to level 1.

When a Speed Change Button is Pressed (Tapped)

The app sends the Speed Pressed and Speed Release commands twice (60ms apart, 4 total commands).

When a Speed Change Button is Held

The app sends the Speed Pressed and Speed Release commands 60ms apart continuously. However, the internal counters only consider the value to have changed by 1 every 200ms.

When a Suction Change Button is Pressed (Tapped) or Held

The app sends the Suction Pressed signal followed by the Suction Release signal. If the button is held, the Release signal is not sent until the button is released.

When the On/Off Button is Pressed (Tapped) or Held

The app sends the On/Off Pressed signal followed by the On/Off Release signal. If the button is held, the two signals are not sent until the button is released.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants