protocol for WL Heli V911-s

More
06 Nov 2018 13:49 #71572 by planger
Replied by planger on topic protocol for WL Heli V911-s
I've started to use already SDR with the Star Trek air hogs model last weekend. I've used it to find the channel, bitrate and then demodulate the sync word to finally configure the nrf and receive packets.
This is therefore my second attempt in a short time window.

I'm using a Pluto SDR box running on pothosware and MATLAB. I haven't been able to get gnuradio to recognize directly the Pluto on my windows... I'm using MATLAB to quickly see the signal and demodulate it using some math. Basically, I'm looking at the unwrapped phase variations to determine the 0 and 1. Therefore I don't need to know the sync word at all, it's just coming out from the data.

Pascal

Please Log in or Create an account to join the conversation.

More
06 Nov 2018 13:59 - 06 Nov 2018 14:00 #71573 by goebish
Replied by goebish on topic protocol for WL Heli V911-s
Thanks, I should give another shot at pothosware, I tried it some time ago but it didn't work very well (or I didn't understand how to use it properly :p) but I like its API based on Qt.
Last edit: 06 Nov 2018 14:00 by goebish.

Please Log in or Create an account to join the conversation.

More
06 Nov 2018 14:19 #71575 by SeByDocKy
Replied by SeByDocKy on topic protocol for WL Heli V911-s

planger wrote: II'm using MATLAB to quickly see the signal and demodulate it using some math. Basically, I'm looking at the unwrapped phase variations to determine the 0 and 1. Therefore I don't need to know the sync word at all, it's just coming out from the data.

Pascal



Haaa Matlab :) my old and faithfull compagnon since 20+ years .. (OMG .... I am old now :( )

Please Log in or Create an account to join the conversation.

More
06 Nov 2018 14:21 - 07 Nov 2018 11:33 #71576 by goebish
Replied by goebish on topic protocol for WL Heli V911-s
The PlutoSDR looks really nice given the price, 12 bit ADC & DAC, full duplex, 20Mbps instantaneous bandwidth, it only lacks the lower bands of the spectrum... I would get one if I didn't already have a bladerf x40.
Most of the time I use the hackrf, I like it for its large spectrum capability (1MHz-6GHz) but the ADC/DAC is 8 bit only (not good at all for weak signals) and it's not full duplex but I don't need that yet, also I feel like I would be able to repair it if I ever fry the rf frontend or something else.
Last edit: 07 Nov 2018 11:33 by goebish.

Please Log in or Create an account to join the conversation.

More
06 Nov 2018 15:39 - 06 Nov 2018 15:43 #71581 by planger
Replied by planger on topic protocol for WL Heli V911-s

SeByDocKy wrote: Haaa Matlab :) my old and faithfull compagnon since 20+ years .. (OMG .... I am old now :( )

;-)
The attached picture is the unwrapped phase of the RF signal plotted in MATLAB.
You can read from there: 0x71, 0x0F, 0x55, 0x95, 0x3C,... (down is 0 up is 1)
I see it coming, obviously I'm not reading the paylod by hand :P It's the output of my script.
Attachments:
Last edit: 06 Nov 2018 15:43 by planger.

Please Log in or Create an account to join the conversation.

More
07 Nov 2018 11:32 #71607 by goebish
Replied by goebish on topic protocol for WL Heli V911-s
Interesting, I've never tried this very low level approach ...

Please Log in or Create an account to join the conversation.

More
07 Nov 2018 20:41 - 08 Nov 2018 13:08 #71626 by planger
Replied by planger on topic protocol for WL Heli V911-s
Here is what a normal packet looks like:
0x19, 0x00, 0x00, 0x00, 0xFE, 0x00, 0x00, 0x00, 0xE8, 0x1F, 0xFF, 0x03, 0x20, 0x00, 0x00, 0x00
With the following parameters: XN297 @250Kbps, payload 16 bytes, scrambled and not enhanced.
TX Address: 0XA5, 0xFF, 0x70, 0x8D, 0x76

byte 0: value changes at each power up. Seen 0x04, 0x0E, 0x13, 0x19, 0x1A...
byte 1: flag 0x04 when pressing the button on the remote (0x00=default), not sure what it does. I'll look at the manual later...
byte 4: 0xFE unknown
bytes 8..12: packed TAER 11 bits.

I've added a CRC check to the XN297_ReadPayload function since I was getting way too much noise in the incoming packets preventing me to understand the content...

I'll look at the bind packets later. The pieces are coming together slowly but...

Pascal
Last edit: 08 Nov 2018 13:08 by planger.

Please Log in or Create an account to join the conversation.

More
07 Nov 2018 20:50 #71628 by planger
Replied by planger on topic protocol for WL Heli V911-s

goebish wrote: Interesting, I've never tried this very low level approach ...

You can obtain kind of the same result in pothosware or gnuradio by sending directly the block RF ouput (complex numbers) in an "angle" block which will show you the phase. The problem is that the ouput (real) is wrapped around -pi and +pi. I haven't found how to unwrap it within these tools (might be possible but...). This is why I've used MATLAB to do the math work.
Pascal

Please Log in or Create an account to join the conversation.

More
07 Nov 2018 22:29 #71630 by goebish
Replied by goebish on topic protocol for WL Heli V911-s

planger wrote: I've added a CRC check to the XN297_ReadPayload function since I was getting way too much noise in the incoming packets


Nice, this has been on my todo list for a long time ;)

Please Log in or Create an account to join the conversation.

More
08 Nov 2018 11:22 - 08 Nov 2018 12:45 #71644 by planger
Replied by planger on topic protocol for WL Heli V911-s
It looks like they made bind easy :cheer:
I've just decoded using my MATLAB script one of the captured bind packets:
- RF channel: 35
- TX address: 0x4B 0x4E 0x42 0x4E 0x44
- Payload 16 bytes: 0x42 0x4E 0x44 0xA5 0xFF 0x70 0x8D 0x76 0x11 0x15 0x1A 0x1F 0x24 0x29 0x2E 0x33
byte 0-2: padding from the TX adddress? I expect it to be constant to be checked by some live tests.
byte 3-7: TX address for normal mode
byte 8-15: RF channels for normal mode
- sent every 3ms for 100 packets then every 10ms for 100 packets then switch to normal mode

The only unknown and needed info at this stage is the 1st byte of the normal packet.

Pascal
Last edit: 08 Nov 2018 12:45 by planger.

Please Log in or Create an account to join the conversation.

More
08 Nov 2018 11:27 #71645 by goebish
Replied by goebish on topic protocol for WL Heli V911-s
Great, I like when they send the data address and channel hopping sequence in clear text during bind :p

Please Log in or Create an account to join the conversation.

More
08 Nov 2018 12:01 - 09 Nov 2018 12:58 #71646 by goebish
Replied by goebish on topic protocol for WL Heli V911-s
I think I understand why you're getting that much noise, XN297L emulation @ 250kbps is not the most reliable, many people can't get the E010 or the i6S to work (I believe they're the only (sub)protocols using this mode so far). It seems like it partially depends on crystal accuracy as the XN297L datasheet states better accuracy crystal (±20ppm) is required for 250kbps mode compared to the nrf24l01 (±60ppm). I suppose the Xin1 module manufacturers are getting the cheaper ones (±60ppm) as the nrf24l01 datasheet states that's fine ...

Excerpt from the XN297L datasheet (use google translator):

1M / 2Mbps模式,需要晶振精度 ±40ppm
250kbps模式,需要晶振精度 ±20ppm

While the nrf24l01 datasheet states:

Accepts low cost ±60ppm 16MHz crystal

Though in theory in the XN297L(Tx) --> NRF24L01(Rx) direction that should be less of an issue; but you may have noticed with SDR that xn297(L) channels usually have a frequency drift of ~+200kHz compared to the nrf, that probably doesn't help either... That's +80ppm @ 16MHz, we're already way out of spec, even @ 1Mbps, that's a wonder it works that well already.

Anyone ever tried to fiddle with the "do not touch" registers on the nrf24l01 (0x18 to 0x1B) ?
I should try to do some fuzz testing on those registers while watching the resulting FFT on SDR, there might be an undocumented one that allows to set a base frequency offset like on the a7105/cyrf6936/cc2500...
Last edit: 09 Nov 2018 12:58 by goebish.

Please Log in or Create an account to join the conversation.

More
08 Nov 2018 12:50 #71647 by goebish
Replied by goebish on topic protocol for WL Heli V911-s
Someone on the forum was in contact with someone working at Nordic, but I don't remember who :/

Please Log in or Create an account to join the conversation.

More
08 Nov 2018 13:26 #71649 by planger
Replied by planger on topic protocol for WL Heli V911-s

goebish wrote:

planger wrote: I've added a CRC check to the XN297_ReadPayload function since I was getting way too much noise in the incoming packets

Nice, this has been on my todo list for a long time ;)

Here is the XN297_ReadPayload with CRC check. It's fully compatible with the previous function (so no need to change any protocols unless you want to improve them by checking CRC). The return indicates CRC OK=true, CRC NOK=false.
The payload is always decrypted so you still can see what's incoming even if the CRC is considered bad.
boolean XN297_ReadPayload(uint8_t* msg, uint8_t len)
{ //!!! Don't forget if using CRC to do a +2 on any of the used NRF24L01_11_RX_PW_Px !!!
	uint8_t buf[32];
	if (xn297_crc)
		NRF24L01_ReadPayload(buf, len+2);	// Read payload + CRC 
	else
		NRF24L01_ReadPayload(buf, len);
	// Decode payload
	for(uint8_t i=0; i<len; i++)
	{
		uint8_t b_in=buf[i];
		if(xn297_scramble_enabled)
			b_in ^= xn297_scramble[i+xn297_addr_len];
		msg[i] = bit_reverse(b_in);
	}
	if (!xn297_crc)
		return true;	// No CRC so OK by default...

	// Calculate CRC
	uint16_t crc = 0xb5d2;
	//process address
	for (uint8_t i = 0; i < xn297_addr_len; ++i)
	{
		uint8_t b_in=xn297_tx_addr[xn297_addr_len-i-1];
		if(xn297_scramble_enabled)
			b_in ^=  xn297_scramble[i];
		crc = crc16_update(crc, b_in, 8);
	}
	//process payload
	for (uint8_t i = 0; i < len; ++i)
		crc = crc16_update(crc, buf[i], 8);
	//xorout
	if(xn297_scramble_enabled)
		crc ^= pgm_read_word(&xn297_crc_xorout_scrambled[xn297_addr_len - 3 + len]);
	else
		crc ^= pgm_read_word(&xn297_crc_xorout[xn297_addr_len - 3 + len]);
	//test
	if( (crc >> 8) == buf[len] && (crc & 0xff) == buf[len+1])
		return true;	// CRC  OK
	return false;		// CRC NOK
}
Pascal

Please Log in or Create an account to join the conversation.

More
08 Nov 2018 13:29 - 08 Nov 2018 13:43 #71650 by goebish
Replied by goebish on topic protocol for WL Heli V911-s
Thanks and thanks for the warning at the beginning of the function, I've already wasted lots of time because I had forgotten those 2 extra bytes in other circumstances ;)
Last edit: 08 Nov 2018 13:43 by goebish.

Please Log in or Create an account to join the conversation.

More
08 Nov 2018 14:38 #71651 by planger
Replied by planger on topic protocol for WL Heli V911-s

planger wrote: The only unknown and needed info at this stage is the 1st byte of the normal packet.

A little more work to fully reverse the protocol:
- The 8 RF frequncies in the bind packet are fixed increasing values: 0x11 0x15 0x1A 0x1F 0x24 0x29 0x2E 0x33. (Will test later if they can be anything and in any order...)
- The way to play the frequencies is encoded in the 1st byte of the normal packet (increasing/decreasing/every odd_even/...). It also tells which frequency (or table index) needs to be used next.

Anyway at this stage, I have enough information to code a working protocol with hopefully a random ID and random channels (even if they are played in order for now).
More to come soon.

Please Log in or Create an account to join the conversation.

More
08 Nov 2018 19:02 #71654 by planger
Replied by planger on topic protocol for WL Heli V911-s
V911S bind and fly B)
Ok using the original remote control details but still :cheer: .

Please Log in or Create an account to join the conversation.

More
08 Nov 2018 19:30 #71655 by planger
Replied by planger on topic protocol for WL Heli V911-s
It also works well with another ID.Now to the hopping freqs...

The flag is for high/low rate. Forcing it to high...

Please Log in or Create an account to join the conversation.

More
08 Nov 2018 21:46 #71657 by planger
Replied by planger on topic protocol for WL Heli V911-s
For the hopping, it has 4 read modes of the freq table based on the 1st byte of the normal payload:
a. bit3=0 & bit4=0 => 0 1 2 3 4 5 6 7
b. bit3=0 & bit4=1 => 7 6 5 4 3 2 1 0
c. bit3=1 & bit4=0 => 4 0 5 1 6 2 7 3
d. bit3=1 & bit4=1 => 3 7 2 6 1 5 0 4

Calculation:
a. val=index
b. val=7-index
c. if(index&1) val=index>>1; else val=4+(index>>1)
d. val=7-c

With that the protocol is fully reversed.

What I don't know is the rf channel range to create the initial freq table...
The current table is created like this:
for(uint8_t i=0;i<V911S_NUM_RF_CHANNELS;i++)
hopping_frequency=0x10+i*5;
hopping_frequency[0]++;
In this example 0x10 seems not allowed since they add 1 to it.
0x23 is the bind address so they might avoid it but it's not required since it uses a different ID.

To stay within the original spirit, I'm thinking to use something like this (pseudo code):
rand=random(0xfefefefe)%5; //0-4
for(uint8_t i=0;i<V911S_NUM_RF_CHANNELS;i++)
hopping_frequency=0x10+i*5+rand;
if(!rand) hopping_frequency[0]++;
order=random(0xfefefefe)&0x03; // table read order

Pascal

Please Log in or Create an account to join the conversation.

More
08 Nov 2018 23:02 #71658 by planger
Replied by planger on topic protocol for WL Heli V911-s
Ok, I've implemented the above and tested ok.

From the manual there is a yaw calibration mode. When you long press the left button for more than 3 sec (and not 3 press like the doc states...) the heli starts to blink and the original remote blink/beep. This sets packet[2] to 0x01 which I've currently assigned to CH5. It's so well explained that I'm not sure how the calib works...

Also I've noticed that the heli does remember to which ID/freqs it was last bound to. So no need to bind each time.

Please Log in or Create an account to join the conversation.

Time to create page: 0.066 seconds
Powered by Kunena Forum