From 6da7bf8670b31feff95ac6e64ab1c75b1584802b Mon Sep 17 00:00:00 2001 From: "pls.153" Date: Tue, 7 Nov 2023 18:06:17 +0100 Subject: [PATCH] fix/revision of example 'meshtastic' --- examples/meshtastic/hardware/radio.htm | 8 + examples/meshtastic/lisp/location.lisp | 1 + examples/meshtastic/lisp/lora.lisp | 205 +++++++++++++------------ examples/meshtastic/lisp/messages.lisp | 20 ++- examples/meshtastic/lisp/package.lisp | 2 +- 5 files changed, 126 insertions(+), 110 deletions(-) diff --git a/examples/meshtastic/hardware/radio.htm b/examples/meshtastic/hardware/radio.htm index f46bd5c..6cb8902 100644 --- a/examples/meshtastic/hardware/radio.htm +++ b/examples/meshtastic/hardware/radio.htm @@ -25,5 +25,13 @@

All parts above combined cost me around 50€.

I used a soldering iron, a hot glue gun, a step drill bit, double sided tape.

+
+

Antennas

+

+ A good antenna is crucial for the radio to function properly. A NanoVNA is very helpful to test if an antenna is resonant at the specified frequency (otherwise it's useless). You can find good clones for about 50€/$ (beware of really cheap/bad clones). +

+

+ Antennas listed in the RAK store are generally of good/industrial quality. Some other mass produced offerings are of such bad quality that I had to throw them away (after measuring them). +

diff --git a/examples/meshtastic/lisp/location.lisp b/examples/meshtastic/lisp/location.lisp index e40c5bc..720f41d 100644 --- a/examples/meshtastic/lisp/location.lisp +++ b/examples/meshtastic/lisp/location.lisp @@ -78,6 +78,7 @@ (/ (* deg pi) 180)) (defun distance (from to) + (qlog :distance from to) ;; Haversine formula (destructuring-bind ((lat-1 lon-1) (lat-2 lon-2)) (list from to) diff --git a/examples/meshtastic/lisp/lora.lisp b/examples/meshtastic/lisp/lora.lisp index 44d8e0a..04de556 100644 --- a/examples/meshtastic/lisp/lora.lisp +++ b/examples/meshtastic/lisp/lora.lisp @@ -191,107 +191,110 @@ :alt (me:altitude pos) :time (me:time pos)))))) -(defun process-received () - "Walks *RECEIVED* FROM-RADIOs and saves relevant data." - (setf *received* (nreverse *received*)) - (unless *ble-names* - (setf *ble-names* (qt:short-names qt:*cpp*))) - (dolist (struct *received*) - (cond ((me:from-radio.has-packet struct) - (let* ((packet (me:from-radio.packet struct)) - (decoded (me:decoded packet))) - (when decoded - (let ((payload (me:payload decoded))) - (case (me:portnum decoded) - ;; text-message - (:text-message-app - (let ((timestamp (get-universal-time)) - (mid (me:id packet)) - (text (qfrom-utf8 payload))) - (setf msg:*message-id* (max mid msg:*message-id*)) - (if (x:starts-with ":e" text) ; 'echo' - (qsingle-shot 1000 (lambda () (send-message (x:cc "echo:" (subseq text #.(length ":e")))))) - (progn - (when (x:starts-with "echo:" text) - (setf text (msg:echo-message text (me:from packet) (me:rx-snr packet) (me:rx-rssi packet)))) - (msg:add-message - (list :receiver (my-name) - :sender (node-to-name (me:from packet)) - :timestamp timestamp - :hour (timestamp-to-hour timestamp) - :text (add-line-breaks text) - :mid mid)))))) - ;; for :ack-state (acknowledgement state) - (:routing-app - (let ((state (me:routing.error-reason - (pr:deserialize-from-bytes 'me:routing payload)))) - (msg:change-state (case state - (:none - :received) - (t - (qlog "message state changed: ~A" state) - :not-received)) - (me:request-id decoded)))) - ;; GPS location - (:position-app - (unless (zerop (length payload)) - (set-gps-position (me:from packet) - (pr:deserialize-from-bytes 'me:position payload))))))))) - ;; my-info - ((me:from-radio.has-my-info struct) - (setf *my-node-info* (me:my-node-num (me:my-info struct)))) - ;; node-info - ((me:from-radio.has-node-info struct) - (let ((info (me:node-info struct))) - (if (eql *my-node-info* (me:num info)) - (setf *my-node-info* info) - (setf *node-infos* - (nconc *node-infos* (list info)))) - (x:when-it (me:position info) - (set-gps-position (me:num info) x:it)) - (when *schedule-clear* - (radios:clear) - (group:clear)) - (let ((name (me:short-name (me:user info))) - (current (= (me:num info) - (me:num *my-node-info*))) - (metrics (me:device-metrics info))) - (unless current - (group:add-person - (list :radio-name name - :custom-name (or (app:setting name :custom-name) "") - :node-num (me:num info) - :current (equal name (app:setting :latest-receiver))))) - (when (find name *ble-names* :test 'string=) - (setf radios:*found* t) - (radios:add-radio - (list :name name - :hw-model (symbol-name (me:hw-model (me:user info))) - :battery-level (float (if metrics (me:battery-level metrics) 0)) - :current current)) - (when current - (app:change-setting :device name)))))) - ;; channel - ((me:from-radio.has-channel struct) - (let ((channel (me:channel struct))) - (when (eql :primary (me:role channel)) - (setf *my-channel* channel)) - (push channel *channels*))) - ;; config lora - ((me:from-radio.has-config struct) - (let ((config (me:config struct))) - (when (me:config.has-lora config) - (setf *config-lora* (me:lora config))))) - ;; config-complete-id - ((me:from-radio.has-config-complete-id struct) - (when (= *config-id* (me:config-complete-id struct)) - (setf *config-complete* t) - (q> |playing| ui:*busy* nil) - (qlog "config-complete id: ~A" *config-id*) - (unless (string= *my-channel-name* - (me:name (me:settings *my-channel*))) - (qlater 'config-device)))))) - (setf *received* nil)) +(let (echo-text) + (defun process-received () + "Walks *RECEIVED* FROM-RADIOs and saves relevant data." + (setf *received* (nreverse *received*)) + (unless *ble-names* + (setf *ble-names* (qt:short-names qt:*cpp*))) + (dolist (struct *received*) + (cond ((me:from-radio.has-packet struct) + (let* ((packet (me:from-radio.packet struct)) + (decoded (me:decoded packet))) + (when decoded + (let ((payload (me:payload decoded))) + (case (me:portnum decoded) + ;; text-message + (:text-message-app + (let ((timestamp (get-universal-time)) + (mid (me:id packet)) + (text (qfrom-utf8 payload))) + (setf msg:*message-id* (max mid msg:*message-id*)) + (if (x:starts-with ":e" text) ; 'echo' + (progn + (setf echo-text (subseq text #.(length ":e"))) + (qsingle-shot 1000 (lambda () (send-message (x:cc "echo:" echo-text))))) + (progn + (when (x:starts-with "echo:" text) + (setf text (msg:echo-message text (me:from packet) (me:rx-snr packet) (me:rx-rssi packet)))) + (msg:add-message + (list :receiver (my-name) + :sender (node-to-name (me:from packet)) + :timestamp timestamp + :hour (timestamp-to-hour timestamp) + :text (add-line-breaks text) + :mid mid)))))) + ;; for :ack-state (acknowledgement state) + (:routing-app + (let ((state (me:routing.error-reason + (pr:deserialize-from-bytes 'me:routing payload)))) + (msg:change-state (case state + (:none + :received) + (t + (qlog "message state changed: ~A" state) + :not-received)) + (me:request-id decoded)))) + ;; GPS location + (:position-app + (unless (zerop (length payload)) + (set-gps-position (me:from packet) + (pr:deserialize-from-bytes 'me:position payload))))))))) + ;; my-info + ((me:from-radio.has-my-info struct) + (setf *my-node-info* (me:my-node-num (me:my-info struct)))) + ;; node-info + ((me:from-radio.has-node-info struct) + (let ((info (me:node-info struct))) + (if (eql *my-node-info* (me:num info)) + (setf *my-node-info* info) + (setf *node-infos* + (nconc *node-infos* (list info)))) + (x:when-it (me:position info) + (set-gps-position (me:num info) x:it)) + (when *schedule-clear* + (radios:clear) + (group:clear)) + (let ((name (me:short-name (me:user info))) + (current (= (me:num info) + (me:num *my-node-info*))) + (metrics (me:device-metrics info))) + (unless current + (group:add-person + (list :radio-name name + :custom-name (or (app:setting name :custom-name) "") + :node-num (me:num info) + :current (equal name (app:setting :latest-receiver))))) + (when (find name *ble-names* :test 'string=) + (setf radios:*found* t) + (radios:add-radio + (list :name name + :hw-model (symbol-name (me:hw-model (me:user info))) + :battery-level (float (if metrics (me:battery-level metrics) 0)) + :current current)) + (when current + (app:change-setting :device name)))))) + ;; channel + ((me:from-radio.has-channel struct) + (let ((channel (me:channel struct))) + (when (eql :primary (me:role channel)) + (setf *my-channel* channel)) + (push channel *channels*))) + ;; config lora + ((me:from-radio.has-config struct) + (let ((config (me:config struct))) + (when (me:config.has-lora config) + (setf *config-lora* (me:lora config))))) + ;; config-complete-id + ((me:from-radio.has-config-complete-id struct) + (when (= *config-id* (me:config-complete-id struct)) + (setf *config-complete* t) + (q> |playing| ui:*busy* nil) + (qlog "config-complete id: ~A" *config-id*) + (unless (string= *my-channel-name* + (me:name (me:settings *my-channel*))) + (qlater 'config-device)))))) + (setf *received* nil))) (defun send-admin (admin-message) (send-to-radio diff --git a/examples/meshtastic/lisp/messages.lisp b/examples/meshtastic/lisp/messages.lisp index f6c96ae..f0a0ee0 100644 --- a/examples/meshtastic/lisp/messages.lisp +++ b/examples/meshtastic/lisp/messages.lisp @@ -124,15 +124,19 @@ sending an ':e ...' text message, which will be echoed with info about signal strength, position and distance." (let ((from-pos (loc:position* from)) - (my-pos #+mobile (nbutlast (loc:last-gps-position) 1) + (my-pos #+mobile (nbutlast (loc:latest-gps-position) 1) #-mobile nil)) - (format nil "~A~%~%snr: ~F rssi: ~D~%lat: ~,5F lon: ~,5F~%distance: ~:D m" - text snr rssi - (if my-pos (first my-pos) "-") - (if my-pos (second my-pos) "-") - (if (and from-pos my-pos) - (loc:distance my-pos from-pos) - "-")))) + (x:cc (format nil "~A~%~%snr: ~F rssi: ~D" + text snr rssi) + (if my-pos + (format nil "~%lat: ~,5F lon: ~,5F" + (first my-pos) + (second my-pos)) + "") + (if (and my-pos from-pos) + (format nil "~%distance: ~:D m" + (loc:distance my-pos from-pos)) + "")))) (defun swipe-to-left () ; see QML (q> |currentIndex| ui:*main-view* 0) diff --git a/examples/meshtastic/lisp/package.lisp b/examples/meshtastic/lisp/package.lisp index d2d095a..7afcd97 100644 --- a/examples/meshtastic/lisp/package.lisp +++ b/examples/meshtastic/lisp/package.lisp @@ -128,7 +128,7 @@ #:distance #:extract-map-bin #:ini - #:last-gps-position + #:latest-gps-position #:make-map-bin #:position* #:position-count