You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
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.
@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.
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.
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.
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.
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.
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
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.
Activity
qdot commentedon Sep 26, 2026
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.
BytewaveMLP commentedon Oct 3, 2026
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.
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.
It seems like you need to send
B0commands 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. SendingB3without waveform data is a noop.The
50instruction seems a little buggy - the DG-Lab Android app will update both the power meter AND corner indicator colors, but50only updates the corner indicators.B2seems like what the Android app is actually using - see below.The
B2command 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
0xB20–2000–200Color fields use big-endian RGB565.
Product Icons
000102Warning: Out-of-bound writes caused the device to stop responding to commands until reset.
Channel Labels
0x000x010x020x030x040x050x060x070x080x09Warning: Out-of-bound writes caused the device to stop responding to commands until reset.
Display w/ labels
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.