반응형
C# 에서 GPS 를 연결하여 정보를 얻어야 할 일이 생겼다.
우선 GPS 기기를 블르투스 나 시리얼 케이블을 이용하여 컴퓨터에 연결하면 COM 포트로 연결이 되는데
프로그램에서 이 GPS의 수신 메시지를 받아 사용해 보자.
GPS의 NMEA 프로토콜 중에서 GPGGA 를 사용하려고 하는데 인터넷을 검색해 보면 NMEA 에 대해서
자세하게 설명한 것이 많으므로 프로토콜 설명은 일단 넘어가도록 하겠다.
GPS NMEA 프로토콜 참고 블로그- 출처: 초심자용 에린 입문서 블로그 (http://erine.egloos.com/2233135)
using System.IO.Ports;
//GPS 실행 시작
Thread ThreadGPS = null ; //GPS 쓰레드
SerialPort GPSserialPort; //시리얼 포트
bool isStartGPS = false; //시작여부
private void startGPS()
{
GPSserialPort= new SerialPort();
GPSserialPort.PortName = "COM6"; //COM 포트 설정
GPSserialPort.BaudRate = "4800"; //통신속도 설정- 크게 차이는 없으나 제품에서 권장하는 값을로 셋팅
GPSserialPort.Parity = Parity.None;
GPSserialPort.DataBits = 8;
GPSserialPort.StopBits = StopBits.One;
GPSserialPort.ReadBufferSize = 600;
if (!GPSserialPort.IsOpen) //GPS 포트가 열려있지 않으면 오픈한다.
GPSserialPort.Open();
isStartGPS = true;
//나같은 경우는 필요에 따라 GPS 수신을 쓰레드에서 처리하기로 했다.
ThreadGPS = new Thread(new ThreadStart(this.receiveGPSMsg));
ThreadGPS.IsBackground = true;
ThreadGPS.Start();
GPSserialPort.PortName = "COM6"; //COM 포트 설정
GPSserialPort.BaudRate = "4800"; //통신속도 설정- 크게 차이는 없으나 제품에서 권장하는 값을로 셋팅
GPSserialPort.Parity = Parity.None;
GPSserialPort.DataBits = 8;
GPSserialPort.StopBits = StopBits.One;
GPSserialPort.ReadBufferSize = 600;
if (!GPSserialPort.IsOpen) //GPS 포트가 열려있지 않으면 오픈한다.
GPSserialPort.Open();
isStartGPS = true;
//나같은 경우는 필요에 따라 GPS 수신을 쓰레드에서 처리하기로 했다.
ThreadGPS = new Thread(new ThreadStart(this.receiveGPSMsg));
ThreadGPS.IsBackground = true;
ThreadGPS.Start();
}
//GPS 수신 처리
// COM 포트가 연결된 상태에서는 계속에서 GPS 수신 문자열이 수신되므로
//주기를 이용하여 약3초정도 마다 문자열을 끊어서 제일 마지막 GPGGA만을 가지고 메세지 처리를 하였다.
/// <summary>
/// GPS 메세지 읽기 -처리
/// </summary>
private void receiveGPSMsg()
{
try
{
while (isStartGPS)
{
//GPS 수신 처리
// COM 포트가 연결된 상태에서는 계속에서 GPS 수신 문자열이 수신되므로
//주기를 이용하여 약3초정도 마다 문자열을 끊어서 제일 마지막 GPGGA만을 가지고 메세지 처리를 하였다.
/// <summary>
/// GPS 메세지 읽기 -처리
/// </summary>
private void receiveGPSMsg()
{
try
{
while (isStartGPS)
{
if (!GPSserialPort.IsOpen)
{
MessageBox.Show("GPS 연결이 끊겼습니다. GPS 접속환경 및 GPS연결정보를 살펴보시기 바랍니다.");
return;
}
Thread.Sleep(3000); //3초간 대기후 데이터 읽음
string GPSData = "";
try
{
GPSData=GPSserialPort.ReadExisting(); //시리얼 포트에서 GPS 데이터 읽기
{
MessageBox.Show("GPS 연결이 끊겼습니다. GPS 접속환경 및 GPS연결정보를 살펴보시기 바랍니다.");
return;
}
Thread.Sleep(3000); //3초간 대기후 데이터 읽음
string GPSData = "";
try
{
GPSData=GPSserialPort.ReadExisting(); //시리얼 포트에서 GPS 데이터 읽기
parsingMsg(GPSData ); //함수 호출..... 데이터 처리하기
}
catch (Exception e)
{
MessageBox.Show(e.ToString());
return;
}
}
catch (Exception e)
{
MessageBox.Show(e.ToString());
return;
}
}
}
catch (ThreadInterruptedException)
{
return;
}
}
//GPGGA 메세지 분석
// GPS NMEA 프로토콜 참고 블로그- 출처: 초심자용 에린 입문서 블로그 (http://erine.egloos.com/2233135)
public void parsingMsg(string Msg, bool isSave)
{
//GPGGA 메세지 분석
// GPS NMEA 프로토콜 참고 블로그- 출처: 초심자용 에린 입문서 블로그 (http://erine.egloos.com/2233135)
public void parsingMsg(string Msg, bool isSave)
{
string 위도= null;
string 경도 = null;
string 수신시간= "";
string GPS수신종류= "";
string 위성갯수= "";
string 고도(해수면기준)= "";
string[] ChkMsg = null;
string temp = "";
if (Msg == null || Msg.Equals(""))
{
}
else
{
try
{
Msg.Replace("\n\r", "");
int selectIDX = -1;
string[] strArr = Msg.Split('$');
for (int i = strArr.Length-1; i >= 0; i--) //최근의 GPGGA 문자열 찾기
{
if (strArr[i].ToString().Substring(0, 5).Equals("GPGGA"))
{
ChkMsg = strArr[i].ToString().Split(',');
if (ChkMsg[2] == null || ChkMsg[3] == null || ChkMsg[4] == null || ChkMsg[5] == null)
{
continue;
}
else if (ChkMsg[2].ToString().Replace(" ", "").Equals("") || ChkMsg[3].ToString().Replace(" ", "").Equals("") || ChkMsg[4].ToString().Replace(" ", "").Equals("") || ChkMsg[5].ToString().Replace(" ", "").Equals(""))
{
continue;
}
else
{
selectIDX = i;
break;
}
}
}
else
{
try
{
Msg.Replace("\n\r", "");
int selectIDX = -1;
string[] strArr = Msg.Split('$');
for (int i = strArr.Length-1; i >= 0; i--) //최근의 GPGGA 문자열 찾기
{
if (strArr[i].ToString().Substring(0, 5).Equals("GPGGA"))
{
ChkMsg = strArr[i].ToString().Split(',');
if (ChkMsg[2] == null || ChkMsg[3] == null || ChkMsg[4] == null || ChkMsg[5] == null)
{
continue;
}
else if (ChkMsg[2].ToString().Replace(" ", "").Equals("") || ChkMsg[3].ToString().Replace(" ", "").Equals("") || ChkMsg[4].ToString().Replace(" ", "").Equals("") || ChkMsg[5].ToString().Replace(" ", "").Equals(""))
{
continue;
}
else
{
selectIDX = i;
break;
}
}
}
if (selectIDX < 0) //수신 문자열중 GPGGA 없을때
{
위도= null;
{
위도= null;
경도 = null;
수신시간= "";
GPS수신종류= "";
위성갯수= "";
고도(해수면기준)= "";
}
수신시간= "";
GPS수신종류= "";
위성갯수= "";
고도(해수면기준)= "";
}
else
{
string[] ArrMsg = ChkMsg;
{
string[] ArrMsg = ChkMsg;
temp = ArrMsg[1].ToString();
int hour = Convert.ToInt16(temp.Substring(0, 2)) + 9;
if (hour > 24)
{
hour = hour - 24;
}
수신시간= "" + hour + "시";
수신시간+= " " + temp.Substring(2, 2) + "분 " + temp.Substring(4, 5) + "초"; //시간
위도 = ArrMsg[2].ToString();
경도 = ArrMsg[4].ToString();
int hour = Convert.ToInt16(temp.Substring(0, 2)) + 9;
if (hour > 24)
{
hour = hour - 24;
}
수신시간= "" + hour + "시";
수신시간+= " " + temp.Substring(2, 2) + "분 " + temp.Substring(4, 5) + "초"; //시간
위도 = ArrMsg[2].ToString();
경도 = ArrMsg[4].ToString();
수신종류= ArrMsg[6].ToString();
/* 수신종류값별 GPS
//1 = GPS fix (SPS)
//2 = DGPS fix
//3 = PPS fix
//4 = Real Time Kinematic
//5 = Float RTK
//6 = estimated (dead reckoning) (2.3 feature)
//7 = Manual input mode
//8 = Simulation mode
*/
//2 = DGPS fix
//3 = PPS fix
//4 = Real Time Kinematic
//5 = Float RTK
//6 = estimated (dead reckoning) (2.3 feature)
//7 = Manual input mode
//8 = Simulation mode
*/
위성갯수= ArrMsg[7].ToString();
고도(해수면기준) = ArrMsg[9].ToString();
}
}
catch(Exception e)
{
}
}
catch(Exception e)
{
}
}
}
반응형
'C# & ASP.NET' 카테고리의 다른 글
C#: 파일 또는 폴더(하위 폴더포함) 읽기전용 해제 (0) | 2010.12.13 |
---|---|
C# 프로세스 킬하기 (Application.Exit() 를 해도 프로세스에 남아있을때..) (0) | 2010.12.07 |
C# DataTable 그룹핑 하기 - 프로그램에서 DataTable 를 group by 하기 (2) | 2010.12.06 |
C# 쓰레드 사용시 크로스 스레드 작업이 잘못되었습니다 컨트롤이 자신이 만들어진 스레드가 아닌.... (0) | 2010.09.10 |
한글 파라메터 깨질때.. 자바스크립트에서 넘긴 한글 파라메터 깨지지 않고 받기 (0) | 2010.01.06 |