GPSデータ受信プログラムで表示されるデータが正しくありません

このQ&Aのポイント
  • 私は現在、GPSから受信したデータをRS232Cで接続したPCに表示させるプログラムを作成していますが、表示されるデータが正しくありません。
  • 開発環境はUNIXのC言語で、GPSはGARMIN社のgeko201(ハンディGPS)を使用しています。
  • RS232CでPCに接続して受信したNMEAセンテンス(ボーレート:4800)を表示したいのですが、コードの設定やアルゴリズムに問題があるようです。参考になる資料やヒントがあれば教えてください。
回答を見る
  • ベストアンサー

受信したデータを出力したいのですが

私は現在、GPSから受信したデータをRS232Cで接続したPCに表示させるプログラムを作成していたのですが、解決できないことがあり困っています。参考になる資料やHPをご存知な方がいらっしゃいましたらアドバイスをください。よろしくお願いします。 開発環境はUNIX C言語、GPSはGARMIN社 geko201(ハンディGPS)を使用し、RS232CでPCに接続して受信したNMEAセンテンス(ボーレート:4800)を表示したいのですが、 $GPGGA,0933……といったNMEAセンテンスではなく 2c8080803030301………といったデータが表示されてしまいます。 ポートの設定は以下で行っています。 newtio.c_cflag = B4800 | CS8 | CREAD | CLOCAL; newtio.c_iflag = 0; newtio.c_oflag = 0; newtio.c_lflag = 0; newtio.c_cc[VTIME]=1; RS232Cからデータを得て表示する部分のアルゴリズムで参考になるものがございましたらどうかご教授ください。

質問者が選んだベストアンサー

  • ベストアンサー
  • hidebun
  • ベストアンサー率50% (92/181)
回答No.4

>どのようにNo2やNo3のページを探索したのかも 基本的にキーワードを入力しただけです。 「GPS」に限定すると、情報が偏ってしまうので、より大きな枠組みとして、 Googleで、「シリアル RS-232C C」で検索しました。 そこでヒットした 「Linuxでシリアル通信(RS232C) - 佐藤伸吾(akio0911)のデジタルライフハック」というページの中にリンクとして貼ってあったものです。 パーサーについては、 「NMEA C Parser」で検索して、4件目ぐらいにヒットしました。 では、完成まで頑張って下さい。

abcmottu
質問者

お礼

とても勉強になりました。なんとかプログラムを完成することができ、先に進むことができます。本当にありがとうございました。

その他の回答 (3)

  • hidebun
  • ベストアンサー率50% (92/181)
回答No.3

あ、NMEA183センテンスのパーサーライブラリ (C言語で書かれているもの)もみつけたので、 もし文字列が受信できたら、使ってみて下さい。 http://www.dmh2000.com/nmea/nmeap.shtml テストプログラムも梱包されているようなので、 すぐに使えると思います。

  • hidebun
  • ベストアンサー率50% (92/181)
回答No.2

こんな感じのプログラムを書いているのでしょうか。 http://0n0.fc2web.com/paso/serial/serial00.html > 2c8080803030301………といったデータが表示されてしまいます。 ハイパーターミナルでNMEA出力の確認が取れているのに、 受信プログラムの取得処理で、このような文字列が取得されるのでしょうか? プログラム貼り付けてもらったほうが、多くの方からアドバイスが得られると思いますが。

abcmottu
質問者

お礼

hidebunさん、お忙しい中何度も助言頂きありがとうございます。 >​http://0n0.fc2web.com/paso/serial/serial00.html 上記のURLがまさしく探し求めていたもので非常に参考になりました。 本当にありがとうございます。 お礼のポイントはどうすれば提供できるのでしょうか。 また、今回私が探し回ってたどり着くことができなかった有効なページを、hidebunさんが瞬時に探し当ててくださったことに驚嘆しております。今後のデータへのアプローチの参考にしたいのでhidebunさんがどのようにNo2やNo3のページを探索したのかも、よろしければ是非教えて頂きたいです。

  • hidebun
  • ベストアンサー率50% (92/181)
回答No.1

全くGPSについて詳しくないのですが、 本体側の設定は、 http://www.rakuten.co.jp/gps/385104/464629/464680/#NMEAOUTSET のようにして、NMEA形式で出力する設定になっているのですか? また、このページには、 > 測位結果を、 > パソコンに添付されているハイパーターミナル等のソフトで、 > 実際に目で見て確認することができます。 とありますので、Windowsをお持ちなら、ハイパーターミナルで 一度出力データの確認をされてはいかがでしょうか。 設定さえきちんとしていれば、NMEA書式でデータが送られてくる のではないかと思います。 まずは出力側の確認が先決だと思います。

abcmottu
質問者

補足

早急な対応本当にありがとうございます。ハイパーターミナルの4800bpsでNMEAデータの取得は確認できました。 しかし今回作成したいプログラムはRS232Cを制御することを踏まえた受信データの表示プログラムです。説明不足で申し訳ございません。 GPSが受信したデータをパソコンに表示する方法がわからず、質問させていただきました。NMEA形式の文字と数字の組み合わせのデータを読み込んで表示するにはどのようにプログラミングをすればよいでしょうか。アドバイスがあればよろしくお願いいたします。

関連するQ&A

  • GPSデータ(NMEA)受信

    USB接続のGPS受信機の購入を検討中で、 GPS受信機よりNMEAデータのUTCを取得したいと考えています、 NMEAデータ取得の方法について教えてください。 プログラム上(VB.net,C#)より RS232CのようにUSBのポートに接続し、 ボーレートを設定して受信すればよいのでしょうか? NMEAデータがRS232Cシリアル通信のように垂れ流されてくるイメージなのですが、 問題ないでしょうか?

  • GPS受信機時計ConnectionError

    GPSでのPC時刻同期のため、以下のハード・ソフトを使用しています。 (1)USB GPS Resiver VFAN UG-353 (2)GPS受信機時計 GPS_Clock.EXE Version 1.4.0.0 for Windows 7/8/10 (1)でGPS測位できることを確認しNMEAフォーマットデータが表示されることは確認できたのですが、(2)でのデータ取り込みに失敗。(2)で Communication Failed!! になってしまいます。 (2)の「ツール」→「設定」→「通信ポート」「ボーレート」を確認・設定し「OK」を設定すると Connection Error COM4  (このときはCOM4:(1)とおなじCOMポートを設定)になってしまいます(ボーレートは9600に設定。これは(1)のボーレートと一致させている)。 デバイスマネジャーを確認すると、 ポート(COMとLPT) → u-blox Virtual COM Port(COM4) と出るので、COMポート設定は合っていると思われます。 なぜ「Connection Error COM4 」となってしまのか、原因がわかりません。 どなたか原因と対処方法をご教授願えないでしょうか。

  • geko201とマイコンのシリアル通信について

    GPS受信機(geko201)をマイコン(pic18f452)の基板にrs23-2cで接続して、 GPS受信機からのデータを取り、その数値を計算するプログラムをC言語で組んでいます。 処理手順としては マイコン側のボタンを押すと、 GPS受信機からのデータ(@051125004805N3529538E13638632G005+00041E0000N0000D0000) を受信してその値の計算をはじめます。 そこで問題があり、 仮想GPSとしてプログラムで任意のタイミングで一件だけマイコンにGPSデータを送った場合 ちゃんと計算してくれるんですが、 本物のGPS受信機は1秒毎にデータを垂れ流し状態で そこで受信したら、受信待ちで止まってしまいます 改善策がわからないので、どなたか教えてください 受信部分のソース↓ while(1) { if(input(PIN_A0)){ gets(mes);          以下略 } }//roop end

  • 受信データから必要な部分のみ表示するプログラム

    現在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分 */実行結果は上記のように出力され、何も表示されないこともあります。ご指摘よろしくお願いいたします。

  • データ受信ができません

    現在、Turbo C++を用いてソフトを作っています。WinAPI関数を用いて、RS232Cによって電子回路とPC間でシリアル通信を行っています。デスクトップのパソコンでは通信はうまくできていたのですが、ノートパソコンに、USBとRS232Cの変換ケーブルを用いて同じプログラムを動かしたところ、データ受信が全くされません。CreateFile関数はエラーは出ませんが、ReadFile関数などは受信されずに待機しているような状況です。コムポートの設定も問題はないと思うのですが、他に何か問題はあるでしょうか。 予想できる範囲でわかる方お願いします。

  • GPS受信機で位置情報を取得できません

    GPS受信機を用いて自己位置同定を行いたいと考えています. 現在,購入したGPS受信機は San Jose Navigation Inc.の『FV-M8』 (Etek Navigationの『EB-85A』) です. この受信機の出力信号の詳細がわかりません. 市販されているGPS受信機は電源投入後,位置情報が出力され,その出力信号がRS232Cに対応していると思われるので, 動作確認のために受信機をPCに接続してハイパーターミナルを用いてみたのですが,うまく受信できませんでした. そこで,RS232Cの規格を確認したところ,出力電圧が(+または-)5~12Vであったので GPS受信機の出力とPCの出力信号を(+または-)12Vに変換して再度同じ方法を試みましたが,やはりうまくいきませんでした. GPS受信機の出力信号をオシロスコープで確認したところ,パルス信号を周期的に出力されています. ハイパーターミナルの設定は 4800bps,8ビット・パリティなし,1ストップビット で行いました. このGPS受信機について,なにか参考になるサイトや,情報をお持ちの方は是非,教えてください. よろしくお願いします.

  • AccessでRS232Cからデータを受信したい

    Access2019を使用しています。 RS232C経由で、外部機器データを取り込みたいと思います。 スィッチがオンになったときとオフになったときのデータをその都度取り込みたいです。 通信方法も設定、受信方法などもわかりません。 サンプルプログラムなどありましたら教えてください。 よろしくお願いいたします。

  • GPSモジュールに関して

    GPSモジュールに関して GPSモジュールは大体の場合、 出力されるデータ形式はNMEAだと思うんですけど この原理を教えてもらえますでしょうか? 自分で調べた結果、受信機とどう違うのかが わかりませんでした。 得られたデータのひとつである衛星の仰角から hopfieldモデルを利用して 対流圏遅延を求めたいのですが、 出力データの信頼性がわからなく困っている状態です どうぞよろしくお願いします 長文失礼しました

  • ひとつのプログラムにしたいのですが

    (1)以前GPSで取得した測位データをRS232C通信でPCに表示するプログラムを作成するに当たって、多くの方に助言を頂けたことでなんとかNMEAデータを表示できるようになりました。 (2)そこで次の段階として、取得したNMEAデータに含まれる”緯度””経度””時刻”の要素のみ取り出して表示する方法として、strtok関数を用いたプログラムを教わり、用意した文章から必要な要素のみを出力する方法も確認できました。 (1)と(2)のプログラムをあわせて、受信したデータから緯度経度時刻のみを表示するプログラムを作成したいのですが、 assignment makes pointer from integer without とコンパイル時に表示されてしまいます。ポインタの受け渡しに問題があるということでしょうか?どのように組み合わせれば受信データから必要なデータを表示できるようになるでしょうか。方法があればご教授お願いします。 以下が(1)と(2)のプログラムです。 (1)受信したデータをRS232C通信でPCに指定した行数表示するプログラム #include<unistd.h> #include<fcntl.h> #include<strings.h> #include<termios.h> #include<stdio.h> #define BAUDRATE B4800 #define MODEMDEVICE "/dev/ttyS0" int main() { int fd, c, res; int i=0; int j=0; struct termios oldtio, newtio; unsigned char buf[512]; 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); while (i==0) { res = read(fd,buf,512); buf[--res]=0; j++; printf("%s\n",buf); //j++; if(j==48)i++; /*NMEAセンテンス1セットは24行(12種と1行ずつのスペース)なのでここでは48行で2セット分のループ*/ } tcsetattr(fd, TCSANOW, &oldtio); close(fd); return(0); } (1)実行結果 $GPRMC,081312,A,3428.9433,N,13549.4905,E,0.0,0.0,060808,6.7,W,A*06 $GPRMB,A,,,,,,,,,,,,A,A* $GPGSA,A,3,03,06,07,,16,,21,,25,27,,,2.3,2.0,1.0*34 ・・と48行このようなNMEAセンテンスを表示します。 (2)NMEAセンテンスから時刻、緯度、経度のみを出力 #include <stdio.h> #include <string.h> #include <math.h> char buf[512]="$GPRMC,143514,A,3428.9468,N,13549.4507,E,0.0,196.2,180708,6.7,W,A*05"; /*緯度経度時刻がすべて含まれているGPRMCからデータを取得したいのでGPRMCのモデルを1行用意*/ void pnmea(void) { int utc; double lat; /*緯*/ double lon; /*経*/ char ew; /*東西*/ char ns; /*南北*/ char stat; char *p; /*一行のNMEAセンテンスから時刻緯度経度のみを取り出すために、strtokで”,”ごとのトークンを得る*/ if ((p=strtok(buf,","))==NULL) return; if (strcmp(p,"$GPRMC")!=0) return; /*センテンスの先頭は$GPRMCか?*/ if ((p=strtok(NULL,","))==NULL) return; sscanf(p,"%d",&utc); if ((p=strtok(NULL,","))==NULL) return; stat=p[0]; if ((p=strtok(NULL,","))==NULL) return; /緯度*/ sscanf(p,"%lf",&lat); if ((p=strtok(NULL,","))==NULL) return; ns=p[0]; if ((p=strtok(NULL,","))==NULL) return; /*経度*/ sscanf(p,"%lf",&lon); if ((p=strtok(NULL,","))==NULL) return; ew=p[0]; if (stat!='A') return; printf("%02d時%02d分%02d秒(UTC) ",utc/10000, (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)); if (ew=='E') printf("東経"); else if (ns=='W') printf("西経"); printf("%.0lf度%.4lf分",floor(lon/100.0), fmod(lon,100.0)); printf("\n"); } int main(void) { pnmea(); return 0; } (2)実行結果 14時35分14秒(UTC) 北緯34度28.9468分東経135度49.4507分 (1)で得たデータを(2)でGPRMCか判別し、必要な部分を取り出し表示 したいと考えています。よろしくお願いします。

  • データ送信

    MSCommのOutPutプロパティを使用して送信します。 Dim Buffer As String  Buffer = "Dummy" MSComm1.Output = Buffer RS-232C接続をしたデバイスにデータを送信します。 このとき、受信するデバイスがいないとMSComm1.Outputステートメントの処理に約4-5秒かかります。 これは仕様ですか? MSComm1.Iutputプロパティを含めて、タイムアウトに関して参考になるドキュメントやサイトがございましたら教えていただけませんか?