I’ve been playing around with my transmitter a lot recently as flying season is starting up again and the darn thing isn’t working well. Likewise, the receiver I’ve just installed in the Pulsar refuses to bind to my radio. So a big fail all round by Spektrum, which has lead me to seek alternative solutions.
I’ve seen a few forum threads discussing the serial protocol used by Spektrum’s remote receivers and it seems pretty straight forward to collect the data from them; bypassing the main receiver completely. Unfortunately the only decent write up of the details that I could find was a bit out of date, and only covered the 7 channel case. So here is what I’ve learnt from poking this device with an oscilloscope and a logic analyser for a few hours.
I’m using a Spektrum DX8 for all my testing and will focus on the DSMX modulation as that’s what made the most sense to me.
The physical layer is a very simple asynchronous serial stream. There are three wires: the orange is 3.3V, and will draw about 30mA, the black is ground, and the grey is serial data (3.3V).
The serial data is standard 115200 baud, 8 bit wide, no parity and one stop bit (8N1). I’ve seen many different reports on what this speed should actually be. My own measurements of the few receivers I have puts it around the 110 kbps mark. I’m pretty sure it’s ‘supposed’ to be 115.2K and you won’t have much trouble if you just use the standard speed.
Now things start to get a little tricky. My DX8 allows me to select either DSM2 or DSMX modulation as well as either an 11ms or 22ms frame speed. This seems to decide what resolution your data is (1024/2048) and will vary the packet format slightly. As far as I can tell, the DX8 always transmits packets 11ms apart, but as my main receiver won’t talk to me I can’t see the variations in the PWM output rate.
The data format is set when binding the receiver, and is stored along with the model data in the transmitter. You can bind multiple remote receivers, one at time as long as you have the same modulation and frame rate selected. I just use the AR8000 to bind the remote receivers and won’t look into binding without it.
Once powered up, the receiver will wait for the radio it is bound to, to begin transmitting. It will not send any data if it’s not receiving anything. This is also true if the transmitter is turned off, the remote receiver will simply stop sending data.
A frame consists of 16 bytes which includes 7 channels of data. If you are using more than 7 channels, which is the case for the DX8 then your frames will include two packets of 16 bytes, 11ms seconds apart.
Each data word is two bytes long (16 bits). The first word is a count of missed frames which uses at least 10 bits, I didn’t manage to get it to wrap around. The remaining seven words are channel data for the current stick positions.
The channel data is given in a seemingly random order, although during my testing it remained constant for a given modulation and frame speed even after power cycling and rebinding.
Each 16 bits contains the channel ID and the channel value, as well as a couple of zeros. Be aware that the channel ID bits did move when the receiver was bound using a 1024 mode versus a 2048 mode. The channel value is the 10 LSBs in a 1024 mode and the 11 LSBs in a 2048 mode. I believe DMS2 at 22ms is the only 1024 mode for this transmitter/receiver.
The channel ID is the 3 or 4 bits above the channel value. I say 3 or 4 as I expect this protocol can handle more than 8 channels, but I have nothing to test that with. This identifies the channel to which the value following should be assigned. 0: Throttle, 1: Aileron, 2: Elevator, 3: Rudder, 4: Gear, 5: Aux1, 6: Aux2, 7: Aux3.
For DSMX, each channel will only be included once in each frame, so the spare words in each packet are set to all 1′s (0xFFFF). In DSM2-2048 A few channels were repeated in the second packet.
The MSB of each word appears to identify the packet within each frame. It is usually 0 except in the case where the word is not used for channel data (as above) or immediately following the Frame Loss Count in the second packet of the frame.
The channel values provide the duration of the pulse used to control the servos. The following is how I plan to implement my own PWM and not necessarily how the Spektrum receivers do it. It could be the same, I just can’t measure it while my receiver is broken.
The DX8 allows servo travel to range from -150% up to 150%. A typical PWM controller will go from 1000us up to 2000us for the full range of the servo, so I’ve decided to go from 750us up to 2250us to match my transmitters range. You’ll find most of the scaling and direction of the data is done in the transmitter and only absolute positions are sent to the receiver.
There are a few details I didn’t really look into during the last few hours as I have enough to keep me going. So hopefully this is helpful to someone else and always remember that your mileage may vary.