Compare commits

...

3 Commits

Author SHA1 Message Date
bf7eac5fac parse nmea from socket 2025-05-17 23:23:32 +00:00
59c7b53022 nmea: add GGA, RMC 2025-05-17 23:22:37 +00:00
a687c946d2 nmea: convert empty fields to nil 2025-05-17 23:20:55 +00:00
2 changed files with 81 additions and 16 deletions

View File

@ -1,5 +1,6 @@
; (local { : view } (require :fennel)) ; (local { : view } (require :fennel))
(local { : fdopen } (require :posix.stdio)) (local { : fdopen } (require :posix.stdio))
(local nmea (require :nmea))
(local { (local {
: Gtk : Gtk
@ -71,7 +72,10 @@ label.readout {
(fn read-gnss [socket] (fn read-gnss [socket]
(each [l #(socket:read "l")] (each [l #(socket:read "l")]
(print "gnss" l)) ; (print "gnss" l)
(if (not (= l ""))
(print (view (nmea.parse l)))))
true) true)
(let [sock (gnss-socket:get_socket) (let [sock (gnss-socket:get_socket)

View File

@ -3,9 +3,8 @@
;; 3-5 are the message type ;; 3-5 are the message type
;; fields are comma-delimited ;; fields are comma-delimited
;; we assume that we can parse the message based only on type ;; we can parse the message based only on type (i.e. the same type is
;; (i.e. that the same type should always be parsed the same way no ;; always parsed the same way no matter who the talker)
;; matter who the talker)
;; outline: split message into lines, extract values between ;; outline: split message into lines, extract values between
;; $ and * as talker, type, fields ;; $ and * as talker, type, fields
@ -50,32 +49,92 @@
} }
) )
(local latlon-signs { :N 1 :S -1 :W -1 :E 1 } ) (fn try-number [s]
(if (= s "")
nil
(tonumber s)))
(local (local
msg-types msg-types
{ {
:GGA
(fn [fields]
(let [[utc lat latsign lon lonsign
fix-quality
total-space-vehicles
hdop
altitude _
geoidal-separation _
_ _ ] fields
latf (if (= lat "")
nil
(* (tonumber lat) 0.01 (case latsign :N 1 :S -1)))
lonf (if (= lon "")
nil
(* (tonumber lon) 0.01 (case lonsign :E 1 :W -1)))]
{ :lat latf
:lon lonf
: fix-quality
:total-space-vehicles (try-number total-space-vehicles)
:hdop (try-number hdop)
:altitude (try-number altitude)
:geoidal-separation (try-number geoidal-separation)
}))
:RMC
(fn [[utc valid lat latsign lon lonsign
knots bearing-true date
magn-var magn-var-sign
mode nav-status &as fields]]
(let [latf (if (= lat "")
nil
(* (tonumber lat) 0.01 (case latsign :N 1 :S -1)))
lonf (if (= lon "")
nil
(* (tonumber lon) 0.01 (case lonsign :E 1 :W -1)))
magnetic-variation (if (= magn-var "")
nil
(* (tonumber magn-var)
(case magn-var-sign :E 1 :W -1)))]
{ : utc
: valid
:lat latf
:lon lonf
:speed-knots (try-number knots)
:bearing-true (try-number bearing-true)
: date
: magnetic-variation
: mode
}))
:GNS :GNS
(fn [fields] (fn [fields]
(let [[utc lat latsign lon lonsign mode total-space-vehicles (let [[utc lat latsign lon lonsign mode total-space-vehicles
hdop altitude geoidal-separation _ _ nav-status] fields] hdop altitude geoidal-separation _ _ nav-status] fields
{ :lat (* (/ (tonumber lat) 100) (. latlon-signs latsign)) latf (if (= lat "")
:lon (* (/ (tonumber lon) 100) (. latlon-signs lonsign)) nil
(* (tonumber lat) 0.01 (case latsign :N 1 :S -1)))
lonf (if (= lon "")
nil
(* (tonumber lon) 0.01 (case lonsign :E 1 :W -1)))]
{ :lat latf
:lon lonf
: mode : mode
:total-space-vehicles (tonumber total-space-vehicles) :total-space-vehicles (try-number total-space-vehicles)
:hdop (tonumber hdop) :hdop (try-number hdop)
:altitude (tonumber altitude) :altitude (try-number altitude)
:geoidal-separation (tonumber geoidal-separation) :geoidal-separation (try-number geoidal-separation)
: nav-status : nav-status
} }
)) ))
:VTG :VTG
(fn [[bearing-true _ bearing-mag _ knots _ kmh _ mode]] (fn [[bearing-true _ bearing-mag _ knots _ kmh _ mode]]
{ {
:bearing-true (tonumber bearing-true) :bearing-true (try-number bearing-true)
:bearing-magnetic (tonumber bearing-mag) :bearing-magnetic (try-number bearing-mag)
:speed-knots (tonumber knots) :speed-knots (try-number knots)
:speed-kmh (tonumber kmh) :speed-kmh (try-number kmh)
: mode : mode
} }
) )
@ -117,3 +176,5 @@
:speed-kmh 2.9 :speed-kmh 2.9
:mode :A :mode :A
}) })
{ :parse parse-line }