main.c
0.01MB
stm32f4xx_it.c
0.01MB
GPS.c
0.00MB
GPS.h
0.00MB

 

멀티콥터들이 일정한 위치에서 안정적으로 호버링 하려면 위치에 대한 정보가 필요하다. 그래서 GPS를 사용하여 위치정보를 받고 받은 데이터를 기반으로 위치를 조정한다.

 

잠깐 비가 안 오는 시간에 빠르게 테스트를 하고 확인을 했기 때문에 GPS 모듈 설정을 하고 데이터를 받아 출력하는 과정에 대해 쓰려한다.

 

GPS 모듈은 U-blox에서 나온 M8N GPS 모듈을 사용한다.

 

 

 

NMEA, UBX - (0)

실제 NMEA 데이터를 받는 사진, 실제 위치정보가 나와 그 부분을 지움

GPS 모듈을 아무 설정하지 않고 UART to USB 모듈에 RX, TX와 전원을 연결하고 Baud Rate를 9600으로 맞추면 NMEA데이터를 받아볼 수 있다.

 

위 사진은 실제 아무 설정도 하지 않고 데이터를 받는 모습이며 NMEA는 텍스트 형태의 데이터이다.

 

하지만 아무 설정을 하지 않으면 들어오는 데이터의 양이 너무 많고 텍스트 형태의 데이터다 보니 데이터를 원하는 형태로 가공하려면 어려울 수 있다.

 

따라서 U-blox 회사에서 자체적으로 만든 UBX 프로토콜을 사용할 것인데, 텍스트 형태의 데이터가 아닌 Binary 형태의 데이터를 받을 수 있고 데이터의 길이도 더 짧다.

 

NMEA에서 UBX 프로토콜로 변경하고 원하는 데이터를 받기 위해서는 GPS모듈에 명령 데이터를 보내야 하는데 이는 U-blox에서 만든 u-center라는 프로그램에서 확인할 수 있다.

 

https://www.u-blox.com/en/product/u-center

 

u-center

GNSS evaluation software for Windows

www.u-blox.com

이 프로그램은 GPS정보를 보여주는 터미널 기능과 명령을 보내는 기능, 실제 위치를 보여주는 기능 등 여러 가지 기능이 있다.

 

 

UBX - (1)

 

https://www.u-blox.com/sites/default/files/products/documents/u-blox8-M8_ReceiverDescrProtSpec_%28UBX-13003221%29.pdf

M8N 모듈의 프로토콜에 관한 내용이 써져있으므로 읽어보는게 좋다.

 

 

기본적인 설정을 하기위해 GPS 모듈에 보내는 명령 데이터를 알기 위해 u-center프로그램을 실행하고 왼쪽 위에 사진에 표신한 버튼을 눌러보면

 

 

이런 형태의 창이 뜬다. 여기서 PRT, RATE, MSG 를 변경할 것이다.

 

 

PRT를 눌러보면 Target과 Protocol in, Protocol out, Baudrate를 변경할 수 있는 명령어를 볼 수 있는데 왼쪽 아래 아래 화살표가 그려진 버튼을 누르면 명령을 볼 수 있다.

 

0xB5, 0x62로 시작하는 데이터가 NMEA에서 UBX로 데이터를 출력하게 하는 명령이다.

 

 

GPS 모듈은 기본적으로 1Hz로 데이터를 내보낸다.

 

하지만 1초에 한 번씩 데이터를 받으면 데이터 업데이트 속도가 느리므로 조금 더 빠른 5Hz로 변경하여 사용할 것이다.

 

NAV-POSLLH 프로토콜을 사용할 것이다.

 

U4, I4와 같은 Format은 데이터 시트에 나와있다.

 

Scaling의 경우 받은 값에 Scaling값을 곱해주면 실제 데이터 값이 나오며 단위는 Unit에 나온 형태를 가진다.

 

POSLLH에서 우리가 사용할 값은 lon과 lat값이다.

 

 

UBX Frame 형태를 보여주며 이를 확인하면서 원하는 데이터를 추출할 수 있다.

 

 

UART4 코드 생성 - (2)

Parmeter Settings
NVIC Settings
DMA Settings

 

UART4를 사용하고 DMA와 IDLE Interrupt를 사용한다.

 

GPS 모듈의 Baud Rate의 경우 9600이므로 주의하길 바란다.

 

 

코드 - main.c (3)

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
 /* USER CODE BEGIN 2 */
 
  GPS_RAW_MESSAGE gps_raw_message;
  GPS_DATA gps_data;
 
  init_GPS(&gps_raw_message,UART4,DMA1,LL_DMA_STREAM_2);
 
  /* USER CODE END 2 */
 
  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
      if(gps_condition){
 
          LL_DMA_DisableStream(DMA1,LL_DMA_STREAM_2);
          DMA1->LIFCR=0x003D0000;    //DMA1 STREAM2 CLEAR ALL FLAG
          LL_DMA_EnableStream(DMA1,LL_DMA_STREAM_2);
          GPS_Parsing(&gps_raw_message,&gps_data);
 
          printf("lon:%d\t\tlat:%d\r\n",gps_data.lon,gps_data.lat);
          printf("lon_deg:%d\tlon_min:%d\tlon_sec:%.2f\r\n",gps_data.longitude_deg, gps_data.longitude_min, gps_data.longitude_sec);
          printf("lat_deg:%d\tlat_min:%d\tlat_sec:%.2f\r\n",gps_data.latitude_deg, gps_data.latitude_min, gps_data.latitude_sec);
          printf("sec_lon:%.2f\tsec_lat%.2f\n\n\r",gps_data.sec_lon,gps_data.sec_lat);
 
          gps_condition=0;
      }
    /* USER CODE END WHILE */
 
    /* USER CODE BEGIN 3 */
  }
  /* USER CODE END 3 */
 

 

3, 4번째 줄은 GPS.h에 정의되어있는 구조체들이며 각각 RAW 데이터를 받고 RAW 데이터에서 위도, 경도 데이터를 추출하고 저장한다.

 

6번째 줄 init_GPS는 GPS 모듈이 연결되어있는 UART, DMA를 설정하고 모듈에 위에서 알아본 명령 데이터를 보내 초기화하는 과정이 담겨있다. init_GPS의 경우 분석하기 쉬우므로 길게 설명하지 않을 생각이다.

 

while문 내부에서 gps_condition은 stm32f4xx_it.c 파일에서 UART4가 IDLE Interrupt가 발생하면 SET 한다. stm32f4xx_it.c 파일은 이미 많이 사용한 내용이므로 생략한다.

 

GPS_Parsing은 받은 RAW 데이터에서 위도 경도 데이터로 추출하는 과정이 담겨있다.

 

 

코드 - GPS.c (4)

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
void GPS_Parsing(GPS_RAW_MESSAGE* message, GPS_DATA* gps_data){
    uint8_t* ptr,*gps_ptr=message->gps_raw_buf;
    int32_t temp;
    if(gps_ptr[0]==0xB5 && gps_ptr[1]==0x62){
        ptr=gps_ptr+6+4;
        gps_data->lon = (ptr[3<< 24+ (ptr[2<< 16+ (ptr[1<< 8+ (ptr[0]);
        gps_data->longitude_deg=gps_data->lon/10000000;
        temp=gps_data->lon%10000000;
        gps_data->longitude_min=(temp*60)/10000000;
        temp=(temp*60)%10000000;
        gps_data->longitude_sec=((float)(temp*60))/10000000;
 
        if(gps_data->longitude_deg<124 || gps_data->longitude_deg>132){
            gps_data->sec_lon=0;
        }
        else{
            gps_data->sec_lon = (float)(gps_data->longitude_deg - LONGITUDE_OFFSET) * 3600 + (float)gps_data->longitude_min * 60 + gps_data->longitude_sec;
        }
 
        ptr += 4;
        gps_data->lat = (ptr[3<< 24+ (ptr[2<< 16+ (ptr[1<< 8+ (ptr[0]);
        gps_data->latitude_deg=gps_data->lat/10000000;
        temp=gps_data->lat%10000000;
        gps_data->latitude_min=(temp*60)/10000000;
        temp=(temp*60)%10000000;
        gps_data->latitude_sec=((float)(temp*60))/10000000;
 
        if(gps_data->latitude_deg<33 || gps_data->latitude_deg>43){
            gps_data->sec_lat=0;
        }
        else{
            gps_data->sec_lat = (float)(gps_data->latitude_deg - LATITUDE_OFFSET) * 3600 + (float)gps_data->latitude_min * 60 + gps_data->latitude_sec;
        }
        gps_ptr+=36;
    }
}
 

 

GPS_Parsing은 받은 RAW데이터에서 위도 경도를 추출하는 과정이 담겨있다.

 

gps_ptr 포인터는 NAV-POSLLH 외의 데이터가 추가될 경우 사용할 포인터이다. 위의 코드에서는 없어도 문제없다.

 

5번째 줄은 ptr포인터를 실제 lon데이터가 있는 위치로 옮기는 것이다.

 

6번째 줄은 lon데이터의 값을 배열에서 추출하는 과정이다.

 

7번째 줄은 받은 데이터를 실제값으로 바꿔주기 위해 10^7을 나눠주는데 이는 데이터 시트에 Scaling값인 1e-7을 곱해줘야 실제 값이 나온다고 쓰여있기 때문이다.

 

그리고 longitude_deg는 각, longitude_min은 분, longitude_sec은 초를 나타내기 때문에 9, 11번째 줄에서 60씩을 곱해주는 것이다.

 

GPS_DATA 구조체에서 sec_lon, sec_lat이 따로 존재하는데 이 값들은 쿼드콥터, 헥사콥터를 제어할 때 사용할 값들인데, 불필요한 값들을 지우고 sec단위로 값을 변환한 값들이다.

 

또한 한국의 위도, 경도 범위인 33 ~ 43, 124 ~ 132를 벗어나는 범위일 경우 0을 저장하게 돼있다.

 

 

결과 - (5)

 

비가 안 오는 시간에 빠르게 옥상에서 테스트했다.

 

현재의 위도, 경도가 출력되며 위치를 노출할 수 있기 때문에 위치 데이터들은 지웠다.

 

 

 

-

https://ddtxrx.tistory.com/7

 

[쿼드콥터] STM32 간단한 GPS제어

최근에 다시 드론을 만들기 시작해서 GPS를 추가했다. 아직 완벽한 호버링은 아니지만 어느 정도 위치를 유지하는 모습을 보여준다. 고도제어를 아직 만들지 않아 쓰로틀만 직접 만지고 한 손으�

ddtxrx.tistory.com

초기에 GPS 제어 영상을 올린 글이다. 진자운동을 하는 것처럼 출렁이지만 현재 쿼드콥터는 많이 안정적이다. 

 

 

이번 글은 드론의 안정적인 호버링을 위해 꼭 사용해야 하는 GPS 모듈의 설정과 데이터를 추출하는 과정이다.

 

아직 헥사콥터에 GPS를 사용하여 호버링 하는 코드는 작성하지 않았다. 그래도 쿼드콥터에 적용한 코드가 있으므로 시간이 오래 걸리지는 않을 것 같다.

 

장마가 끝나면 테스트한 후 후기글을 작성하겠다.

 

코드들은 직접 받아 분석해보면 이해하기 쉬울 것이다.

Posted by DDTXRX
,