受信データから必要な部分のみ表示するプログラム
現在C言語を使用して、受信したデータから必要な部分だけを表示するプログラムを作成しております。
以前作成した、GPSからデータを受信するpg1と、必要な部分のみ表示するpg2をあわせることで、受信したデータから必要な部分を抜き出すことができました。
次の段階として、そのプログラムを指定した回数表示が行えるよう変更を試みたのですが、一度表示するとそこで終了してしまう状態から抜け出せません。どの点を改良すれば、回数を指定して表示ができるようになるのでしょうか。よろしくお願いいたします。
このときGPS端末はRS232CでPCに接続GPS端末で受信しています。
受信したNMEAと呼ばれるフォーマットのデータから時刻,緯度,経度に対応する要素を取り出して表示しようとしています。
#include<stdlib.h>
#include<unistd.h>
#include<fcntl.h>
#include<string.h>
#include<termios.h>
#include<stdio.h>
#include<math.h>
#define BAUDRATE B4800
#define MODEMDEVICE "/dev/ttyS0"
int main()
{
int fd, c, res;
int utc;
char stat;
char ns;
char ew;
char *p;
double lat;
double lon;
struct termios oldtio, newtio;
char buf[512];
FILE *fp_gps;
while(1){
if((fd = open(MODEMDEVICE, O_RDWR | O_NOCTTY ))==-1){
perror(MODEMDEVICE);
exit(-1);
}
tcgetattr(fd, &oldtio); /*シリアルポートの設定を待避*/
bzero(&newtio, sizeof(newtio)); /*新しいポートの設定の構造体をクリア*/
newtio.c_cflag = (BAUDRATE | CRTSCTS | CS8 | CLOCAL | CREAD);/*ボー:4800*/
newtio.c_iflag = (IGNPAR | ICRNL);
newtio.c_oflag = 0;
newtio.c_lflag = ICANON;
tcflush(fd, TCIFLUSH);
tcsetattr(fd,TCSANOW,&newtio);
res = read(fd,buf,512);
buf[--res]=0; /* 文字列終端をセット */
if ((p=strtok(buf,","))==NULL) return;
if (strcmp(p,"$GPRMC")!=0) return; /*センテンスの先頭は$GPRMCか?*/
if ((p=strtok(NULL,","))==NULL) return; /*utc:世界標準時*/
sscanf(p,"%d",&utc);
if ((p=strtok(NULL,","))==NULL) return; /*stat:ステータス*/
stat=p[0];
if ((p=strtok(NULL,","))==NULL) return; /*lat:緯度*/
sscanf(p,"%lf",&lat);
if ((p=strtok(NULL,","))==NULL) return; /*ns:南北*/
ns=p[0];
if ((p=strtok(NULL,","))==NULL) return; /*lon:経度*/
sscanf(p,"%lf",&lon);
if ((p=strtok(NULL,","))==NULL) return; /*ew:東西*/
ew=p[0];
if (ew==p[0]){
fp_gps = fopen("gdata/gdata.dat","w");
if (fp_gps == NULL){
printf("open fp_gps err\n");
}
}
/*時刻緯度経度に対応するトークン表示*/
if (stat!='A') return; /*ステータスチェック*/
printf("%02d時%02d分%02d秒(UTC) ",utc/10000+9, (utc%10000)/100, utc%100);/*utc+9時間は日本時間における標準時*/
fprintf(fp_gps,"%02d時%02d分%02d秒(UTC) ",utc/10000+9, (utc%10000)/100, utc%100);
if (ns=='N') printf("北緯"); else if (ns=='S') printf("南緯");
printf("%.0lf度%.4lf分",floor(lat/100.0), fmod(lat,100.0));
fprintf(fp_gps,"%.0lf度%.4lf分",floor(lat/100.0), fmod(lat,100.0));
if (ew=='E') printf("東経"); else if (ns=='W') printf("西経");
printf("%.0lf度%.4lf分",floor(lon/100.0), fmod(lon,100.0));
fprintf(fp_gps,"%.0lf度%.4lf分",floor(lon/100.0), fmod(lon,100.0));
printf("\n");
}
tcsetattr(fd, TCSANOW, &oldtio); /*退避前の設定に戻す*/
fclose(fp_gps);
close(fd); /*ポートを閉じる */
}
/*実行結果
./a.out
./a.out
14時15分48秒(UTC) 北緯34度28.9393分東経136度49.4900分
*/実行結果は上記のように出力され、何も表示されないこともあります。ご指摘よろしくお願いいたします。
お礼
ご回答ありがとうございます。 同期方式と伝送制御手順を全く関連付けて考えていませんでした。組み合わせて使われるとymmasayanさんに指摘され頭の中すっきりしました。教えていただいたURLも見てもう一度勉強しなおしてみます。ほんとうにありがとうございました。