April 24, 2009

C# Serial Port 통신 - GPS 수신 (1/2)

요즘 공부하고 있는 GPS 에 대해서...

 

GPS 와 컴퓨터와 통신을 하기 위해서는 RS232 라는 시리얼  포트를 사용하여 통신을 해야합니다. 그를 위해 보통(내가 현재 속해있는 실험실)은 MFC 를 이용하여 연습을 하던데 나는 이번에 C# 을 이용하여 도전하기로 했습니다.

 

우선 이를 위해 알아야할 가장 중요한것은 바로

 

using System.IO.Ports;

SerialPort sp = new SerialPort();

 

시리얼 통신을 하기 위해서는 몇가지 설정을 해주어야 합니다.

통신할 대상에 맞추어(대상 매뉴얼 참조) 셋팅을 해주면 되는데 이번에 사용할 GPS 의 셋팅은 다음과 같습니다.

 

sp.PortName = label_selected_port.Text;
sp.BaudRate = 9600;
sp.Parity = Parity.None;
sp.DataBits = 8;
sp.StopBits = StopBits.One;

 

다음으로 데이터를 읽기위한 이벤트를 추가해주어야 합니다.

sp.DataReceived += new SerialDataReceivedEventHandler(sp_DataReceived);
//데이터 읽기
void sp_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
      this.Invoke(new EventHandler(ReadGPSData));
}

 

여기서 sp.ReadExisting() 요것이 나오게 되는데 이것은 데이터가 있을데 데이터를(String)을 반환해준다. 이렇게 들어온 데이터를 Parsing 하여 원하는 데이터로 가공하면 시리얼 통신의 목적을 달성 할 수 있습니다.

 

private void ReadGPSData(object s,EventArgs e)
{
    string buff;
    buff = sp.ReadExisting();
    if (buff != null)
    {
        richTextBox_data.Text += buff;

        //데이터 처리하기
        ProcessGPSData(buff);
    }
}

 

바로 이벤트안에 코딩하게 되면 프로그램이 "먹통"이 될 수 있으니 잘 처리해야 합니다. Invoke 를 사용 하면 잘 되는군요^^

 

다음으로 GPS에서 나오는 데이터를 보겠습니다.

$GPGGA,134807.000,3732.6627,N,12701.3549,E,1,04,2.6,39.7,M,19.7,M,,0000*69
$GPGSA,A,3,20,28,17,11,,,,,,,,,6.5,2.6,6.0*3D
$GPGSV,2,1,08,17,60,325,22,28,57,210,34,20,52,066,19,04,32,260,*76
$GPGSV,2,2,08,11,30,066,19,23,10,120,18,01,08,062,,02,00,252,*7A
$GPRMC,134807.000,A,3732.6627,N,12701.3549,E,1.58,329.68,110808,,,A*63

GPS를 통해 나오는 값을 보면 위의 데이터가 화면에 주르르르르륵 나오게 됩니다. 여기서우리가 필요한 정보를 얻기 위해서는 파싱을 해야합니다. 우선 위와 같은 데이터는 NMEA라는 하나의 프로토콜? 이라고 할 수 있습니다.

 

여기서 $GPGGA 가 그리니치 표준시, 경도, 위도 의 정보가 담겨 있다고 하네요

 

다음 포스트에는 요것을 Parsing 해볼까요?

C# Serial Port 통신 - GPS 수신 (2/2)

 

 

April 6, 2009

ATMEGA128 PWM - led on/off

/*****************************************************

Chip type           : ATmega128
Program type        : Application
Clock frequency     : 16.000000 MHz
Memory model        : Small
External RAM size   : 0
Data Stack size     : 1024
*****************************************************/

#include <mega128.h>

void delay_us(unsigned int us)

{
    unsigned int i,j;
    for(i=0;i<us;i++)
    {
        for(j=0;j<2650;j++)
        {
       
        }
    }
}
void delay_ms(unsigned int ms)

{

             unsigned int i;

 

             for(i = 0; i < ms; i++)

                           delay_us(1000);

}

 

 

void pwm0_out(unsigned char duty)
{
 OCR0=duty;
}


void main( void )
{
    unsigned char number=0;
 unsigned int ss=256;
    
    DDRB=0xFF;     // 포트 B 출력
    PORTB=0xFF;
  
    DDRB = 0x10; // PORTB.4를 OC0로 설정한다.

    //init_LCD();    //LCD 초기화 함수 실행
   
    TCCR0=0x6A;    // (0110 1010) Fast PWM, Non-inverting, 8 prescaler
                   // f=16MHz/(N*256), N=8 prescaler factor 
                   // f= 7.8125KHz, T=128usec
       // PWM의 주기는 128usec가 된다.
   
    TCNT0=0x00;    // T/C value=0
 OCR0=0x00;   
   
    delay_us(10);  // 10msec 대기
    //instruction_out(0x01);  //clear LCD
   
    //string_out(0x80,"PWM0/OC0");
 //instruction_out(0xC5);   // LCD 위치 지정
 //char_out('H');
  
 
 while(1)
    {
 if(number<ss)
  {
  number++;
  pwm0_out(number);
  delay_us(10000);
  }

  }
 }