Petrainer PET998-Series E-Collar

Brand: Petrainer

FCC ID: 2AATP-PET998DRU

Modulation

The collars use pulse-position modulation (PPM) at 433MHz to encode command messages. A regular button press on the remote will repeat the message 3 times, though you can get it to send only one if you press the button quickly enough. The reciever seems to have diffuculty picking up the command if it isn’t repeated at least 3 times. Holding down the button will continuously repeat the message.

Messages begin with an 780µs pulse followed by a 780µs gap as a starting signal, followed by a series of 216µs pulses. The binary data is encoded in the gaps between pulses: a 780µs gap for a 0 or a 1580µs gap for a 1.

We can use the wonderful rtl_433 program to record the signal and generate some nice visualizations:

rtl_433 -A -R 0 -S all
💡 Command options used (click to expand)
[-A] Pulse Analyzer. Enable pulse analysis and decode attempt.
     Disable all decoders with -R 0 if you want analyzer output only.
[-S none | all | unknown | known] Signal auto save. Creates one file per signal.
     Note: Saves raw I/Q samples (uint8 pcm, 2 channel). Preferred mode for generating test files.

Here’s the result:

Using this we can easily decode our signal to binary (ignoring the extra 0 pulseview shows at the start)

  • Binary: 11110010 00101011 00111010 00101101 10110000
  • Hex: F2 2B 3A 2D B0

Binary Encoding

The first 4 bits encode the channel (The remote supports switching between 2 channels).

#- -- -- -- --
F2 2B 3A 2D B0
Binary Hex Decimal Channel
1000 0x8 8 Channel 1
1111 0xF 15 Channel 2

The second 4 bits encode the command mode.

-# -- -- -- --
F2 2B 3A 2D B0
Binary Hex Decimal Mode
0001 0x1 1 Shock
0010 0x2 2 Vibrate
0100 0x4 4 Beep
1000 0x8 8 Flash

The second and third bytes encode the remote’s unique id.

-- ## ## -- --
F2 2B 3A 2D B0
Binary Hex
00101011 00111010 2B 3A

The fourth byte encodes the shock/vibrate intensity (0-100).

*In my testing, the PET998DBB would not go higher than 100, but I’ve seen people using generic older versions of the collar that say they will.

-- -- -- ## --
F2 2B 3A 2D B0
Binary Hex Decimal
00101101 0x2D 45

The fifth byte is an inverted, flipped copy of the first byte (probably used as a weak error check).

-- -- -- -- ##
F2 2B 3A 2D B0
  Binary Hex Decimal
First Byte 11110010 0xF2 242
Last Byte 10110000 0xB0 176

Here’s an example rtl_433 command that can decode the signal and break it into it’s components:

rtl_433 -F json -R 0 -X "name=petrainer,modulation=OOK_PPM,short=784,long=1580,gap=3000,reset=16000,get=channel:@1:{4}:[8:channel_1 15:channel_2],get=mode:@5:{4}:[1:shock 2:vibration 4:beep 8:flash],get=UID:@9:{16}:%X,get=intensity:@25:{8}"
{
  "time": "2023-01-13 21:41:05",
  "model": "petrainer",
  "count": 4,
  "num_rows": 4,
  "rows": [
    {
      "len": 41,
      "data": "79159d16d80",
      "channel": "channel_2",
      "mode": "vibration",
      "UID": 11066,
      "intensity": 45
    },
    {
      "len": 41,
      "data": "79159d16d80",
      "channel": "channel_2",
      "mode": "vibration",
      "UID": 11066,
      "intensity": 45
    },
    {
      "len": 41,
      "data": "79159d16d80",
      "channel": "channel_2",
      "mode": "vibration",
      "UID": 11066,
      "intensity": 45
    },
    {
      "len": 0,
      "data": "",
      "channel": 0,
      "mode": 0,
      "UID": 0,
      "intensity": 0
    }
  ],
  "codes": [
    "{41}79159d16d80",
    "{41}79159d16d80",
    "{41}79159d16d80",
    {0}
  ]
}

*this output isn’t fully valid JSON - there seems to be a bug in rtl_433 when it writes the codes array.

Full Model List

ModelNotesLinks
PET998D1
(IS-PET998D-1)
Seems to be the original? Not rechargeable
PET998D2
(IS-PET998D-2)
Two-collar bundle for PET998D
PET998DR1
(IS-PET998DR-1)
Rechargeable (5v barrel)
PET998DR2
(IS-PET998DR-2)
Two-collar bundle for PET998DR
PET998DRB1
(IS-PET998DRB-1)
Rechargeable (5v barrel)
PET998DRB2
(IS-PET998DRB-2)
Two-collar bundle for PET998DRB
PET998DRU1
(IS-PET998DRU-1)
Rechargeable (micro-usb)
PET998DRU2
(IS-PET998DRU-2)
Two-collar bundle for PET998DRU
PET998DB1
(IS-PET998DB 1 for 1)
Thinner design. Rechargeable (5v barrel)
PET998DB2
(IS-PET998DB 1 for 2)
Two-collar bundle for PET998DB
PET998DBB1 Thinner design. Rechargeable (5v barrel). Links to the same manual as the PET998DB.
PET998DBB2 Two-collar bundle for PET998DBB
PET998DBU
(IS-PET998DBU 1 for 1)
Thinner design. Rechargeable (micro-usb). The manual also shows a 2-collar bundle but I haven't found any listings for it.

PET998DBB Teardown

Remote Teardown
Front Back Battery Back PCB Back PCB Top Front PCB Front PCB 2 Front PCB Top Front PCB Bottom
Reciever Teardown

Other Resources

*there seems to be some conflicting information in this repo about the protocol from older models. Contact me if you find a PET988 model collar that uses a different protocol.