Skip to content

Instantly share code, notes, and snippets.

@keiya
Created January 7, 2011 08:16
Show Gist options
  • Save keiya/769244 to your computer and use it in GitHub Desktop.
Save keiya/769244 to your computer and use it in GitHub Desktop.
NMEA GPS Logger
Win32::SerialPort_Configuration_File -- DO NOT EDIT --
\\.\COM5
CFG_1,none
eol,10
clear,-@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@-
RCONST,0
istrip,0
CFG_2,none
XOFFCHAR,0
PARITY_EN,0
WCONST,200
intr,3
U_MSG,1
STOP,1
XONLIM,2048
erase,8
XONCHAR,0
BINARY,1
RTOT,25
echonl,0
XOFFLIM,512
icrnl,0
inlcr,0
READBUF,4096
igncr,0
EOFCHAR,0
WRITEBUF,0
RINT,100
ocrnl,0
bsdel, 
opost,0
echoke,1
PARITY,none
HNAME,localhost
echoctl,0
CFG_3,none
EVTCHAR,0
icanon,0
isig,0
HADDR,0
E_MSG,1
DATA,8
DVTYPE,none
echo,0
quit,4
s_eof,26
s_kill,21
ERRCHAR,0
onlcr,1
ALIAS,COM5
HSHAKE,none
DATYPE,raw
echok,1
echoe,1
BAUD,38400
WTOT,10
#!c:/perl/bin/perl
#┌──────────────────
#│ radio_ini v1.0 <radio_ini.cgi>
#│ Copyright(C) Scoal Mayeda 2006
#│ mayeda@amigo2.ne.jp
#│ http://www.amigo2.ne.jp/~mayeda/
#└──────────────────
#このプログラムは初期設定します。実行後はini.confというファイルが作成されます。
#このプログラムを実行後、radio_perl.cgiを実行させて信号を受信できます。
#
#尚、このプログラムは下記のサイトを参考にさせていただきました。(感謝)
#http://www9.ocn.ne.jp/~ymt/perl/serialport.html
#
use strict;
use Win32::SerialPort;
my $conf_file = 'ini.conf';
#-25-----------設定ここから-------------------------
#自分のCOM番号にあわせてください。
my $port_name = 'COM5';
#この行は変更しないでください
my $com_ini = new Win32::SerialPort($port_name) or die;
# 自分の通信機器と合わせてください。
#$com_ini->are_match("text", "\n"); # possible end strings
$com_ini->lookclear; # empty buffers
$com_ini->baudrate(38400);
$com_ini->parity('none');
$com_ini->databits(8);
$com_ini->stopbits(1);
# 読み込み時の時間間隔の設定です。
# 小さすぎると計測機器の反応速度が
# パソコンに追いつけなくなります。
$com_ini->read_interval(100);
$com_ini->read_char_time(25);
$com_ini->error_msg(1); #Framing Error detected などを出す
$com_ini->user_msg(1); #Waiting for CTS などを出す
$com_ini->write_settings;
$com_ini->save($conf_file);
# フロー制御の方法。rts(ハードウェア制御),
# xoff(ソフトウェア制御),dtr(ハードウェア制御,rtsとはピンが違う)
#
$com_ini->handshake('rts');
# 読み込み,書き込みバッファ。
# あまり小さすぎると全文を受け取れない事があります
$com_ini->buffers(
1024 * 10, # 読み込みバッファ
1024 * 4 # 書き込みバッファ
);
#------------設定ここまで-------------------------
print "初期設定ファイルができました。プログラムを作動できます。<br>\n";
#!c:/perl/bin/perl
$| = 1;
use strict;
use Win32::SerialPort;
use LWP::UserAgent;
use LWP::ConnCache;
my $wating_time=0.1;
my $conf_file = "ini.conf";
tie *PORT, 'Win32::SerialPort', $conf_file or die "Can't open serialport";
#open(LOG, ">>data.txt");
my($clock,$long,$lat,$sat,$mode,$kt,$km,$pdop,$hdop,$vdop,$dime,$dirtru,$dirmag,$alt);
my($llat,$llong);
my $i=0;
my $conncache = LWP::ConnCache->new;
while(1){
($llat,$llong)=($lat,$long);
my $line = readline(*PORT);
$line =~ s/[^\w\d\$,.\n\*]+//g;
#print LOG $line;
if ($line =~ /^\$GPGGA/) { #位置
$line =~ m/^\$GPGGA,([\d\.]+),([\d\.]+),(\w),([\d\.]+),(\w),(\d),(\d+),([\d\.]+),([\d\.]+)/;
if ($6 ne 0) {
if ($6 eq 2) {$mode = "D"} elsif ($6 eq 1) {$mode = "A"};
$clock = $1;
if ($3 eq 'S') {$lat=0-$lat};
$lat = $2;
if ($5 eq 'W') {$long=0-$long};
$long = $4;
$sat = $7;
$hdop = $8;
$alt = $9;
}
} elsif ($line =~ /^\$GPGLL/) {
$line =~ m/^\$GPGLL,([\d\.]+?),N,([\d\.]+?),E,([\d\.]+?),\w,(\w)/;
} elsif ($line =~ /^\$GPRMC/) {
$line =~ m/^\$GPRMC,([\d\.]+),(\w),([\d\.]+),(\w),([\d\.]+),(\w),([\d\.]+),([\d\.]+),(\d+),,,(\w)/;
if ($2 ne 'V') {
$mode = $8;
$clock = $1;
if ($4 eq 'S') {$lat=0-$lat};
$lat = $3;
if ($6 eq 'W') {$long=0-$long};
$long = $5;
$kt = $7;
}
} elsif ($line =~ /^\$GPGSA/) { #誤差
$line =~ m/^\$GPGSA,\w,(\d)/;
$dime = $1;
$line =~ m/([\d\.]+),([\d\.]+),([\d\.]+)\*.+$/;
$pdop = $1;
$hdop = $2;
$vdop = $3;
} elsif ($line =~ /^\$GPVTG/) { #速度
$line =~ m/^\$GPVTG,([\d\.]+)?,T,([\d\.]+)?,M,([\d\.]+)?,N,([\d\.]+)?,K,(\w)/;
$mode = $5;
if ($mode ne 'N') {
$dirtru = $1;
$dirmag = $2;
$kt = $3;
$km = $4;
}
} elsif ($line =~ /^\$GPGSV/) {
$line =~ m/^\$GPGSV,\d,\d,(\d+)/;
$sat = $1;
} else {
print "$line";
}
unless ($llat eq $lat && $llong eq $long) {
$clock = &joinclock($clock);
if ($mode eq 'A') {
$mode = 'Normal'
} elsif ($mode eq 'D') {
$mode = 'DGPS';
}
my($clat,$clong);
my @tmpla = split(/\./,$lat);
my $lat0 = sprintf "%3.7f",(substr($tmpla[0], 0, -2));
my $lat1 = sprintf "%3.7f",(substr($tmpla[0], -2, 2));
my $lat2 = sprintf "%3.7f",('0.'.$tmpla[1]);
$clat = sprintf "%3.6f",($lat0 + $lat1/60 + $lat2/60);
my @tmplo = split(/\./,$long);
my $long0 = sprintf "%3.7f",(substr($tmplo[0], 0, -2));
my $long1 = sprintf "%3.7f",(substr($tmplo[0], -2, 2));
my $long2 = sprintf "%3.7f",('0.'.$tmplo[1]);
$clong = sprintf "%3.6f",($long0 + $long1/60 + $long2/60);
my $hh = substr($long, 0, 2);
print "$clock: $clat N $clong E\tPDOP:$pdop\tHDOP:$hdop\tVDOP:$vdop\n";
print " Satelites: $sat Mode:$mode\t[${dime}D]\n";
print " ${kt}kt/${km}km/h\tDirection (TrueN.):$dirtru / (Mag.N.):$dirmag\n";
if ($i % 5 == 0 and $hdop < 100)
{
#open(TW, "+< serv/twi.txt"); # 読み書きモードで開く
open(TW, "+< serv/twi.txt"); # 読み書きモードで開く
#flock(TW, 2); # ロック確認。ロック
#seek(TW, 0, 0); # ファイルポインタを先頭にセット
#print TW "$clat,$clong,$hdop"; # 書き込む
#truncate(TW, tell(OUT)); # ファイルサイズを書き込んだサイズにする
#close(TW); # closeすれば自動でロック解除 open(TW, "+< serv/twi.txt"); # 読み書きモードで開く
flock(TW, 2); # ロック確認。ロック
seek(TW, 0, 0); # ファイルポインタを先頭にセット
print TW "$clat,$clong,$hdop"; # 書き込む
truncate(TW, tell(OUT)); # ファイルサイズを書き込んだサイズにする
close(TW); # closeすれば自動でロック解除
print "Sending location to server...";
my $ua = LWP::UserAgent->new(timeout => 5);
$ua->conn_cache( $conncache );
$ua->env_proxy;
#my $request = HTTP::Request->new('GET', "http://www.keiyac.org/posupdator/index.cgi?lat=$clat&long=$clong&sat=$sat&mode=$mode&spd=$km&alt=$alt");
#my $response = $ua->request($request, 'res.txt');
#if ($response->is_success) {
## print "Completed\n";
#} else {
## print "Failed\n";
#}
}
$i++;
}
sleep $wating_time;
}
#close LOG;
close PORT or warn "Can't close serialport";
sub joinclock {
my $hh = substr($_[0], 0, 2);
my $mm = substr($_[0], 2, 2);
my $ss = substr($_[0], 4, 2);
return "$hh:$mm:$ss";
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment