2015 여름방학 프로젝트 쿼드콥터

요즘 대세는 드론, 남들은 다 사서 쓰지만 뼛속까지 공대생인 나는 직접 제작하려한다.
프레임과 기타 부자재는 돈으로 해결하고(乃) FC와 무선통신 만큼은 직접 코딩하기로 하였다.
(일반인은 완제품 사는게 싸다…)

목표
FC의경우는 CC3D(STM32F103CBT6)를 사용할것인데 OpenPilot는 올리지 않고 직접 제작함(시간낭비)을 목표로 한다.
무선통신은 일단 딱히 정하지는 않았는데, HC-11이나  nRF24L01를 사용하려고 한다.
방학이 끝날때까지 실내 공중 호버링 성공을 목표로 한다.
주 목표는 임베디드 시스템 공부로 인하여 하드웨어 해킹에 날개를 달기위함.(재미, 간지가 더해지면 더좋음)

계획
매번 CC3D에 올리기 귀찮으니까 STM32F4 Discovery Board에 올려서 나중에 최종적으로 포팅
RTOS 선정, 포팅
타겟과 PC 통신을 위한 USB 통신방법(모듈) 제작
자세측정을 위한 센서값 읽어오는 모듈 제작 (GY-86, 비싸다)
모터제어를 위한 모듈 제작(BLDC PWM제어, 컨트롤러 SimonK)
무선통신모듈 제작(인명피해를 줄이기 위한 방법, 노콘났을때 대처방법등 고안필요)
이후, CC3D로 포팅하여 균형잡는것과 호버링 개발.

실행
0. 프레임 주문 및 조립
처음에 프레임도 깎을까 싶었는데 자문을 구한결과 그건 생략키로…
450급 기체를 사고싶었는데 가격의 장벽과 위험성으로 인한 다운사이징 (https://www.youtube.com/watch?v=ji3Hii_LZOc 혐주의)
250급 사용하기로 하고 알리에서 주문
http://www.aliexpress.com/item//32298367112.html (모터한개가 불량이었으나 판매자 측에서 재발송을 해줌, 클레임->재발송 3일걸림)
기타 부자재(프로그래머, 충전기,  XT-60, 배터리(너무큰걸 사버렸다..), 케이블, 10축센서(GY-86), 3엽 프로펠러 등등)
조립하는데 꼬박 반나절 걸렸다. 설계도도 없고, 나사 간섭이 많아서 조였다 풀었다, 경량화를 위한 배선 등등
결과 : 카본인데도 무겁다, 카본이 좋은것만은 아니구나, 카본 별로다, 카본 가루가 손바닥에 박혀서 고생함, 조립하고 보니까 카본 경량모델이 나와있다 -_-, 250인데 생각외로 크다, 배터리랑 프레임무게가 날기 힘들정도로 무거운거같다, 1600mha추천하는데 2200사서 그런듯, 모터 힘이 생각외로 좋다, 책상위에서 테스트하다가 책상유리 깰뻔했다

1. FreeRTOS(v8.2.1) 포팅
무료이고 OpenPilot에서 FreeRTOS를 쓴다는 이유만으로 FreeRTOS를 사용하려고 한다. (+ 필요없더라도 그냥한번 써보고싶다)
F4 Discovery 에 먼저 대부분 기능 구현해놓고 CC3D로 포팅할것이므로, 모든기초공사는 디스커버리 보드에서 하는것으로.
따라서, RTOS도 디스커버리보드에, 포팅하는 예제는 널렸다. 정말많다. 게다가 예제없어도 할 수 있을정도로 쉽다.
다만 문제가 USB통신에 있었는데, 3.0포트를 쓰다보니 아직도 불안정한xhci가 자꾸 죽어댐(재부팅전까지 USB사용불가)
자꾸 따로 올렸을때는 동작하던 VCP예제가 RTOS만 올라가면 정상동작을 안함
ㄴ 이유로 : 최신버전의 system_stm32f4xx.c파일에서 클럭값세팅이 올바르지 못함(PPL_M, PPL_N 등 확인필요) // 디스커버리보드면 반표준 아닌가? 왜 디스커버리는 8Mhz 쓰면서 기본세팅은 16Mhz로 해놓은거지?
ㄴㄴ이유2 : 인터럽트 정의가 제대로 안됨, 겹침, 우선순위를 다른게 먼저가져가버림 // 어떻게 해야되는지 몰라서 관련 인터페이스 우선순위 0으로
ㄴㄴ이유3 : VCP templet에서 USART 응답기다리는 루프발견, 제거 // 3개가 겹치니까 지옥이 따로없었음…
ㄴ 인터럽트는 빨리 눈치챗는데, 클럭은 진짜 이거일줄은 몰랐다…. 매크로도 바뀌고 USART루프는 바로바로 탐지, 제거ㅋ
RTOS포팅하면서 OpenPilot 처럼 모듈화, 디렉토리화, Makefile 생성.(플래싱까지 한번에 !!)
중간 결과 : 인터럽트 헬, NVIC헬, USB헬, 난 개발자는 못되겠구나.
+ 대부분의 문제가 태스크의 스택사이즈를 늘리니까 "마법처럼" 해결되었다. 기본 스택이 1024byteㅋ 될것도 안되겠다

2. 가속센서,  자이로스코프
MPU6050에서 I2C로 받아오는데 역시 잘 되지 않았다… OTL 역시 스택사이즈를 조금 늘려주니까 마법처럼;…
읽어온 수치를 비쥬얼하게 뿌리는것도 일이다.. Processing 같은걸 써볼까 했으나 맘에 들지 않았다. 적절한 라이브러리도 찾지못했다 ㅠㅠ.
결국 Ruby + Qt4를 이용해서 직접 다… 짜버렸다.
gg문제는 데이터를 직접 뽑으면 초당 2000번이상 샘플링 가능한데, 뿌리면서 뽑으니 50회밖에 되지않는다 … 그래픽카드의 부재가 이유인듯 하다. 뭐 크게 딜레이 같은건 느껴지지 않으니 디버깅용도로는 충분할것 같다.
가속센서 오차보정 : 50번 추출해서 평균만큼 빼줘서 영점조정 하였는데, 시간이 지날수록 z축이 영점에서 벗어나더라…
칼만필터? 그런거 아직 모르겠고 30번 누적해서 그 평균값을 취하도록 했다. 뭔가 확실히 부드러워졌다.
처음에 100번 누적했는데 딜레이가 보여서 30번으로 ㄱㄱ, 초당 700번 넘게 샘플링하기에 큰 영향은 없을거같다.

3. HC-11
HC11모듈은 434MHz를 사용하여 무선통신한다. MCU와는 UART를 사용하는데 112500 baud rate 까지 지원한다.
따라서 나는 UART5를 사용해서 STM32와 통신을 하는데 인터럽트가 발목을 잡았다… UART5_IRQHandler 에서 xQueueSendFromISR 를 호출하는순간 죽어댔는데 자고 일어나서 다시해보니까 잘된다.. (뭐지? 뭐야 너 왜 왜그런거니 딱히 해준거도 없는데 잘되는이유는 또 뭐야? 무슨속셈이니)
HC11모듈을 max232물려서 ftdi로 설정, 테스트하는과정에서 AT커맨드가 먹지않았다… 분명히 입력내용이 434MHz로송출되는거까지 확인했는데.. 안됫던 이유가 minicom에 A,T 한자씩 입력하니까 안되더라… 복사 붙여넣기하니 바로 OK떨어졌고 나의 HC-11모듈 버젼은 "HC-11_V1.9"를 리턴해왔다.
기본 설정된 FU1 모드로 사용시에 값을 스트리밍해오는데 문제가 좀 있었다.
매뉴얼에
Mode Duplex Limit Current Delay
FU1   H U 3.4mA // Default
FU2   H L 80μA 400mS // Low Current
FU3   F U 22mA 10mS // Urgent
FU4   H U 22mA 300mS // Long Distance
로 나와있어 FU3으로 세팅하니 눈에 띄게 좋아졌다. 그래도 조금 긴시간 스트리밍하니 딜레이가 발생하는거같은데… 써보고 안되겠다 싶으면 구매해놓은 nRF24L01를 사용하는것으로…
아직은 무선으로 조종할 필요가 없기에, 이부분은 여기까지 개발해놓는거로 하고 다음으로 ㄱㄱ

4. ESC
알리에서 샀을때 모터하나가 정상작동하지 않았었는데(엄청난 진동과 소음과 발열 ㄷㄷ) 판매자가 새로 하나 보내줬다. 새로 받은거도 딱히 상태가 좋아보이진 않는다. 은색캡은 완전 조용하고 잘도는데 검정캡 모터들이 상태가 비교적 좋지않다. 모터 바꿔달면서 회전 방향도 전부다 체크하고 새로 잡아줬다. 서멀패드가 너덜너덜해졌다…
PWM 제어에 성공했다. 찾아보니 칩셋에서 특정 타이머 출력을 PWM으로 사용할수 있게 되어있었다.
인터럽트도 필요없고 그냥 초기 설정 적당히 해주고(예제 많다) 주기와 프리스케일러는 다음과 같이 설정하였다.
TIM_TimeBaseStructure.TIM_Period = 2500 -1 ; // 400Hz == 2.5ms == 2500us
TIM_TimeBaseStructure.TIM_Prescaler = 168 – 1 ; // APB2_Freq == 84 , PLL에 의해서 168로 두배 뻥튀기 된단다.
이후 TIM1->CCR1 =2000 과 같이 1000~2000정도의 값을 주니까 되더라. 생각보다 쉽게 끝났다. 로직 분석기도 구매해놨는데 필요가 없어졌다.
's' 신호시 Throttle 풀개방, 'S' 신호시 최저로 설정하고 ESC 캘리브레이션까지 하였다.
이후 실수로 s를 누르는 바람에 기체가 뒤집어지면서 손가락에 상처를 내었다 ㅠㅠ  반사적으로 S를 눌러 스크래치 선에서 종결되었는데 앞으로는 캘리브레이션이 끝나면 바로 풀스로틀 안되도록 제한해야겠다…
추가 490Hz로 제어하기위해선 아래 설정을 사용하면된다.
TIM_TimeBaseStructure.TIM_Period = 57142 -1 ;
TIM_TimeBaseStructure.TIM_Prescaler = 6 – 1 ;
제어를 위해서는 28000~56000의 값을 주면 1~2ms 값을 조정가능하다.

5. 균형잡기
일단 과학상자로 시소를 만드는게 좋을거같아서 화요일날 과학상자를 빌리러 가기로 했다. (나의 6호 과학상자는 어디갔을까? 비싸게 줬는데 ㅠ)
는 일단 패스하고

6. CC3D로 포팅
자세제어 이전에 커다란 DISCOVERY 보드를 떼어내는게 좋을거같아서 이거 먼저 진행하기로 했다.
DISCOVERY는 STM32F407을 사용하고있어 플래시 1M, 램 192Kb로 아주 아주 아주 넉넉하다.
반면 CC3D는 STM32F103을 사용하고 플래시128Kb, 램 20Kb로 8배정도 차이난다.
앞선 코딩에서 뭔가 잘 안되면 무조건 스택이나 힙 사이즈를 늘려놓은관계로 많은 문제점들이 예상된다.
처음 DISCOVERY 보드에 작업할땐 라이브러리만 바꿔주면 잘 작동할거라 생각했는데 컴파일부터 되지 않았다.
"section `.bss' will not fit in region" BSS 영역 사이즈를 초과했다고 뜨는데 이유를 몰라서 프로그램 다 뜯어서 하나하나 결합을 하다가 arm-none-eabi-size 를 사용하여 전체 출력파일을 살펴보니 heap_2 에서 BSS 영역을 과하게 많이 사용하고 있었다.  설정에서 configTOTAL_HEAP_SIZE 를 적절하게 줄여주니 정상적으로 컴파일되고 보드에 올라갔다. 하지만 스택 오버플로우가 나를 기다리고 있었다…
기존의 sprintf에서 자꾸 터져서 찾아보니 2k정도의 스택이 필요하다는데 어떤 이유인지 몰라도 태스크에 스택 할당이 700b밖에 안되더라…. 힙, 스택 사이즈 열심히 조정해봤으나 실패.
Light 버전의 sprintf를 구해서 컴파일 하니까 성공, (printf-stdarg.c) 다만 float형은 출력이 안된다.(안쓰지뭐!)
자이로 센서의경우 MPU-6050의경우 I2C를 사용하나, CC3D에 내장된 자이로는 MPU6000으로 칩스펙은 SPI/I2C 겸용이나 SPI를 사용하는 핀에 고정되어있다…
겸사겸사 I2C포팅하며 DMA에 인터럽트까지 받아들이려고 하는데 잘안되네 -_-

Note
USB Full Speed = 12 Mbit/s
USB High Speed = 480 Mbit/s (DMA써야되고 디스커버리보드엔 FS가 USB에 연결되어있음)

해야되는것들
USB(시리얼) 과 HC-11 명령어 통합. 현재 다 따로되어있어서 코드도 길고 기능추가에 두번일해야… ㅠㅠ
전파법, 항공법 숙지 필요, 또 무슨법있나?… ( 너무 복잡해서 지방 항공청에 민원 예정 )
I2C DMA로 받아오기(cpu타임으 쵸큼 줄일수 있단다)
**스로틀 개방시 60%쯤 이상에서 한쪽 프롭이 속도가 떨어지는 현상을 발견했다. 비정상 작동하는 프롭이 랜덤(? 아직까지는)해서 전류가 딸리는것으로 추측해본다.
**4번 ESC에서 비정상적인 과열이 있다. 1~2분정도 돌리고 만져보면 다른건 따뜻한 정도인데 해당 ESC는 만지기 힘들정도. 보드 전원을 4번에서 끌어오는데 그것인 문제인가?! – 전원 끌어쓰는 문제로 확인되었다. 외부 BEC를 쓰던지 1cell 배터리를 사용해야겠다.
보드에 캐패시터를 달아주는것이 좋을거같은데 용량 선정에서 큰 딜레마에 빠졌다. 굴러다니는 소형 리튬배터리를 달까?
– 역시나 BEC때문, 외부전원 사용시 발열 없었다

– – 위 문서는 프로젝트 끝날때까지 지속 업데이트예정 – –
—  Suspended —  다음 방학… 아니 휴가… 아니 … 뭐지..  ㅠㅠ 다음기회에..
***** gg  프로펠러에 손가락 몇개 자르고나서 무서워서 진행못하겠음…
가끔 드론 날리는거 보면 부럽기보다는 그자리를 피하고 싶다는 생각뿐….

Leave a Reply

Your email address will not be published. Required fields are marked *