วันจันทร์ที่ 21 กันยายน พ.ศ. 2552

ติดต่อ GPS ได้แล้วครับ






























การอ่านค่าของ GPS

หลักการอ่านค่าของ GPS นั้นต้องศึกษา โปรโตคอล NMEA 0183 ซึ่งจะมีข้อมูลส่งออกมาในรูปแบบการสื่อสายแบบอนุกรม RS-232 Baud rate(bps) 9600 Data bit 8 Parity None จากนั้นจะได้ข้อมูลออกมาดังนี้

06:27:58 $GPRMC,062758.00,V,,,,,,,210909,,,N*70
06:27:58 $GPVTG,,,,,,,,,N*30
06:27:58 $GPGGA,062758.00,,,,,0,00,99.99,,,,,,*68
06:27:58 $GPGSA,A,1,,,,,,,,,,,,,99.99,99.99,99.99*30
06:27:58 $GPGSV,4,1,13,25,73,147,,13,31,206,,11,71,087,,19,19,034,*75
06:27:58 $GPGSV,4,2,13,07,83,005,,23,10,172,,32,05,127,,08,42,332,*7C
06:27:58 $GPGSV,4,3,13,07,83,005,,28,20,316,,20,12,150,,17,26,251,*78
06:27:58 $GPGSV,4,4,13,08,42,332,*47
06:27:58 $GPGLL,,,,,062758.00,V,N*44
06:27:58 $GPZDA,062758.00,21,09,2009,00,00*69
06:27:59 $GPRMC,062759.00,V,,,,,,,210909,,,N*71
06:27:59 $GPVTG,,,,,,,,,N*30
06:27:59 $GPGGA,062759.00,,,,,0,00,99.99,,,,,,*69
06:27:59 $GPGSA,A,1,,,,,,,,,,,,,99.99,99.99,99.99*30
06:27:59 $GPGSV,4,1,13,25,73,147,,13,31,206,,11,71,087,,19,19,034,*75
06:27:59 $GPGSV,4,2,13,07,83,005,,23,09,171,,32,05,127,,08,42,332,*77
06:27:59 $GPGSV,4,3,13,07,83,005,,28,20,316,,20,12,150,,17,26,251,*78
06:27:59 $GPGSV,4,4,13,08,42,332,*47
06:27:59 $GPGLL,,,,,062759.00,V,N*45
06:27:59 $GPZDA,062759.00,21,09,2009,00,00*68

เมื่อได้ข้อมูลต่างๆมาแล้ว ก็มาทำการคัดเอาเฉพาะโปรโตคอลที่ต้องการ ยกตัวอย่างเช่น $GPGGA หรือ $GPRMC จากนั้นก็รับค่าเข้ามาเก็บใน Buffer แล้วทำการตัดขอมูลที่ได้ออกเป็นช่วงๆ เพื่อให้ได้ตำแหน่งที่ต้องการ เช่น ตำแหน่งของ Latitude กับ Longitude แล้วทำการแปลงตัวอักขระที่เก็บใว้ใน Buffer ให้เป็นตัวเลข เพื่อที่จะได้คำนวนหาค่าที่ใช้ได้ เพราะมาตรฐานของค่าที่ได้ไม่ตรงกับ Google Map

การคำนวนค่า GPS

เมื่อทำการแปลงค่าเป็นตัวเลขได้แล้ว ก็นำค่าที่ได้มาหารด้วย 100 เพื่อเลื่อนจุดทศนิยม จากนั้นก็ mod ด้วย 1 เพื่อทำการคัดเอาแต่ทศนิยม จากนั้นก็เอาค่าหลังจุดทศนิยมที่ mod ได้มาลบกับค่าแรก ก็จะได้ค่า ก่อนจุดทศนิยม จากนั้นเอา ค่าหลังจุดทศนิยมมา หารด้วย 60 จากนั้นก็คูณด้วย 100 ก็จะได้ค่าหลังจุดทศนิยมค่าใหม่ จากนั้นก็เอาค่าหลังจุดทศนิยมค่าใหม่ที่ได้บวกกับค่าก่อนจุดทศนิยม ก็จะได้ ค่าที่สามารรถใช้กับ Google ได้

เช่น 12.3456 mod 1 จะได้ 0.3456 จากนั้นก็เอา 12.3456-0.3456 จะได้ 12 จากนั้นเอา (0.3456/60)*100 = 0.576 จากนั้นก็เอามาบวกกับ 12 ก็จะได้ 12+0.576 = 12.576

12.576 คือค่าที่ทำการคำนวณแล้ว ที่สามารถใช้กับ Google ได้ทันที

ส่วนการคำนวนเวลาซึ่งต้องบวกเพิ่มอีก 7 ชั่วโมงลองดูเอานะครับ ผมเขียนแบบลูกทุ่งเลย



เหนื่อยจิงๆกับการอดหลับอดนอนมาเป็นอาทิตย์ แต่ก็คุ้มเพราะเป็นความรู้ใหม่ที่เราต้องตามให้ทันเทคโนโลยี

โค๊ดครับ
#include <18f452.h>
#include
#use delay(clock=20000000)
#fuses HS,NOPROTECT,NOWDT,NOBROWNOUT
#use rs232(baud=9600,xmit=pin_c6,rcv=pin_c7,stream=GPS,stream=HOSTPC,stream=B,errors)

#include
#include
#include

void readMessage();
void convert();
void show();

char timei[10],lati[15],loni[15],speedi[10],dayi[10];
float time,lat,lon,speed,day;
float lat1,lat2,lat3,lon1,lon2,lon3,time1,time2,time3;
int sh;

void readMessage()
{
char c;
char buffer[80];
char k;
char sentent[]="GPRMC";
int16 i,j=0,time_count=0,lat_count=0,lon_count=0,speed_count=0,day_count=0;
do
{
for(i=0;i<15;i++)
{
timei[i]= 0;
lati[i]= 0;
loni[i]= 0;
speedi[i]= 0;
dayi[i]= 0;
}

do
{
while ( fgetc(GPS) != '$' );
for (k=0;k<5;k++) buffer[k]=fgetc(GPS);
} while (strncmp(buffer,sentent,5)!=0);
c=0;
while ( c !='*' && k<79)
{
c = fgetc(GPS);
buffer[k++]= c;
}
if(k<40)
{
lcd_send_byte(0,0x01);
lcd_putc(" Connecting GPS");
lcd_putc("\n BY NONT_PEET");
output_high(pin_c3);
delay_ms(250);
output_low(pin_c3);
delay_ms(250);
}
}while(k<40);

for (i=0;i
{
if (buffer[i]==','){j++;}
if (j==1)
{
timei[time_count++]=buffer[i+1];
}
if (j==3)
{
lati[lat_count++]=buffer[i+1];
}
if (j==5)
{
loni[lon_count++]=buffer[i+1];
}
if (j==7)
{
speedi[speed_count++]=buffer[i+1];
}
if (j==9)
{
dayi[day_count++]=buffer[i+1];
}
}

time = atof(timei);
lat = atof(lati);
lon = atof(loni);
speed = atof(speedi);
day = atof(dayi);

}


void show(void)
{
fprintf(B,"\n\rtime : %6.0f",time3);
fprintf(B,"\n\rLat : %4.5f",lat3);
fprintf(B,"\n\rLon : %5.5f",lon3);
fprintf(B,"\n\rSpeed : %3.0f",speed);
fprintf(B,"\n\rDay : %6.0f",day);
}
void convert(void)
{

time=time*0.0001;
time1=fmod(time,1);
time2=time-time1;
if(time2<=17)
{
time2=time2+7;
}
else
{
time2=(17-time2)*-1;
}
time3=(time2+time1)*10000;

lat=lat/100;
lat1=fmod(lat,1);
lat2=lat-lat1;
lat1=(lat1/60)*100;
lat3=lat1+lat2;

lon=lon/100;
lon1=fmod(lon,1);
lon2=lon-lon1;
lon1=(lon1/60)*100;
lon3=lon1+lon2;
}


void main()
{
lcd_init();
while(true)
{
readMessage();
convert();
//show();
if(sh==1)
{
lcd_send_byte(0,0x01);
printf(lcd_putc,"LAT : %4.5f",lat3);
printf(lcd_putc,"\nLON : %4.5f",lon3);
//fprintf(B,"\n\rDATA:%6.0f:%4.5f:%4.5f:%3.0f:%6.0f:",time3,lat3,lon3,speed,day);
delay_ms(1500);
sh=0;
}
else
{
lcd_send_byte(0,0x01);
printf(lcd_putc,"DAY : %6.0f",day);
printf(lcd_putc,"\nTIME : %6.0f",time3);
delay_ms(1500);
sh=1;
}
output_toggle(pin_c2);
//delay_ms(500);
}

4 ความคิดเห็น: