Created
August 26, 2024 20:10
-
-
Save yath/909b469940ae6ac7707bef0acefb0863 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/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 3*1000] | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment