In this note I describe the on-air protocol of Pixel Pawn wireless flash trigger.
Tools and methods
To interact with the flash trigger, I used Lime Microsystems LimeSDR Mini. To determine the center frequency of transmissions, I used SDRAngel in spectrogram mode, knowing that the device is advertised to work in the 2.4 GHz range. To determine bit rate, modulation, and packet format, I used Universal Radio Hacker as described in its documentation. To understand commands better, I used the Glasgow debug tool’s
radio-nrf24l applet in transmit and receive mode as described below.
Modulation GMSK, data rate 250 kbps, on-air time 356.00 µs, of which settling time 60.75 µs, transmission time 295.25 µs. Packet format:
1010101010101010101010101010101010101100001101010111111001001110101-1100000 < 67 fixed bits > < CMD >
Each button press produces a burst of 5-10 packets. However, holding a button or being in an active mode only produces a single packet every few hundred ms.
The channel to frequency mapping is as follows:
Commands are specified in 7 last bits of the packet.
||power on, mode switch, other command prefix|
||mode 1 press|
||mode 2 first press|
||mode 2 second press|
||mode 3 first press|
||mode 3 second press|
The preamble can be quite short, as few as 2 octets long. However, commands that are not preceded by
1100000 will be often not recognized, regardless of preamble length.
Considering the framing, any appropriately encoded octet sequence that includes the following one will trigger a command:
aa aa aa aa b0 d5 f9 3a (80|CMD)
An elegant way to emulate a transmitter is to use an nRF24L01(+) in nRF2401 compatible mode with 4 address bytes set to
aa aa aa aa and data bytes set to
b0 d5 f9 3a (80|CMD). However, in a pinch, just transmitting this as a kind of in-band signal in any other packet framing also works just fine.
Similarly, an elegant way to emulate a receiver is to use an nRF24L01(+) in nRF2401 compatible mode with 4 address bytes set to
b0 d5 f9 3a. (It uses the same
aa preamble, and synchronizes to address bytes.)
nRF24L01(+) only support channel frequencies of integer MHz; this flash trigger uses some channels of half-integer MHz, e.g. 2.4465. The nRF24L01(+) is promiscuous enough that it easily and reliably locks to transmissions on half-integer MHz channels. However, the flash trigger receiver configured to use such a channel ignores any transmissions half MHz apart. This means that an nRF24L01(+) can only transmit on half of the defined channels.
One could notice that nRF24L01(+) transmits with its PLL in open loop, and the frequency of said PLL drifts down. By issuing the
REUSE_TX_PL command and pulsing CE for a few ms, it will transmit the last command in a loop while drifting down, and eventually hitting the right frequency. This, however, is a rather disgusting workaround.