Skip to content

[Device Request] DG-LAB Opossum #958

Open

Description

@BytewaveMLP

Bluetooth protocol documented here (CN)

I know this project doesn't support other DG-LAB products for liability reasons since they're mostly e-stim related, but the Opoosum is a purely dual-channel vibrator toy, typically sold along with the Civet edging sensor.

Activity

  1. qdot commented on Sep 26, 2026

    @qdot
    Member

    Sure, I don't see why not.

    @LF112 anything else we should know about the device? We could also possibly look at supporting the civet for our sensor system, though I'm not sure we have the correct descriptors for that yet.

  2. BytewaveMLP commented on Oct 3, 2026

    @BytewaveMLP
    Author

    So I don't feel super comfortable contributing it myself (I don't really know Rust), but I was messing around with prototyping a device protocol implementation/config entry with substantial help from Copilot, and I have a couple notes that might be worth sharing.

    1. The device seems to be affected by the coded PHY bug addressed in feat(winrtble): allow overriding Coded PHY support deviceplug/btleplug#493 - I was able to get the device announcements to appear on my Linux machine, but not on my Windows one until I switched to this fork and disabled coded PHY.

    2. It seems like you need to send B0 commands with new waveform data every ~100ms or the device doesn't vibrate at all. I'm not sure if there's functionality in buttplug currently for custom waveforms, so this could probably just use some static data, but worth noting. Sending B3 without waveform data is a noop.

    3. The 50 instruction seems a little buggy - the DG-Lab Android app will update both the power meter AND corner indicator colors, but 50 only updates the corner indicators. B2 seems like what the Android app is actually using - see below.

    4. The B2 command controls a lot more aspects of the display than updating the channel strength numbers. I don't know how useful these fields are since they're mostly related to controlling the display, and I don't think there's a great way to expose these details in the library itself (except maybe as LED features?), but I documented it here below mostly because of the above point.

      B2 command fields

      Command Layout

      Offset Size Meaning
      0 1 Command: 0xB2
      1–2 2 Product icon color
      3 1 Product icon
      4–5 2 Top-left indicator color
      6–7 2 Top-right indicator color
      8–9 2 Channel A power bar color
      10–11 2 Channel B power bar color
      12–13 2 Channel A label color
      14–15 2 Channel B label color
      16–17 2 Channel A intensity color
      18–19 2 Channel B intensity color
      20 1 Channel A label
      21 1 Channel B label
      22 1 Displayed channel A intensity, 0–200
      23 1 Displayed channel B intensity, 0–200

      Color fields use big-endian RGB565.

      Product Icons

      Value Observed Icon
      00 Opossum
      01 Coyote 3.0
      02 Coyote 2.0(?)

      Warning: Out-of-bound writes caused the device to stop responding to commands until reset.

      Channel Labels

      Selector Displayed Label
      0x00 Mode 1
      0x01 Mode 2
      0x02 Mode 3
      0x03 Mode 4
      0x04 Mode 5
      0x05 Mode 6
      0x06 Mode 7
      0x07 Mode 8
      0x08 Ch. A
      0x09 Ch. B

      Warning: Out-of-bound writes caused the device to stop responding to commands until reset.

      Display w/ labels Image

    I was able to get a working prototype of the protocol implementation put together, but don't want to dump that on you and not be able to back it up in code review. I can put it up in a fork if you'd like, though.

    I also didn't probe to see if there were any undocumented commands beyond the behaviour expressed in B2, since I think there's sufficient coverage for controlling the toy via Buttplug with the documented commands.

  3. LF112 commented on Oct 15, 2026

    @LF112

    Hi @qdot, thanks! And thanks @BytewaveMLP for the prototype work and detailed testing notes.
    We’d like to contribute Opossum and Civet support upstream. We have both devices and can handle implementation and hardware testing. Before opening PRs, we’d like to check the scope and capability mapping.
    A few details about Opossum:

    1. Waveform data and channel strength are separate controls. As @BytewaveMLP noted, B0 waveform packets need to be sent approximately every 100ms; setting channel strength through B3 alone is insufficient for continuous vibration. Initial support could expose two independent Vibrate outputs for channels A/B.
    2. The display needs separate updates. The indicator settings in 50 do not replace channel-value display updates through B2. Strength changes from Bluetooth commands or physical buttons produce B3 notifications, which need to be handled to keep the display synchronized. The B2 display-update packet is also 24 bytes, so the implementation needs to accommodate that longer write.
    3. Testing would cover continuous transmission, stopping, and reconnection. We’d also include the Windows discovery issue reported by @BytewaveMLP in hardware testing and coordinate with the existing prototype work to avoid duplication.
      For Civet, initial support could expose one pressure input and battery reading. Pressure arrives through D0 notifications: zero-based byte offsets 8–9 contain a little-endian signed int16, in units of 0.01 kPa.

    Would the existing Pressure descriptor be appropriate for Civet? We’d like to preserve the sign and precision and agree on the representation first.
    We propose starting with Opossum and submitting Civet support separately. Does that split sound reasonable? Any structural preferences before we open PRs?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

FeaturesNew things to add to the project

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions