nmea.tcl
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009 package require Tcl 8.2
00010 package provide nmea 0.1.1
00011
00012 namespace ::nmea {
00013 ::nmea = ::nmea(checksum) 1
00014 ::nmea = ::nmea(log) ""
00015 }
00016
00017 ret ::nmea::open_port (type port , optional speed =4800) {
00018 variable nmea
00019 set nmea(fh) [open $port]
00020 fconfigure $nmea(fh) -mode $speed,n,8,1 -handshake xonxoff -buffering line -translation crlf
00021 fileevent $nmea(fh) readable [list ::nmea::read_port $nmea(fh)]
00022 return 1
00023 }
00024
00025 ret ::nmea::open_file (type file , type rate) {
00026 variable nmea
00027 set nmea(fh) [open $file]
00028 set nmea(rate) $rate
00029 fconfigure $nmea(fh) -buffering line -blocking 0 -translation auto
00030 if {$rate > 0} {
00031 after $rate [list ::nmea::read_file $nmea(fh)]
00032 }
00033 }
00034
00035 ret ::nmea::configure_port (type settings) {
00036 variable nmea
00037 fconfigure $nmea(fh) -mode $settings
00038 }
00039
00040 ret ::nmea::close_port () {
00041 variable nmea
00042 catch {close $nmea(fh)}
00043 }
00044
00045 ret ::nmea::close_file () {
00046 variable nmea
00047 catch {close $nmea(fh)}
00048 }
00049
00050 ret ::nmea::read_port (type f) {
00051 set line [gets $f]
00052 if {$::nmea::nmea(log) != ""} {
00053 puts $::nmea::nmea(log) $line
00054 }
00055 ::nmea::parse_nmea $line
00056 }
00057
00058 ret ::nmea::read_file (type f) {
00059 variable nmea
00060 if {![eof $f]} {
00061 set line [gets $f]
00062 if {[string match {$*} $line]} {
00063 ::nmea::parse_nmea $line
00064 } else {
00065 ::nmea::parse_nmea \$$line
00066 }
00067 }
00068 after $nmea(rate) [list ::nmea::read_file $f]
00069 }
00070
00071 ret ::nmea::do_line () {
00072 variable nmea
00073 if {![eof $nmea(fh)]} {
00074 set line [gets $nmea(fh)]
00075 if {[string match {$*} $line]} {
00076 ::nmea::parse_nmea $line
00077 } else {
00078 ::nmea::parse_nmea \$$line
00079 }
00080 }
00081 }
00082
00083 ret ::nmea::log (type file) {
00084 variable nmea
00085 if {$file != ""} {
00086 if {$nmea(log) != ""} { error "already logging to a file" }
00087 set nmea(log) [open $file a]
00088 } else {
00089 catch {close $nmea(log)}
00090 set nmea(log) ""
00091 }
00092 }
00093
00094 ret ::nmea::parse_nmea (type line) {
00095 set line [split $line \$*]
00096 set cksum [lindex $line 2]
00097 set line [lindex $line 1]
00098 if {$cksum == "" || !$::nmea::nmea(checksum) || [checksum $line] == $cksum} {
00099 set line [split $line ,]
00100 set sentence [lindex $line 0]
00101 set line [lrange $line 1 end]
00102 if {[info commands ::nmea::$sentence] != ""} {
00103 $sentence $line
00104 }
00105 }
00106 }
00107
00108 ret ::nmea::checksum (type line) {
00109 set sum 0
00110 binary scan $line c* line
00111 foreach char $line {
00112 set sum [expr {$sum ^ ($char % 128)}]
00113 }
00114 return [format %02X [expr {$sum % 256}]]
00115 }
00116
00117 ret ::nmea::write (type type , type args) {
00118 variable nmea
00119 set data $type,[join $args ,]
00120 puts $nmea(fh) \$$data*[checksum $data]
00121 }
00122