꼬부기의 끄적끄적

DJI Phantom 2.4G RX RF V4 + DJ6 조종기 Protocol 파해치기 본문

카테고리 없음

DJI Phantom 2.4G RX RF V4 + DJ6 조종기 Protocol 파해치기

Koboogy 2015. 11. 25. 22:19

최근 Freescale Kinetis로 Drone을 날려보자는 프로젝트를 진행하고 있는데 엊그제 갑자기...

DJI 조종기를 사용하자며 프로토콜을 뚫어달라는 친구얘기로 한번 해봤습니다.

 

 

우선 제가 사용했던 조종기는 DJI사의 DJ6이라는 모델이였습니다.

 

 

 

그리고 수신기는 아래와 같이 조그마한 애로, 5V, GND, Signal이 나옵니다.

 

 

자.. 우선 가장 먼저 어떠한 통신으로 수신이 되는지 분석하기 위해 일단 오실로스코프에 띄워봤습니다.

 

 

고대로 연결했는데 웬걸.. 엄청나게 긴 통신이 오네요

 

구글링을 해봐도 도대체 나오지 않는 이녀석 답답합니다.

 

 

 

 

일단 가장 얇은놈을 잡아서 너비를 재보니 10us..

10us를 1bit로 가정하고 신호 분석에 나섰습니다.

 

 

 

가장 앞의 신호를 따 보니

0 ... 0 0 0 1 0 0 0 0 1 1 1 1 1 0 0

그 뒤도 어디선가 본 듯한 모양새입니다.

 

0 ... 0 0 0 / 1 / 0 0 0 0 1 1 1 1 / 1 / 0 0

이렇게 쪼개어 보니 UART의 형식과 동일합니다. (반전 형태)

처음 1 - Start bit

8 bits - Data bit

뒤쪽 1 - Stop Bit 바로 전인데, 9bit 데이터거나 Parity Bit이거나 둘 중 하나라는 가정을 세웠습니다.

UART 관련 내용 : https://ko.wikipedia.org/wiki/UART

 

이러한 가정을 바탕으로 수없이 대입을 해본 결과..

 

뒤쪽 1bit가 항상 홀수를 유지한다는(Parity 검사) 사실을 깨닫고 Parity bit라고 확정을 지었습니다.

 

이렇게

통신 형식: UART (Inverted)

통신 주기: 14ms

bit rate: 10us

data: 8 bits

parity: even -> 계산상으로는 odd(Parity bit 까지 합쳐서 홀수)였는데 Freescale Kinetis Design Studio에서는 even으로 하니 정상작동 합니다.

stop bit: 2 bits(?) -> 사실 상관 없을듯

 

라는 결론이 나왔습니다.

 

원래 baud rate가 start bit + data + parity + end 까지 합쳐서 1초에 몇 번 전송하는 것인줄 알았는데 그냥 bit rate를 쓰면 되는 거더군요.

 

그래서 Baud rate를 100,000으로 설정하고,

Parity bit를 Hardware even

으로 설정하니 데이터가 들어오기 시작합니다.

 

(사실 baud 10만으로 설정하기 전에 115200인줄알고 PC랑 연결해서 받았다가 손상된 데이터를 정상인 줄 알고 Protocol 망칠 뻔 했습니다.. )

 

아무튼 우여곡절 끝에 데이터가 총 25개가 들어온다는 사실까지 알아냈습니다.

 

이제 리모컨으로 하나씩 조작하면서 Protocol을 분석하였습니다.

(RX = Right X, RY = Right Y, LX = Left X, LY = Left Y, BK = Back[뒤에있는 레버] LS = Left Switch, RS = Right Switch)

 

Byte Bit 7 6 5 4 3 2 1 0
0 0x0F 0 0 0 0 1 1 1 1
1   RX:7             RX:0
2   RY:4       RY:0 RX:10   RX:8
3   LY:1 LY:0 RY:10         RY:5
4   LY:9             LY:2
5   LX:6           LX:0 LY:10
6   BK:3     BK:0 LX:10     LX:7
7   LS:0 BK:10           BK:4
8   LS:8             LS:1
9   RS:5         RS:0 LS:10 LS:9
10   0 0 0 RS:10       RS:6
11 0x80                
12 0x00                
13 0x04                
14 0x20                
15 0x00                
16 0x01                
17 0x08                
18 0x40                
19 0x00                
20 0x02                
21 0x10                
22 0x80                
23 0x00                
24 0x00                

 

프로토콜 분석 결과 이렇게 나왔는데.. 문제는 Analog데이터가 음의 값을 갖는다는 것 이였습니다.

 

8bit, 16bit였다면 간단하게 받을 수 있을텐데 각 데이터는 11bit씩 나오고 ADC 데이터는 11번째 비트(XX:10)이 부호를 결정 해 주는 비트, 0~9비트는 수를 담고 있었습니다.

 

근데 보통.. 음수일 때 sign bit가 1이되고, 양수일 때 sign bit가 0이되는 것으로 알고있었는데 이상하게도 이 Protocol에서는 음수일 때 0이 됩니다..

 

1 1 1 1 1 1 1 1 = -1

1 1 1 1 1 1 1 0 = -2

라고 생각했던 저는 이상한 값을 마주할 수 있었습니다...

이 프로토콜에서는

1 / 0 0 0 0 0 / 0 0 0 0 1 = 1

1 / 0 0 0 0 0 / 0 0 0 0 0 = 0

0 / 1 1 1 1 1 / 1 1 1 1 1 = -1

이였습니다.

 

결국 코딩 시 단순한 bit연산으로는 할 수 없게 되어


 int _nTempData;
 _nTempData = ((pbArr[2] & 0b00000011) << 8) + pbArr[1];
 if(!(pbArr[2] & 0b00000100))
 {
  _nTempData += 0xFFFFFC00; // 음수 설정
 }

 

와 같이 하게 되었습니다. (32bit Processor)

 

아무튼 결과적으로는 정상적으로 값을 받아 잘 사용중입니다.

 

 

이러한 삽질의 결과를 github에 올려두었으니 참고하시길...

https://github.com/kwrobit/robit_k64f_drone

 

*개발환경

보드: FRDM-K64F

IDE: Kinetis Design Studio 3.0

 

 

 

 

 

2 Comments
댓글쓰기 폼