#!/usr/bin/tclsh | |
# IV-11 doesn’t know about time zones, so doesn’t know about DST, so it’s set | |
# to a UTC offset of 0 and this script sends the local time (as defined by $TZ | |
# or $TCL_TZ, cf. https://www.tcl.tk/man/tcl8.6/TclCmd/clock.htm#M21). | |
package require Tcl 8.5 | |
package require nmea | |
# formats a number decimally as ddd.fff with zero-padding. Basically [format "%0[d].[f]f"]. | |
proc decfmt {num d f} { | |
set numi [expr {entier($num)}] | |
set ret [format "%0${d}d" $numi] | |
if {$f > 0} { | |
set numf [expr {$num-$numi}] | |
set fi [expr {entier($numf * pow(10, $f))}] | |
set ret "$ret.$fi" | |
} | |
return $ret | |
} | |
# converts a decimal, signed coordinate into DEGMM.MMM,[NE] format. | |
proc coord {dec islat} { | |
set dir [expr { ($dec < 0) ? ($islat ? "S" : "E") : ($islat ? "N" : "W") }] | |
set degs [expr { int(abs($dec)) }] | |
set mins [expr { (abs($dec) - $degs) * 60 }] | |
set intwidth [expr {$islat ? 4 : 5}] | |
return "[decfmt [expr { $degs*100 + $mins }] $intwidth 3],$dir" | |
} | |
# converts a decimal latitude with coord. | |
proc lat {dec} { | |
return [coord $dec 1] | |
} | |
# converts a decimal longitude with coord. | |
proc lon {dec} { | |
return [coord $dec 0] | |
} | |
# converts a timestamp in milliseconds from epoch into local HHMMSS.mmm | |
proc localtime {ms} { | |
set ts [expr {$ms/1000}] | |
set micros [decfmt [expr {$ms%1000}] 3 0] | |
return [clock format $ts -format "%H%M%S.$micros"] | |
} | |
# converts a timestamp in milliseconds from epoch into UTC HHMMSS.mmm | |
proc unused_utctime {ms} { | |
set ts [expr {$ms/1000}] | |
set micros [decfmt [expr {$ms%1000}] 3 0] | |
return [clock format $ts -format "%H%M%S.$micros" -timezone :UTC] | |
} | |
# formats a decimal number as meters. | |
proc meters {dec} { | |
return [format {%.1f,M} $dec] | |
} | |
# returns the arguments joined by comma, surrounded with $ and * and the checksum. | |
proc gpsmsg args { | |
set msg [join $args ","] | |
return "\$$msg*[::nmea::checksum $msg]" | |
} | |
# returns a Recommended Minimum Sentence C record (https://www.gpsinformation.org/dale/nmea.htm#RMC). | |
proc gprmc {ts lat lon {speed 0} {angle 0} {magvar 003.1,W}} { | |
set utcdate [clock format $ts -format %d%m%y -timezone :UTC] | |
return [gpsmsg GPRMC [localtime $ts] A [lat $lat] [lon $lon] $speed $angle $utcdate $magvar] | |
} | |
# returns a GPS Fix Data record (https://www.gpsinformation.org/dale/nmea.htm#GGA). | |
proc gpgga {ts lat lon {alt 100} {geoid 50} {quality 1} {nsats 8} {hdop 0.9}} { | |
return [gpsmsg GPGGA [localtime $ts] [lat $lat] [lon $lon] $quality [format %02d $nsats] [format %.1f $hdop] [meters $alt] [meters $geoid] "" ""] | |
} | |
# returns a Geograpgic Latitude and Longitude record (https://www.gpsinformation.org/dale/nmea.htm#GLL). | |
proc gpgll {ts lat lon} { | |
return [gpsmsg GPGLL [lat $lat] [lon $lon] [localtime $ts] A] | |
} | |
# returns a DOP and Active Satellites record (https://www.gpsinformation.org/dale/nmea.htm#GSA). | |
proc gpgsa {pdop hdop vdop {sats {}}} { | |
while {[llength $sats] < 12} { | |
lappend sats "" | |
} | |
return [gpsmsg GPGSA A 3 [join $sats ","] $pdop $hdop $vdop] | |
} | |
set lat 48.0569522 | |
set lon 11.4810454 | |
set dop 1.5 | |
while 1 { | |
set now [expr {[clock milliseconds]-6}] | |
puts [gprmc $now $lat $lon] | |
puts [gpgga $now $lat $lon] | |
puts [gpgll $now $lat $lon] | |
puts [gpgsa $dop $dop $dop] | |
after [expr 30*1000] | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment