mirror of
https://github.com/meshtastic/firmware.git
synced 2026-01-08 10:57:51 +00:00
Compare commits
166 Commits
v2.2.0.9f6
...
v2.2.12.09
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
092e6f2424 | ||
|
|
e6b20bff77 | ||
|
|
2c625f6ba1 | ||
|
|
142d56c663 | ||
|
|
f4b40562d3 | ||
|
|
9e203532d0 | ||
|
|
8bd7b5e779 | ||
|
|
1af970765f | ||
|
|
def55ec063 | ||
|
|
092c6cac66 | ||
|
|
e39f129bd6 | ||
|
|
9d1fe8c245 | ||
|
|
786248a6b1 | ||
|
|
d1ac2dc6ea | ||
|
|
87396d9105 | ||
|
|
10265aabd5 | ||
|
|
8780d93941 | ||
|
|
54f0c045e4 | ||
|
|
3ddad671a5 | ||
|
|
dc6f0b8e0b | ||
|
|
33f28c3d56 | ||
|
|
ef1d8c8eee | ||
|
|
950d5f0946 | ||
|
|
fc06754e1f | ||
|
|
fbf74fc0b2 | ||
|
|
7cebd79475 | ||
|
|
aa38f53aed | ||
|
|
2a6c8be684 | ||
|
|
37c3d15978 | ||
|
|
f301e236eb | ||
|
|
94c2ade272 | ||
|
|
a6e4402e41 | ||
|
|
50db2d0e9b | ||
|
|
5ecdbd0dbb | ||
|
|
47c6738c0d | ||
|
|
1552aa0081 | ||
|
|
6ebec8fcd9 | ||
|
|
e9215a5d70 | ||
|
|
4e3576ae48 | ||
|
|
98290e5d7b | ||
|
|
ad529924f1 | ||
|
|
07d51a2ca4 | ||
|
|
47301a5ac0 | ||
|
|
0d023ea215 | ||
|
|
b5e952db24 | ||
|
|
a1c433748a | ||
|
|
04b2ab82dc | ||
|
|
e96ba7cbcf | ||
|
|
61f6fb22c5 | ||
|
|
db7b77c76e | ||
|
|
350090ec0d | ||
|
|
cdac643749 | ||
|
|
1a2c7f00e1 | ||
|
|
7eff5e7bcb | ||
|
|
17207681ef | ||
|
|
94f7c7e472 | ||
|
|
0a12d67d19 | ||
|
|
3175a3d630 | ||
|
|
4e9bf75340 | ||
|
|
e8970ad66b | ||
|
|
f737ee59ec | ||
|
|
6d211815d9 | ||
|
|
1bae926576 | ||
|
|
a1514b8b64 | ||
|
|
8b82ae6fe3 | ||
|
|
822c150e0d | ||
|
|
0731902744 | ||
|
|
b53cb38a09 | ||
|
|
b02dd0e964 | ||
|
|
c608f0ba81 | ||
|
|
e1839e33f2 | ||
|
|
d6d51bc3f4 | ||
|
|
44a77a10e1 | ||
|
|
8255128eae | ||
|
|
d7a98519f4 | ||
|
|
e256520336 | ||
|
|
fcf798df98 | ||
|
|
dcdf9b64de | ||
|
|
fd563e41f1 | ||
|
|
0fa3685161 | ||
|
|
899f9dd7bf | ||
|
|
9af4ecf48f | ||
|
|
cfb6a1394c | ||
|
|
1254031f7d | ||
|
|
c91e306659 | ||
|
|
4ff343b20f | ||
|
|
134fc75b67 | ||
|
|
fb23e479ac | ||
|
|
5a61695016 | ||
|
|
3bcab0e223 | ||
|
|
17617ce031 | ||
|
|
97f0c734e0 | ||
|
|
e943fffe8c | ||
|
|
ffcb131171 | ||
|
|
bb1fe7cad3 | ||
|
|
ad40493a39 | ||
|
|
ac62330e1c | ||
|
|
53f6a43661 | ||
|
|
7ad94da1c6 | ||
|
|
ecdb75aae0 | ||
|
|
7c98445ca3 | ||
|
|
b21368ecfa | ||
|
|
1a178c7d33 | ||
|
|
5d6f0ea6c4 | ||
|
|
5bd861f3d8 | ||
|
|
6d93fab495 | ||
|
|
6803fd7949 | ||
|
|
a61f969773 | ||
|
|
79cfc4b725 | ||
|
|
cf762bbd42 | ||
|
|
3d2c419d0d | ||
|
|
903f619609 | ||
|
|
2e3f762d3d | ||
|
|
a42266f74b | ||
|
|
a605c69eb4 | ||
|
|
282cc0b16a | ||
|
|
4ab67f3668 | ||
|
|
312028b161 | ||
|
|
ecd48db69c | ||
|
|
03dc36ea12 | ||
|
|
c2ae38405e | ||
|
|
2a1d8c40b4 | ||
|
|
e2441c425a | ||
|
|
00ffe73ebd | ||
|
|
3355019de3 | ||
|
|
5bb207d88b | ||
|
|
5453e4d123 | ||
|
|
7f1b58a222 | ||
|
|
39357b2686 | ||
|
|
d6b629ae04 | ||
|
|
7b1aeb60cd | ||
|
|
5c7c1cd253 | ||
|
|
8cfe130df3 | ||
|
|
feef86942d | ||
|
|
5f3a8b4924 | ||
|
|
0fcaaf39b0 | ||
|
|
a55eac5c20 | ||
|
|
b47c9c165a | ||
|
|
ecceb10910 | ||
|
|
6fc76103a0 | ||
|
|
f35c7be917 | ||
|
|
364364263b | ||
|
|
ef957bfac5 | ||
|
|
5d78795065 | ||
|
|
2dbdda204f | ||
|
|
4767bd5497 | ||
|
|
05efd68097 | ||
|
|
a90eef432f | ||
|
|
929b8f6209 | ||
|
|
5d76771fab | ||
|
|
91eb64d7b7 | ||
|
|
03fe4c629a | ||
|
|
144dfe9805 | ||
|
|
18899fd168 | ||
|
|
fcfd83bc89 | ||
|
|
a3d2b6166c | ||
|
|
fb5f2e48a5 | ||
|
|
d29c975e3c | ||
|
|
c44986127e | ||
|
|
6e0b6684ee | ||
|
|
84ddfea491 | ||
|
|
3d6fb13f9a | ||
|
|
54c48329c8 | ||
|
|
ede31a2080 | ||
|
|
9470d4694b | ||
|
|
2074c76780 |
2
.github/pull_request_template.md
vendored
2
.github/pull_request_template.md
vendored
@@ -7,7 +7,7 @@
|
|||||||
is appreciated." This will allow other devs to potentially save you time by not accidentially duplicating work etc...
|
is appreciated." This will allow other devs to potentially save you time by not accidentially duplicating work etc...
|
||||||
- Please do not check in files that don't have real changes
|
- Please do not check in files that don't have real changes
|
||||||
- Please do not reformat lines that you didn't have to change the code on
|
- Please do not reformat lines that you didn't have to change the code on
|
||||||
- We recommend using the [Visual Studio Code](https://platformio.org/install/ide?install=vscode) editor along with the ['Trunk Check' extension](https://marketplace.visualstudio.com/items?itemName=trunk.io) (WSL2 is required on windows),
|
- We recommend using the [Visual Studio Code](https://platformio.org/install/ide?install=vscode) editor along with the ['Trunk Check' extension](https://marketplace.visualstudio.com/items?itemName=trunk.io) (In beta for windows, WSL2 for the linux version),
|
||||||
because it automatically follows our indentation rules and its auto reformatting will not cause spurious changes to lines.
|
because it automatically follows our indentation rules and its auto reformatting will not cause spurious changes to lines.
|
||||||
- If your PR fixes a bug, mention "fixes #bugnum" somewhere in your pull request description.
|
- If your PR fixes a bug, mention "fixes #bugnum" somewhere in your pull request description.
|
||||||
- If your other co-developers have comments on your PR please tweak as needed.
|
- If your other co-developers have comments on your PR please tweak as needed.
|
||||||
|
|||||||
22
.github/workflows/trunk-check.yml
vendored
Normal file
22
.github/workflows/trunk-check.yml
vendored
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
name: Pull Request
|
||||||
|
on: [pull_request]
|
||||||
|
concurrency:
|
||||||
|
group: ${{ github.head_ref || github.run_id }}
|
||||||
|
cancel-in-progress: true
|
||||||
|
|
||||||
|
permissions: read-all
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
trunk_check:
|
||||||
|
name: Trunk Check Runner
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
permissions:
|
||||||
|
checks: write # For trunk to post annotations
|
||||||
|
contents: read # For repo checkout
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v3
|
||||||
|
|
||||||
|
- name: Trunk Check
|
||||||
|
uses: trunk-io/trunk-action@v1
|
||||||
2
.trunk/.gitignore
vendored
2
.trunk/.gitignore
vendored
@@ -2,7 +2,7 @@
|
|||||||
*logs
|
*logs
|
||||||
*actions
|
*actions
|
||||||
*notifications
|
*notifications
|
||||||
|
*tools
|
||||||
plugins
|
plugins
|
||||||
user_trunk.yaml
|
user_trunk.yaml
|
||||||
user.yaml
|
user.yaml
|
||||||
shims
|
|
||||||
|
|||||||
@@ -1,48 +1,53 @@
|
|||||||
version: 0.1
|
version: 0.1
|
||||||
cli:
|
cli:
|
||||||
version: 1.10.0
|
version: 1.17.0
|
||||||
plugins:
|
plugins:
|
||||||
sources:
|
sources:
|
||||||
- id: trunk
|
- id: trunk
|
||||||
ref: v0.0.17
|
ref: v1.2.5
|
||||||
uri: https://github.com/trunk-io/plugins
|
uri: https://github.com/trunk-io/plugins
|
||||||
lint:
|
lint:
|
||||||
enabled:
|
enabled:
|
||||||
- taplo@0.7.0
|
- bandit@1.7.5
|
||||||
- ruff@0.0.265
|
- checkov@2.5.0
|
||||||
|
- terrascan@1.18.3
|
||||||
|
- trivy@0.45.1
|
||||||
|
- trufflehog@3.59.0
|
||||||
|
- taplo@0.8.1
|
||||||
|
- ruff@0.0.292
|
||||||
- yamllint@1.32.0
|
- yamllint@1.32.0
|
||||||
- isort@5.12.0
|
- isort@5.12.0
|
||||||
- markdownlint@0.34.0
|
- markdownlint@0.37.0
|
||||||
- oxipng@8.0.0
|
- oxipng@8.0.0
|
||||||
- svgo@3.0.2
|
- svgo@3.0.2
|
||||||
- actionlint@1.6.24
|
- actionlint@1.6.26
|
||||||
- flake8@6.0.0
|
- flake8@6.1.0
|
||||||
- hadolint@2.12.0
|
- hadolint@2.12.0
|
||||||
- shfmt@3.5.0
|
- shfmt@3.6.0
|
||||||
- shellcheck@0.9.0
|
- shellcheck@0.9.0
|
||||||
- black@23.3.0
|
- black@23.9.1
|
||||||
- git-diff-check
|
- git-diff-check
|
||||||
- gitleaks@8.16.3
|
- gitleaks@8.18.0
|
||||||
- clang-format@14.0.0
|
- clang-format@16.0.3
|
||||||
- prettier@2.8.8
|
- prettier@3.0.3
|
||||||
disabled:
|
disabled:
|
||||||
- taplo@0.7.0
|
- taplo@0.8.1
|
||||||
- shellcheck@0.9.0
|
- shellcheck@0.9.0
|
||||||
- shfmt@3.5.0
|
- shfmt@3.6.0
|
||||||
- oxipng@8.0.0
|
- oxipng@8.0.0
|
||||||
- actionlint@1.6.22
|
- actionlint@1.6.22
|
||||||
- markdownlint@0.34.0
|
- markdownlint@0.37.0
|
||||||
- hadolint@2.12.0
|
- hadolint@2.12.0
|
||||||
- svgo@3.0.2
|
- svgo@3.0.2
|
||||||
runtimes:
|
runtimes:
|
||||||
enabled:
|
enabled:
|
||||||
- python@3.10.8
|
- python@3.10.8
|
||||||
- go@1.19.5
|
- go@1.21.0
|
||||||
- node@18.12.1
|
- node@18.12.1
|
||||||
actions:
|
actions:
|
||||||
disabled:
|
disabled:
|
||||||
- trunk-announce
|
- trunk-announce
|
||||||
- trunk-check-pre-push
|
|
||||||
- trunk-fmt-pre-commit
|
|
||||||
enabled:
|
enabled:
|
||||||
|
- trunk-fmt-pre-commit
|
||||||
|
- trunk-check-pre-push
|
||||||
- trunk-upgrade-available
|
- trunk-upgrade-available
|
||||||
|
|||||||
@@ -10,8 +10,8 @@
|
|||||||
|
|
||||||
This repository contains the device firmware for the Meshtastic project.
|
This repository contains the device firmware for the Meshtastic project.
|
||||||
|
|
||||||
**[Building Instructions](https://meshtastic.org/docs/development/firmware/build)**
|
- **[Building Instructions](https://meshtastic.org/docs/development/firmware/build)**
|
||||||
**[Flashing Instructions](https://meshtastic.org/docs/getting-started/flashing-firmware/)**
|
- **[Flashing Instructions](https://meshtastic.org/docs/getting-started/flashing-firmware/)**
|
||||||
|
|
||||||
## Stats
|
## Stats
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
; Common settings for ESP targes, mixin with extends = esp32_base
|
; Common settings for ESP targes, mixin with extends = esp32_base
|
||||||
[esp32_base]
|
[esp32_base]
|
||||||
extends = arduino_base
|
extends = arduino_base
|
||||||
platform = platformio/espressif32@^6.3.2
|
platform = platformio/espressif32@6.3.2 # This is a temporary fix to the S3-based devices bluetooth issues until we can determine what within ESP-IDF changed and can develop a suitable patch.
|
||||||
|
|
||||||
build_src_filter =
|
build_src_filter =
|
||||||
${arduino_base.build_src_filter} -<platform/nrf52/> -<platform/stm32wl> -<platform/rp2040> -<mesh/eth/>
|
${arduino_base.build_src_filter} -<platform/nrf52/> -<platform/stm32wl> -<platform/rp2040> -<mesh/eth/>
|
||||||
@@ -30,6 +30,7 @@ build_flags =
|
|||||||
-DCONFIG_BT_NIMBLE_MAX_CCCDS=20
|
-DCONFIG_BT_NIMBLE_MAX_CCCDS=20
|
||||||
-DCONFIG_BT_NIMBLE_HOST_TASK_STACK_SIZE=5120
|
-DCONFIG_BT_NIMBLE_HOST_TASK_STACK_SIZE=5120
|
||||||
-DESP_OPENSSL_SUPPRESS_LEGACY_WARNING
|
-DESP_OPENSSL_SUPPRESS_LEGACY_WARNING
|
||||||
|
-DSERIAL_BUFFER_SIZE=4096
|
||||||
;-DDEBUG_HEAP
|
;-DDEBUG_HEAP
|
||||||
|
|
||||||
lib_deps =
|
lib_deps =
|
||||||
@@ -37,7 +38,7 @@ lib_deps =
|
|||||||
${networking_base.lib_deps}
|
${networking_base.lib_deps}
|
||||||
${environmental_base.lib_deps}
|
${environmental_base.lib_deps}
|
||||||
https://github.com/meshtastic/esp32_https_server.git#23665b3adc080a311dcbb586ed5941b5f94d6ea2
|
https://github.com/meshtastic/esp32_https_server.git#23665b3adc080a311dcbb586ed5941b5f94d6ea2
|
||||||
h2zero/NimBLE-Arduino@^1.4.0
|
h2zero/NimBLE-Arduino@^1.4.1
|
||||||
jgromes/RadioLib@^6.1.0
|
jgromes/RadioLib@^6.1.0
|
||||||
https://github.com/lewisxhe/XPowersLib.git#84b7373faea3118b6c37954d52f98b8a337148d6
|
https://github.com/lewisxhe/XPowersLib.git#84b7373faea3118b6c37954d52f98b8a337148d6
|
||||||
https://github.com/meshtastic/ESP32_Codec2.git#633326c78ac251c059ab3a8c430fcdf25b41672f
|
https://github.com/meshtastic/ESP32_Codec2.git#633326c78ac251c059ab3a8c430fcdf25b41672f
|
||||||
@@ -56,4 +57,4 @@ lib_ignore =
|
|||||||
|
|
||||||
; customize the partition table
|
; customize the partition table
|
||||||
; http://docs.platformio.org/en/latest/platforms/espressif32.html#partition-tables
|
; http://docs.platformio.org/en/latest/platforms/espressif32.html#partition-tables
|
||||||
board_build.partitions = partition-table.csv
|
board_build.partitions = partition-table.csv
|
||||||
|
|||||||
@@ -4,23 +4,23 @@
|
|||||||
|
|
||||||
set -e
|
set -e
|
||||||
|
|
||||||
VERSION=`bin/buildinfo.py long`
|
VERSION=$(bin/buildinfo.py long)
|
||||||
|
|
||||||
# The shell vars the build tool expects to find
|
# The shell vars the build tool expects to find
|
||||||
export APP_VERSION=$VERSION
|
export APP_VERSION=$VERSION
|
||||||
|
|
||||||
if [[ $# -gt 0 ]]; then
|
if [[ $# -gt 0 ]]; then
|
||||||
# can override which environment by passing arg
|
# can override which environment by passing arg
|
||||||
BOARDS="$@"
|
BOARDS="$@"
|
||||||
else
|
else
|
||||||
BOARDS="tlora-v2 tlora-v1 tlora_v1_3 tlora-v2-1-1.6 tbeam heltec-v1 heltec-v2.0 heltec-v2.1 tbeam0.7 meshtastic-diy-v1 rak4631 rak4631_eink rak11200 t-echo pca10059_diy_eink"
|
BOARDS="tlora-v2 tlora-v1 tlora_v1_3 tlora-v2-1-1.6 tbeam heltec-v1 heltec-v2.0 heltec-v2.1 tbeam0.7 meshtastic-diy-v1 rak4631 rak4631_eink rak11200 t-echo pca10059_diy_eink"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
echo "BOARDS:${BOARDS}"
|
echo "BOARDS:${BOARDS}"
|
||||||
|
|
||||||
CHECK=""
|
CHECK=""
|
||||||
for BOARD in $BOARDS; do
|
for BOARD in $BOARDS; do
|
||||||
CHECK="${CHECK} -e ${BOARD}"
|
CHECK="${CHECK} -e ${BOARD}"
|
||||||
done
|
done
|
||||||
|
|
||||||
pio check --flags "-DAPP_VERSION=${APP_VERSION} --suppressions-list=suppressions.txt" $CHECK --skip-packages --pattern="src/" --fail-on-defect=low --fail-on-defect=medium --fail-on-defect=high
|
pio check --flags "-DAPP_VERSION=${APP_VERSION} --suppressions-list=suppressions.txt" $CHECK --skip-packages --pattern="src/" --fail-on-defect=medium --fail-on-defect=high
|
||||||
|
|||||||
@@ -1,7 +1,8 @@
|
|||||||
{
|
{
|
||||||
"build": {
|
"build": {
|
||||||
"arduino": {
|
"arduino": {
|
||||||
"ldscript": "esp32s3_out.ld"
|
"ldscript": "esp32s3_out.ld",
|
||||||
|
"memory_type": "qio_opi"
|
||||||
},
|
},
|
||||||
"core": "esp32",
|
"core": "esp32",
|
||||||
"extra_flags": [
|
"extra_flags": [
|
||||||
@@ -13,7 +14,7 @@
|
|||||||
],
|
],
|
||||||
"f_cpu": "240000000L",
|
"f_cpu": "240000000L",
|
||||||
"f_flash": "80000000L",
|
"f_flash": "80000000L",
|
||||||
"flash_mode": "dio",
|
"flash_mode": "qio",
|
||||||
"hwids": [["0x303A", "0x1001"]],
|
"hwids": [["0x303A", "0x1001"]],
|
||||||
"mcu": "esp32s3",
|
"mcu": "esp32s3",
|
||||||
"variant": "t-deck"
|
"variant": "t-deck"
|
||||||
|
|||||||
@@ -1,7 +1,8 @@
|
|||||||
{
|
{
|
||||||
"build": {
|
"build": {
|
||||||
"arduino": {
|
"arduino": {
|
||||||
"ldscript": "esp32s3_out.ld"
|
"ldscript": "esp32s3_out.ld",
|
||||||
|
"memory_type": "qio_opi"
|
||||||
},
|
},
|
||||||
"core": "esp32",
|
"core": "esp32",
|
||||||
"extra_flags": [
|
"extra_flags": [
|
||||||
@@ -14,7 +15,7 @@
|
|||||||
],
|
],
|
||||||
"f_cpu": "240000000L",
|
"f_cpu": "240000000L",
|
||||||
"f_flash": "80000000L",
|
"f_flash": "80000000L",
|
||||||
"flash_mode": "dio",
|
"flash_mode": "qio",
|
||||||
"hwids": [["0x303A", "0x1001"]],
|
"hwids": [["0x303A", "0x1001"]],
|
||||||
"mcu": "esp32s3",
|
"mcu": "esp32s3",
|
||||||
"variant": "t-watch-s3"
|
"variant": "t-watch-s3"
|
||||||
@@ -31,8 +32,9 @@
|
|||||||
"maximum_size": 8388608,
|
"maximum_size": 8388608,
|
||||||
"require_upload_port": true,
|
"require_upload_port": true,
|
||||||
"use_1200bps_touch": true,
|
"use_1200bps_touch": true,
|
||||||
"wait_for_upload_port": true
|
"wait_for_upload_port": true,
|
||||||
|
"speed": 921600
|
||||||
},
|
},
|
||||||
"url": "http://www.lilygo.cn/",
|
"url": "https://www.lilygo.cc/en-pl/products/t-watch-s3",
|
||||||
"vendor": "LilyGo"
|
"vendor": "LilyGo"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,7 +15,7 @@
|
|||||||
"f_cpu": "240000000L",
|
"f_cpu": "240000000L",
|
||||||
"f_flash": "80000000L",
|
"f_flash": "80000000L",
|
||||||
"flash_mode": "dio",
|
"flash_mode": "dio",
|
||||||
"hwids": [["0X303A", "0x1001"]],
|
"hwids": [["0x303A", "0x1001"]],
|
||||||
"mcu": "esp32s3",
|
"mcu": "esp32s3",
|
||||||
"variant": "tbeam-s3-core"
|
"variant": "tbeam-s3-core"
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -70,7 +70,7 @@ lib_deps =
|
|||||||
https://github.com/meshtastic/esp8266-oled-ssd1306.git#b38094e03dfa964fbc0e799bc374e91a605c1223 ; ESP8266_SSD1306
|
https://github.com/meshtastic/esp8266-oled-ssd1306.git#b38094e03dfa964fbc0e799bc374e91a605c1223 ; ESP8266_SSD1306
|
||||||
https://github.com/mathertel/OneButton#2.1.0 ; OneButton library for non-blocking button debounce
|
https://github.com/mathertel/OneButton#2.1.0 ; OneButton library for non-blocking button debounce
|
||||||
https://github.com/meshtastic/arduino-fsm.git#7db3702bf0cfe97b783d6c72595e3f38e0b19159
|
https://github.com/meshtastic/arduino-fsm.git#7db3702bf0cfe97b783d6c72595e3f38e0b19159
|
||||||
https://github.com/meshtastic/TinyGPSPlus.git#127ad674ef85f0201cb68a065879653ed94792c4
|
https://github.com/meshtastic/TinyGPSPlus.git#076e8d2c8fb702d9be5b08c55b93ff76f8af7e61
|
||||||
https://github.com/meshtastic/ArduinoThread.git#72921ac222eed6f526ba1682023cee290d9aa1b3
|
https://github.com/meshtastic/ArduinoThread.git#72921ac222eed6f526ba1682023cee290d9aa1b3
|
||||||
nanopb/Nanopb@^0.4.7
|
nanopb/Nanopb@^0.4.7
|
||||||
erriez/ErriezCRC32@^1.0.1
|
erriez/ErriezCRC32@^1.0.1
|
||||||
|
|||||||
Submodule protobufs updated: d473009659...6290ee0f6a
75
src/AmbientLightingThread.h
Normal file
75
src/AmbientLightingThread.h
Normal file
@@ -0,0 +1,75 @@
|
|||||||
|
#include "configuration.h"
|
||||||
|
|
||||||
|
#ifdef HAS_NCP5623
|
||||||
|
#include <graphics/RAKled.h>
|
||||||
|
NCP5623 rgb;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
namespace concurrency
|
||||||
|
{
|
||||||
|
class AmbientLightingThread : public concurrency::OSThread
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
AmbientLightingThread(ScanI2C::DeviceType type) : OSThread("AmbientLightingThread")
|
||||||
|
{
|
||||||
|
// Uncomment to test module
|
||||||
|
// moduleConfig.ambient_lighting.led_state = true;
|
||||||
|
// moduleConfig.ambient_lighting.current = 10;
|
||||||
|
// // Default to a color based on our node number
|
||||||
|
// moduleConfig.ambient_lighting.red = (myNodeInfo.my_node_num & 0xFF0000) >> 16;
|
||||||
|
// moduleConfig.ambient_lighting.green = (myNodeInfo.my_node_num & 0x00FF00) >> 8;
|
||||||
|
// moduleConfig.ambient_lighting.blue = myNodeInfo.my_node_num & 0x0000FF;
|
||||||
|
|
||||||
|
#ifdef HAS_NCP5623
|
||||||
|
_type = type;
|
||||||
|
if (_type == ScanI2C::DeviceType::NONE) {
|
||||||
|
LOG_DEBUG("AmbientLightingThread disabling due to no RGB leds found on I2C bus\n");
|
||||||
|
disable();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!moduleConfig.ambient_lighting.led_state) {
|
||||||
|
LOG_DEBUG("AmbientLightingThread disabling due to moduleConfig.ambient_lighting.led_state OFF\n");
|
||||||
|
disable();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
LOG_DEBUG("AmbientLightingThread initializing\n");
|
||||||
|
if (_type == ScanI2C::NCP5623) {
|
||||||
|
rgb.begin();
|
||||||
|
setLighting();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
int32_t runOnce() override
|
||||||
|
{
|
||||||
|
#ifdef HAS_NCP5623
|
||||||
|
if (_type == ScanI2C::NCP5623 && moduleConfig.ambient_lighting.led_state) {
|
||||||
|
setLighting();
|
||||||
|
return 30000; // 30 seconds to reset from any animations that may have been running from Ext. Notification
|
||||||
|
} else {
|
||||||
|
return disable();
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
return disable();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
ScanI2C::DeviceType _type = ScanI2C::DeviceType::NONE;
|
||||||
|
|
||||||
|
void setLighting()
|
||||||
|
{
|
||||||
|
#ifdef HAS_NCP5623
|
||||||
|
rgb.setCurrent(moduleConfig.ambient_lighting.current);
|
||||||
|
rgb.setRed(moduleConfig.ambient_lighting.red);
|
||||||
|
rgb.setGreen(moduleConfig.ambient_lighting.green);
|
||||||
|
rgb.setBlue(moduleConfig.ambient_lighting.blue);
|
||||||
|
LOG_DEBUG("Initializing Ambient lighting w/ current=%d, red=%d, green=%d, blue=%d\n",
|
||||||
|
moduleConfig.ambient_lighting.current, moduleConfig.ambient_lighting.red, moduleConfig.ambient_lighting.green,
|
||||||
|
moduleConfig.ambient_lighting.blue);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace concurrency
|
||||||
@@ -164,15 +164,17 @@ class ButtonThread : public concurrency::OSThread
|
|||||||
|
|
||||||
static void userButtonMultiPressed()
|
static void userButtonMultiPressed()
|
||||||
{
|
{
|
||||||
#if defined(GPS_POWER_TOGGLE)
|
if (!config.device.disable_triple_click && (gps != nullptr)) {
|
||||||
if (config.position.gps_enabled) {
|
config.position.gps_enabled = !(config.position.gps_enabled);
|
||||||
LOG_DEBUG("Flag set to false for gps power\n");
|
if (config.position.gps_enabled) {
|
||||||
} else {
|
LOG_DEBUG("Flag set to true to restore power\n");
|
||||||
LOG_DEBUG("Flag set to true to restore power\n");
|
gps->enable();
|
||||||
|
|
||||||
|
} else {
|
||||||
|
LOG_DEBUG("Flag set to false for gps power\n");
|
||||||
|
gps->disable();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
config.position.gps_enabled = !(config.position.gps_enabled);
|
|
||||||
doGPSpowersave(config.position.gps_enabled);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void userButtonPressedLongStart()
|
static void userButtonPressedLongStart()
|
||||||
|
|||||||
34
src/DisplayFormatters.cpp
Normal file
34
src/DisplayFormatters.cpp
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
#include "DisplayFormatters.h"
|
||||||
|
|
||||||
|
const char *DisplayFormatters::getModemPresetDisplayName(meshtastic_Config_LoRaConfig_ModemPreset preset, bool useShortName)
|
||||||
|
{
|
||||||
|
switch (preset) {
|
||||||
|
case meshtastic_Config_LoRaConfig_ModemPreset_SHORT_SLOW:
|
||||||
|
return useShortName ? "ShortS" : "ShortSlow";
|
||||||
|
break;
|
||||||
|
case meshtastic_Config_LoRaConfig_ModemPreset_SHORT_FAST:
|
||||||
|
return useShortName ? "ShortF" : "ShortFast";
|
||||||
|
break;
|
||||||
|
case meshtastic_Config_LoRaConfig_ModemPreset_MEDIUM_SLOW:
|
||||||
|
return useShortName ? "MedS" : "MediumSlow";
|
||||||
|
break;
|
||||||
|
case meshtastic_Config_LoRaConfig_ModemPreset_MEDIUM_FAST:
|
||||||
|
return useShortName ? "MedF" : "MediumFast";
|
||||||
|
break;
|
||||||
|
case meshtastic_Config_LoRaConfig_ModemPreset_LONG_SLOW:
|
||||||
|
return useShortName ? "LongS" : "LongSlow";
|
||||||
|
break;
|
||||||
|
case meshtastic_Config_LoRaConfig_ModemPreset_LONG_FAST:
|
||||||
|
return useShortName ? "LongF" : "LongFast";
|
||||||
|
break;
|
||||||
|
case meshtastic_Config_LoRaConfig_ModemPreset_LONG_MODERATE:
|
||||||
|
return useShortName ? "LongM" : "LongMod";
|
||||||
|
break;
|
||||||
|
case meshtastic_Config_LoRaConfig_ModemPreset_VERY_LONG_SLOW:
|
||||||
|
return useShortName ? "VeryL" : "VLongSlow";
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return useShortName ? "Custom" : "Invalid";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
8
src/DisplayFormatters.h
Normal file
8
src/DisplayFormatters.h
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
#pragma once
|
||||||
|
#include "NodeDB.h"
|
||||||
|
|
||||||
|
class DisplayFormatters
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static const char *getModemPresetDisplayName(meshtastic_Config_LoRaConfig_ModemPreset preset, bool useShortName);
|
||||||
|
};
|
||||||
@@ -16,8 +16,8 @@
|
|||||||
#include "buzz/buzz.h"
|
#include "buzz/buzz.h"
|
||||||
#include "configuration.h"
|
#include "configuration.h"
|
||||||
#include "main.h"
|
#include "main.h"
|
||||||
|
#include "meshUtils.h"
|
||||||
#include "sleep.h"
|
#include "sleep.h"
|
||||||
#include "utils.h"
|
|
||||||
|
|
||||||
#ifdef DEBUG_HEAP_MQTT
|
#ifdef DEBUG_HEAP_MQTT
|
||||||
#include "mqtt/MQTT.h"
|
#include "mqtt/MQTT.h"
|
||||||
@@ -175,9 +175,21 @@ class AnalogBatteryLevel : public HasBatteryLevel
|
|||||||
uint32_t raw = 0;
|
uint32_t raw = 0;
|
||||||
#ifdef ARCH_ESP32
|
#ifdef ARCH_ESP32
|
||||||
#ifndef BAT_MEASURE_ADC_UNIT // ADC1
|
#ifndef BAT_MEASURE_ADC_UNIT // ADC1
|
||||||
|
#ifdef ADC_CTRL
|
||||||
|
if (heltec_version == 5) {
|
||||||
|
pinMode(ADC_CTRL, OUTPUT);
|
||||||
|
digitalWrite(ADC_CTRL, HIGH);
|
||||||
|
delay(10);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
for (int i = 0; i < BATTERY_SENSE_SAMPLES; i++) {
|
for (int i = 0; i < BATTERY_SENSE_SAMPLES; i++) {
|
||||||
raw += adc1_get_raw(adc_channel);
|
raw += adc1_get_raw(adc_channel);
|
||||||
}
|
}
|
||||||
|
#ifdef ADC_CTRL
|
||||||
|
if (heltec_version == 5) {
|
||||||
|
digitalWrite(ADC_CTRL, LOW);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
#else // ADC2
|
#else // ADC2
|
||||||
int32_t adc_buf = 0;
|
int32_t adc_buf = 0;
|
||||||
for (int i = 0; i < BATTERY_SENSE_SAMPLES; i++) {
|
for (int i = 0; i < BATTERY_SENSE_SAMPLES; i++) {
|
||||||
@@ -221,10 +233,7 @@ class AnalogBatteryLevel : public HasBatteryLevel
|
|||||||
/**
|
/**
|
||||||
* return true if there is a battery installed in this unit
|
* return true if there is a battery installed in this unit
|
||||||
*/
|
*/
|
||||||
virtual bool isBatteryConnect() override
|
virtual bool isBatteryConnect() override { return getBatteryPercent() != -1; }
|
||||||
{
|
|
||||||
return getBatteryPercent() != -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// If we see a battery voltage higher than physics allows - assume charger is pumping
|
/// If we see a battery voltage higher than physics allows - assume charger is pumping
|
||||||
/// in power
|
/// in power
|
||||||
@@ -245,10 +254,7 @@ class AnalogBatteryLevel : public HasBatteryLevel
|
|||||||
|
|
||||||
/// Assume charging if we have a battery and external power is connected.
|
/// Assume charging if we have a battery and external power is connected.
|
||||||
/// we can't be smart enough to say 'full'?
|
/// we can't be smart enough to say 'full'?
|
||||||
virtual bool isCharging() override
|
virtual bool isCharging() override { return isBatteryConnect() && isVbusIn(); }
|
||||||
{
|
|
||||||
return isBatteryConnect() && isVbusIn();
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/// If we see a battery voltage higher than physics allows - assume charger is pumping
|
/// If we see a battery voltage higher than physics allows - assume charger is pumping
|
||||||
@@ -275,9 +281,10 @@ class AnalogBatteryLevel : public HasBatteryLevel
|
|||||||
#if defined(HAS_TELEMETRY) && !defined(ARCH_PORTDUINO)
|
#if defined(HAS_TELEMETRY) && !defined(ARCH_PORTDUINO)
|
||||||
uint16_t getINAVoltage()
|
uint16_t getINAVoltage()
|
||||||
{
|
{
|
||||||
if (nodeTelemetrySensorsMap[meshtastic_TelemetrySensorType_INA219] == config.power.device_battery_ina_address) {
|
if (nodeTelemetrySensorsMap[meshtastic_TelemetrySensorType_INA219].first == config.power.device_battery_ina_address) {
|
||||||
return ina219Sensor.getBusVoltageMv();
|
return ina219Sensor.getBusVoltageMv();
|
||||||
} else if (nodeTelemetrySensorsMap[meshtastic_TelemetrySensorType_INA260] == config.power.device_battery_ina_address) {
|
} else if (nodeTelemetrySensorsMap[meshtastic_TelemetrySensorType_INA260].first ==
|
||||||
|
config.power.device_battery_ina_address) {
|
||||||
return ina260Sensor.getBusVoltageMv();
|
return ina260Sensor.getBusVoltageMv();
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
@@ -288,11 +295,12 @@ class AnalogBatteryLevel : public HasBatteryLevel
|
|||||||
if (!config.power.device_battery_ina_address) {
|
if (!config.power.device_battery_ina_address) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (nodeTelemetrySensorsMap[meshtastic_TelemetrySensorType_INA219] == config.power.device_battery_ina_address) {
|
if (nodeTelemetrySensorsMap[meshtastic_TelemetrySensorType_INA219].first == config.power.device_battery_ina_address) {
|
||||||
if (!ina219Sensor.isInitialized())
|
if (!ina219Sensor.isInitialized())
|
||||||
return ina219Sensor.runOnce() > 0;
|
return ina219Sensor.runOnce() > 0;
|
||||||
return ina219Sensor.isRunning();
|
return ina219Sensor.isRunning();
|
||||||
} else if (nodeTelemetrySensorsMap[meshtastic_TelemetrySensorType_INA260] == config.power.device_battery_ina_address) {
|
} else if (nodeTelemetrySensorsMap[meshtastic_TelemetrySensorType_INA260].first ==
|
||||||
|
config.power.device_battery_ina_address) {
|
||||||
if (!ina260Sensor.isInitialized())
|
if (!ina260Sensor.isInitialized())
|
||||||
return ina260Sensor.runOnce() > 0;
|
return ina260Sensor.runOnce() > 0;
|
||||||
return ina260Sensor.isRunning();
|
return ina260Sensor.isRunning();
|
||||||
@@ -420,7 +428,7 @@ void Power::shutdown()
|
|||||||
#ifdef PIN_LED3
|
#ifdef PIN_LED3
|
||||||
ledOff(PIN_LED2);
|
ledOff(PIN_LED2);
|
||||||
#endif
|
#endif
|
||||||
doDeepSleep(DELAY_FOREVER);
|
doDeepSleep(DELAY_FOREVER, false);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -8,7 +8,6 @@
|
|||||||
* actions to be taken upon entering or exiting each state.
|
* actions to be taken upon entering or exiting each state.
|
||||||
*/
|
*/
|
||||||
#include "PowerFSM.h"
|
#include "PowerFSM.h"
|
||||||
#include "GPS.h"
|
|
||||||
#include "MeshService.h"
|
#include "MeshService.h"
|
||||||
#include "NodeDB.h"
|
#include "NodeDB.h"
|
||||||
#include "configuration.h"
|
#include "configuration.h"
|
||||||
@@ -46,7 +45,7 @@ static void sdsEnter()
|
|||||||
{
|
{
|
||||||
LOG_DEBUG("Enter state: SDS\n");
|
LOG_DEBUG("Enter state: SDS\n");
|
||||||
// FIXME - make sure GPS and LORA radio are off first - because we want close to zero current draw
|
// FIXME - make sure GPS and LORA radio are off first - because we want close to zero current draw
|
||||||
doDeepSleep(getConfiguredOrDefaultMs(config.power.sds_secs));
|
doDeepSleep(getConfiguredOrDefaultMs(config.power.sds_secs), false);
|
||||||
}
|
}
|
||||||
|
|
||||||
extern Power *power;
|
extern Power *power;
|
||||||
@@ -137,9 +136,6 @@ static void lsIdle()
|
|||||||
static void lsExit()
|
static void lsExit()
|
||||||
{
|
{
|
||||||
LOG_INFO("Exit state: LS\n");
|
LOG_INFO("Exit state: LS\n");
|
||||||
// setGPSPower(true); // restore GPS power
|
|
||||||
if (gps)
|
|
||||||
gps->forceWake(true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void nbEnter()
|
static void nbEnter()
|
||||||
@@ -177,7 +173,7 @@ static void serialExit()
|
|||||||
|
|
||||||
static void powerEnter()
|
static void powerEnter()
|
||||||
{
|
{
|
||||||
LOG_DEBUG("Enter state: POWER\n");
|
// LOG_DEBUG("Enter state: POWER\n");
|
||||||
if (!isPowered()) {
|
if (!isPowered()) {
|
||||||
// If we got here, we are in the wrong state - we should be in powered, let that state ahndle things
|
// If we got here, we are in the wrong state - we should be in powered, let that state ahndle things
|
||||||
LOG_INFO("Loss of power in Powered\n");
|
LOG_INFO("Loss of power in Powered\n");
|
||||||
@@ -249,6 +245,8 @@ Fsm powerFSM(&stateBOOT);
|
|||||||
void PowerFSM_setup()
|
void PowerFSM_setup()
|
||||||
{
|
{
|
||||||
bool isRouter = (config.device.role == meshtastic_Config_DeviceConfig_Role_ROUTER ? 1 : 0);
|
bool isRouter = (config.device.role == meshtastic_Config_DeviceConfig_Role_ROUTER ? 1 : 0);
|
||||||
|
bool isTrackerOrSensor = config.device.role == meshtastic_Config_DeviceConfig_Role_TRACKER ||
|
||||||
|
config.device.role == meshtastic_Config_DeviceConfig_Role_SENSOR;
|
||||||
bool hasPower = isPowered();
|
bool hasPower = isPowered();
|
||||||
|
|
||||||
LOG_INFO("PowerFSM init, USB power=%d\n", hasPower ? 1 : 0);
|
LOG_INFO("PowerFSM init, USB power=%d\n", hasPower ? 1 : 0);
|
||||||
@@ -352,12 +350,12 @@ void PowerFSM_setup()
|
|||||||
getConfiguredOrDefaultMs(config.display.screen_on_secs, default_screen_on_secs), NULL,
|
getConfiguredOrDefaultMs(config.display.screen_on_secs, default_screen_on_secs), NULL,
|
||||||
"Screen-on timeout");
|
"Screen-on timeout");
|
||||||
|
|
||||||
|
// We never enter light-sleep or NB states on NRF52 (because the CPU uses so little power normally)
|
||||||
#ifdef ARCH_ESP32
|
#ifdef ARCH_ESP32
|
||||||
State *lowPowerState = &stateLS;
|
|
||||||
// We never enter light-sleep or NB states on NRF52 (because the CPU uses so little power normally)
|
|
||||||
|
|
||||||
// See: https://github.com/meshtastic/firmware/issues/1071
|
// See: https://github.com/meshtastic/firmware/issues/1071
|
||||||
if (isRouter || config.power.is_power_saving) {
|
// Don't add power saving transitions if we are a power saving tracker or sensor. Sleep will be initiatiated through the
|
||||||
|
// modules
|
||||||
|
if ((isRouter || config.power.is_power_saving) && !isTrackerOrSensor) {
|
||||||
powerFSM.add_timed_transition(&stateNB, &stateLS,
|
powerFSM.add_timed_transition(&stateNB, &stateLS,
|
||||||
getConfiguredOrDefaultMs(config.power.min_wake_secs, default_min_wake_secs), NULL,
|
getConfiguredOrDefaultMs(config.power.min_wake_secs, default_min_wake_secs), NULL,
|
||||||
"Min wake timeout");
|
"Min wake timeout");
|
||||||
@@ -365,10 +363,6 @@ void PowerFSM_setup()
|
|||||||
getConfiguredOrDefaultMs(config.power.wait_bluetooth_secs, default_wait_bluetooth_secs),
|
getConfiguredOrDefaultMs(config.power.wait_bluetooth_secs, default_wait_bluetooth_secs),
|
||||||
NULL, "Bluetooth timeout");
|
NULL, "Bluetooth timeout");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (config.power.sds_secs != UINT32_MAX)
|
|
||||||
powerFSM.add_timed_transition(lowPowerState, &stateSDS, getConfiguredOrDefaultMs(config.power.sds_secs), NULL,
|
|
||||||
"mesh timeout");
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
powerFSM.run_machine(); // run one iteration of the state machine, so we run our on enter tasks for the initial DARK state
|
powerFSM.run_machine(); // run one iteration of the state machine, so we run our on enter tasks for the initial DARK state
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ class PowerFSMThread : public OSThread
|
|||||||
|
|
||||||
/// If we are in power state we force the CPU to wake every 10ms to check for serial characters (we don't yet wake
|
/// If we are in power state we force the CPU to wake every 10ms to check for serial characters (we don't yet wake
|
||||||
/// cpu for serial rx - FIXME)
|
/// cpu for serial rx - FIXME)
|
||||||
auto state = powerFSM.getState();
|
const auto state = powerFSM.getState();
|
||||||
canSleep = (state != &statePOWER) && (state != &stateSERIAL);
|
canSleep = (state != &statePOWER) && (state != &stateSERIAL);
|
||||||
|
|
||||||
if (powerStatus->getHasUSB()) {
|
if (powerStatus->getHasUSB()) {
|
||||||
|
|||||||
@@ -18,6 +18,12 @@ NoopPrint noopPrint;
|
|||||||
#if HAS_WIFI || HAS_ETHERNET
|
#if HAS_WIFI || HAS_ETHERNET
|
||||||
extern Syslog syslog;
|
extern Syslog syslog;
|
||||||
#endif
|
#endif
|
||||||
|
void RedirectablePrint::rpInit()
|
||||||
|
{
|
||||||
|
#ifdef HAS_FREE_RTOS
|
||||||
|
inDebugPrint = xSemaphoreCreateMutexStatic(&this->_MutexStorageSpace);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
void RedirectablePrint::setDestination(Print *_dest)
|
void RedirectablePrint::setDestination(Print *_dest)
|
||||||
{
|
{
|
||||||
@@ -66,9 +72,12 @@ size_t RedirectablePrint::log(const char *logLevel, const char *format, ...)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
size_t r = 0;
|
size_t r = 0;
|
||||||
|
#ifdef HAS_FREE_RTOS
|
||||||
|
if (inDebugPrint != nullptr && xSemaphoreTake(inDebugPrint, portMAX_DELAY) == pdTRUE) {
|
||||||
|
#else
|
||||||
if (!inDebugPrint) {
|
if (!inDebugPrint) {
|
||||||
inDebugPrint = true;
|
inDebugPrint = true;
|
||||||
|
#endif
|
||||||
|
|
||||||
va_list arg;
|
va_list arg;
|
||||||
va_start(arg, format);
|
va_start(arg, format);
|
||||||
@@ -141,7 +150,11 @@ size_t RedirectablePrint::log(const char *logLevel, const char *format, ...)
|
|||||||
va_end(arg);
|
va_end(arg);
|
||||||
|
|
||||||
isContinuationMessage = !hasNewline;
|
isContinuationMessage = !hasNewline;
|
||||||
|
#ifdef HAS_FREE_RTOS
|
||||||
|
xSemaphoreGive(inDebugPrint);
|
||||||
|
#else
|
||||||
inDebugPrint = false;
|
inDebugPrint = false;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
return r;
|
return r;
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "../freertosinc.h"
|
||||||
#include <Print.h>
|
#include <Print.h>
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
#include <string>
|
#include <string>
|
||||||
@@ -16,14 +17,19 @@ class RedirectablePrint : public Print
|
|||||||
/// Used to allow multiple logDebug messages to appear on a single log line
|
/// Used to allow multiple logDebug messages to appear on a single log line
|
||||||
bool isContinuationMessage = false;
|
bool isContinuationMessage = false;
|
||||||
|
|
||||||
|
#ifdef HAS_FREE_RTOS
|
||||||
|
SemaphoreHandle_t inDebugPrint = nullptr;
|
||||||
|
StaticSemaphore_t _MutexStorageSpace;
|
||||||
|
#else
|
||||||
volatile bool inDebugPrint = false;
|
volatile bool inDebugPrint = false;
|
||||||
|
#endif
|
||||||
public:
|
public:
|
||||||
explicit RedirectablePrint(Print *_dest) : dest(_dest) {}
|
explicit RedirectablePrint(Print *_dest) : dest(_dest) {}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set a new destination
|
* Set a new destination
|
||||||
*/
|
*/
|
||||||
|
void rpInit();
|
||||||
void setDestination(Print *dest);
|
void setDestination(Print *dest);
|
||||||
|
|
||||||
virtual size_t write(uint8_t c);
|
virtual size_t write(uint8_t c);
|
||||||
@@ -54,4 +60,4 @@ class NoopPrint : public Print
|
|||||||
/**
|
/**
|
||||||
* A printer that doesn't go anywhere
|
* A printer that doesn't go anywhere
|
||||||
*/
|
*/
|
||||||
extern NoopPrint noopPrint;
|
extern NoopPrint noopPrint;
|
||||||
@@ -12,6 +12,7 @@ SerialConsole *console;
|
|||||||
void consoleInit()
|
void consoleInit()
|
||||||
{
|
{
|
||||||
new SerialConsole(); // Must be dynamically allocated because we are now inheriting from thread
|
new SerialConsole(); // Must be dynamically allocated because we are now inheriting from thread
|
||||||
|
DEBUG_PORT.rpInit(); // Simply sets up semaphore
|
||||||
}
|
}
|
||||||
|
|
||||||
void consolePrintf(const char *format, ...)
|
void consolePrintf(const char *format, ...)
|
||||||
|
|||||||
@@ -53,7 +53,7 @@ class OSThread : public Thread
|
|||||||
|
|
||||||
static void setup();
|
static void setup();
|
||||||
|
|
||||||
int32_t disable();
|
virtual int32_t disable();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Wait a specified number msecs starting from the current time (rather than the last time we were run)
|
* Wait a specified number msecs starting from the current time (rather than the last time we were run)
|
||||||
@@ -67,6 +67,7 @@ class OSThread : public Thread
|
|||||||
* Returns desired period for next invocation (or RUN_SAME for no change)
|
* Returns desired period for next invocation (or RUN_SAME for no change)
|
||||||
*/
|
*/
|
||||||
virtual int32_t runOnce() = 0;
|
virtual int32_t runOnce() = 0;
|
||||||
|
bool sleepOnNextExecution = false;
|
||||||
|
|
||||||
// Do not override this
|
// Do not override this
|
||||||
virtual void run();
|
virtual void run();
|
||||||
@@ -87,4 +88,4 @@ extern bool hasBeenSetup;
|
|||||||
|
|
||||||
void assertIsSetup();
|
void assertIsSetup();
|
||||||
|
|
||||||
} // namespace concurrency
|
} // namespace concurrency
|
||||||
@@ -101,6 +101,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||||||
// I2C Keyboards (M5Stack, RAK14004, T-Deck)
|
// I2C Keyboards (M5Stack, RAK14004, T-Deck)
|
||||||
#define CARDKB_ADDR 0x5F
|
#define CARDKB_ADDR 0x5F
|
||||||
#define TDECK_KB_ADDR 0x55
|
#define TDECK_KB_ADDR 0x55
|
||||||
|
#define BBQ10_KB_ADDR 0x1F
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
// SENSOR
|
// SENSOR
|
||||||
@@ -144,9 +145,12 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||||||
#define GPS_BAUDRATE 9600
|
#define GPS_BAUDRATE 9600
|
||||||
|
|
||||||
#ifndef GPS_THREAD_INTERVAL
|
#ifndef GPS_THREAD_INTERVAL
|
||||||
#define GPS_THREAD_INTERVAL 100
|
#define GPS_THREAD_INTERVAL 200
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// convert 24-bit color to 16-bit (56K)
|
||||||
|
#define COLOR565(r, g, b) (((r & 0xF8) << 8) | ((g & 0xFC) << 3) | ((b & 0xF8) >> 3))
|
||||||
|
|
||||||
/* Step #1: offer chance for variant-specific defines */
|
/* Step #1: offer chance for variant-specific defines */
|
||||||
#include "variant.h"
|
#include "variant.h"
|
||||||
|
|
||||||
|
|||||||
@@ -30,8 +30,8 @@ ScanI2C::FoundDevice ScanI2C::firstRTC() const
|
|||||||
|
|
||||||
ScanI2C::FoundDevice ScanI2C::firstKeyboard() const
|
ScanI2C::FoundDevice ScanI2C::firstKeyboard() const
|
||||||
{
|
{
|
||||||
ScanI2C::DeviceType types[] = {CARDKB, TDECKKB, RAK14004};
|
ScanI2C::DeviceType types[] = {CARDKB, TDECKKB, BBQ10KB, RAK14004};
|
||||||
return firstOfOrNONE(3, types);
|
return firstOfOrNONE(4, types);
|
||||||
}
|
}
|
||||||
|
|
||||||
ScanI2C::FoundDevice ScanI2C::firstAccelerometer() const
|
ScanI2C::FoundDevice ScanI2C::firstAccelerometer() const
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ class ScanI2C
|
|||||||
RTC_PCF8563,
|
RTC_PCF8563,
|
||||||
CARDKB,
|
CARDKB,
|
||||||
TDECKKB,
|
TDECKKB,
|
||||||
|
BBQ10KB,
|
||||||
RAK14004,
|
RAK14004,
|
||||||
PMU_AXP192_AXP2101,
|
PMU_AXP192_AXP2101,
|
||||||
BME_680,
|
BME_680,
|
||||||
|
|||||||
@@ -213,6 +213,7 @@ void ScanI2CTwoWire::scanPort(I2CPort port)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
SCAN_SIMPLE_CASE(TDECK_KB_ADDR, TDECKKB, "T-Deck keyboard found\n");
|
SCAN_SIMPLE_CASE(TDECK_KB_ADDR, TDECKKB, "T-Deck keyboard found\n");
|
||||||
|
SCAN_SIMPLE_CASE(BBQ10_KB_ADDR, BBQ10KB, "BB Q10 keyboard found\n");
|
||||||
SCAN_SIMPLE_CASE(ST7567_ADDRESS, SCREEN_ST7567, "st7567 display found\n");
|
SCAN_SIMPLE_CASE(ST7567_ADDRESS, SCREEN_ST7567, "st7567 display found\n");
|
||||||
#ifdef HAS_NCP5623
|
#ifdef HAS_NCP5623
|
||||||
SCAN_SIMPLE_CASE(NCP5623_ADDR, NCP5623, "NCP5623 RGB LED found\n");
|
SCAN_SIMPLE_CASE(NCP5623_ADDR, NCP5623, "NCP5623 RGB LED found\n");
|
||||||
|
|||||||
@@ -18,6 +18,8 @@ class ScanI2CTwoWire : public ScanI2C
|
|||||||
|
|
||||||
ScanI2C::FoundDevice find(ScanI2C::DeviceType) const override;
|
ScanI2C::FoundDevice find(ScanI2C::DeviceType) const override;
|
||||||
|
|
||||||
|
TwoWire *fetchI2CBus(ScanI2C::DeviceAddress) const;
|
||||||
|
|
||||||
bool exists(ScanI2C::DeviceType) const override;
|
bool exists(ScanI2C::DeviceType) const override;
|
||||||
|
|
||||||
size_t countDevices() const override;
|
size_t countDevices() const override;
|
||||||
@@ -51,6 +53,4 @@ class ScanI2CTwoWire : public ScanI2C
|
|||||||
uint16_t getRegisterValue(const RegisterLocation &, ResponseWidth) const;
|
uint16_t getRegisterValue(const RegisterLocation &, ResponseWidth) const;
|
||||||
|
|
||||||
DeviceType probeOLED(ScanI2C::DeviceAddress) const;
|
DeviceType probeOLED(ScanI2C::DeviceAddress) const;
|
||||||
|
|
||||||
TwoWire *fetchI2CBus(ScanI2C::DeviceAddress) const;
|
|
||||||
};
|
};
|
||||||
|
|||||||
1344
src/gps/GPS.cpp
1344
src/gps/GPS.cpp
File diff suppressed because it is too large
Load Diff
202
src/gps/GPS.h
202
src/gps/GPS.h
@@ -2,7 +2,16 @@
|
|||||||
|
|
||||||
#include "GPSStatus.h"
|
#include "GPSStatus.h"
|
||||||
#include "Observer.h"
|
#include "Observer.h"
|
||||||
|
#include "TinyGPS++.h"
|
||||||
#include "concurrency/OSThread.h"
|
#include "concurrency/OSThread.h"
|
||||||
|
#include "input/RotaryEncoderInterruptImpl1.h"
|
||||||
|
#include "input/UpDownInterruptImpl1.h"
|
||||||
|
#include "modules/PositionModule.h"
|
||||||
|
|
||||||
|
// Allow defining the polarity of the ENABLE output. default is active high
|
||||||
|
#ifndef GPS_EN_ACTIVE
|
||||||
|
#define GPS_EN_ACTIVE 1
|
||||||
|
#endif
|
||||||
|
|
||||||
struct uBloxGnssModelInfo {
|
struct uBloxGnssModelInfo {
|
||||||
char swVersion[30];
|
char swVersion[30];
|
||||||
@@ -18,6 +27,13 @@ typedef enum {
|
|||||||
GNSS_MODEL_UNKNOWN,
|
GNSS_MODEL_UNKNOWN,
|
||||||
} GnssModel_t;
|
} GnssModel_t;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
GNSS_RESPONSE_NONE,
|
||||||
|
GNSS_RESPONSE_NAK,
|
||||||
|
GNSS_RESPONSE_FRAME_ERRORS,
|
||||||
|
GNSS_RESPONSE_OK,
|
||||||
|
} GPS_RESPONSE;
|
||||||
|
|
||||||
// Generate a string representation of DOP
|
// Generate a string representation of DOP
|
||||||
const char *getDOPString(uint32_t dop);
|
const char *getDOPString(uint32_t dop);
|
||||||
|
|
||||||
@@ -28,8 +44,29 @@ const char *getDOPString(uint32_t dop);
|
|||||||
*/
|
*/
|
||||||
class GPS : private concurrency::OSThread
|
class GPS : private concurrency::OSThread
|
||||||
{
|
{
|
||||||
|
TinyGPSPlus reader;
|
||||||
|
uint8_t fixQual = 0; // fix quality from GPGGA
|
||||||
|
uint32_t lastChecksumFailCount = 0;
|
||||||
|
|
||||||
|
#ifndef TINYGPS_OPTION_NO_CUSTOM_FIELDS
|
||||||
|
// (20210908) TinyGps++ can only read the GPGSA "FIX TYPE" field
|
||||||
|
// via optional feature "custom fields", currently disabled (bug #525)
|
||||||
|
TinyGPSCustom gsafixtype; // custom extract fix type from GPGSA
|
||||||
|
TinyGPSCustom gsapdop; // custom extract PDOP from GPGSA
|
||||||
|
uint8_t fixType = 0; // fix type from GPGSA
|
||||||
|
#endif
|
||||||
private:
|
private:
|
||||||
uint32_t lastWakeStartMsec = 0, lastSleepStartMsec = 0, lastWhileActiveMsec = 0;
|
uint32_t lastWakeStartMsec = 0, lastSleepStartMsec = 0;
|
||||||
|
const int serialSpeeds[6] = {9600, 4800, 38400, 57600, 115200, 9600};
|
||||||
|
|
||||||
|
uint32_t rx_gpio = 0;
|
||||||
|
uint32_t tx_gpio = 0;
|
||||||
|
uint32_t en_gpio = 0;
|
||||||
|
int32_t averageLockTime = 0;
|
||||||
|
uint32_t GPSCycles = 0;
|
||||||
|
|
||||||
|
int speedSelect = 0;
|
||||||
|
int probeTries = 2;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* hasValidLocation - indicates that the position variables contain a complete
|
* hasValidLocation - indicates that the position variables contain a complete
|
||||||
@@ -39,15 +76,17 @@ class GPS : private concurrency::OSThread
|
|||||||
|
|
||||||
bool isAwake = false; // true if we want a location right now
|
bool isAwake = false; // true if we want a location right now
|
||||||
|
|
||||||
bool wakeAllowed = true; // false if gps must be forced to sleep regardless of what time it is
|
bool isInPowersave = false;
|
||||||
|
|
||||||
bool shouldPublish = false; // If we've changed GPS state, this will force a publish the next loop()
|
bool shouldPublish = false; // If we've changed GPS state, this will force a publish the next loop()
|
||||||
|
|
||||||
bool hasGPS = false; // Do we have a GPS we are talking to
|
bool hasGPS = false; // Do we have a GPS we are talking to
|
||||||
|
|
||||||
|
bool GPSInitFinished = false; // Init thread finished?
|
||||||
|
bool GPSInitStarted = false; // Init thread finished?
|
||||||
|
|
||||||
uint8_t numSatellites = 0;
|
uint8_t numSatellites = 0;
|
||||||
|
|
||||||
CallbackObserver<GPS, void *> notifySleepObserver = CallbackObserver<GPS, void *>(this, &GPS::prepareSleep);
|
|
||||||
CallbackObserver<GPS, void *> notifyDeepSleepObserver = CallbackObserver<GPS, void *>(this, &GPS::prepareDeepSleep);
|
CallbackObserver<GPS, void *> notifyDeepSleepObserver = CallbackObserver<GPS, void *>(this, &GPS::prepareDeepSleep);
|
||||||
CallbackObserver<GPS, void *> notifyGPSSleepObserver = CallbackObserver<GPS, void *>(this, &GPS::prepareDeepSleep);
|
CallbackObserver<GPS, void *> notifyGPSSleepObserver = CallbackObserver<GPS, void *>(this, &GPS::prepareDeepSleep);
|
||||||
|
|
||||||
@@ -55,6 +94,24 @@ class GPS : private concurrency::OSThread
|
|||||||
/** If !NULL we will use this serial port to construct our GPS */
|
/** If !NULL we will use this serial port to construct our GPS */
|
||||||
static HardwareSerial *_serial_gps;
|
static HardwareSerial *_serial_gps;
|
||||||
|
|
||||||
|
static uint8_t _message_PMREQ[];
|
||||||
|
static const uint8_t _message_CFG_RXM_PSM[];
|
||||||
|
static const uint8_t _message_CFG_RXM_ECO[];
|
||||||
|
static const uint8_t _message_CFG_PM2[];
|
||||||
|
static const uint8_t _message_GNSS_7[];
|
||||||
|
static const uint8_t _message_GNSS[];
|
||||||
|
static const uint8_t _message_JAM[];
|
||||||
|
static const uint8_t _message_NAVX5[];
|
||||||
|
static const uint8_t _message_1HZ[];
|
||||||
|
static const uint8_t _message_GGL[];
|
||||||
|
static const uint8_t _message_GSA[];
|
||||||
|
static const uint8_t _message_GSV[];
|
||||||
|
static const uint8_t _message_VTG[];
|
||||||
|
static const uint8_t _message_RMC[];
|
||||||
|
static const uint8_t _message_GGA[];
|
||||||
|
static const uint8_t _message_PMS[];
|
||||||
|
static const uint8_t _message_SAVE[];
|
||||||
|
|
||||||
meshtastic_Position p = meshtastic_Position_init_default;
|
meshtastic_Position p = meshtastic_Position_init_default;
|
||||||
|
|
||||||
GPS() : concurrency::OSThread("GPS") {}
|
GPS() : concurrency::OSThread("GPS") {}
|
||||||
@@ -69,6 +126,14 @@ class GPS : private concurrency::OSThread
|
|||||||
*/
|
*/
|
||||||
virtual bool setup();
|
virtual bool setup();
|
||||||
|
|
||||||
|
// re-enable the thread
|
||||||
|
void enable();
|
||||||
|
|
||||||
|
// Disable the thread
|
||||||
|
int32_t disable() override;
|
||||||
|
|
||||||
|
void setGPSPower(bool on, bool standbyOnly, uint32_t sleepTime);
|
||||||
|
|
||||||
/// Returns true if we have acquired GPS lock.
|
/// Returns true if we have acquired GPS lock.
|
||||||
virtual bool hasLock();
|
virtual bool hasLock();
|
||||||
|
|
||||||
@@ -80,68 +145,20 @@ class GPS : private concurrency::OSThread
|
|||||||
|
|
||||||
bool isPowerSaving() const { return !config.position.gps_enabled; }
|
bool isPowerSaving() const { return !config.position.gps_enabled; }
|
||||||
|
|
||||||
/**
|
// Empty the input buffer as quickly as possible
|
||||||
* Restart our lock attempt - try to get and broadcast a GPS reading ASAP
|
void clearBuffer();
|
||||||
* called after the CPU wakes from light-sleep state
|
|
||||||
*
|
|
||||||
* Or set to false, to disallow any sort of waking
|
|
||||||
* */
|
|
||||||
void forceWake(bool on);
|
|
||||||
|
|
||||||
// Some GPS modules (ublock) require factory reset
|
// Create a ublox packet for editing in memory
|
||||||
virtual bool factoryReset() { return true; }
|
uint8_t makeUBXPacket(uint8_t class_id, uint8_t msg_id, uint8_t payload_size, const uint8_t *msg);
|
||||||
|
|
||||||
protected:
|
// scratch space for creating ublox packets
|
||||||
/// Do gps chipset specific init, return true for success
|
uint8_t UBXscratch[250] = {0};
|
||||||
virtual bool setupGPS();
|
|
||||||
|
|
||||||
/// If possible force the GPS into sleep/low power mode
|
int rebootsSeen = 0;
|
||||||
virtual void sleep();
|
|
||||||
|
|
||||||
/// wake the GPS into normal operation mode
|
int getACK(uint8_t *buffer, uint16_t size, uint8_t requestedClass, uint8_t requestedID, uint32_t waitMillis);
|
||||||
virtual void wake();
|
GPS_RESPONSE getACK(uint8_t c, uint8_t i, uint32_t waitMillis);
|
||||||
|
GPS_RESPONSE getACK(const char *message, uint32_t waitMillis);
|
||||||
/** Subclasses should look for serial rx characters here and feed it to their GPS parser
|
|
||||||
*
|
|
||||||
* Return true if we received a valid message from the GPS
|
|
||||||
*/
|
|
||||||
virtual bool whileIdle() = 0;
|
|
||||||
|
|
||||||
/** Idle processing while GPS is looking for lock, called once per secondish */
|
|
||||||
virtual void whileActive() {}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Perform any processing that should be done only while the GPS is awake and looking for a fix.
|
|
||||||
* Override this method to check for new locations
|
|
||||||
*
|
|
||||||
* @return true if we've acquired a time
|
|
||||||
*/
|
|
||||||
virtual bool lookForTime() = 0;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Perform any processing that should be done only while the GPS is awake and looking for a fix.
|
|
||||||
* Override this method to check for new locations
|
|
||||||
*
|
|
||||||
* @return true if we've acquired a new location
|
|
||||||
*/
|
|
||||||
virtual bool lookForLocation() = 0;
|
|
||||||
|
|
||||||
/// Record that we have a GPS
|
|
||||||
void setConnected();
|
|
||||||
|
|
||||||
void setNumSatellites(uint8_t n);
|
|
||||||
|
|
||||||
private:
|
|
||||||
/// Prepare the GPS for the cpu entering deep or light sleep, expect to be gone for at least 100s of msecs
|
|
||||||
/// always returns 0 to indicate okay to sleep
|
|
||||||
int prepareSleep(void *unused);
|
|
||||||
|
|
||||||
/// Prepare the GPS for the cpu entering deep sleep, expect to be gone for at least 100s of msecs
|
|
||||||
/// always returns 0 to indicate okay to sleep
|
|
||||||
int prepareDeepSleep(void *unused);
|
|
||||||
|
|
||||||
// Calculate checksum
|
|
||||||
void UBXChecksum(byte *message, size_t length);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Switch the GPS into a mode where we are actively looking for a lock, or alternatively switch GPS into a low power mode
|
* Switch the GPS into a mode where we are actively looking for a lock, or alternatively switch GPS into a low power mode
|
||||||
@@ -149,6 +166,59 @@ class GPS : private concurrency::OSThread
|
|||||||
* calls sleep/wake
|
* calls sleep/wake
|
||||||
*/
|
*/
|
||||||
void setAwake(bool on);
|
void setAwake(bool on);
|
||||||
|
virtual bool factoryReset();
|
||||||
|
|
||||||
|
// Creates an instance of the GPS class.
|
||||||
|
// Returns the new instance or null if the GPS is not present.
|
||||||
|
static GPS *createGps();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
/**
|
||||||
|
* Perform any processing that should be done only while the GPS is awake and looking for a fix.
|
||||||
|
* Override this method to check for new locations
|
||||||
|
*
|
||||||
|
* @return true if we've acquired a time
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Perform any processing that should be done only while the GPS is awake and looking for a fix.
|
||||||
|
* Override this method to check for new locations
|
||||||
|
*
|
||||||
|
* @return true if we've acquired a new location
|
||||||
|
*/
|
||||||
|
|
||||||
|
/// Record that we have a GPS
|
||||||
|
void setConnected();
|
||||||
|
|
||||||
|
/** Subclasses should look for serial rx characters here and feed it to their GPS parser
|
||||||
|
*
|
||||||
|
* Return true if we received a valid message from the GPS
|
||||||
|
*/
|
||||||
|
virtual bool whileIdle();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Perform any processing that should be done only while the GPS is awake and looking for a fix.
|
||||||
|
* Override this method to check for new locations
|
||||||
|
*
|
||||||
|
* @return true if we've acquired a time
|
||||||
|
*/
|
||||||
|
virtual bool lookForTime();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Perform any processing that should be done only while the GPS is awake and looking for a fix.
|
||||||
|
* Override this method to check for new locations
|
||||||
|
*
|
||||||
|
* @return true if we've acquired a new location
|
||||||
|
*/
|
||||||
|
virtual bool lookForLocation();
|
||||||
|
|
||||||
|
private:
|
||||||
|
/// Prepare the GPS for the cpu entering deep sleep, expect to be gone for at least 100s of msecs
|
||||||
|
/// always returns 0 to indicate okay to sleep
|
||||||
|
int prepareDeepSleep(void *unused);
|
||||||
|
|
||||||
|
// Calculate checksum
|
||||||
|
void UBXChecksum(uint8_t *message, size_t length);
|
||||||
|
|
||||||
/** Get how long we should stay looking for each aquisition
|
/** Get how long we should stay looking for each aquisition
|
||||||
*/
|
*/
|
||||||
@@ -158,8 +228,6 @@ class GPS : private concurrency::OSThread
|
|||||||
*/
|
*/
|
||||||
uint32_t getSleepTime() const;
|
uint32_t getSleepTime() const;
|
||||||
|
|
||||||
bool getACK(uint8_t c, uint8_t i);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tell users we have new GPS readings
|
* Tell users we have new GPS readings
|
||||||
*/
|
*/
|
||||||
@@ -169,9 +237,7 @@ class GPS : private concurrency::OSThread
|
|||||||
|
|
||||||
// Get GNSS model
|
// Get GNSS model
|
||||||
String getNMEA();
|
String getNMEA();
|
||||||
GnssModel_t probe();
|
GnssModel_t probe(int serialSpeed);
|
||||||
|
|
||||||
int getAck(uint8_t *buffer, uint16_t size, uint8_t requestedClass, uint8_t requestedID);
|
|
||||||
|
|
||||||
// delay counter to allow more sats before fixed position stops GPS thread
|
// delay counter to allow more sats before fixed position stops GPS thread
|
||||||
uint8_t fixeddelayCtr = 0;
|
uint8_t fixeddelayCtr = 0;
|
||||||
@@ -180,8 +246,4 @@ class GPS : private concurrency::OSThread
|
|||||||
GnssModel_t gnssModel = GNSS_MODEL_UNKNOWN;
|
GnssModel_t gnssModel = GNSS_MODEL_UNKNOWN;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Creates an instance of the GPS class.
|
|
||||||
// Returns the new instance or null if the GPS is not present.
|
|
||||||
GPS *createGps();
|
|
||||||
|
|
||||||
extern GPS *gps;
|
extern GPS *gps;
|
||||||
@@ -1,266 +0,0 @@
|
|||||||
#include "NMEAGPS.h"
|
|
||||||
#include "RTC.h"
|
|
||||||
#include "configuration.h"
|
|
||||||
|
|
||||||
#include <TinyGPS++.h>
|
|
||||||
|
|
||||||
// GPS solutions older than this will be rejected - see TinyGPSDatum::age()
|
|
||||||
#define GPS_SOL_EXPIRY_MS 5000 // in millis. give 1 second time to combine different sentences. NMEA Frequency isn't higher anyway
|
|
||||||
#define NMEA_MSG_GXGSA "GNGSA" // GSA message (GPGSA, GNGSA etc)
|
|
||||||
|
|
||||||
static int32_t toDegInt(RawDegrees d)
|
|
||||||
{
|
|
||||||
int32_t degMult = 10000000; // 1e7
|
|
||||||
int32_t r = d.deg * degMult + d.billionths / 100;
|
|
||||||
if (d.negative)
|
|
||||||
r *= -1;
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool NMEAGPS::factoryReset()
|
|
||||||
{
|
|
||||||
#ifdef PIN_GPS_REINIT
|
|
||||||
// The L76K GNSS on the T-Echo requires the RESET pin to be pulled LOW
|
|
||||||
digitalWrite(PIN_GPS_REINIT, 0);
|
|
||||||
pinMode(PIN_GPS_REINIT, OUTPUT);
|
|
||||||
delay(150); // The L76K datasheet calls for at least 100MS delay
|
|
||||||
digitalWrite(PIN_GPS_REINIT, 1);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// send the UBLOX Factory Reset Command regardless of detect state, something is very wrong, just assume it's UBLOX.
|
|
||||||
// Factory Reset
|
|
||||||
byte _message_reset[] = {0xB5, 0x62, 0x06, 0x09, 0x0D, 0x00, 0xFF, 0xFB, 0x00, 0x00, 0x00,
|
|
||||||
0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x17, 0x2B, 0x7E};
|
|
||||||
_serial_gps->write(_message_reset, sizeof(_message_reset));
|
|
||||||
delay(1000);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool NMEAGPS::setupGPS()
|
|
||||||
{
|
|
||||||
GPS::setupGPS();
|
|
||||||
|
|
||||||
#ifdef PIN_GPS_PPS
|
|
||||||
// pulse per second
|
|
||||||
// FIXME - move into shared GPS code
|
|
||||||
pinMode(PIN_GPS_PPS, INPUT);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Currently disabled per issue #525 (TinyGPS++ crash bug)
|
|
||||||
// when fixed upstream, can be un-disabled to enable 3D FixType and PDOP
|
|
||||||
#ifndef TINYGPS_OPTION_NO_CUSTOM_FIELDS
|
|
||||||
// see NMEAGPS.h
|
|
||||||
gsafixtype.begin(reader, NMEA_MSG_GXGSA, 2);
|
|
||||||
gsapdop.begin(reader, NMEA_MSG_GXGSA, 15);
|
|
||||||
LOG_DEBUG("Using " NMEA_MSG_GXGSA " for 3DFIX and PDOP\n");
|
|
||||||
#else
|
|
||||||
LOG_DEBUG("GxGSA NOT available\n");
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Perform any processing that should be done only while the GPS is awake and looking for a fix.
|
|
||||||
* Override this method to check for new locations
|
|
||||||
*
|
|
||||||
* @return true if we've acquired a new location
|
|
||||||
*/
|
|
||||||
bool NMEAGPS::lookForTime()
|
|
||||||
{
|
|
||||||
auto ti = reader.time;
|
|
||||||
auto d = reader.date;
|
|
||||||
if (ti.isValid() && d.isValid()) { // Note: we don't check for updated, because we'll only be called if needed
|
|
||||||
/* Convert to unix time
|
|
||||||
The Unix epoch (or Unix time or POSIX time or Unix timestamp) is the number of seconds that have elapsed since January 1, 1970
|
|
||||||
(midnight UTC/GMT), not counting leap seconds (in ISO 8601: 1970-01-01T00:00:00Z).
|
|
||||||
*/
|
|
||||||
struct tm t;
|
|
||||||
t.tm_sec = ti.second();
|
|
||||||
t.tm_min = ti.minute();
|
|
||||||
t.tm_hour = ti.hour();
|
|
||||||
t.tm_mday = d.day();
|
|
||||||
t.tm_mon = d.month() - 1;
|
|
||||||
t.tm_year = d.year() - 1900;
|
|
||||||
t.tm_isdst = false;
|
|
||||||
if (t.tm_mon > -1) {
|
|
||||||
LOG_DEBUG("NMEA GPS time %02d-%02d-%02d %02d:%02d:%02d\n", d.year(), d.month(), t.tm_mday, t.tm_hour, t.tm_min,
|
|
||||||
t.tm_sec);
|
|
||||||
perhapsSetRTC(RTCQualityGPS, t);
|
|
||||||
return true;
|
|
||||||
} else
|
|
||||||
return false;
|
|
||||||
} else
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Perform any processing that should be done only while the GPS is awake and looking for a fix.
|
|
||||||
* Override this method to check for new locations
|
|
||||||
*
|
|
||||||
* @return true if we've acquired a new location
|
|
||||||
*/
|
|
||||||
bool NMEAGPS::lookForLocation()
|
|
||||||
{
|
|
||||||
// By default, TinyGPS++ does not parse GPGSA lines, which give us
|
|
||||||
// the 2D/3D fixType (see NMEAGPS.h)
|
|
||||||
// At a minimum, use the fixQuality indicator in GPGGA (FIXME?)
|
|
||||||
fixQual = reader.fixQuality();
|
|
||||||
|
|
||||||
#ifndef TINYGPS_OPTION_NO_STATISTICS
|
|
||||||
if (reader.failedChecksum() > lastChecksumFailCount) {
|
|
||||||
LOG_WARN("Warning, %u new GPS checksum failures, for a total of %u.\n", reader.failedChecksum() - lastChecksumFailCount,
|
|
||||||
reader.failedChecksum());
|
|
||||||
lastChecksumFailCount = reader.failedChecksum();
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef TINYGPS_OPTION_NO_CUSTOM_FIELDS
|
|
||||||
fixType = atoi(gsafixtype.value()); // will set to zero if no data
|
|
||||||
// LOG_DEBUG("FIX QUAL=%d, TYPE=%d\n", fixQual, fixType);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// check if GPS has an acceptable lock
|
|
||||||
if (!hasLock())
|
|
||||||
return false;
|
|
||||||
|
|
||||||
#ifdef GPS_EXTRAVERBOSE
|
|
||||||
LOG_DEBUG("AGE: LOC=%d FIX=%d DATE=%d TIME=%d\n", reader.location.age(),
|
|
||||||
#ifndef TINYGPS_OPTION_NO_CUSTOM_FIELDS
|
|
||||||
gsafixtype.age(),
|
|
||||||
#else
|
|
||||||
0,
|
|
||||||
#endif
|
|
||||||
reader.date.age(), reader.time.age());
|
|
||||||
#endif // GPS_EXTRAVERBOSE
|
|
||||||
|
|
||||||
// check if a complete GPS solution set is available for reading
|
|
||||||
// tinyGPSDatum::age() also includes isValid() test
|
|
||||||
// FIXME
|
|
||||||
if (!((reader.location.age() < GPS_SOL_EXPIRY_MS) &&
|
|
||||||
#ifndef TINYGPS_OPTION_NO_CUSTOM_FIELDS
|
|
||||||
(gsafixtype.age() < GPS_SOL_EXPIRY_MS) &&
|
|
||||||
#endif
|
|
||||||
(reader.time.age() < GPS_SOL_EXPIRY_MS) && (reader.date.age() < GPS_SOL_EXPIRY_MS))) {
|
|
||||||
LOG_WARN("SOME data is TOO OLD: LOC %u, TIME %u, DATE %u\n", reader.location.age(), reader.time.age(), reader.date.age());
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Is this a new point or are we re-reading the previous one?
|
|
||||||
if (!reader.location.isUpdated())
|
|
||||||
return false;
|
|
||||||
|
|
||||||
// We know the solution is fresh and valid, so just read the data
|
|
||||||
auto loc = reader.location.value();
|
|
||||||
|
|
||||||
// Bail out EARLY to avoid overwriting previous good data (like #857)
|
|
||||||
if (toDegInt(loc.lat) > 900000000) {
|
|
||||||
#ifdef GPS_EXTRAVERBOSE
|
|
||||||
LOG_DEBUG("Bail out EARLY on LAT %i\n", toDegInt(loc.lat));
|
|
||||||
#endif
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (toDegInt(loc.lng) > 1800000000) {
|
|
||||||
#ifdef GPS_EXTRAVERBOSE
|
|
||||||
LOG_DEBUG("Bail out EARLY on LNG %i\n", toDegInt(loc.lng));
|
|
||||||
#endif
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
p.location_source = meshtastic_Position_LocSource_LOC_INTERNAL;
|
|
||||||
|
|
||||||
// Dilution of precision (an accuracy metric) is reported in 10^2 units, so we need to scale down when we use it
|
|
||||||
#ifndef TINYGPS_OPTION_NO_CUSTOM_FIELDS
|
|
||||||
p.HDOP = reader.hdop.value();
|
|
||||||
p.PDOP = TinyGPSPlus::parseDecimal(gsapdop.value());
|
|
||||||
// LOG_DEBUG("PDOP=%d, HDOP=%d\n", p.PDOP, p.HDOP);
|
|
||||||
#else
|
|
||||||
// FIXME! naive PDOP emulation (assumes VDOP==HDOP)
|
|
||||||
// correct formula is PDOP = SQRT(HDOP^2 + VDOP^2)
|
|
||||||
p.HDOP = reader.hdop.value();
|
|
||||||
p.PDOP = 1.41 * reader.hdop.value();
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Discard incomplete or erroneous readings
|
|
||||||
if (reader.hdop.value() == 0) {
|
|
||||||
LOG_WARN("BOGUS hdop.value() REJECTED: %d\n", reader.hdop.value());
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
p.latitude_i = toDegInt(loc.lat);
|
|
||||||
p.longitude_i = toDegInt(loc.lng);
|
|
||||||
|
|
||||||
p.altitude_geoidal_separation = reader.geoidHeight.meters();
|
|
||||||
p.altitude_hae = reader.altitude.meters() + p.altitude_geoidal_separation;
|
|
||||||
p.altitude = reader.altitude.meters();
|
|
||||||
|
|
||||||
p.fix_quality = fixQual;
|
|
||||||
#ifndef TINYGPS_OPTION_NO_CUSTOM_FIELDS
|
|
||||||
p.fix_type = fixType;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// positional timestamp
|
|
||||||
struct tm t;
|
|
||||||
t.tm_sec = reader.time.second();
|
|
||||||
t.tm_min = reader.time.minute();
|
|
||||||
t.tm_hour = reader.time.hour();
|
|
||||||
t.tm_mday = reader.date.day();
|
|
||||||
t.tm_mon = reader.date.month() - 1;
|
|
||||||
t.tm_year = reader.date.year() - 1900;
|
|
||||||
t.tm_isdst = false;
|
|
||||||
p.timestamp = mktime(&t);
|
|
||||||
|
|
||||||
// Nice to have, if available
|
|
||||||
if (reader.satellites.isUpdated()) {
|
|
||||||
p.sats_in_view = reader.satellites.value();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (reader.course.isUpdated() && reader.course.isValid()) {
|
|
||||||
if (reader.course.value() < 36000) { // sanity check
|
|
||||||
p.ground_track =
|
|
||||||
reader.course.value() * 1e3; // Scale the heading (in degrees * 10^-2) to match the expected degrees * 10^-5
|
|
||||||
} else {
|
|
||||||
LOG_WARN("BOGUS course.value() REJECTED: %d\n", reader.course.value());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (reader.speed.isUpdated() && reader.speed.isValid()) {
|
|
||||||
p.ground_speed = reader.speed.kmph();
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool NMEAGPS::hasLock()
|
|
||||||
{
|
|
||||||
// Using GPGGA fix quality indicator
|
|
||||||
if (fixQual >= 1 && fixQual <= 5) {
|
|
||||||
#ifndef TINYGPS_OPTION_NO_CUSTOM_FIELDS
|
|
||||||
// Use GPGSA fix type 2D/3D (better) if available
|
|
||||||
if (fixType == 3 || fixType == 0) // zero means "no data received"
|
|
||||||
#endif
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool NMEAGPS::hasFlow()
|
|
||||||
{
|
|
||||||
return reader.passedChecksum() > 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool NMEAGPS::whileIdle()
|
|
||||||
{
|
|
||||||
bool isValid = false;
|
|
||||||
// if (_serial_gps->available() > 0)
|
|
||||||
// LOG_DEBUG("GPS Bytes Waiting: %u\n", _serial_gps->available());
|
|
||||||
// First consume any chars that have piled up at the receiver
|
|
||||||
while (_serial_gps->available() > 0) {
|
|
||||||
int c = _serial_gps->read();
|
|
||||||
// LOG_DEBUG("%c", c);
|
|
||||||
isValid |= reader.encode(c);
|
|
||||||
}
|
|
||||||
|
|
||||||
return isValid;
|
|
||||||
}
|
|
||||||
@@ -1,57 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include "GPS.h"
|
|
||||||
#include "Observer.h"
|
|
||||||
#include "TinyGPS++.h"
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A gps class thatreads from a NMEA GPS stream (and FIXME - eventually keeps the gps powered down except when reading)
|
|
||||||
*
|
|
||||||
* When new data is available it will notify observers.
|
|
||||||
*/
|
|
||||||
class NMEAGPS : public GPS
|
|
||||||
{
|
|
||||||
TinyGPSPlus reader;
|
|
||||||
uint8_t fixQual = 0; // fix quality from GPGGA
|
|
||||||
uint32_t lastChecksumFailCount = 0;
|
|
||||||
|
|
||||||
#ifndef TINYGPS_OPTION_NO_CUSTOM_FIELDS
|
|
||||||
// (20210908) TinyGps++ can only read the GPGSA "FIX TYPE" field
|
|
||||||
// via optional feature "custom fields", currently disabled (bug #525)
|
|
||||||
TinyGPSCustom gsafixtype; // custom extract fix type from GPGSA
|
|
||||||
TinyGPSCustom gsapdop; // custom extract PDOP from GPGSA
|
|
||||||
uint8_t fixType = 0; // fix type from GPGSA
|
|
||||||
#endif
|
|
||||||
|
|
||||||
public:
|
|
||||||
virtual bool setupGPS() override;
|
|
||||||
|
|
||||||
virtual bool factoryReset() override;
|
|
||||||
|
|
||||||
protected:
|
|
||||||
/** Subclasses should look for serial rx characters here and feed it to their GPS parser
|
|
||||||
*
|
|
||||||
* Return true if we received a valid message from the GPS
|
|
||||||
*/
|
|
||||||
virtual bool whileIdle() override;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Perform any processing that should be done only while the GPS is awake and looking for a fix.
|
|
||||||
* Override this method to check for new locations
|
|
||||||
*
|
|
||||||
* @return true if we've acquired a time
|
|
||||||
*/
|
|
||||||
virtual bool lookForTime() override;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Perform any processing that should be done only while the GPS is awake and looking for a fix.
|
|
||||||
* Override this method to check for new locations
|
|
||||||
*
|
|
||||||
* @return true if we've acquired a new location
|
|
||||||
*/
|
|
||||||
virtual bool lookForLocation() override;
|
|
||||||
|
|
||||||
virtual bool hasLock() override;
|
|
||||||
|
|
||||||
virtual bool hasFlow() override;
|
|
||||||
};
|
|
||||||
@@ -103,9 +103,8 @@ bool perhapsSetRTC(RTCQuality q, const struct timeval *tv)
|
|||||||
|
|
||||||
bool shouldSet;
|
bool shouldSet;
|
||||||
if (q > currentQuality) {
|
if (q > currentQuality) {
|
||||||
currentQuality = q;
|
|
||||||
shouldSet = true;
|
shouldSet = true;
|
||||||
LOG_DEBUG("Upgrading time to RTC %ld secs (quality %d)\n", tv->tv_sec, q);
|
LOG_DEBUG("Upgrading time to quality %d\n", q);
|
||||||
} else if (q == RTCQualityGPS && (now - lastSetMsec) > (12 * 60 * 60 * 1000UL)) {
|
} else if (q == RTCQualityGPS && (now - lastSetMsec) > (12 * 60 * 60 * 1000UL)) {
|
||||||
// Every 12 hrs we will slam in a new GPS time, to correct for local RTC clock drift
|
// Every 12 hrs we will slam in a new GPS time, to correct for local RTC clock drift
|
||||||
shouldSet = true;
|
shouldSet = true;
|
||||||
@@ -114,12 +113,12 @@ bool perhapsSetRTC(RTCQuality q, const struct timeval *tv)
|
|||||||
shouldSet = false;
|
shouldSet = false;
|
||||||
|
|
||||||
if (shouldSet) {
|
if (shouldSet) {
|
||||||
|
currentQuality = q;
|
||||||
lastSetMsec = now;
|
lastSetMsec = now;
|
||||||
|
|
||||||
// This delta value works on all platforms
|
// This delta value works on all platforms
|
||||||
timeStartMsec = now;
|
timeStartMsec = now;
|
||||||
zeroOffsetSecs = tv->tv_sec;
|
zeroOffsetSecs = tv->tv_sec;
|
||||||
|
|
||||||
// If this platform has a setable RTC, set it
|
// If this platform has a setable RTC, set it
|
||||||
#ifdef RV3028_RTC
|
#ifdef RV3028_RTC
|
||||||
if (rtc_found.address == RV3028_RTC) {
|
if (rtc_found.address == RV3028_RTC) {
|
||||||
@@ -209,4 +208,4 @@ uint32_t getTime()
|
|||||||
uint32_t getValidTime(RTCQuality minQuality)
|
uint32_t getValidTime(RTCQuality minQuality)
|
||||||
{
|
{
|
||||||
return (currentQuality >= minQuality) ? getTime() : 0;
|
return (currentQuality >= minQuality) ? getTime() : 0;
|
||||||
}
|
}
|
||||||
192
src/gps/ubx.h
Normal file
192
src/gps/ubx.h
Normal file
@@ -0,0 +1,192 @@
|
|||||||
|
uint8_t GPS::_message_PMREQ[] PROGMEM = {
|
||||||
|
0x00, 0x00, // 4 bytes duration of request task
|
||||||
|
0x00, 0x00, // (milliseconds)
|
||||||
|
0x02, 0x00, // Task flag bitfield
|
||||||
|
0x00, 0x00 // byte index 1 = sleep mode
|
||||||
|
};
|
||||||
|
|
||||||
|
const uint8_t GPS::_message_CFG_RXM_PSM[] PROGMEM = {
|
||||||
|
0x08, // Reserved
|
||||||
|
0x01 // Power save mode
|
||||||
|
};
|
||||||
|
|
||||||
|
const uint8_t GPS::_message_CFG_RXM_ECO[] PROGMEM = {
|
||||||
|
0x08, // Reserved
|
||||||
|
0x04 // eco mode
|
||||||
|
};
|
||||||
|
|
||||||
|
const uint8_t GPS::_message_CFG_PM2[] PROGMEM = {
|
||||||
|
0x01, 0x06, 0x00, 0x00, // version, Reserved
|
||||||
|
0x0E, 0x81, 0x43, 0x01, // flags
|
||||||
|
0xE8, 0x03, 0x00, 0x00, // update period 1000 ms
|
||||||
|
0x10, 0x27, 0x00, 0x00, // search period 10s
|
||||||
|
0x00, 0x00, 0x00, 0x00, // Grod offset 0
|
||||||
|
0x01, 0x00, // onTime 1 second
|
||||||
|
0x00, 0x00, // min search time 0
|
||||||
|
0x2C, 0x01, // reserved
|
||||||
|
0x00, 0x00, 0x4F, 0xC1, // reserved
|
||||||
|
0x03, 0x00, 0x87, 0x02, // reserved
|
||||||
|
0x00, 0x00, 0xFF, 0x00, // reserved
|
||||||
|
0x01, 0x00, 0xD6, 0x4D // reserved
|
||||||
|
};
|
||||||
|
|
||||||
|
const uint8_t GPS::_message_GNSS_7[] = {
|
||||||
|
0x00, // msgVer (0 for this version)
|
||||||
|
0x00, // numTrkChHw (max number of hardware channels, read only, so it's always 0)
|
||||||
|
0xff, // numTrkChUse (max number of channels to use, 0xff = max available)
|
||||||
|
0x02, // numConfigBlocks (number of GNSS systems), most modules support maximum 3 GNSS systems
|
||||||
|
// GNSS config format: gnssId, resTrkCh, maxTrkCh, reserved1, flags
|
||||||
|
0x00, 0x08, 0x10, 0x00, 0x01, 0x00, 0x00, 0x01, // GPS
|
||||||
|
0x01, 0x01, 0x03, 0x00, 0x01, 0x00, 0x00, 0x01 // SBAS
|
||||||
|
};
|
||||||
|
|
||||||
|
// It's not critical if the module doesn't acknowledge this configuration.
|
||||||
|
// The module should operate adequately with its factory or previously saved settings.
|
||||||
|
// It appears that there is a firmware bug in some GPS modules: When an attempt is made
|
||||||
|
// to overwrite a saved state with identical values, no ACK/NAK is received, contrary to
|
||||||
|
// what is specified in the Ublox documentation.
|
||||||
|
// There is also a possibility that the module may be GPS-only.
|
||||||
|
const uint8_t GPS::_message_GNSS[] = {
|
||||||
|
0x00, // msgVer (0 for this version)
|
||||||
|
0x00, // numTrkChHw (max number of hardware channels, read only, so it's always 0)
|
||||||
|
0xff, // numTrkChUse (max number of channels to use, 0xff = max available)
|
||||||
|
0x03, // numConfigBlocks (number of GNSS systems), most modules support maximum 3 GNSS systems
|
||||||
|
// GNSS config format: gnssId, resTrkCh, maxTrkCh, reserved1, flags
|
||||||
|
0x00, 0x08, 0x10, 0x00, 0x01, 0x00, 0x01, 0x01, // GPS
|
||||||
|
0x01, 0x01, 0x03, 0x00, 0x01, 0x00, 0x01, 0x01, // SBAS
|
||||||
|
0x06, 0x08, 0x0e, 0x00, 0x01, 0x00, 0x01, 0x01 // GLONASS
|
||||||
|
};
|
||||||
|
|
||||||
|
// Enable interference resistance, because we are using LoRa, WiFi and Bluetooth on same board,
|
||||||
|
// and we need to reduce interference from them
|
||||||
|
const uint8_t GPS::_message_JAM[] = {
|
||||||
|
// bbThreshold (Broadband jamming detection threshold) is set to 0x3F (63 in decimal)
|
||||||
|
// cwThreshold (CW jamming detection threshold) is set to 0x10 (16 in decimal)
|
||||||
|
// algorithmBits (Reserved algorithm settings) is set to 0x16B156 as recommended
|
||||||
|
// enable (Enable interference detection) is set to 1 (enabled)
|
||||||
|
0x3F, 0x10, 0xB1, 0x56, // config: Interference config word
|
||||||
|
// generalBits (General settings) is set to 0x31E as recommended
|
||||||
|
// antSetting (Antenna setting, 0=unknown, 1=passive, 2=active) is set to 0 (unknown)
|
||||||
|
// ToDo: Set to 1 (passive) or 2 (active) if known, for example from UBX-MON-HW, or from board info
|
||||||
|
// enable2 (Set to 1 to scan auxiliary bands, u-blox 8 / u-blox M8 only, otherwise ignored) is set to 1
|
||||||
|
// (enabled)
|
||||||
|
0x1E, 0x03, 0x00, 0x01 // config2: Extra settings for jamming/interference monitor
|
||||||
|
};
|
||||||
|
|
||||||
|
// Configure navigation engine expert settings:
|
||||||
|
const uint8_t GPS::_message_NAVX5[] = {
|
||||||
|
0x00, 0x00, // msgVer (0 for this version)
|
||||||
|
// minMax flag = 1: apply min/max SVs settings
|
||||||
|
// minCno flag = 1: apply minimum C/N0 setting
|
||||||
|
// initial3dfix flag = 0: apply initial 3D fix settings
|
||||||
|
// aop flag = 1: apply aopCfg (useAOP flag) settings (AssistNow Autonomous)
|
||||||
|
0x1B, 0x00, // mask1 (First parameters bitmask)
|
||||||
|
// adr flag = 0: apply ADR sensor fusion on/off setting (useAdr flag)
|
||||||
|
// If firmware is not ADR/UDR, enabling this flag will fail configuration
|
||||||
|
// ToDo: check this with UBX-MON-VER
|
||||||
|
0x00, 0x00, 0x00, 0x00, // mask2 (Second parameters bitmask)
|
||||||
|
0x00, 0x00, // Reserved
|
||||||
|
0x03, // minSVs (Minimum number of satellites for navigation) = 3
|
||||||
|
0x10, // maxSVs (Maximum number of satellites for navigation) = 16
|
||||||
|
0x06, // minCNO (Minimum satellite signal level for navigation) = 6 dBHz
|
||||||
|
0x00, // Reserved
|
||||||
|
0x00, // iniFix3D (Initial fix must be 3D) = 0 (disabled)
|
||||||
|
0x00, 0x00, // Reserved
|
||||||
|
0x00, // ackAiding (Issue acknowledgements for assistance message input) = 0 (disabled)
|
||||||
|
0x00, 0x00, // Reserved
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Reserved
|
||||||
|
0x00, // Reserved
|
||||||
|
0x01, // aopCfg (AssistNow Autonomous configuration) = 1 (enabled)
|
||||||
|
0x00, 0x00, // Reserved
|
||||||
|
0x00, 0x00, // Reserved
|
||||||
|
0x00, 0x00, 0x00, 0x00, // Reserved
|
||||||
|
0x00, 0x00, 0x00, // Reserved
|
||||||
|
0x01, // useAdr (Enable/disable ADR sensor fusion) = 1 (enabled)
|
||||||
|
};
|
||||||
|
|
||||||
|
// Set GPS update rate to 1Hz
|
||||||
|
// Lowering the update rate helps to save power.
|
||||||
|
// Additionally, for some new modules like the M9/M10, an update rate lower than 5Hz
|
||||||
|
// is recommended to avoid a known issue with satellites disappearing.
|
||||||
|
const uint8_t GPS::_message_1HZ[] = {
|
||||||
|
0xE8, 0x03, // Measurement Rate (1000ms for 1Hz)
|
||||||
|
0x01, 0x00, // Navigation rate, always 1 in GPS mode
|
||||||
|
0x01, 0x00, // Time reference
|
||||||
|
};
|
||||||
|
|
||||||
|
// Disable GGL. GGL - Geographic position (latitude and longitude), which provides the current geographical
|
||||||
|
// coordinates.
|
||||||
|
const uint8_t GPS::_message_GGL[] = {
|
||||||
|
0xF0, 0x01, // NMEA ID for GLL
|
||||||
|
0x01, // I/O Target 0=I/O, 1=UART1, 2=UART2, 3=USB, 4=SPI
|
||||||
|
0x00, // Disable
|
||||||
|
0x01, 0x01, 0x01, 0x01 // Reserved
|
||||||
|
};
|
||||||
|
|
||||||
|
// Enable GSA. GSA - GPS DOP and active satellites, used for detailing the satellites used in the positioning and
|
||||||
|
// the DOP (Dilution of Precision)
|
||||||
|
const uint8_t GPS::_message_GSA[] = {
|
||||||
|
0xF0, 0x02, // NMEA ID for GSA
|
||||||
|
0x01, // I/O Target 0=I/O, 1=UART1, 2=UART2, 3=USB, 4=SPI
|
||||||
|
0x01, // Enable
|
||||||
|
0x01, 0x01, 0x01, 0x01 // Reserved
|
||||||
|
};
|
||||||
|
|
||||||
|
// Disable GSV. GSV - Satellites in view, details the number and location of satellites in view.
|
||||||
|
const uint8_t GPS::_message_GSV[] = {
|
||||||
|
0xF0, 0x03, // NMEA ID for GSV
|
||||||
|
0x01, // I/O Target 0=I/O, 1=UART1, 2=UART2, 3=USB, 4=SPI
|
||||||
|
0x00, // Disable
|
||||||
|
0x01, 0x01, 0x01, 0x01 // Reserved
|
||||||
|
};
|
||||||
|
|
||||||
|
// Disable VTG. VTG - Track made good and ground speed, which provides course and speed information relative to
|
||||||
|
// the ground.
|
||||||
|
const uint8_t GPS::_message_VTG[] = {
|
||||||
|
0xF0, 0x05, // NMEA ID for VTG
|
||||||
|
0x01, // I/O Target 0=I/O, 1=UART1, 2=UART2, 3=USB, 4=SPI
|
||||||
|
0x00, // Disable
|
||||||
|
0x01, 0x01, 0x01, 0x01 // Reserved
|
||||||
|
};
|
||||||
|
|
||||||
|
// Enable RMC. RMC - Recommended Minimum data, the essential gps pvt (position, velocity, time) data.
|
||||||
|
const uint8_t GPS::_message_RMC[] = {
|
||||||
|
0xF0, 0x04, // NMEA ID for RMC
|
||||||
|
0x01, // I/O Target 0=I/O, 1=UART1, 2=UART2, 3=USB, 4=SPI
|
||||||
|
0x01, // Enable
|
||||||
|
0x01, 0x01, 0x01, 0x01 // Reserved
|
||||||
|
};
|
||||||
|
|
||||||
|
// Enable GGA. GGA - Global Positioning System Fix Data, which provides 3D location and accuracy data.
|
||||||
|
const uint8_t GPS::_message_GGA[] = {
|
||||||
|
0xF0, 0x00, // NMEA ID for GGA
|
||||||
|
0x01, // I/O Target 0=I/O, 1=UART1, 2=UART2, 3=USB, 4=SPI
|
||||||
|
0x01, // Enable
|
||||||
|
0x01, 0x01, 0x01, 0x01 // Reserved
|
||||||
|
};
|
||||||
|
|
||||||
|
// The Power Management configuration allows the GPS module to operate in different power modes for optimized
|
||||||
|
// power consumption. The modes supported are: 0x00 = Full power: The module operates at full power with no power
|
||||||
|
// saving. 0x01 = Balanced: The module dynamically adjusts the tracking behavior to balance power consumption.
|
||||||
|
// 0x02 = Interval: The module operates in a periodic mode, cycling between tracking and power saving states.
|
||||||
|
// 0x03 = Aggressive with 1 Hz: The module operates in a power saving mode with a 1 Hz update rate.
|
||||||
|
// 0x04 = Aggressive with 2 Hz: The module operates in a power saving mode with a 2 Hz update rate.
|
||||||
|
// 0x05 = Aggressive with 4 Hz: The module operates in a power saving mode with a 4 Hz update rate.
|
||||||
|
// The 'period' field specifies the position update and search period. It is only valid when the powerSetupValue
|
||||||
|
// is set to Interval; otherwise, it must be set to '0'. The 'onTime' field specifies the duration of the ON phase
|
||||||
|
// and must be smaller than the period. It is only valid when the powerSetupValue is set to Interval; otherwise,
|
||||||
|
// it must be set to '0'.
|
||||||
|
const uint8_t GPS::_message_PMS[] = {
|
||||||
|
0x00, // Version (0)
|
||||||
|
0x03, // Power setup value
|
||||||
|
0x00, 0x00, // period: not applicable, set to 0
|
||||||
|
0x00, 0x00, // onTime: not applicable, set to 0
|
||||||
|
0x97, 0x6F // reserved, generated by u-center
|
||||||
|
};
|
||||||
|
|
||||||
|
const uint8_t GPS::_message_SAVE[] = {
|
||||||
|
0x00, 0x00, 0x00, 0x00, // clearMask: no sections cleared
|
||||||
|
0xFF, 0xFF, 0x00, 0x00, // saveMask: save all sections
|
||||||
|
0x00, 0x00, 0x00, 0x00, // loadMask: no sections loaded
|
||||||
|
0x0F // deviceMask: BBR, Flash, EEPROM, and SPI Flash
|
||||||
|
};
|
||||||
@@ -1,5 +1,3 @@
|
|||||||
#include "main.h"
|
|
||||||
|
|
||||||
#ifdef HAS_NCP5623
|
#ifdef HAS_NCP5623
|
||||||
#include <NCP5623.h>
|
#include <NCP5623.h>
|
||||||
extern NCP5623 rgb;
|
extern NCP5623 rgb;
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||||||
#if HAS_SCREEN
|
#if HAS_SCREEN
|
||||||
#include <OLEDDisplay.h>
|
#include <OLEDDisplay.h>
|
||||||
|
|
||||||
|
#include "DisplayFormatters.h"
|
||||||
#include "GPS.h"
|
#include "GPS.h"
|
||||||
#include "MeshService.h"
|
#include "MeshService.h"
|
||||||
#include "NodeDB.h"
|
#include "NodeDB.h"
|
||||||
@@ -36,11 +37,11 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||||||
#include "mesh-pb-constants.h"
|
#include "mesh-pb-constants.h"
|
||||||
#include "mesh/Channels.h"
|
#include "mesh/Channels.h"
|
||||||
#include "mesh/generated/meshtastic/deviceonly.pb.h"
|
#include "mesh/generated/meshtastic/deviceonly.pb.h"
|
||||||
|
#include "meshUtils.h"
|
||||||
#include "modules/ExternalNotificationModule.h"
|
#include "modules/ExternalNotificationModule.h"
|
||||||
#include "modules/TextMessageModule.h"
|
#include "modules/TextMessageModule.h"
|
||||||
#include "sleep.h"
|
#include "sleep.h"
|
||||||
#include "target_specific.h"
|
#include "target_specific.h"
|
||||||
#include "utils.h"
|
|
||||||
|
|
||||||
#ifdef ARCH_ESP32
|
#ifdef ARCH_ESP32
|
||||||
#include "esp_task_wdt.h"
|
#include "esp_task_wdt.h"
|
||||||
@@ -160,17 +161,9 @@ static void drawIconScreen(const char *upperMsg, OLEDDisplay *display, OLEDDispl
|
|||||||
xstr(APP_VERSION_SHORT)); // Note: we don't bother printing region or now, it makes the string too long
|
xstr(APP_VERSION_SHORT)); // Note: we don't bother printing region or now, it makes the string too long
|
||||||
display->drawString(x + SCREEN_WIDTH - display->getStringWidth(buf), y + 0, buf);
|
display->drawString(x + SCREEN_WIDTH - display->getStringWidth(buf), y + 0, buf);
|
||||||
screen->forceDisplay();
|
screen->forceDisplay();
|
||||||
|
|
||||||
// FIXME - draw serial # somewhere?
|
// FIXME - draw serial # somewhere?
|
||||||
}
|
}
|
||||||
|
|
||||||
static void drawBootScreen(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y)
|
|
||||||
{
|
|
||||||
// Draw region in upper left
|
|
||||||
const char *region = myRegion ? myRegion->name : NULL;
|
|
||||||
drawIconScreen(region, display, state, x, y);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void drawOEMIconScreen(const char *upperMsg, OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y)
|
static void drawOEMIconScreen(const char *upperMsg, OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y)
|
||||||
{
|
{
|
||||||
// draw an xbm image.
|
// draw an xbm image.
|
||||||
@@ -220,6 +213,28 @@ static void drawOEMBootScreen(OLEDDisplay *display, OLEDDisplayUiState *state, i
|
|||||||
drawOEMIconScreen(region, display, state, x, y);
|
drawOEMIconScreen(region, display, state, x, y);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void drawFrameText(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y, const char *message)
|
||||||
|
{
|
||||||
|
uint16_t x_offset = display->width() / 2;
|
||||||
|
display->setTextAlignment(TEXT_ALIGN_CENTER);
|
||||||
|
display->setFont(FONT_MEDIUM);
|
||||||
|
display->drawString(x_offset + x, 26 + y, message);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void drawBootScreen(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y)
|
||||||
|
{
|
||||||
|
#ifdef ARCH_ESP32
|
||||||
|
if (wakeCause == ESP_SLEEP_WAKEUP_TIMER || wakeCause == ESP_SLEEP_WAKEUP_EXT1) {
|
||||||
|
drawFrameText(display, state, x, y, "Resuming...");
|
||||||
|
} else
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
// Draw region in upper left
|
||||||
|
const char *region = myRegion ? myRegion->name : NULL;
|
||||||
|
drawIconScreen(region, display, state, x, y);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Used on boot when a certificate is being created
|
// Used on boot when a certificate is being created
|
||||||
static void drawSSLScreen(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y)
|
static void drawSSLScreen(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y)
|
||||||
{
|
{
|
||||||
@@ -320,22 +335,6 @@ static void drawFrameBluetooth(OLEDDisplay *display, OLEDDisplayUiState *state,
|
|||||||
display->drawString(x_offset + x, y_offset + y, deviceName);
|
display->drawString(x_offset + x, y_offset + y, deviceName);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void drawFrameShutdown(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y)
|
|
||||||
{
|
|
||||||
uint16_t x_offset = display->width() / 2;
|
|
||||||
display->setTextAlignment(TEXT_ALIGN_CENTER);
|
|
||||||
display->setFont(FONT_MEDIUM);
|
|
||||||
display->drawString(x_offset + x, 26 + y, "Shutting down...");
|
|
||||||
}
|
|
||||||
|
|
||||||
static void drawFrameReboot(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y)
|
|
||||||
{
|
|
||||||
uint16_t x_offset = display->width() / 2;
|
|
||||||
display->setTextAlignment(TEXT_ALIGN_CENTER);
|
|
||||||
display->setFont(FONT_MEDIUM);
|
|
||||||
display->drawString(x_offset + x, 26 + y, "Rebooting...");
|
|
||||||
}
|
|
||||||
|
|
||||||
static void drawFrameFirmware(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y)
|
static void drawFrameFirmware(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y)
|
||||||
{
|
{
|
||||||
display->setTextAlignment(TEXT_ALIGN_CENTER);
|
display->setTextAlignment(TEXT_ALIGN_CENTER);
|
||||||
@@ -365,7 +364,7 @@ static void drawCriticalFaultFrame(OLEDDisplay *display, OLEDDisplayUiState *sta
|
|||||||
// Ignore messages originating from phone (from the current node 0x0) unless range test or store and forward module are enabled
|
// Ignore messages originating from phone (from the current node 0x0) unless range test or store and forward module are enabled
|
||||||
static bool shouldDrawMessage(const meshtastic_MeshPacket *packet)
|
static bool shouldDrawMessage(const meshtastic_MeshPacket *packet)
|
||||||
{
|
{
|
||||||
return packet->from != 0 && !moduleConfig.range_test.enabled && !moduleConfig.store_forward.enabled;
|
return packet->from != 0 && !moduleConfig.store_forward.enabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Draw the last text message we received
|
/// Draw the last text message we received
|
||||||
@@ -374,7 +373,7 @@ static void drawTextMessageFrame(OLEDDisplay *display, OLEDDisplayUiState *state
|
|||||||
// the max length of this buffer is much longer than we can possibly print
|
// the max length of this buffer is much longer than we can possibly print
|
||||||
static char tempBuf[237];
|
static char tempBuf[237];
|
||||||
|
|
||||||
meshtastic_MeshPacket &mp = devicestate.rx_text_message;
|
const meshtastic_MeshPacket &mp = devicestate.rx_text_message;
|
||||||
meshtastic_NodeInfoLite *node = nodeDB.getMeshNode(getFrom(&mp));
|
meshtastic_NodeInfoLite *node = nodeDB.getMeshNode(getFrom(&mp));
|
||||||
// LOG_DEBUG("drawing text message from 0x%x: %s\n", mp.from,
|
// LOG_DEBUG("drawing text message from 0x%x: %s\n", mp.from,
|
||||||
// mp.decoded.variant.data.decoded.bytes);
|
// mp.decoded.variant.data.decoded.bytes);
|
||||||
@@ -490,7 +489,7 @@ static void drawBattery(OLEDDisplay *display, int16_t x, int16_t y, uint8_t *img
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Draw nodes status
|
// Draw nodes status
|
||||||
static void drawNodes(OLEDDisplay *display, int16_t x, int16_t y, NodeStatus *nodeStatus)
|
static void drawNodes(OLEDDisplay *display, int16_t x, int16_t y, const NodeStatus *nodeStatus)
|
||||||
{
|
{
|
||||||
char usersString[20];
|
char usersString[20];
|
||||||
snprintf(usersString, sizeof(usersString), "%d/%d", nodeStatus->getNumOnline(), nodeStatus->getNumTotal());
|
snprintf(usersString, sizeof(usersString), "%d/%d", nodeStatus->getNumOnline(), nodeStatus->getNumTotal());
|
||||||
@@ -858,14 +857,14 @@ static void drawNodeInfo(OLEDDisplay *display, OLEDDisplayUiState *state, int16_
|
|||||||
bool hasNodeHeading = false;
|
bool hasNodeHeading = false;
|
||||||
|
|
||||||
if (ourNode && hasValidPosition(ourNode)) {
|
if (ourNode && hasValidPosition(ourNode)) {
|
||||||
meshtastic_PositionLite &op = ourNode->position;
|
const meshtastic_PositionLite &op = ourNode->position;
|
||||||
float myHeading = estimatedHeading(DegD(op.latitude_i), DegD(op.longitude_i));
|
float myHeading = estimatedHeading(DegD(op.latitude_i), DegD(op.longitude_i));
|
||||||
drawCompassNorth(display, compassX, compassY, myHeading);
|
drawCompassNorth(display, compassX, compassY, myHeading);
|
||||||
|
|
||||||
if (hasValidPosition(node)) {
|
if (hasValidPosition(node)) {
|
||||||
// display direction toward node
|
// display direction toward node
|
||||||
hasNodeHeading = true;
|
hasNodeHeading = true;
|
||||||
meshtastic_PositionLite &p = node->position;
|
const meshtastic_PositionLite &p = node->position;
|
||||||
float d =
|
float d =
|
||||||
GeoCoord::latLongToMeter(DegD(p.latitude_i), DegD(p.longitude_i), DegD(op.latitude_i), DegD(op.longitude_i));
|
GeoCoord::latLongToMeter(DegD(p.latitude_i), DegD(p.longitude_i), DegD(op.latitude_i), DegD(op.longitude_i));
|
||||||
|
|
||||||
@@ -906,20 +905,6 @@ static void drawNodeInfo(OLEDDisplay *display, OLEDDisplayUiState *state, int16_
|
|||||||
drawColumns(display, x, y, fields);
|
drawColumns(display, x, y, fields);
|
||||||
}
|
}
|
||||||
|
|
||||||
// #ifdef RAK4630
|
|
||||||
// Screen::Screen(uint8_t address, int sda, int scl) : OSThread("Screen"), cmdQueue(32), dispdev(address, sda, scl),
|
|
||||||
// dispdev_oled(address, sda, scl), ui(&dispdev)
|
|
||||||
// {
|
|
||||||
// address_found = address;
|
|
||||||
// cmdQueue.setReader(this);
|
|
||||||
// if (screen_found) {
|
|
||||||
// (void)dispdev;
|
|
||||||
// AutoOLEDWire dispdev = dispdev_oled;
|
|
||||||
// (void)ui;
|
|
||||||
// OLEDDisplayUi ui(&dispdev);
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// #else
|
|
||||||
Screen::Screen(ScanI2C::DeviceAddress address, meshtastic_Config_DisplayConfig_OledType screenType, OLEDDISPLAY_GEOMETRY geometry)
|
Screen::Screen(ScanI2C::DeviceAddress address, meshtastic_Config_DisplayConfig_OledType screenType, OLEDDISPLAY_GEOMETRY geometry)
|
||||||
: concurrency::OSThread("Screen"), address_found(address), model(screenType), geometry(geometry), cmdQueue(32),
|
: concurrency::OSThread("Screen"), address_found(address), model(screenType), geometry(geometry), cmdQueue(32),
|
||||||
dispdev(address.address, -1, -1, geometry, (address.port == ScanI2C::I2CPort::WIRE1) ? HW_I2C::I2C_TWO : HW_I2C::I2C_ONE),
|
dispdev(address.address, -1, -1, geometry, (address.port == ScanI2C::I2CPort::WIRE1) ? HW_I2C::I2C_TWO : HW_I2C::I2C_ONE),
|
||||||
@@ -927,7 +912,7 @@ Screen::Screen(ScanI2C::DeviceAddress address, meshtastic_Config_DisplayConfig_O
|
|||||||
{
|
{
|
||||||
cmdQueue.setReader(this);
|
cmdQueue.setReader(this);
|
||||||
}
|
}
|
||||||
// #endif
|
|
||||||
/**
|
/**
|
||||||
* Prepare the display for the unit going to the lowest power mode possible. Most screens will just
|
* Prepare the display for the unit going to the lowest power mode possible. Most screens will just
|
||||||
* poweroff, but eink screens will show a "I'm sleeping" graphic, possibly with a QR code
|
* poweroff, but eink screens will show a "I'm sleeping" graphic, possibly with a QR code
|
||||||
@@ -1058,7 +1043,8 @@ void Screen::setup()
|
|||||||
nodeStatusObserver.observe(&nodeStatus->onNewStatus);
|
nodeStatusObserver.observe(&nodeStatus->onNewStatus);
|
||||||
if (textMessageModule)
|
if (textMessageModule)
|
||||||
textMessageObserver.observe(textMessageModule);
|
textMessageObserver.observe(textMessageModule);
|
||||||
inputObserver.observe(inputBroker);
|
if (inputBroker)
|
||||||
|
inputObserver.observe(inputBroker);
|
||||||
|
|
||||||
// Modules can notify screen about refresh
|
// Modules can notify screen about refresh
|
||||||
MeshModule::observeUIEvents(&uiFrameEventObserver);
|
MeshModule::observeUIEvents(&uiFrameEventObserver);
|
||||||
@@ -1243,11 +1229,8 @@ void Screen::setWelcomeFrames()
|
|||||||
{
|
{
|
||||||
if (address_found.address) {
|
if (address_found.address) {
|
||||||
// LOG_DEBUG("showing Welcome frames\n");
|
// LOG_DEBUG("showing Welcome frames\n");
|
||||||
ui.disableAllIndicators();
|
static FrameCallback frames[] = {drawWelcomeScreen};
|
||||||
|
setFrameImmediateDraw(frames);
|
||||||
static FrameCallback welcomeFrames[] = {drawWelcomeScreen};
|
|
||||||
ui.setFrames(welcomeFrames, 1);
|
|
||||||
ui.update();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1334,12 +1317,15 @@ void Screen::handleStartBluetoothPinScreen(uint32_t pin)
|
|||||||
LOG_DEBUG("showing bluetooth screen\n");
|
LOG_DEBUG("showing bluetooth screen\n");
|
||||||
showingNormalScreen = false;
|
showingNormalScreen = false;
|
||||||
|
|
||||||
static FrameCallback btFrames[] = {drawFrameBluetooth};
|
static FrameCallback frames[] = {drawFrameBluetooth};
|
||||||
|
|
||||||
snprintf(btPIN, sizeof(btPIN), "%06u", pin);
|
snprintf(btPIN, sizeof(btPIN), "%06u", pin);
|
||||||
|
setFrameImmediateDraw(frames);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Screen::setFrameImmediateDraw(FrameCallback *drawFrames)
|
||||||
|
{
|
||||||
ui.disableAllIndicators();
|
ui.disableAllIndicators();
|
||||||
ui.setFrames(btFrames, 1);
|
ui.setFrames(drawFrames, 1);
|
||||||
setFastFramerate();
|
setFastFramerate();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1348,11 +1334,12 @@ void Screen::handleShutdownScreen()
|
|||||||
LOG_DEBUG("showing shutdown screen\n");
|
LOG_DEBUG("showing shutdown screen\n");
|
||||||
showingNormalScreen = false;
|
showingNormalScreen = false;
|
||||||
|
|
||||||
static FrameCallback shutdownFrames[] = {drawFrameShutdown};
|
auto frame = [](OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y) -> void {
|
||||||
|
drawFrameText(display, state, x, y, "Shutting down...");
|
||||||
|
};
|
||||||
|
static FrameCallback frames[] = {frame};
|
||||||
|
|
||||||
ui.disableAllIndicators();
|
setFrameImmediateDraw(frames);
|
||||||
ui.setFrames(shutdownFrames, 1);
|
|
||||||
setFastFramerate();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Screen::handleRebootScreen()
|
void Screen::handleRebootScreen()
|
||||||
@@ -1360,11 +1347,11 @@ void Screen::handleRebootScreen()
|
|||||||
LOG_DEBUG("showing reboot screen\n");
|
LOG_DEBUG("showing reboot screen\n");
|
||||||
showingNormalScreen = false;
|
showingNormalScreen = false;
|
||||||
|
|
||||||
static FrameCallback rebootFrames[] = {drawFrameReboot};
|
auto frame = [](OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y) -> void {
|
||||||
|
drawFrameText(display, state, x, y, "Rebooting...");
|
||||||
ui.disableAllIndicators();
|
};
|
||||||
ui.setFrames(rebootFrames, 1);
|
static FrameCallback frames[] = {frame};
|
||||||
setFastFramerate();
|
setFrameImmediateDraw(frames);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Screen::handleStartFirmwareUpdateScreen()
|
void Screen::handleStartFirmwareUpdateScreen()
|
||||||
@@ -1372,11 +1359,8 @@ void Screen::handleStartFirmwareUpdateScreen()
|
|||||||
LOG_DEBUG("showing firmware screen\n");
|
LOG_DEBUG("showing firmware screen\n");
|
||||||
showingNormalScreen = false;
|
showingNormalScreen = false;
|
||||||
|
|
||||||
static FrameCallback btFrames[] = {drawFrameFirmware};
|
static FrameCallback frames[] = {drawFrameFirmware};
|
||||||
|
setFrameImmediateDraw(frames);
|
||||||
ui.disableAllIndicators();
|
|
||||||
ui.setFrames(btFrames, 1);
|
|
||||||
setFastFramerate();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Screen::blink()
|
void Screen::blink()
|
||||||
@@ -1637,65 +1621,8 @@ void DebugInfo::drawFrameWiFi(OLEDDisplay *display, OLEDDisplayUiState *state, i
|
|||||||
} else {
|
} else {
|
||||||
// Codes:
|
// Codes:
|
||||||
// https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-guides/wifi.html#wi-fi-reason-code
|
// https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-guides/wifi.html#wi-fi-reason-code
|
||||||
if (getWifiDisconnectReason() == 2) {
|
display->drawString(x, y + FONT_HEIGHT_SMALL * 1,
|
||||||
display->drawString(x, y + FONT_HEIGHT_SMALL * 1, "Authentication Invalid");
|
WiFi.disconnectReasonName(static_cast<wifi_err_reason_t>(getWifiDisconnectReason())));
|
||||||
} else if (getWifiDisconnectReason() == 3) {
|
|
||||||
display->drawString(x, y + FONT_HEIGHT_SMALL * 1, "De-authenticated");
|
|
||||||
} else if (getWifiDisconnectReason() == 4) {
|
|
||||||
display->drawString(x, y + FONT_HEIGHT_SMALL * 1, "Disassociated Expired");
|
|
||||||
} else if (getWifiDisconnectReason() == 5) {
|
|
||||||
display->drawString(x, y + FONT_HEIGHT_SMALL * 1, "AP - Too Many Clients");
|
|
||||||
} else if (getWifiDisconnectReason() == 6) {
|
|
||||||
display->drawString(x, y + FONT_HEIGHT_SMALL * 1, "NOT_AUTHED");
|
|
||||||
} else if (getWifiDisconnectReason() == 7) {
|
|
||||||
display->drawString(x, y + FONT_HEIGHT_SMALL * 1, "NOT_ASSOCED");
|
|
||||||
} else if (getWifiDisconnectReason() == 8) {
|
|
||||||
display->drawString(x, y + FONT_HEIGHT_SMALL * 1, "Disassociated");
|
|
||||||
} else if (getWifiDisconnectReason() == 9) {
|
|
||||||
display->drawString(x, y + FONT_HEIGHT_SMALL * 1, "ASSOC_NOT_AUTHED");
|
|
||||||
} else if (getWifiDisconnectReason() == 10) {
|
|
||||||
display->drawString(x, y + FONT_HEIGHT_SMALL * 1, "DISASSOC_PWRCAP_BAD");
|
|
||||||
} else if (getWifiDisconnectReason() == 11) {
|
|
||||||
display->drawString(x, y + FONT_HEIGHT_SMALL * 1, "DISASSOC_SUPCHAN_BAD");
|
|
||||||
} else if (getWifiDisconnectReason() == 13) {
|
|
||||||
display->drawString(x, y + FONT_HEIGHT_SMALL * 1, "IE_INVALID");
|
|
||||||
} else if (getWifiDisconnectReason() == 14) {
|
|
||||||
display->drawString(x, y + FONT_HEIGHT_SMALL * 1, "MIC_FAILURE");
|
|
||||||
} else if (getWifiDisconnectReason() == 15) {
|
|
||||||
display->drawString(x, y + FONT_HEIGHT_SMALL * 1, "AP Handshake Timeout");
|
|
||||||
} else if (getWifiDisconnectReason() == 16) {
|
|
||||||
display->drawString(x, y + FONT_HEIGHT_SMALL * 1, "GROUP_KEY_UPDATE_TIMEOUT");
|
|
||||||
} else if (getWifiDisconnectReason() == 17) {
|
|
||||||
display->drawString(x, y + FONT_HEIGHT_SMALL * 1, "IE_IN_4WAY_DIFFERS");
|
|
||||||
} else if (getWifiDisconnectReason() == 18) {
|
|
||||||
display->drawString(x, y + FONT_HEIGHT_SMALL * 1, "Invalid Group Cipher");
|
|
||||||
} else if (getWifiDisconnectReason() == 19) {
|
|
||||||
display->drawString(x, y + FONT_HEIGHT_SMALL * 1, "Invalid Pairwise Cipher");
|
|
||||||
} else if (getWifiDisconnectReason() == 20) {
|
|
||||||
display->drawString(x, y + FONT_HEIGHT_SMALL * 1, "AKMP_INVALID");
|
|
||||||
} else if (getWifiDisconnectReason() == 21) {
|
|
||||||
display->drawString(x, y + FONT_HEIGHT_SMALL * 1, "UNSUPP_RSN_IE_VERSION");
|
|
||||||
} else if (getWifiDisconnectReason() == 22) {
|
|
||||||
display->drawString(x, y + FONT_HEIGHT_SMALL * 1, "INVALID_RSN_IE_CAP");
|
|
||||||
} else if (getWifiDisconnectReason() == 23) {
|
|
||||||
display->drawString(x, y + FONT_HEIGHT_SMALL * 1, "802_1X_AUTH_FAILED");
|
|
||||||
} else if (getWifiDisconnectReason() == 24) {
|
|
||||||
display->drawString(x, y + FONT_HEIGHT_SMALL * 1, "CIPHER_SUITE_REJECTED");
|
|
||||||
} else if (getWifiDisconnectReason() == 200) {
|
|
||||||
display->drawString(x, y + FONT_HEIGHT_SMALL * 1, "BEACON_TIMEOUT");
|
|
||||||
} else if (getWifiDisconnectReason() == 201) {
|
|
||||||
display->drawString(x, y + FONT_HEIGHT_SMALL * 1, "AP Not Found");
|
|
||||||
} else if (getWifiDisconnectReason() == 202) {
|
|
||||||
display->drawString(x, y + FONT_HEIGHT_SMALL * 1, "AUTH_FAIL");
|
|
||||||
} else if (getWifiDisconnectReason() == 203) {
|
|
||||||
display->drawString(x, y + FONT_HEIGHT_SMALL * 1, "ASSOC_FAIL");
|
|
||||||
} else if (getWifiDisconnectReason() == 204) {
|
|
||||||
display->drawString(x, y + FONT_HEIGHT_SMALL * 1, "HANDSHAKE_TIMEOUT");
|
|
||||||
} else if (getWifiDisconnectReason() == 205) {
|
|
||||||
display->drawString(x, y + FONT_HEIGHT_SMALL * 1, "Connection Failed");
|
|
||||||
} else {
|
|
||||||
display->drawString(x, y + FONT_HEIGHT_SMALL * 1, "Unknown Status");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
display->drawString(x, y + FONT_HEIGHT_SMALL * 2, "SSID: " + String(wifiName));
|
display->drawString(x, y + FONT_HEIGHT_SMALL * 2, "SSID: " + String(wifiName));
|
||||||
@@ -1742,37 +1669,7 @@ void DebugInfo::drawFrameSettings(OLEDDisplay *display, OLEDDisplayUiState *stat
|
|||||||
display->drawString(x + 1, y, String("USB"));
|
display->drawString(x + 1, y, String("USB"));
|
||||||
}
|
}
|
||||||
|
|
||||||
auto mode = "";
|
auto mode = DisplayFormatters::getModemPresetDisplayName(config.lora.modem_preset, true);
|
||||||
|
|
||||||
switch (config.lora.modem_preset) {
|
|
||||||
case meshtastic_Config_LoRaConfig_ModemPreset_SHORT_SLOW:
|
|
||||||
mode = "ShortS";
|
|
||||||
break;
|
|
||||||
case meshtastic_Config_LoRaConfig_ModemPreset_SHORT_FAST:
|
|
||||||
mode = "ShortF";
|
|
||||||
break;
|
|
||||||
case meshtastic_Config_LoRaConfig_ModemPreset_MEDIUM_SLOW:
|
|
||||||
mode = "MedS";
|
|
||||||
break;
|
|
||||||
case meshtastic_Config_LoRaConfig_ModemPreset_MEDIUM_FAST:
|
|
||||||
mode = "MedF";
|
|
||||||
break;
|
|
||||||
case meshtastic_Config_LoRaConfig_ModemPreset_LONG_SLOW:
|
|
||||||
mode = "LongS";
|
|
||||||
break;
|
|
||||||
case meshtastic_Config_LoRaConfig_ModemPreset_LONG_FAST:
|
|
||||||
mode = "LongF";
|
|
||||||
break;
|
|
||||||
case meshtastic_Config_LoRaConfig_ModemPreset_LONG_MODERATE:
|
|
||||||
mode = "LongM";
|
|
||||||
break;
|
|
||||||
case meshtastic_Config_LoRaConfig_ModemPreset_VERY_LONG_SLOW:
|
|
||||||
mode = "VeryL";
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
mode = "Custom";
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
display->drawString(x + SCREEN_WIDTH - display->getStringWidth(mode), y, mode);
|
display->drawString(x + SCREEN_WIDTH - display->getStringWidth(mode), y, mode);
|
||||||
if (config.display.heading_bold)
|
if (config.display.heading_bold)
|
||||||
@@ -1839,23 +1736,6 @@ void DebugInfo::drawFrameSettings(OLEDDisplay *display, OLEDDisplayUiState *stat
|
|||||||
heartbeat = !heartbeat;
|
heartbeat = !heartbeat;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
// adjust Brightness cycle through 1 to 254 as long as attachDuringLongPress is true
|
|
||||||
void Screen::adjustBrightness()
|
|
||||||
{
|
|
||||||
if (!useDisplay)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (brightness == 254) {
|
|
||||||
brightness = 0;
|
|
||||||
} else {
|
|
||||||
brightness++;
|
|
||||||
}
|
|
||||||
int width = brightness / (254.00 / SCREEN_WIDTH);
|
|
||||||
dispdev.drawRect(0, 30, SCREEN_WIDTH, 4);
|
|
||||||
dispdev.fillRect(0, 31, width, 2);
|
|
||||||
dispdev.display();
|
|
||||||
dispdev.setBrightness(brightness);
|
|
||||||
}
|
|
||||||
|
|
||||||
int Screen::handleStatusUpdate(const meshtastic::Status *arg)
|
int Screen::handleStatusUpdate(const meshtastic::Status *arg)
|
||||||
{
|
{
|
||||||
@@ -1900,7 +1780,7 @@ int Screen::handleUIFrameEvent(const UIFrameEvent *event)
|
|||||||
int Screen::handleInputEvent(const InputEvent *event)
|
int Screen::handleInputEvent(const InputEvent *event)
|
||||||
{
|
{
|
||||||
if (showingNormalScreen && moduleFrames.size() == 0) {
|
if (showingNormalScreen && moduleFrames.size() == 0) {
|
||||||
LOG_DEBUG("Screen::handleInputEvent from %s\n", event->source);
|
// LOG_DEBUG("Screen::handleInputEvent from %s\n", event->source);
|
||||||
if (event->inputEvent == static_cast<char>(meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_LEFT)) {
|
if (event->inputEvent == static_cast<char>(meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_LEFT)) {
|
||||||
showPrevFrame();
|
showPrevFrame();
|
||||||
} else if (event->inputEvent == static_cast<char>(meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_RIGHT)) {
|
} else if (event->inputEvent == static_cast<char>(meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_RIGHT)) {
|
||||||
|
|||||||
@@ -19,7 +19,6 @@ class Screen
|
|||||||
void setup() {}
|
void setup() {}
|
||||||
void setOn(bool) {}
|
void setOn(bool) {}
|
||||||
void print(const char *) {}
|
void print(const char *) {}
|
||||||
void adjustBrightness() {}
|
|
||||||
void doDeepSleep() {}
|
void doDeepSleep() {}
|
||||||
void forceDisplay() {}
|
void forceDisplay() {}
|
||||||
void startBluetoothPinScreen(uint32_t pin) {}
|
void startBluetoothPinScreen(uint32_t pin) {}
|
||||||
@@ -161,7 +160,6 @@ class Screen : public concurrency::OSThread
|
|||||||
void showNextFrame() { enqueueCmd(ScreenCmd{.cmd = Cmd::SHOW_NEXT_FRAME}); }
|
void showNextFrame() { enqueueCmd(ScreenCmd{.cmd = Cmd::SHOW_NEXT_FRAME}); }
|
||||||
|
|
||||||
// Implementation to Adjust Brightness
|
// Implementation to Adjust Brightness
|
||||||
void adjustBrightness();
|
|
||||||
uint8_t brightness = BRIGHTNESS_DEFAULT;
|
uint8_t brightness = BRIGHTNESS_DEFAULT;
|
||||||
|
|
||||||
/// Starts showing the Bluetooth PIN screen.
|
/// Starts showing the Bluetooth PIN screen.
|
||||||
@@ -363,6 +361,9 @@ class Screen : public concurrency::OSThread
|
|||||||
/// Try to start drawing ASAP
|
/// Try to start drawing ASAP
|
||||||
void setFastFramerate();
|
void setFastFramerate();
|
||||||
|
|
||||||
|
// Sets frame up for immediate drawing
|
||||||
|
void setFrameImmediateDraw(FrameCallback *drawFrames);
|
||||||
|
|
||||||
/// Called when debug screen is to be drawn, calls through to debugInfo.drawFrame.
|
/// Called when debug screen is to be drawn, calls through to debugInfo.drawFrame.
|
||||||
static void drawDebugInfoTrampoline(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y);
|
static void drawDebugInfoTrampoline(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y);
|
||||||
|
|
||||||
|
|||||||
@@ -1,12 +1,13 @@
|
|||||||
#include "configuration.h"
|
#include "configuration.h"
|
||||||
|
#include "main.h"
|
||||||
|
|
||||||
#ifndef TFT_BACKLIGHT_ON
|
#ifndef TFT_BACKLIGHT_ON
|
||||||
#define TFT_BACKLIGHT_ON HIGH
|
#define TFT_BACKLIGHT_ON HIGH
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// convert 24-bit color to 16-bit (56K)
|
#ifndef TFT_MESH
|
||||||
#define COLOR565(r, g, b) (((r & 0xF8) << 8) | ((g & 0xFC) << 3) | ((b & 0xF8) >> 3))
|
|
||||||
#define TFT_MESH COLOR565(0x67, 0xEA, 0x94)
|
#define TFT_MESH COLOR565(0x67, 0xEA, 0x94)
|
||||||
|
#endif
|
||||||
|
|
||||||
#if defined(ST7735S)
|
#if defined(ST7735S)
|
||||||
#include <LovyanGFX.hpp> // Graphics and font library for ST7735 driver chip
|
#include <LovyanGFX.hpp> // Graphics and font library for ST7735 driver chip
|
||||||
@@ -81,8 +82,16 @@ class LGFX : public lgfx::LGFX_Device
|
|||||||
{
|
{
|
||||||
auto cfg = _light_instance.config(); // Gets a structure for backlight settings.
|
auto cfg = _light_instance.config(); // Gets a structure for backlight settings.
|
||||||
|
|
||||||
|
#ifdef ST7735_BL_V03
|
||||||
|
if (heltec_version == 3) {
|
||||||
|
cfg.pin_bl = ST7735_BL_V03;
|
||||||
|
} else {
|
||||||
|
cfg.pin_bl = ST7735_BL_V05;
|
||||||
|
}
|
||||||
|
#else
|
||||||
cfg.pin_bl = ST7735_BL; // Pin number to which the backlight is connected
|
cfg.pin_bl = ST7735_BL; // Pin number to which the backlight is connected
|
||||||
cfg.invert = true; // true to invert the brightness of the backlight
|
#endif
|
||||||
|
cfg.invert = true; // true to invert the brightness of the backlight
|
||||||
// cfg.freq = 44100; // PWM frequency of backlight
|
// cfg.freq = 44100; // PWM frequency of backlight
|
||||||
// cfg.pwm_channel = 1; // PWM channel number to use
|
// cfg.pwm_channel = 1; // PWM channel number to use
|
||||||
|
|
||||||
@@ -364,9 +373,23 @@ void TFTDisplay::sendCommand(uint8_t com)
|
|||||||
// handle display on/off directly
|
// handle display on/off directly
|
||||||
switch (com) {
|
switch (com) {
|
||||||
case DISPLAYON: {
|
case DISPLAYON: {
|
||||||
|
#if defined(ST7735_BACKLIGHT_EN_V03) && defined(TFT_BACKLIGHT_ON)
|
||||||
|
if (heltec_version == 3) {
|
||||||
|
digitalWrite(ST7735_BACKLIGHT_EN_V03, TFT_BACKLIGHT_ON);
|
||||||
|
} else {
|
||||||
|
digitalWrite(ST7735_BACKLIGHT_EN_V05, TFT_BACKLIGHT_ON);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
#if defined(TFT_BL) && defined(TFT_BACKLIGHT_ON)
|
#if defined(TFT_BL) && defined(TFT_BACKLIGHT_ON)
|
||||||
digitalWrite(TFT_BL, TFT_BACKLIGHT_ON);
|
digitalWrite(TFT_BL, TFT_BACKLIGHT_ON);
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef VTFT_CTRL_V03
|
||||||
|
if (heltec_version == 3) {
|
||||||
|
digitalWrite(VTFT_CTRL_V03, LOW);
|
||||||
|
} else {
|
||||||
|
digitalWrite(VTFT_CTRL_V05, LOW);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
#ifdef VTFT_CTRL
|
#ifdef VTFT_CTRL
|
||||||
digitalWrite(VTFT_CTRL, LOW);
|
digitalWrite(VTFT_CTRL, LOW);
|
||||||
#endif
|
#endif
|
||||||
@@ -376,9 +399,23 @@ void TFTDisplay::sendCommand(uint8_t com)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case DISPLAYOFF: {
|
case DISPLAYOFF: {
|
||||||
|
#if defined(ST7735_BACKLIGHT_EN_V03) && defined(TFT_BACKLIGHT_ON)
|
||||||
|
if (heltec_version == 3) {
|
||||||
|
digitalWrite(ST7735_BACKLIGHT_EN_V03, !TFT_BACKLIGHT_ON);
|
||||||
|
} else {
|
||||||
|
digitalWrite(ST7735_BACKLIGHT_EN_V05, !TFT_BACKLIGHT_ON);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
#if defined(TFT_BL) && defined(TFT_BACKLIGHT_ON)
|
#if defined(TFT_BL) && defined(TFT_BACKLIGHT_ON)
|
||||||
digitalWrite(TFT_BL, !TFT_BACKLIGHT_ON);
|
digitalWrite(TFT_BL, !TFT_BACKLIGHT_ON);
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef VTFT_CTRL_V03
|
||||||
|
if (heltec_version == 3) {
|
||||||
|
digitalWrite(VTFT_CTRL_V03, HIGH);
|
||||||
|
} else {
|
||||||
|
digitalWrite(VTFT_CTRL_V05, HIGH);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
#ifdef VTFT_CTRL
|
#ifdef VTFT_CTRL
|
||||||
digitalWrite(VTFT_CTRL, HIGH);
|
digitalWrite(VTFT_CTRL, HIGH);
|
||||||
#endif
|
#endif
|
||||||
@@ -436,6 +473,16 @@ bool TFTDisplay::connect()
|
|||||||
pinMode(TFT_BL, OUTPUT);
|
pinMode(TFT_BL, OUTPUT);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef ST7735_BACKLIGHT_EN_V03
|
||||||
|
if (heltec_version == 3) {
|
||||||
|
digitalWrite(ST7735_BACKLIGHT_EN_V03, TFT_BACKLIGHT_ON);
|
||||||
|
pinMode(ST7735_BACKLIGHT_EN_V03, OUTPUT);
|
||||||
|
} else {
|
||||||
|
digitalWrite(ST7735_BACKLIGHT_EN_V05, TFT_BACKLIGHT_ON);
|
||||||
|
pinMode(ST7735_BACKLIGHT_EN_V05, OUTPUT);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
tft.init();
|
tft.init();
|
||||||
#if defined(M5STACK)
|
#if defined(M5STACK)
|
||||||
tft.setRotation(0);
|
tft.setRotation(0);
|
||||||
|
|||||||
181
src/input/BBQ10Keyboard.cpp
Normal file
181
src/input/BBQ10Keyboard.cpp
Normal file
@@ -0,0 +1,181 @@
|
|||||||
|
// Based on arturo182 arduino_bbq10kbd library https://github.com/arturo182/arduino_bbq10kbd
|
||||||
|
|
||||||
|
#include <Arduino.h>
|
||||||
|
|
||||||
|
#include "BBQ10Keyboard.h"
|
||||||
|
|
||||||
|
#define _REG_VER 1
|
||||||
|
#define _REG_CFG 2
|
||||||
|
#define _REG_INT 3
|
||||||
|
#define _REG_KEY 4
|
||||||
|
#define _REG_BKL 5
|
||||||
|
#define _REG_DEB 6
|
||||||
|
#define _REG_FRQ 7
|
||||||
|
#define _REG_RST 8
|
||||||
|
#define _REG_FIF 9
|
||||||
|
|
||||||
|
#define _WRITE_MASK (1 << 7)
|
||||||
|
|
||||||
|
#define CFG_OVERFLOW_ON (1 << 0)
|
||||||
|
#define CFG_OVERFLOW_INT (1 << 1)
|
||||||
|
#define CFG_CAPSLOCK_INT (1 << 2)
|
||||||
|
#define CFG_NUMLOCK_INT (1 << 3)
|
||||||
|
#define CFG_KEY_INT (1 << 4)
|
||||||
|
#define CFG_PANIC_INT (1 << 5)
|
||||||
|
#define CFG_REPORT_MODS (1 << 6)
|
||||||
|
#define CFG_USE_MODS (1 << 7)
|
||||||
|
|
||||||
|
#define INT_OVERFLOW (1 << 0)
|
||||||
|
#define INT_CAPSLOCK (1 << 1)
|
||||||
|
#define INT_NUMLOCK (1 << 2)
|
||||||
|
#define INT_KEY (1 << 3)
|
||||||
|
#define INT_PANIC (1 << 4)
|
||||||
|
|
||||||
|
#define KEY_CAPSLOCK (1 << 5)
|
||||||
|
#define KEY_NUMLOCK (1 << 6)
|
||||||
|
#define KEY_COUNT_MASK (0x1F)
|
||||||
|
|
||||||
|
BBQ10Keyboard::BBQ10Keyboard() : m_wire(nullptr), m_addr(0), readCallback(nullptr), writeCallback(nullptr) {}
|
||||||
|
|
||||||
|
void BBQ10Keyboard::begin(uint8_t addr, TwoWire *wire)
|
||||||
|
{
|
||||||
|
m_addr = addr;
|
||||||
|
m_wire = wire;
|
||||||
|
|
||||||
|
m_wire->begin();
|
||||||
|
|
||||||
|
reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
void BBQ10Keyboard::begin(i2c_com_fptr_t r, i2c_com_fptr_t w, uint8_t addr)
|
||||||
|
{
|
||||||
|
m_addr = addr;
|
||||||
|
m_wire = nullptr;
|
||||||
|
writeCallback = w;
|
||||||
|
readCallback = r;
|
||||||
|
reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
void BBQ10Keyboard::reset()
|
||||||
|
{
|
||||||
|
if (m_wire) {
|
||||||
|
m_wire->beginTransmission(m_addr);
|
||||||
|
m_wire->write(_REG_RST);
|
||||||
|
m_wire->endTransmission();
|
||||||
|
}
|
||||||
|
if (writeCallback) {
|
||||||
|
uint8_t data = 0;
|
||||||
|
writeCallback(m_addr, _REG_RST, &data, 0);
|
||||||
|
}
|
||||||
|
delay(100);
|
||||||
|
writeRegister(_REG_CFG, readRegister8(_REG_CFG) | CFG_REPORT_MODS);
|
||||||
|
delay(100);
|
||||||
|
}
|
||||||
|
|
||||||
|
void BBQ10Keyboard::attachInterrupt(uint8_t pin, void (*func)(void)) const
|
||||||
|
{
|
||||||
|
pinMode(pin, INPUT_PULLUP);
|
||||||
|
::attachInterrupt(digitalPinToInterrupt(pin), func, RISING);
|
||||||
|
}
|
||||||
|
|
||||||
|
void BBQ10Keyboard::detachInterrupt(uint8_t pin) const
|
||||||
|
{
|
||||||
|
::detachInterrupt(pin);
|
||||||
|
}
|
||||||
|
|
||||||
|
void BBQ10Keyboard::clearInterruptStatus()
|
||||||
|
{
|
||||||
|
writeRegister(_REG_INT, 0x00);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t BBQ10Keyboard::status() const
|
||||||
|
{
|
||||||
|
return readRegister8(_REG_KEY);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t BBQ10Keyboard::keyCount() const
|
||||||
|
{
|
||||||
|
return status() & KEY_COUNT_MASK;
|
||||||
|
}
|
||||||
|
|
||||||
|
BBQ10Keyboard::KeyEvent BBQ10Keyboard::keyEvent() const
|
||||||
|
{
|
||||||
|
KeyEvent event = {.key = '\0', .state = StateIdle};
|
||||||
|
|
||||||
|
if (keyCount() == 0)
|
||||||
|
return event;
|
||||||
|
|
||||||
|
const uint16_t buf = readRegister16(_REG_FIF);
|
||||||
|
event.key = buf >> 8;
|
||||||
|
event.state = KeyState(buf & 0xFF);
|
||||||
|
|
||||||
|
return event;
|
||||||
|
}
|
||||||
|
|
||||||
|
float BBQ10Keyboard::backlight() const
|
||||||
|
{
|
||||||
|
return readRegister8(_REG_BKL) / 255.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
void BBQ10Keyboard::setBacklight(float value)
|
||||||
|
{
|
||||||
|
writeRegister(_REG_BKL, value * 255);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t BBQ10Keyboard::readRegister8(uint8_t reg) const
|
||||||
|
{
|
||||||
|
if (m_wire) {
|
||||||
|
m_wire->beginTransmission(m_addr);
|
||||||
|
m_wire->write(reg);
|
||||||
|
m_wire->endTransmission();
|
||||||
|
|
||||||
|
m_wire->requestFrom(m_addr, (uint8_t)1);
|
||||||
|
if (m_wire->available() < 1)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
return m_wire->read();
|
||||||
|
}
|
||||||
|
if (readCallback) {
|
||||||
|
uint8_t data;
|
||||||
|
readCallback(m_addr, reg, &data, 1);
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t BBQ10Keyboard::readRegister16(uint8_t reg) const
|
||||||
|
{
|
||||||
|
uint8_t data[2] = {0};
|
||||||
|
// uint8_t low = 0, high = 0;
|
||||||
|
if (m_wire) {
|
||||||
|
m_wire->beginTransmission(m_addr);
|
||||||
|
m_wire->write(reg);
|
||||||
|
m_wire->endTransmission();
|
||||||
|
|
||||||
|
m_wire->requestFrom(m_addr, (uint8_t)2);
|
||||||
|
if (m_wire->available() < 2)
|
||||||
|
return 0;
|
||||||
|
data[0] = m_wire->read();
|
||||||
|
data[1] = m_wire->read();
|
||||||
|
}
|
||||||
|
if (readCallback) {
|
||||||
|
readCallback(m_addr, reg, data, 2);
|
||||||
|
}
|
||||||
|
return (data[1] << 8) | data[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
void BBQ10Keyboard::writeRegister(uint8_t reg, uint8_t value)
|
||||||
|
{
|
||||||
|
uint8_t data[2];
|
||||||
|
data[0] = reg | _WRITE_MASK;
|
||||||
|
data[1] = value;
|
||||||
|
|
||||||
|
if (m_wire) {
|
||||||
|
m_wire->beginTransmission(m_addr);
|
||||||
|
m_wire->write(data, sizeof(uint8_t) * 2);
|
||||||
|
m_wire->endTransmission();
|
||||||
|
}
|
||||||
|
if (writeCallback) {
|
||||||
|
writeCallback(m_addr, data[0], &(data[1]), 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
51
src/input/BBQ10Keyboard.h
Normal file
51
src/input/BBQ10Keyboard.h
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
// Based on arturo182 arduino_bbq10kbd library https://github.com/arturo182/arduino_bbq10kbd
|
||||||
|
|
||||||
|
#include "configuration.h"
|
||||||
|
#include <Wire.h>
|
||||||
|
|
||||||
|
#define KEY_MOD_ALT (0x1A)
|
||||||
|
#define KEY_MOD_SHL (0x1B)
|
||||||
|
#define KEY_MOD_SHR (0x1C)
|
||||||
|
#define KEY_MOD_SYM (0x1D)
|
||||||
|
|
||||||
|
class BBQ10Keyboard
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
typedef uint8_t (*i2c_com_fptr_t)(uint8_t dev_addr, uint8_t reg_addr, uint8_t *data, uint8_t len);
|
||||||
|
|
||||||
|
enum KeyState { StateIdle = 0, StatePress, StateLongPress, StateRelease };
|
||||||
|
|
||||||
|
struct KeyEvent {
|
||||||
|
char key;
|
||||||
|
KeyState state;
|
||||||
|
};
|
||||||
|
|
||||||
|
BBQ10Keyboard();
|
||||||
|
|
||||||
|
void begin(uint8_t addr = BBQ10_KB_ADDR, TwoWire *wire = &Wire);
|
||||||
|
|
||||||
|
void begin(i2c_com_fptr_t r, i2c_com_fptr_t w, uint8_t addr = BBQ10_KB_ADDR);
|
||||||
|
|
||||||
|
void reset(void);
|
||||||
|
|
||||||
|
void attachInterrupt(uint8_t pin, void (*func)(void)) const;
|
||||||
|
void detachInterrupt(uint8_t pin) const;
|
||||||
|
void clearInterruptStatus(void);
|
||||||
|
|
||||||
|
uint8_t status(void) const;
|
||||||
|
uint8_t keyCount(void) const;
|
||||||
|
KeyEvent keyEvent(void) const;
|
||||||
|
|
||||||
|
float backlight() const;
|
||||||
|
void setBacklight(float value);
|
||||||
|
|
||||||
|
uint8_t readRegister8(uint8_t reg) const;
|
||||||
|
uint16_t readRegister16(uint8_t reg) const;
|
||||||
|
void writeRegister(uint8_t reg, uint8_t value);
|
||||||
|
|
||||||
|
private:
|
||||||
|
TwoWire *m_wire;
|
||||||
|
uint8_t m_addr;
|
||||||
|
i2c_com_fptr_t readCallback;
|
||||||
|
i2c_com_fptr_t writeCallback;
|
||||||
|
};
|
||||||
@@ -5,12 +5,12 @@ RotaryEncoderInterruptImpl1 *rotaryEncoderInterruptImpl1;
|
|||||||
|
|
||||||
RotaryEncoderInterruptImpl1::RotaryEncoderInterruptImpl1() : RotaryEncoderInterruptBase("rotEnc1") {}
|
RotaryEncoderInterruptImpl1::RotaryEncoderInterruptImpl1() : RotaryEncoderInterruptBase("rotEnc1") {}
|
||||||
|
|
||||||
void RotaryEncoderInterruptImpl1::init()
|
bool RotaryEncoderInterruptImpl1::init()
|
||||||
{
|
{
|
||||||
if (!moduleConfig.canned_message.rotary1_enabled) {
|
if (!moduleConfig.canned_message.rotary1_enabled) {
|
||||||
// Input device is disabled.
|
// Input device is disabled.
|
||||||
disable();
|
disable();
|
||||||
return;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t pinA = moduleConfig.canned_message.inputbroker_pin_a;
|
uint8_t pinA = moduleConfig.canned_message.inputbroker_pin_a;
|
||||||
@@ -25,6 +25,7 @@ void RotaryEncoderInterruptImpl1::init()
|
|||||||
RotaryEncoderInterruptImpl1::handleIntA, RotaryEncoderInterruptImpl1::handleIntB,
|
RotaryEncoderInterruptImpl1::handleIntA, RotaryEncoderInterruptImpl1::handleIntB,
|
||||||
RotaryEncoderInterruptImpl1::handleIntPressed);
|
RotaryEncoderInterruptImpl1::handleIntPressed);
|
||||||
inputBroker->registerSource(this);
|
inputBroker->registerSource(this);
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void RotaryEncoderInterruptImpl1::handleIntA()
|
void RotaryEncoderInterruptImpl1::handleIntA()
|
||||||
@@ -38,4 +39,4 @@ void RotaryEncoderInterruptImpl1::handleIntB()
|
|||||||
void RotaryEncoderInterruptImpl1::handleIntPressed()
|
void RotaryEncoderInterruptImpl1::handleIntPressed()
|
||||||
{
|
{
|
||||||
rotaryEncoderInterruptImpl1->intPressHandler();
|
rotaryEncoderInterruptImpl1->intPressHandler();
|
||||||
}
|
}
|
||||||
@@ -12,7 +12,7 @@ class RotaryEncoderInterruptImpl1 : public RotaryEncoderInterruptBase
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
RotaryEncoderInterruptImpl1();
|
RotaryEncoderInterruptImpl1();
|
||||||
void init();
|
bool init();
|
||||||
static void handleIntA();
|
static void handleIntA();
|
||||||
static void handleIntB();
|
static void handleIntB();
|
||||||
static void handleIntPressed();
|
static void handleIntPressed();
|
||||||
|
|||||||
@@ -1,10 +1,7 @@
|
|||||||
#include "TrackballInterruptBase.h"
|
#include "TrackballInterruptBase.h"
|
||||||
#include "configuration.h"
|
#include "configuration.h"
|
||||||
|
|
||||||
TrackballInterruptBase::TrackballInterruptBase(const char *name)
|
TrackballInterruptBase::TrackballInterruptBase(const char *name) : concurrency::OSThread(name), _originName(name) {}
|
||||||
{
|
|
||||||
this->_originName = name;
|
|
||||||
}
|
|
||||||
|
|
||||||
void TrackballInterruptBase::init(uint8_t pinDown, uint8_t pinUp, uint8_t pinLeft, uint8_t pinRight, uint8_t pinPress,
|
void TrackballInterruptBase::init(uint8_t pinDown, uint8_t pinUp, uint8_t pinLeft, uint8_t pinRight, uint8_t pinPress,
|
||||||
char eventDown, char eventUp, char eventLeft, char eventRight, char eventPressed,
|
char eventDown, char eventUp, char eventLeft, char eventRight, char eventPressed,
|
||||||
@@ -35,44 +32,64 @@ void TrackballInterruptBase::init(uint8_t pinDown, uint8_t pinUp, uint8_t pinLef
|
|||||||
|
|
||||||
LOG_DEBUG("Trackball GPIO initialized (%d, %d, %d, %d, %d)\n", this->_pinUp, this->_pinDown, this->_pinLeft, this->_pinRight,
|
LOG_DEBUG("Trackball GPIO initialized (%d, %d, %d, %d, %d)\n", this->_pinUp, this->_pinDown, this->_pinLeft, this->_pinRight,
|
||||||
pinPress);
|
pinPress);
|
||||||
|
|
||||||
|
this->setInterval(100);
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t TrackballInterruptBase::runOnce()
|
||||||
|
{
|
||||||
|
InputEvent e;
|
||||||
|
e.inputEvent = meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_NONE;
|
||||||
|
|
||||||
|
if (this->action == TB_ACTION_PRESSED) {
|
||||||
|
// LOG_DEBUG("Trackball event Press\n");
|
||||||
|
e.inputEvent = this->_eventPressed;
|
||||||
|
} else if (this->action == TB_ACTION_UP) {
|
||||||
|
// LOG_DEBUG("Trackball event UP\n");
|
||||||
|
e.inputEvent = this->_eventUp;
|
||||||
|
} else if (this->action == TB_ACTION_DOWN) {
|
||||||
|
// LOG_DEBUG("Trackball event DOWN\n");
|
||||||
|
e.inputEvent = this->_eventDown;
|
||||||
|
} else if (this->action == TB_ACTION_LEFT) {
|
||||||
|
// LOG_DEBUG("Trackball event LEFT\n");
|
||||||
|
e.inputEvent = this->_eventLeft;
|
||||||
|
} else if (this->action == TB_ACTION_RIGHT) {
|
||||||
|
// LOG_DEBUG("Trackball event RIGHT\n");
|
||||||
|
e.inputEvent = this->_eventRight;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (e.inputEvent != meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_NONE) {
|
||||||
|
e.source = this->_originName;
|
||||||
|
e.kbchar = 0x00;
|
||||||
|
this->notifyObservers(&e);
|
||||||
|
}
|
||||||
|
|
||||||
|
this->action = TB_ACTION_NONE;
|
||||||
|
|
||||||
|
return 100;
|
||||||
}
|
}
|
||||||
|
|
||||||
void TrackballInterruptBase::intPressHandler()
|
void TrackballInterruptBase::intPressHandler()
|
||||||
{
|
{
|
||||||
InputEvent e;
|
this->action = TB_ACTION_PRESSED;
|
||||||
e.source = this->_originName;
|
|
||||||
e.inputEvent = this->_eventPressed;
|
|
||||||
this->notifyObservers(&e);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void TrackballInterruptBase::intDownHandler()
|
void TrackballInterruptBase::intDownHandler()
|
||||||
{
|
{
|
||||||
InputEvent e;
|
this->action = TB_ACTION_DOWN;
|
||||||
e.source = this->_originName;
|
|
||||||
e.inputEvent = this->_eventDown;
|
|
||||||
this->notifyObservers(&e);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void TrackballInterruptBase::intUpHandler()
|
void TrackballInterruptBase::intUpHandler()
|
||||||
{
|
{
|
||||||
InputEvent e;
|
this->action = TB_ACTION_UP;
|
||||||
e.source = this->_originName;
|
|
||||||
e.inputEvent = this->_eventUp;
|
|
||||||
this->notifyObservers(&e);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void TrackballInterruptBase::intLeftHandler()
|
void TrackballInterruptBase::intLeftHandler()
|
||||||
{
|
{
|
||||||
InputEvent e;
|
this->action = TB_ACTION_LEFT;
|
||||||
e.source = this->_originName;
|
|
||||||
e.inputEvent = this->_eventLeft;
|
|
||||||
this->notifyObservers(&e);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void TrackballInterruptBase::intRightHandler()
|
void TrackballInterruptBase::intRightHandler()
|
||||||
{
|
{
|
||||||
InputEvent e;
|
this->action = TB_ACTION_RIGHT;
|
||||||
e.source = this->_originName;
|
|
||||||
e.inputEvent = this->_eventRight;
|
|
||||||
this->notifyObservers(&e);
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
#include "InputBroker.h"
|
#include "InputBroker.h"
|
||||||
#include "mesh/NodeDB.h"
|
#include "mesh/NodeDB.h"
|
||||||
|
|
||||||
class TrackballInterruptBase : public Observable<const InputEvent *>
|
class TrackballInterruptBase : public Observable<const InputEvent *>, public concurrency::OSThread
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
explicit TrackballInterruptBase(const char *name);
|
explicit TrackballInterruptBase(const char *name);
|
||||||
@@ -16,6 +16,20 @@ class TrackballInterruptBase : public Observable<const InputEvent *>
|
|||||||
void intLeftHandler();
|
void intLeftHandler();
|
||||||
void intRightHandler();
|
void intRightHandler();
|
||||||
|
|
||||||
|
virtual int32_t runOnce() override;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
enum TrackballInterruptBaseActionType {
|
||||||
|
TB_ACTION_NONE,
|
||||||
|
TB_ACTION_PRESSED,
|
||||||
|
TB_ACTION_UP,
|
||||||
|
TB_ACTION_DOWN,
|
||||||
|
TB_ACTION_LEFT,
|
||||||
|
TB_ACTION_RIGHT
|
||||||
|
};
|
||||||
|
|
||||||
|
volatile TrackballInterruptBaseActionType action = TB_ACTION_NONE;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
uint8_t _pinDown = 0;
|
uint8_t _pinDown = 0;
|
||||||
uint8_t _pinUp = 0;
|
uint8_t _pinUp = 0;
|
||||||
|
|||||||
@@ -5,12 +5,12 @@ UpDownInterruptImpl1 *upDownInterruptImpl1;
|
|||||||
|
|
||||||
UpDownInterruptImpl1::UpDownInterruptImpl1() : UpDownInterruptBase("upDown1") {}
|
UpDownInterruptImpl1::UpDownInterruptImpl1() : UpDownInterruptBase("upDown1") {}
|
||||||
|
|
||||||
void UpDownInterruptImpl1::init()
|
bool UpDownInterruptImpl1::init()
|
||||||
{
|
{
|
||||||
|
|
||||||
if (!moduleConfig.canned_message.updown1_enabled) {
|
if (!moduleConfig.canned_message.updown1_enabled) {
|
||||||
// Input device is disabled.
|
// Input device is disabled.
|
||||||
return;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t pinUp = moduleConfig.canned_message.inputbroker_pin_a;
|
uint8_t pinUp = moduleConfig.canned_message.inputbroker_pin_a;
|
||||||
@@ -24,6 +24,7 @@ void UpDownInterruptImpl1::init()
|
|||||||
UpDownInterruptBase::init(pinDown, pinUp, pinPress, eventDown, eventUp, eventPressed, UpDownInterruptImpl1::handleIntDown,
|
UpDownInterruptBase::init(pinDown, pinUp, pinPress, eventDown, eventUp, eventPressed, UpDownInterruptImpl1::handleIntDown,
|
||||||
UpDownInterruptImpl1::handleIntUp, UpDownInterruptImpl1::handleIntPressed);
|
UpDownInterruptImpl1::handleIntUp, UpDownInterruptImpl1::handleIntPressed);
|
||||||
inputBroker->registerSource(this);
|
inputBroker->registerSource(this);
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void UpDownInterruptImpl1::handleIntDown()
|
void UpDownInterruptImpl1::handleIntDown()
|
||||||
@@ -37,4 +38,4 @@ void UpDownInterruptImpl1::handleIntUp()
|
|||||||
void UpDownInterruptImpl1::handleIntPressed()
|
void UpDownInterruptImpl1::handleIntPressed()
|
||||||
{
|
{
|
||||||
upDownInterruptImpl1->intPressHandler();
|
upDownInterruptImpl1->intPressHandler();
|
||||||
}
|
}
|
||||||
@@ -5,10 +5,10 @@ class UpDownInterruptImpl1 : public UpDownInterruptBase
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
UpDownInterruptImpl1();
|
UpDownInterruptImpl1();
|
||||||
void init();
|
bool init();
|
||||||
static void handleIntDown();
|
static void handleIntDown();
|
||||||
static void handleIntUp();
|
static void handleIntUp();
|
||||||
static void handleIntPressed();
|
static void handleIntPressed();
|
||||||
};
|
};
|
||||||
|
|
||||||
extern UpDownInterruptImpl1 *upDownInterruptImpl1;
|
extern UpDownInterruptImpl1 *upDownInterruptImpl1;
|
||||||
@@ -7,7 +7,7 @@ CardKbI2cImpl::CardKbI2cImpl() : KbI2cBase("cardKB") {}
|
|||||||
|
|
||||||
void CardKbI2cImpl::init()
|
void CardKbI2cImpl::init()
|
||||||
{
|
{
|
||||||
if (cardkb_found.address != CARDKB_ADDR && cardkb_found.address != TDECK_KB_ADDR) {
|
if (cardkb_found.address == 0x00) {
|
||||||
disable();
|
disable();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ uint8_t read_from_14004(TwoWire *i2cBus, uint8_t reg, uint8_t *data, uint8_t len
|
|||||||
|
|
||||||
int32_t KbI2cBase::runOnce()
|
int32_t KbI2cBase::runOnce()
|
||||||
{
|
{
|
||||||
if (cardkb_found.address != CARDKB_ADDR && cardkb_found.address != TDECK_KB_ADDR) {
|
if (cardkb_found.address == 0x00) {
|
||||||
// Input device is not detected.
|
// Input device is not detected.
|
||||||
return INT32_MAX;
|
return INT32_MAX;
|
||||||
}
|
}
|
||||||
@@ -41,11 +41,19 @@ int32_t KbI2cBase::runOnce()
|
|||||||
#ifdef I2C_SDA1
|
#ifdef I2C_SDA1
|
||||||
LOG_DEBUG("Using I2C Bus 1 (the second one)\n");
|
LOG_DEBUG("Using I2C Bus 1 (the second one)\n");
|
||||||
i2cBus = &Wire1;
|
i2cBus = &Wire1;
|
||||||
|
if (cardkb_found.address == BBQ10_KB_ADDR) {
|
||||||
|
Q10keyboard.begin(BBQ10_KB_ADDR, &Wire1);
|
||||||
|
Q10keyboard.setBacklight(0);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
case ScanI2C::WIRE:
|
case ScanI2C::WIRE:
|
||||||
LOG_DEBUG("Using I2C Bus 0 (the first one)\n");
|
LOG_DEBUG("Using I2C Bus 0 (the first one)\n");
|
||||||
i2cBus = &Wire;
|
i2cBus = &Wire;
|
||||||
|
if (cardkb_found.address == BBQ10_KB_ADDR) {
|
||||||
|
Q10keyboard.begin(BBQ10_KB_ADDR, &Wire);
|
||||||
|
Q10keyboard.setBacklight(0);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case ScanI2C::NO_I2C:
|
case ScanI2C::NO_I2C:
|
||||||
default:
|
default:
|
||||||
@@ -53,7 +61,105 @@ int32_t KbI2cBase::runOnce()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (kb_model == 0x02) {
|
switch (kb_model) {
|
||||||
|
case 0x11: { // BB Q10
|
||||||
|
int keyCount = Q10keyboard.keyCount();
|
||||||
|
while (keyCount--) {
|
||||||
|
const BBQ10Keyboard::KeyEvent key = Q10keyboard.keyEvent();
|
||||||
|
if ((key.key != 0x00) && (key.state == BBQ10Keyboard::StateRelease)) {
|
||||||
|
InputEvent e;
|
||||||
|
e.inputEvent = meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_NONE;
|
||||||
|
e.source = this->_originName;
|
||||||
|
switch (key.key) {
|
||||||
|
case 'p': // TAB
|
||||||
|
case 't': // TAB as well
|
||||||
|
if (is_sym) {
|
||||||
|
e.inputEvent = ANYKEY;
|
||||||
|
e.kbchar = 0x09; // TAB Scancode
|
||||||
|
is_sym = false; // reset sym state after second keypress
|
||||||
|
} else {
|
||||||
|
e.inputEvent = ANYKEY;
|
||||||
|
e.kbchar = key.key;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'q': // ESC
|
||||||
|
if (is_sym) {
|
||||||
|
e.inputEvent = meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_CANCEL;
|
||||||
|
e.kbchar = 0x1b;
|
||||||
|
is_sym = false; // reset sym state after second keypress
|
||||||
|
} else {
|
||||||
|
e.inputEvent = ANYKEY;
|
||||||
|
e.kbchar = key.key;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 0x08: // Back
|
||||||
|
e.inputEvent = meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_BACK;
|
||||||
|
e.kbchar = key.key;
|
||||||
|
break;
|
||||||
|
case 'e': // sym e
|
||||||
|
if (is_sym) {
|
||||||
|
e.inputEvent = meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_UP;
|
||||||
|
e.kbchar = 0xb5;
|
||||||
|
is_sym = false; // reset sym state after second keypress
|
||||||
|
} else {
|
||||||
|
e.inputEvent = ANYKEY;
|
||||||
|
e.kbchar = key.key;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'x': // sym x
|
||||||
|
if (is_sym) {
|
||||||
|
e.inputEvent = meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_DOWN;
|
||||||
|
e.kbchar = 0xb6;
|
||||||
|
is_sym = false; // reset sym state after second keypress
|
||||||
|
} else {
|
||||||
|
e.inputEvent = ANYKEY;
|
||||||
|
e.kbchar = key.key;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 's': // sym s
|
||||||
|
if (is_sym) {
|
||||||
|
e.inputEvent = meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_LEFT;
|
||||||
|
e.kbchar = 0x00; // tweak for destSelect
|
||||||
|
is_sym = false; // reset sym state after second keypress
|
||||||
|
} else {
|
||||||
|
e.inputEvent = ANYKEY;
|
||||||
|
e.kbchar = key.key;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'f': // sym f
|
||||||
|
if (is_sym) {
|
||||||
|
e.inputEvent = meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_RIGHT;
|
||||||
|
e.kbchar = 0x00; // tweak for destSelect
|
||||||
|
is_sym = false; // reset sym state after second keypress
|
||||||
|
} else {
|
||||||
|
e.inputEvent = ANYKEY;
|
||||||
|
e.kbchar = key.key;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 0x13: // Code scanner says the SYM key is 0x13
|
||||||
|
is_sym = !is_sym;
|
||||||
|
break;
|
||||||
|
case 0x0a: // apparently Enter on Q10 is a line feed instead of carriage return
|
||||||
|
e.inputEvent = meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_SELECT;
|
||||||
|
break;
|
||||||
|
case 0x00: // nopress
|
||||||
|
e.inputEvent = meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_NONE;
|
||||||
|
break;
|
||||||
|
default: // all other keys
|
||||||
|
e.inputEvent = ANYKEY;
|
||||||
|
e.kbchar = key.key;
|
||||||
|
is_sym = false; // reset sym state after second keypress
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (e.inputEvent != meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_NONE) {
|
||||||
|
this->notifyObservers(&e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 0x02: {
|
||||||
// RAK14004
|
// RAK14004
|
||||||
uint8_t rDataBuf[8] = {0};
|
uint8_t rDataBuf[8] = {0};
|
||||||
uint8_t PrintDataBuf = 0;
|
uint8_t PrintDataBuf = 0;
|
||||||
@@ -74,9 +180,12 @@ int32_t KbI2cBase::runOnce()
|
|||||||
e.kbchar = PrintDataBuf;
|
e.kbchar = PrintDataBuf;
|
||||||
this->notifyObservers(&e);
|
this->notifyObservers(&e);
|
||||||
}
|
}
|
||||||
} else if (kb_model == 0x00 || kb_model == 0x10) {
|
break;
|
||||||
// m5 cardkb and T-Deck
|
}
|
||||||
i2cBus->requestFrom(kb_model == 0x00 ? CARDKB_ADDR : TDECK_KB_ADDR, 1);
|
case 0x00: // CARDKB
|
||||||
|
case 0x10: { // T-DECK
|
||||||
|
|
||||||
|
i2cBus->requestFrom((int)cardkb_found.address, 1);
|
||||||
|
|
||||||
while (i2cBus->available()) {
|
while (i2cBus->available()) {
|
||||||
char c = i2cBus->read();
|
char c = i2cBus->read();
|
||||||
@@ -93,17 +202,19 @@ int32_t KbI2cBase::runOnce()
|
|||||||
break;
|
break;
|
||||||
case 0xb5: // Up
|
case 0xb5: // Up
|
||||||
e.inputEvent = meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_UP;
|
e.inputEvent = meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_UP;
|
||||||
|
e.kbchar = 0xb5;
|
||||||
break;
|
break;
|
||||||
case 0xb6: // Down
|
case 0xb6: // Down
|
||||||
e.inputEvent = meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_DOWN;
|
e.inputEvent = meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_DOWN;
|
||||||
|
e.kbchar = 0xb6;
|
||||||
break;
|
break;
|
||||||
case 0xb4: // Left
|
case 0xb4: // Left
|
||||||
e.inputEvent = meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_LEFT;
|
e.inputEvent = meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_LEFT;
|
||||||
e.kbchar = c;
|
e.kbchar = 0xb4;
|
||||||
break;
|
break;
|
||||||
case 0xb7: // Right
|
case 0xb7: // Right
|
||||||
e.inputEvent = meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_RIGHT;
|
e.inputEvent = meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_RIGHT;
|
||||||
e.kbchar = c;
|
e.kbchar = 0xb7;
|
||||||
break;
|
break;
|
||||||
case 0x0d: // Enter
|
case 0x0d: // Enter
|
||||||
e.inputEvent = meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_SELECT;
|
e.inputEvent = meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_SELECT;
|
||||||
@@ -121,7 +232,9 @@ int32_t KbI2cBase::runOnce()
|
|||||||
this->notifyObservers(&e);
|
this->notifyObservers(&e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
LOG_WARN("Unknown kb_model 0x%02x\n", kb_model);
|
LOG_WARN("Unknown kb_model 0x%02x\n", kb_model);
|
||||||
}
|
}
|
||||||
return 300;
|
return 300;
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "BBQ10Keyboard.h"
|
||||||
#include "InputBroker.h"
|
#include "InputBroker.h"
|
||||||
#include "Wire.h"
|
#include "Wire.h"
|
||||||
#include "concurrency/OSThread.h"
|
#include "concurrency/OSThread.h"
|
||||||
@@ -16,4 +17,7 @@ class KbI2cBase : public Observable<const InputEvent *>, public concurrency::OST
|
|||||||
const char *_originName;
|
const char *_originName;
|
||||||
|
|
||||||
TwoWire *i2cBus = 0;
|
TwoWire *i2cBus = 0;
|
||||||
|
|
||||||
|
BBQ10Keyboard Q10keyboard;
|
||||||
|
bool is_sym = false;
|
||||||
};
|
};
|
||||||
|
|||||||
117
src/main.cpp
117
src/main.cpp
@@ -29,6 +29,7 @@
|
|||||||
#include "target_specific.h"
|
#include "target_specific.h"
|
||||||
#include <Wire.h>
|
#include <Wire.h>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
#include <utility>
|
||||||
// #include <driver/rtc_io.h>
|
// #include <driver/rtc_io.h>
|
||||||
|
|
||||||
#include "mesh/eth/ethClient.h"
|
#include "mesh/eth/ethClient.h"
|
||||||
@@ -73,6 +74,7 @@ NRF52Bluetooth *nrf52Bluetooth;
|
|||||||
|
|
||||||
#if !defined(ARCH_PORTDUINO) && !defined(ARCH_STM32WL)
|
#if !defined(ARCH_PORTDUINO) && !defined(ARCH_STM32WL)
|
||||||
#include "AccelerometerThread.h"
|
#include "AccelerometerThread.h"
|
||||||
|
#include "AmbientLightingThread.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
using namespace concurrency;
|
using namespace concurrency;
|
||||||
@@ -121,9 +123,8 @@ uint32_t serialSinceMsec;
|
|||||||
|
|
||||||
bool pmu_found;
|
bool pmu_found;
|
||||||
|
|
||||||
// Array map of sensor types (as array index) and i2c address as value we'll find in the i2c scan
|
// Array map of sensor types with i2c address and wire as we'll find in the i2c scan
|
||||||
uint8_t nodeTelemetrySensorsMap[_meshtastic_TelemetrySensorType_MAX + 1] = {
|
std::pair<uint8_t, TwoWire *> nodeTelemetrySensorsMap[_meshtastic_TelemetrySensorType_MAX + 1] = {};
|
||||||
0}; // one is enough, missing elements will be initialized to 0 anyway.
|
|
||||||
|
|
||||||
Router *router = NULL; // Users of router don't care what sort of subclass implements that API
|
Router *router = NULL; // Users of router don't care what sort of subclass implements that API
|
||||||
|
|
||||||
@@ -145,6 +146,25 @@ const char *getDeviceName()
|
|||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef VEXT_ENABLE_V03
|
||||||
|
|
||||||
|
#include <soc/rtc.h>
|
||||||
|
|
||||||
|
static uint32_t calibrate_one(rtc_cal_sel_t cal_clk, const char *name)
|
||||||
|
{
|
||||||
|
const uint32_t cal_count = 1000;
|
||||||
|
uint32_t cali_val;
|
||||||
|
for (int i = 0; i < 5; ++i) {
|
||||||
|
cali_val = rtc_clk_cal(cal_clk, cal_count);
|
||||||
|
}
|
||||||
|
return cali_val;
|
||||||
|
}
|
||||||
|
|
||||||
|
int heltec_version = 3;
|
||||||
|
|
||||||
|
#define CALIBRATE_ONE(cali_clk) calibrate_one(cali_clk, #cali_clk)
|
||||||
|
#endif
|
||||||
|
|
||||||
static int32_t ledBlinker()
|
static int32_t ledBlinker()
|
||||||
{
|
{
|
||||||
static bool ledOn;
|
static bool ledOn;
|
||||||
@@ -169,6 +189,7 @@ static OSThread *buttonThread;
|
|||||||
uint32_t ButtonThread::longPressTime = 0;
|
uint32_t ButtonThread::longPressTime = 0;
|
||||||
#endif
|
#endif
|
||||||
static OSThread *accelerometerThread;
|
static OSThread *accelerometerThread;
|
||||||
|
static OSThread *ambientLightingThread;
|
||||||
SPISettings spiSettings(4000000, MSBFIRST, SPI_MODE0);
|
SPISettings spiSettings(4000000, MSBFIRST, SPI_MODE0);
|
||||||
|
|
||||||
RadioInterface *rIf = NULL;
|
RadioInterface *rIf = NULL;
|
||||||
@@ -214,12 +235,59 @@ void setup()
|
|||||||
digitalWrite(PIN_EINK_PWR_ON, HIGH);
|
digitalWrite(PIN_EINK_PWR_ON, HIGH);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef VEXT_ENABLE
|
#ifdef ST7735_BL_V03 // Heltec Wireless Tracker PCB Change Detect/Hack
|
||||||
|
|
||||||
|
rtc_clk_32k_enable(true);
|
||||||
|
CALIBRATE_ONE(RTC_CAL_RTC_MUX);
|
||||||
|
if (CALIBRATE_ONE(RTC_CAL_32K_XTAL) != 0) {
|
||||||
|
rtc_clk_slow_freq_set(RTC_SLOW_FREQ_32K_XTAL);
|
||||||
|
CALIBRATE_ONE(RTC_CAL_RTC_MUX);
|
||||||
|
CALIBRATE_ONE(RTC_CAL_32K_XTAL);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rtc_clk_slow_freq_get() != RTC_SLOW_FREQ_32K_XTAL) {
|
||||||
|
heltec_version = 3;
|
||||||
|
} else {
|
||||||
|
heltec_version = 5;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(VEXT_ENABLE_V03)
|
||||||
|
if (heltec_version == 3) {
|
||||||
|
pinMode(VEXT_ENABLE_V03, OUTPUT);
|
||||||
|
digitalWrite(VEXT_ENABLE_V03, 0); // turn on the display power
|
||||||
|
LOG_DEBUG("HELTEC Detect Tracker V1.0\n");
|
||||||
|
} else {
|
||||||
|
pinMode(VEXT_ENABLE_V05, OUTPUT);
|
||||||
|
digitalWrite(VEXT_ENABLE_V05, 1); // turn on the display power
|
||||||
|
LOG_DEBUG("HELTEC Detect Tracker V1.1\n");
|
||||||
|
}
|
||||||
|
#elif defined(VEXT_ENABLE)
|
||||||
pinMode(VEXT_ENABLE, OUTPUT);
|
pinMode(VEXT_ENABLE, OUTPUT);
|
||||||
digitalWrite(VEXT_ENABLE, 0); // turn on the display power
|
digitalWrite(VEXT_ENABLE, 0); // turn on the display power
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef VGNSS_CTRL
|
#if defined(VGNSS_CTRL_V03)
|
||||||
|
if (heltec_version == 3) {
|
||||||
|
pinMode(VGNSS_CTRL_V03, OUTPUT);
|
||||||
|
digitalWrite(VGNSS_CTRL_V03, LOW);
|
||||||
|
} else {
|
||||||
|
pinMode(VGNSS_CTRL_V05, OUTPUT);
|
||||||
|
digitalWrite(VGNSS_CTRL_V05, LOW);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(VTFT_CTRL_V03)
|
||||||
|
if (heltec_version == 3) {
|
||||||
|
pinMode(VTFT_CTRL_V03, OUTPUT);
|
||||||
|
digitalWrite(VTFT_CTRL_V03, LOW);
|
||||||
|
} else {
|
||||||
|
pinMode(VTFT_CTRL_V05, OUTPUT);
|
||||||
|
digitalWrite(VTFT_CTRL_V05, LOW);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(VGNSS_CTRL)
|
||||||
pinMode(VGNSS_CTRL, OUTPUT);
|
pinMode(VGNSS_CTRL, OUTPUT);
|
||||||
digitalWrite(VGNSS_CTRL, LOW);
|
digitalWrite(VGNSS_CTRL, LOW);
|
||||||
#endif
|
#endif
|
||||||
@@ -387,6 +455,10 @@ void setup()
|
|||||||
// assign an arbitrary value to distinguish from other models
|
// assign an arbitrary value to distinguish from other models
|
||||||
kb_model = 0x10;
|
kb_model = 0x10;
|
||||||
break;
|
break;
|
||||||
|
case ScanI2C::DeviceType::BBQ10KB:
|
||||||
|
// assign an arbitrary value to distinguish from other models
|
||||||
|
kb_model = 0x11;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
// use this as default since it's also just zero
|
// use this as default since it's also just zero
|
||||||
LOG_WARN("kb_info.type is unknown(0x%02x), setting kb_model=0x00\n", kb_info.type);
|
LOG_WARN("kb_info.type is unknown(0x%02x), setting kb_model=0x00\n", kb_info.type);
|
||||||
@@ -405,14 +477,6 @@ void setup()
|
|||||||
// Only one supported RGB LED currently
|
// Only one supported RGB LED currently
|
||||||
#ifdef HAS_NCP5623
|
#ifdef HAS_NCP5623
|
||||||
rgb_found = i2cScanner->find(ScanI2C::DeviceType::NCP5623);
|
rgb_found = i2cScanner->find(ScanI2C::DeviceType::NCP5623);
|
||||||
|
|
||||||
// Start the RGB LED at 50%
|
|
||||||
|
|
||||||
if (rgb_found.type == ScanI2C::NCP5623) {
|
|
||||||
rgb.begin();
|
|
||||||
rgb.setCurrent(10);
|
|
||||||
rgb.setColor(128, 128, 128);
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if !defined(ARCH_PORTDUINO) && !defined(ARCH_STM32WL)
|
#if !defined(ARCH_PORTDUINO) && !defined(ARCH_STM32WL)
|
||||||
@@ -427,7 +491,8 @@ void setup()
|
|||||||
{ \
|
{ \
|
||||||
auto found = i2cScanner->find(SCANNER_T); \
|
auto found = i2cScanner->find(SCANNER_T); \
|
||||||
if (found.type != ScanI2C::DeviceType::NONE) { \
|
if (found.type != ScanI2C::DeviceType::NONE) { \
|
||||||
nodeTelemetrySensorsMap[PB_T] = found.address.address; \
|
nodeTelemetrySensorsMap[PB_T].first = found.address.address; \
|
||||||
|
nodeTelemetrySensorsMap[PB_T].second = i2cScanner->fetchI2CBus(found.address); \
|
||||||
LOG_DEBUG("found i2c sensor %s\n", STRING(PB_T)); \
|
LOG_DEBUG("found i2c sensor %s\n", STRING(PB_T)); \
|
||||||
} \
|
} \
|
||||||
}
|
}
|
||||||
@@ -517,6 +582,12 @@ void setup()
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if !defined(ARCH_PORTDUINO) && !defined(ARCH_STM32WL)
|
||||||
|
if (rgb_found.type != ScanI2C::DeviceType::NONE) {
|
||||||
|
ambientLightingThread = new AmbientLightingThread(rgb_found.type);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef T_WATCH_S3
|
#ifdef T_WATCH_S3
|
||||||
drv.begin();
|
drv.begin();
|
||||||
drv.selectLibrary(1);
|
drv.selectLibrary(1);
|
||||||
@@ -554,14 +625,12 @@ void setup()
|
|||||||
|
|
||||||
readFromRTC(); // read the main CPU RTC at first (in case we can't get GPS time)
|
readFromRTC(); // read the main CPU RTC at first (in case we can't get GPS time)
|
||||||
|
|
||||||
gps = createGps();
|
gps = GPS::createGps();
|
||||||
|
|
||||||
if (gps) {
|
if (gps) {
|
||||||
gpsStatus->observe(&gps->newStatus);
|
gpsStatus->observe(&gps->newStatus);
|
||||||
} else {
|
} else {
|
||||||
LOG_WARN("No GPS found - running without GPS\n");
|
LOG_DEBUG("Running without GPS.\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
nodeStatus->observe(&nodeDB.newStatus);
|
nodeStatus->observe(&nodeDB.newStatus);
|
||||||
|
|
||||||
service.init();
|
service.init();
|
||||||
@@ -586,17 +655,6 @@ void setup()
|
|||||||
|
|
||||||
screen->print("Started...\n");
|
screen->print("Started...\n");
|
||||||
|
|
||||||
// We have now loaded our saved preferences from flash
|
|
||||||
|
|
||||||
// ONCE we will factory reset the GPS for bug #327
|
|
||||||
if (gps && !devicestate.did_gps_reset) {
|
|
||||||
LOG_WARN("GPS FactoryReset requested\n");
|
|
||||||
if (gps->factoryReset()) { // If we don't succeed try again next time
|
|
||||||
devicestate.did_gps_reset = true;
|
|
||||||
nodeDB.saveToDisk(SEGMENT_DEVICESTATE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef SX126X_ANT_SW
|
#ifdef SX126X_ANT_SW
|
||||||
// make analog PA vs not PA switch on SX126x eval board work properly
|
// make analog PA vs not PA switch on SX126x eval board work properly
|
||||||
pinMode(SX126X_ANT_SW, OUTPUT);
|
pinMode(SX126X_ANT_SW, OUTPUT);
|
||||||
@@ -751,7 +809,6 @@ void setup()
|
|||||||
PowerFSM_setup(); // we will transition to ON in a couple of seconds, FIXME, only do this for cold boots, not waking from SDS
|
PowerFSM_setup(); // we will transition to ON in a couple of seconds, FIXME, only do this for cold boots, not waking from SDS
|
||||||
powerFSMthread = new PowerFSMThread();
|
powerFSMthread = new PowerFSMThread();
|
||||||
|
|
||||||
// setBluetoothEnable(false); we now don't start bluetooth until we enter the proper state
|
|
||||||
setCPUFast(false); // 80MHz is fine for our slow peripherals
|
setCPUFast(false); // 80MHz is fine for our slow peripherals
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -64,6 +64,8 @@ extern uint32_t shutdownAtMsec;
|
|||||||
|
|
||||||
extern uint32_t serialSinceMsec;
|
extern uint32_t serialSinceMsec;
|
||||||
|
|
||||||
|
extern int heltec_version;
|
||||||
|
|
||||||
// If a thread does something that might need for it to be rescheduled ASAP it can set this flag
|
// If a thread does something that might need for it to be rescheduled ASAP it can set this flag
|
||||||
// This will suppress the current delay and instead try to run ASAP.
|
// This will suppress the current delay and instead try to run ASAP.
|
||||||
extern bool runASAP;
|
extern bool runASAP;
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
#include "Channels.h"
|
#include "Channels.h"
|
||||||
#include "CryptoEngine.h"
|
#include "CryptoEngine.h"
|
||||||
|
#include "DisplayFormatters.h"
|
||||||
#include "NodeDB.h"
|
#include "NodeDB.h"
|
||||||
#include "configuration.h"
|
#include "configuration.h"
|
||||||
|
|
||||||
@@ -239,38 +240,9 @@ const char *Channels::getName(size_t chIndex)
|
|||||||
const char *channelName = channelSettings.name;
|
const char *channelName = channelSettings.name;
|
||||||
if (!*channelName) { // emptystring
|
if (!*channelName) { // emptystring
|
||||||
// Per mesh.proto spec, if bandwidth is specified we must ignore modemPreset enum, we assume that in that case
|
// Per mesh.proto spec, if bandwidth is specified we must ignore modemPreset enum, we assume that in that case
|
||||||
// the app fucked up and forgot to set channelSettings.name
|
// the app effed up and forgot to set channelSettings.name
|
||||||
|
|
||||||
if (config.lora.use_preset) {
|
if (config.lora.use_preset) {
|
||||||
switch (config.lora.modem_preset) {
|
channelName = DisplayFormatters::getModemPresetDisplayName(config.lora.modem_preset, false);
|
||||||
case meshtastic_Config_LoRaConfig_ModemPreset_SHORT_SLOW:
|
|
||||||
channelName = "ShortSlow";
|
|
||||||
break;
|
|
||||||
case meshtastic_Config_LoRaConfig_ModemPreset_SHORT_FAST:
|
|
||||||
channelName = "ShortFast";
|
|
||||||
break;
|
|
||||||
case meshtastic_Config_LoRaConfig_ModemPreset_MEDIUM_SLOW:
|
|
||||||
channelName = "MediumSlow";
|
|
||||||
break;
|
|
||||||
case meshtastic_Config_LoRaConfig_ModemPreset_MEDIUM_FAST:
|
|
||||||
channelName = "MediumFast";
|
|
||||||
break;
|
|
||||||
case meshtastic_Config_LoRaConfig_ModemPreset_LONG_SLOW:
|
|
||||||
channelName = "LongSlow";
|
|
||||||
break;
|
|
||||||
case meshtastic_Config_LoRaConfig_ModemPreset_LONG_FAST:
|
|
||||||
channelName = "LongFast";
|
|
||||||
break;
|
|
||||||
case meshtastic_Config_LoRaConfig_ModemPreset_LONG_MODERATE:
|
|
||||||
channelName = "LongMod";
|
|
||||||
break;
|
|
||||||
case meshtastic_Config_LoRaConfig_ModemPreset_VERY_LONG_SLOW:
|
|
||||||
channelName = "VLongSlow";
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
channelName = "Invalid";
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
channelName = "Custom";
|
channelName = "Custom";
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -320,28 +320,26 @@ meshtastic_NodeInfoLite *MeshService::refreshLocalMeshNode()
|
|||||||
int MeshService::onGPSChanged(const meshtastic::GPSStatus *newStatus)
|
int MeshService::onGPSChanged(const meshtastic::GPSStatus *newStatus)
|
||||||
{
|
{
|
||||||
// Update our local node info with our position (even if we don't decide to update anyone else)
|
// Update our local node info with our position (even if we don't decide to update anyone else)
|
||||||
meshtastic_NodeInfoLite *node = refreshLocalMeshNode();
|
const meshtastic_NodeInfoLite *node = refreshLocalMeshNode();
|
||||||
meshtastic_Position pos = meshtastic_Position_init_default;
|
meshtastic_Position pos = meshtastic_Position_init_default;
|
||||||
|
|
||||||
if (newStatus->getHasLock()) {
|
if (newStatus->getHasLock()) {
|
||||||
// load data from GPS object, will add timestamp + battery further down
|
// load data from GPS object, will add timestamp + battery further down
|
||||||
pos = gps->p;
|
pos = gps->p;
|
||||||
} else {
|
} else {
|
||||||
// The GPS has lost lock, if we are fixed position we should just keep using
|
// The GPS has lost lock
|
||||||
// the old position
|
|
||||||
#ifdef GPS_EXTRAVERBOSE
|
#ifdef GPS_EXTRAVERBOSE
|
||||||
LOG_DEBUG("onGPSchanged() - lost validLocation\n");
|
LOG_DEBUG("onGPSchanged() - lost validLocation\n");
|
||||||
#endif
|
#endif
|
||||||
if (config.position.fixed_position) {
|
}
|
||||||
LOG_WARN("Using fixed position\n");
|
// Used fixed position if configured regalrdless of GPS lock
|
||||||
pos = ConvertToPosition(node->position);
|
if (config.position.fixed_position) {
|
||||||
}
|
LOG_WARN("Using fixed position\n");
|
||||||
|
pos = TypeConversions::ConvertToPosition(node->position);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Finally add a fresh timestamp and battery level reading
|
// Add a fresh timestamp
|
||||||
// I KNOW this is redundant with refreshLocalMeshNode() above, but these are
|
pos.time = getValidTime(RTCQualityFromNet);
|
||||||
// inexpensive nonblocking calls and can be refactored in due course
|
|
||||||
pos.time = getValidTime(RTCQualityGPS);
|
|
||||||
|
|
||||||
// In debug logs, identify position by @timestamp:stage (stage 4 = nodeDB)
|
// In debug logs, identify position by @timestamp:stage (stage 4 = nodeDB)
|
||||||
LOG_DEBUG("onGPSChanged() pos@%x, time=%u, lat=%d, lon=%d, alt=%d\n", pos.timestamp, pos.time, pos.latitude_i,
|
LOG_DEBUG("onGPSChanged() pos@%x, time=%u, lat=%d, lon=%d, alt=%d\n", pos.timestamp, pos.time, pos.latitude_i,
|
||||||
|
|||||||
@@ -48,6 +48,14 @@ class MeshService
|
|||||||
uint32_t oldFromNum = 0;
|
uint32_t oldFromNum = 0;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
static bool isTextPayload(const meshtastic_MeshPacket *p)
|
||||||
|
{
|
||||||
|
if (moduleConfig.range_test.enabled && p->decoded.portnum == meshtastic_PortNum_RANGE_TEST_APP) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return p->decoded.portnum == meshtastic_PortNum_TEXT_MESSAGE_APP ||
|
||||||
|
p->decoded.portnum == meshtastic_PortNum_DETECTION_SENSOR_APP;
|
||||||
|
}
|
||||||
/// Called when some new packets have arrived from one of the radios
|
/// Called when some new packets have arrived from one of the radios
|
||||||
Observable<uint32_t> fromNumChanged;
|
Observable<uint32_t> fromNumChanged;
|
||||||
|
|
||||||
|
|||||||
@@ -169,6 +169,14 @@ void NodeDB::installDefaultConfig()
|
|||||||
config.lora.region = meshtastic_Config_LoRaConfig_RegionCode_UNSET;
|
config.lora.region = meshtastic_Config_LoRaConfig_RegionCode_UNSET;
|
||||||
config.lora.modem_preset = meshtastic_Config_LoRaConfig_ModemPreset_LONG_FAST;
|
config.lora.modem_preset = meshtastic_Config_LoRaConfig_ModemPreset_LONG_FAST;
|
||||||
config.lora.hop_limit = HOP_RELIABLE;
|
config.lora.hop_limit = HOP_RELIABLE;
|
||||||
|
#ifdef PIN_GPS_EN
|
||||||
|
config.position.gps_en_gpio = PIN_GPS_EN;
|
||||||
|
#endif
|
||||||
|
#ifdef GPS_POWER_TOGGLE
|
||||||
|
config.device.disable_triple_click = false;
|
||||||
|
#else
|
||||||
|
config.device.disable_triple_click = true;
|
||||||
|
#endif
|
||||||
config.position.gps_enabled = true;
|
config.position.gps_enabled = true;
|
||||||
config.position.position_broadcast_smart_enabled = true;
|
config.position.position_broadcast_smart_enabled = true;
|
||||||
config.position.broadcast_smart_minimum_distance = 100;
|
config.position.broadcast_smart_minimum_distance = 100;
|
||||||
@@ -190,7 +198,9 @@ void NodeDB::installDefaultConfig()
|
|||||||
: meshtastic_Config_BluetoothConfig_PairingMode_FIXED_PIN;
|
: meshtastic_Config_BluetoothConfig_PairingMode_FIXED_PIN;
|
||||||
// for backward compat, default position flags are ALT+MSL
|
// for backward compat, default position flags are ALT+MSL
|
||||||
config.position.position_flags =
|
config.position.position_flags =
|
||||||
(meshtastic_Config_PositionConfig_PositionFlags_ALTITUDE | meshtastic_Config_PositionConfig_PositionFlags_ALTITUDE_MSL);
|
(meshtastic_Config_PositionConfig_PositionFlags_ALTITUDE | meshtastic_Config_PositionConfig_PositionFlags_ALTITUDE_MSL |
|
||||||
|
meshtastic_Config_PositionConfig_PositionFlags_SPEED | meshtastic_Config_PositionConfig_PositionFlags_HEADING |
|
||||||
|
meshtastic_Config_PositionConfig_PositionFlags_DOP);
|
||||||
|
|
||||||
#ifdef T_WATCH_S3
|
#ifdef T_WATCH_S3
|
||||||
config.display.screen_on_secs = 30;
|
config.display.screen_on_secs = 30;
|
||||||
@@ -244,10 +254,24 @@ void NodeDB::installDefaultModuleConfig()
|
|||||||
strncpy(moduleConfig.mqtt.address, default_mqtt_address, sizeof(moduleConfig.mqtt.address));
|
strncpy(moduleConfig.mqtt.address, default_mqtt_address, sizeof(moduleConfig.mqtt.address));
|
||||||
strncpy(moduleConfig.mqtt.username, default_mqtt_username, sizeof(moduleConfig.mqtt.username));
|
strncpy(moduleConfig.mqtt.username, default_mqtt_username, sizeof(moduleConfig.mqtt.username));
|
||||||
strncpy(moduleConfig.mqtt.password, default_mqtt_password, sizeof(moduleConfig.mqtt.password));
|
strncpy(moduleConfig.mqtt.password, default_mqtt_password, sizeof(moduleConfig.mqtt.password));
|
||||||
|
strncpy(moduleConfig.mqtt.root, default_mqtt_root, sizeof(moduleConfig.mqtt.root));
|
||||||
|
moduleConfig.mqtt.encryption_enabled = true;
|
||||||
|
|
||||||
moduleConfig.has_neighbor_info = true;
|
moduleConfig.has_neighbor_info = true;
|
||||||
moduleConfig.neighbor_info.enabled = false;
|
moduleConfig.neighbor_info.enabled = false;
|
||||||
|
|
||||||
|
moduleConfig.has_detection_sensor = true;
|
||||||
|
moduleConfig.detection_sensor.enabled = false;
|
||||||
|
moduleConfig.detection_sensor.detection_triggered_high = true;
|
||||||
|
moduleConfig.detection_sensor.minimum_broadcast_secs = 45;
|
||||||
|
|
||||||
|
moduleConfig.has_ambient_lighting = true;
|
||||||
|
moduleConfig.ambient_lighting.current = 10;
|
||||||
|
// Default to a color based on our node number
|
||||||
|
moduleConfig.ambient_lighting.red = (myNodeInfo.my_node_num & 0xFF0000) >> 16;
|
||||||
|
moduleConfig.ambient_lighting.green = (myNodeInfo.my_node_num & 0x00FF00) >> 8;
|
||||||
|
moduleConfig.ambient_lighting.blue = myNodeInfo.my_node_num & 0x0000FF;
|
||||||
|
|
||||||
initModuleConfigIntervals();
|
initModuleConfigIntervals();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -263,6 +287,15 @@ void NodeDB::installRoleDefaults(meshtastic_Config_DeviceConfig_Role role)
|
|||||||
} else if (role == meshtastic_Config_DeviceConfig_Role_SENSOR) {
|
} else if (role == meshtastic_Config_DeviceConfig_Role_SENSOR) {
|
||||||
moduleConfig.telemetry.environment_measurement_enabled = true;
|
moduleConfig.telemetry.environment_measurement_enabled = true;
|
||||||
moduleConfig.telemetry.environment_update_interval = 300;
|
moduleConfig.telemetry.environment_update_interval = 300;
|
||||||
|
} else if (role == meshtastic_Config_DeviceConfig_Role_TAK) {
|
||||||
|
config.device.node_info_broadcast_secs = ONE_DAY;
|
||||||
|
config.position.position_broadcast_smart_enabled = false;
|
||||||
|
config.position.position_broadcast_secs = ONE_DAY;
|
||||||
|
// Remove Altitude MSL from flags since CoTs use HAE (height above ellipsoid)
|
||||||
|
config.position.position_flags =
|
||||||
|
(meshtastic_Config_PositionConfig_PositionFlags_ALTITUDE | meshtastic_Config_PositionConfig_PositionFlags_SPEED |
|
||||||
|
meshtastic_Config_PositionConfig_PositionFlags_HEADING | meshtastic_Config_PositionConfig_PositionFlags_DOP);
|
||||||
|
moduleConfig.telemetry.device_update_interval = ONE_DAY;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -290,6 +323,19 @@ void NodeDB::resetNodes()
|
|||||||
neighborInfoModule->resetNeighbors();
|
neighborInfoModule->resetNeighbors();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void NodeDB::cleanupMeshDB()
|
||||||
|
{
|
||||||
|
int newPos = 0, removed = 0;
|
||||||
|
for (int i = 0; i < *numMeshNodes; i++) {
|
||||||
|
if (meshNodes[i].has_user)
|
||||||
|
meshNodes[newPos++] = meshNodes[i];
|
||||||
|
else
|
||||||
|
removed++;
|
||||||
|
}
|
||||||
|
*numMeshNodes -= removed;
|
||||||
|
LOG_DEBUG("cleanupMeshDB purged %d entries\n", removed);
|
||||||
|
}
|
||||||
|
|
||||||
void NodeDB::installDefaultDeviceState()
|
void NodeDB::installDefaultDeviceState()
|
||||||
{
|
{
|
||||||
LOG_INFO("Installing default DeviceState\n");
|
LOG_INFO("Installing default DeviceState\n");
|
||||||
@@ -319,6 +365,7 @@ void NodeDB::init()
|
|||||||
{
|
{
|
||||||
LOG_INFO("Initializing NodeDB\n");
|
LOG_INFO("Initializing NodeDB\n");
|
||||||
loadFromDisk();
|
loadFromDisk();
|
||||||
|
cleanupMeshDB();
|
||||||
|
|
||||||
uint32_t devicestateCRC = crc32Buffer(&devicestate, sizeof(devicestate));
|
uint32_t devicestateCRC = crc32Buffer(&devicestate, sizeof(devicestate));
|
||||||
uint32_t configCRC = crc32Buffer(&config, sizeof(config));
|
uint32_t configCRC = crc32Buffer(&config, sizeof(config));
|
||||||
@@ -374,25 +421,20 @@ void NodeDB::init()
|
|||||||
*/
|
*/
|
||||||
void NodeDB::pickNewNodeNum()
|
void NodeDB::pickNewNodeNum()
|
||||||
{
|
{
|
||||||
NodeNum r = myNodeInfo.my_node_num;
|
|
||||||
|
|
||||||
getMacAddr(ourMacAddr); // Make sure ourMacAddr is set
|
getMacAddr(ourMacAddr); // Make sure ourMacAddr is set
|
||||||
|
|
||||||
// Pick an initial nodenum based on the macaddr
|
// Pick an initial nodenum based on the macaddr
|
||||||
r = (ourMacAddr[2] << 24) | (ourMacAddr[3] << 16) | (ourMacAddr[4] << 8) | ourMacAddr[5];
|
NodeNum nodeNum = (ourMacAddr[2] << 24) | (ourMacAddr[3] << 16) | (ourMacAddr[4] << 8) | ourMacAddr[5];
|
||||||
|
|
||||||
if (r == NODENUM_BROADCAST || r < NUM_RESERVED)
|
|
||||||
r = NUM_RESERVED; // don't pick a reserved node number
|
|
||||||
|
|
||||||
meshtastic_NodeInfoLite *found;
|
meshtastic_NodeInfoLite *found;
|
||||||
while ((found = getMeshNode(r)) && memcmp(found->user.macaddr, owner.macaddr, sizeof(owner.macaddr))) {
|
while ((nodeNum == NODENUM_BROADCAST || nodeNum < NUM_RESERVED) ||
|
||||||
// FIXME: input for random() is int, so NODENUM_BROADCAST becomes -1
|
((found = getMeshNode(nodeNum)) && memcmp(found->user.macaddr, owner.macaddr, sizeof(owner.macaddr)) != 0)) {
|
||||||
NodeNum n = random(NUM_RESERVED, NODENUM_BROADCAST); // try a new random choice
|
NodeNum candidate = random(NUM_RESERVED, LONG_MAX); // try a new random choice
|
||||||
LOG_WARN("NOTE! Our desired nodenum 0x%x is in use, so trying for 0x%x\n", r, n);
|
LOG_WARN("NOTE! Our desired nodenum 0x%x is invalid or in use, so trying for 0x%x\n", nodeNum, candidate);
|
||||||
r = n;
|
nodeNum = candidate;
|
||||||
}
|
}
|
||||||
|
|
||||||
myNodeInfo.my_node_num = r;
|
myNodeInfo.my_node_num = nodeNum;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const char *prefFileName = "/prefs/db.proto";
|
static const char *prefFileName = "/prefs/db.proto";
|
||||||
@@ -656,8 +698,8 @@ void NodeDB::updatePosition(uint32_t nodeId, const meshtastic_Position &p, RxSou
|
|||||||
LOG_INFO("updatePosition LOCAL pos@%x, time=%u, latI=%d, lonI=%d, alt=%d\n", p.timestamp, p.time, p.latitude_i,
|
LOG_INFO("updatePosition LOCAL pos@%x, time=%u, latI=%d, lonI=%d, alt=%d\n", p.timestamp, p.time, p.latitude_i,
|
||||||
p.longitude_i, p.altitude);
|
p.longitude_i, p.altitude);
|
||||||
|
|
||||||
info->position = ConvertToPositionLite(p);
|
setLocalPosition(p);
|
||||||
localPosition = p;
|
info->position = TypeConversions::ConvertToPositionLite(p);
|
||||||
} else if ((p.time > 0) && !p.latitude_i && !p.longitude_i && !p.timestamp && !p.location_source) {
|
} else if ((p.time > 0) && !p.latitude_i && !p.longitude_i && !p.timestamp && !p.location_source) {
|
||||||
// FIXME SPECIAL TIME SETTING PACKET FROM EUD TO RADIO
|
// FIXME SPECIAL TIME SETTING PACKET FROM EUD TO RADIO
|
||||||
// (stop-gap fix for issue #900)
|
// (stop-gap fix for issue #900)
|
||||||
@@ -675,7 +717,7 @@ void NodeDB::updatePosition(uint32_t nodeId, const meshtastic_Position &p, RxSou
|
|||||||
uint32_t tmp_time = info->position.time;
|
uint32_t tmp_time = info->position.time;
|
||||||
|
|
||||||
// Next, update atomically
|
// Next, update atomically
|
||||||
info->position = ConvertToPositionLite(p);
|
info->position = TypeConversions::ConvertToPositionLite(p);
|
||||||
|
|
||||||
// Last, restore any fields that may have been overwritten
|
// Last, restore any fields that may have been overwritten
|
||||||
if (!info->position.time)
|
if (!info->position.time)
|
||||||
@@ -765,7 +807,7 @@ void NodeDB::updateFrom(const meshtastic_MeshPacket &mp)
|
|||||||
|
|
||||||
uint8_t NodeDB::getMeshNodeChannel(NodeNum n)
|
uint8_t NodeDB::getMeshNodeChannel(NodeNum n)
|
||||||
{
|
{
|
||||||
meshtastic_NodeInfoLite *info = getMeshNode(n);
|
const meshtastic_NodeInfoLite *info = getMeshNode(n);
|
||||||
if (!info) {
|
if (!info) {
|
||||||
return 0; // defaults to PRIMARY
|
return 0; // defaults to PRIMARY
|
||||||
}
|
}
|
||||||
@@ -790,7 +832,8 @@ meshtastic_NodeInfoLite *NodeDB::getOrCreateMeshNode(NodeNum n)
|
|||||||
|
|
||||||
if (!lite) {
|
if (!lite) {
|
||||||
if ((*numMeshNodes >= MAX_NUM_NODES) || (memGet.getFreeHeap() < meshtastic_NodeInfoLite_size * 3)) {
|
if ((*numMeshNodes >= MAX_NUM_NODES) || (memGet.getFreeHeap() < meshtastic_NodeInfoLite_size * 3)) {
|
||||||
screen->print("warning: node_db_lite full! erasing oldest entry\n");
|
if (screen)
|
||||||
|
screen->print("warning: node_db_lite full! erasing oldest entry\n");
|
||||||
// look for oldest node and erase it
|
// look for oldest node and erase it
|
||||||
uint32_t oldest = UINT32_MAX;
|
uint32_t oldest = UINT32_MAX;
|
||||||
int oldestIndex = -1;
|
int oldestIndex = -1;
|
||||||
|
|||||||
@@ -131,6 +131,13 @@ class NodeDB
|
|||||||
meshtastic_NodeInfoLite *getMeshNode(NodeNum n);
|
meshtastic_NodeInfoLite *getMeshNode(NodeNum n);
|
||||||
size_t getNumMeshNodes() { return *numMeshNodes; }
|
size_t getNumMeshNodes() { return *numMeshNodes; }
|
||||||
|
|
||||||
|
void setLocalPosition(meshtastic_Position position)
|
||||||
|
{
|
||||||
|
LOG_DEBUG("Setting local position: latitude=%i, longitude=%i, time=%i\n", position.latitude_i, position.longitude_i,
|
||||||
|
position.time);
|
||||||
|
localPosition = position;
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/// Find a node in our DB, create an empty NodeInfoLite if missing
|
/// Find a node in our DB, create an empty NodeInfoLite if missing
|
||||||
meshtastic_NodeInfoLite *getOrCreateMeshNode(NodeNum n);
|
meshtastic_NodeInfoLite *getOrCreateMeshNode(NodeNum n);
|
||||||
@@ -146,6 +153,9 @@ class NodeDB
|
|||||||
/// read our db from flash
|
/// read our db from flash
|
||||||
void loadFromDisk();
|
void loadFromDisk();
|
||||||
|
|
||||||
|
/// purge db entries without user info
|
||||||
|
void cleanupMeshDB();
|
||||||
|
|
||||||
/// Reinit device state from scratch (not loading from disk)
|
/// Reinit device state from scratch (not loading from disk)
|
||||||
void installDefaultDeviceState(), installDefaultChannels(), installDefaultConfig(), installDefaultModuleConfig();
|
void installDefaultDeviceState(), installDefaultChannels(), installDefaultConfig(), installDefaultModuleConfig();
|
||||||
};
|
};
|
||||||
@@ -189,11 +199,12 @@ extern NodeDB nodeDB;
|
|||||||
#define default_sds_secs IF_ROUTER(ONE_DAY, UINT32_MAX) // Default to forever super deep sleep
|
#define default_sds_secs IF_ROUTER(ONE_DAY, UINT32_MAX) // Default to forever super deep sleep
|
||||||
#define default_ls_secs IF_ROUTER(ONE_DAY, 5 * 60)
|
#define default_ls_secs IF_ROUTER(ONE_DAY, 5 * 60)
|
||||||
#define default_min_wake_secs 10
|
#define default_min_wake_secs 10
|
||||||
#define default_screen_on_secs 60 * 10
|
#define default_screen_on_secs IF_ROUTER(1, 60 * 10)
|
||||||
|
|
||||||
#define default_mqtt_address "mqtt.meshtastic.org"
|
#define default_mqtt_address "mqtt.meshtastic.org"
|
||||||
#define default_mqtt_username "meshdev"
|
#define default_mqtt_username "meshdev"
|
||||||
#define default_mqtt_password "large4cats"
|
#define default_mqtt_password "large4cats"
|
||||||
|
#define default_mqtt_root "msh"
|
||||||
|
|
||||||
inline uint32_t getConfiguredOrDefaultMs(uint32_t configuredInterval)
|
inline uint32_t getConfiguredOrDefaultMs(uint32_t configuredInterval)
|
||||||
{
|
{
|
||||||
@@ -209,6 +220,14 @@ inline uint32_t getConfiguredOrDefaultMs(uint32_t configuredInterval, uint32_t d
|
|||||||
return defaultInterval * 1000;
|
return defaultInterval * 1000;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline uint32_t getConfiguredOrDefault(uint32_t configured, uint32_t defaultValue)
|
||||||
|
{
|
||||||
|
if (configured > 0)
|
||||||
|
return configured;
|
||||||
|
|
||||||
|
return defaultValue;
|
||||||
|
}
|
||||||
|
|
||||||
/// Sometimes we will have Position objects that only have a time, so check for
|
/// Sometimes we will have Position objects that only have a time, so check for
|
||||||
/// valid lat/lon
|
/// valid lat/lon
|
||||||
static inline bool hasValidPosition(const meshtastic_NodeInfoLite *n)
|
static inline bool hasValidPosition(const meshtastic_NodeInfoLite *n)
|
||||||
|
|||||||
@@ -155,11 +155,18 @@ size_t PhoneAPI::getFromRadio(uint8_t *buf)
|
|||||||
// app not to send locations on our behalf.
|
// app not to send locations on our behalf.
|
||||||
fromRadioScratch.which_payload_variant = meshtastic_FromRadio_my_info_tag;
|
fromRadioScratch.which_payload_variant = meshtastic_FromRadio_my_info_tag;
|
||||||
fromRadioScratch.my_info = myNodeInfo;
|
fromRadioScratch.my_info = myNodeInfo;
|
||||||
state = STATE_SEND_NODEINFO;
|
state = STATE_SEND_METADATA;
|
||||||
|
|
||||||
service.refreshLocalMeshNode(); // Update my NodeInfo because the client will be asking for it soon.
|
service.refreshLocalMeshNode(); // Update my NodeInfo because the client will be asking for it soon.
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case STATE_SEND_METADATA:
|
||||||
|
LOG_INFO("getFromRadio=STATE_SEND_METADATA\n");
|
||||||
|
fromRadioScratch.which_payload_variant = meshtastic_FromRadio_metadata_tag;
|
||||||
|
fromRadioScratch.metadata = getDeviceMetadata();
|
||||||
|
state = STATE_SEND_NODEINFO;
|
||||||
|
break;
|
||||||
|
|
||||||
case STATE_SEND_NODEINFO: {
|
case STATE_SEND_NODEINFO: {
|
||||||
LOG_INFO("getFromRadio=STATE_SEND_NODEINFO\n");
|
LOG_INFO("getFromRadio=STATE_SEND_NODEINFO\n");
|
||||||
|
|
||||||
@@ -283,6 +290,10 @@ size_t PhoneAPI::getFromRadio(uint8_t *buf)
|
|||||||
fromRadioScratch.moduleConfig.which_payload_variant = meshtastic_ModuleConfig_neighbor_info_tag;
|
fromRadioScratch.moduleConfig.which_payload_variant = meshtastic_ModuleConfig_neighbor_info_tag;
|
||||||
fromRadioScratch.moduleConfig.payload_variant.neighbor_info = moduleConfig.neighbor_info;
|
fromRadioScratch.moduleConfig.payload_variant.neighbor_info = moduleConfig.neighbor_info;
|
||||||
break;
|
break;
|
||||||
|
case meshtastic_ModuleConfig_detection_sensor_tag:
|
||||||
|
fromRadioScratch.moduleConfig.which_payload_variant = meshtastic_ModuleConfig_detection_sensor_tag;
|
||||||
|
fromRadioScratch.moduleConfig.payload_variant.detection_sensor = moduleConfig.detection_sensor;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
LOG_ERROR("Unknown module config type %d\n", config_state);
|
LOG_ERROR("Unknown module config type %d\n", config_state);
|
||||||
}
|
}
|
||||||
@@ -290,15 +301,11 @@ size_t PhoneAPI::getFromRadio(uint8_t *buf)
|
|||||||
config_state++;
|
config_state++;
|
||||||
// Advance when we have sent all of our ModuleConfig objects
|
// Advance when we have sent all of our ModuleConfig objects
|
||||||
if (config_state > (_meshtastic_AdminMessage_ModuleConfigType_MAX + 1)) {
|
if (config_state > (_meshtastic_AdminMessage_ModuleConfigType_MAX + 1)) {
|
||||||
state = STATE_SEND_METADATA;
|
state = STATE_SEND_COMPLETE_ID;
|
||||||
config_state = 0;
|
config_state = 0;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case STATE_SEND_METADATA:
|
|
||||||
fromRadioScratch.which_payload_variant = meshtastic_FromRadio_metadata_tag;
|
|
||||||
fromRadioScratch.metadata = getDeviceMetadata();
|
|
||||||
state = STATE_SEND_COMPLETE_ID;
|
|
||||||
break;
|
|
||||||
case STATE_SEND_COMPLETE_ID:
|
case STATE_SEND_COMPLETE_ID:
|
||||||
LOG_INFO("getFromRadio=STATE_SEND_COMPLETE_ID\n");
|
LOG_INFO("getFromRadio=STATE_SEND_COMPLETE_ID\n");
|
||||||
fromRadioScratch.which_payload_variant = meshtastic_FromRadio_config_complete_id_tag;
|
fromRadioScratch.which_payload_variant = meshtastic_FromRadio_config_complete_id_tag;
|
||||||
@@ -398,7 +405,7 @@ bool PhoneAPI::available()
|
|||||||
if (nodeInfoForPhone.num == 0) {
|
if (nodeInfoForPhone.num == 0) {
|
||||||
auto nextNode = nodeDB.readNextMeshNode(readIndex);
|
auto nextNode = nodeDB.readNextMeshNode(readIndex);
|
||||||
if (nextNode) {
|
if (nextNode) {
|
||||||
nodeInfoForPhone = ConvertToNodeInfo(nextNode);
|
nodeInfoForPhone = TypeConversions::ConvertToNodeInfo(nextNode);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return true; // Always say we have something, because we might need to advance our state machine
|
return true; // Always say we have something, because we might need to advance our state machine
|
||||||
|
|||||||
@@ -534,8 +534,8 @@ size_t RadioInterface::beginSending(meshtastic_MeshPacket *p)
|
|||||||
h->id = p->id;
|
h->id = p->id;
|
||||||
h->channel = p->channel;
|
h->channel = p->channel;
|
||||||
if (p->hop_limit > HOP_MAX) {
|
if (p->hop_limit > HOP_MAX) {
|
||||||
LOG_WARN("hop limit %d is too high, setting to %d\n", p->hop_limit, HOP_MAX);
|
LOG_WARN("hop limit %d is too high, setting to %d\n", p->hop_limit, HOP_RELIABLE);
|
||||||
p->hop_limit = HOP_MAX;
|
p->hop_limit = HOP_RELIABLE;
|
||||||
}
|
}
|
||||||
h->flags = p->hop_limit | (p->want_ack ? PACKET_FLAGS_WANT_ACK_MASK : 0);
|
h->flags = p->hop_limit | (p->want_ack ? PACKET_FLAGS_WANT_ACK_MASK : 0);
|
||||||
|
|
||||||
|
|||||||
@@ -249,29 +249,12 @@ ErrorCode Router::send(meshtastic_MeshPacket *p)
|
|||||||
if (p->which_payload_variant == meshtastic_MeshPacket_decoded_tag) {
|
if (p->which_payload_variant == meshtastic_MeshPacket_decoded_tag) {
|
||||||
ChannelIndex chIndex = p->channel; // keep as a local because we are about to change it
|
ChannelIndex chIndex = p->channel; // keep as a local because we are about to change it
|
||||||
|
|
||||||
bool shouldActuallyEncrypt = true;
|
|
||||||
|
|
||||||
if (moduleConfig.mqtt.enabled) {
|
if (moduleConfig.mqtt.enabled) {
|
||||||
// check if we should send decrypted packets to mqtt
|
|
||||||
|
|
||||||
// truth table:
|
LOG_INFO("Should encrypt MQTT?: %d\n", moduleConfig.mqtt.encryption_enabled);
|
||||||
/* mqtt_server mqtt_encryption_enabled should_encrypt
|
|
||||||
* not set 0 1
|
|
||||||
* not set 1 1
|
|
||||||
* set 0 0
|
|
||||||
* set 1 1
|
|
||||||
*
|
|
||||||
* => so we only decrypt mqtt if they have a custom mqtt server AND mqtt_encryption_enabled is FALSE
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (*moduleConfig.mqtt.address && !moduleConfig.mqtt.encryption_enabled) {
|
|
||||||
shouldActuallyEncrypt = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
LOG_INFO("Should encrypt MQTT?: %d\n", shouldActuallyEncrypt);
|
|
||||||
|
|
||||||
// the packet is currently in a decrypted state. send it now if they want decrypted packets
|
// the packet is currently in a decrypted state. send it now if they want decrypted packets
|
||||||
if (mqtt && !shouldActuallyEncrypt)
|
if (mqtt && !moduleConfig.mqtt.encryption_enabled)
|
||||||
mqtt->onSend(*p, chIndex);
|
mqtt->onSend(*p, chIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -284,7 +267,7 @@ ErrorCode Router::send(meshtastic_MeshPacket *p)
|
|||||||
if (moduleConfig.mqtt.enabled) {
|
if (moduleConfig.mqtt.enabled) {
|
||||||
// the packet is now encrypted.
|
// the packet is now encrypted.
|
||||||
// check if we should send encrypted packets to mqtt
|
// check if we should send encrypted packets to mqtt
|
||||||
if (mqtt && shouldActuallyEncrypt)
|
if (mqtt && moduleConfig.mqtt.encryption_enabled)
|
||||||
mqtt->onSend(*p, chIndex);
|
mqtt->onSend(*p, chIndex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,7 +3,8 @@
|
|||||||
#include "error.h"
|
#include "error.h"
|
||||||
#include "mesh/NodeDB.h"
|
#include "mesh/NodeDB.h"
|
||||||
|
|
||||||
// Particular boards might define a different max power based on what their hardware can do
|
// Particular boards might define a different max power based on what their hardware can do, default to max power output if not
|
||||||
|
// specified (may be dangerous if using external PA and SX126x power config forgotten)
|
||||||
#ifndef SX126X_MAX_POWER
|
#ifndef SX126X_MAX_POWER
|
||||||
#define SX126X_MAX_POWER 22
|
#define SX126X_MAX_POWER 22
|
||||||
#endif
|
#endif
|
||||||
@@ -26,20 +27,23 @@ template <typename T> bool SX126xInterface<T>::init()
|
|||||||
pinMode(SX126X_POWER_EN, OUTPUT);
|
pinMode(SX126X_POWER_EN, OUTPUT);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef SX126X_E22
|
// FIXME: correct logic to default to not using TCXO if no voltage is specified for SX126X_DIO3_TCXO_VOLTAGE
|
||||||
float tcxoVoltage = 0; // None - we use an XTAL
|
#if !defined(SX126X_DIO3_TCXO_VOLTAGE)
|
||||||
|
float tcxoVoltage =
|
||||||
|
0; // "TCXO reference voltage to be set on DIO3. Defaults to 1.6 V, set to 0 to skip." per
|
||||||
|
// https://github.com/jgromes/RadioLib/blob/690a050ebb46e6097c5d00c371e961c1caa3b52e/src/modules/SX126x/SX126x.h#L471C26-L471C104
|
||||||
|
// (DIO3 is free to be used as an IRQ)
|
||||||
|
LOG_DEBUG("SX126X_DIO3_TCXO_VOLTAGE not defined, not using DIO3 as TCXO reference voltage\n");
|
||||||
#else
|
#else
|
||||||
// Use DIO3 to power tcxo per https://github.com/jgromes/RadioLib/issues/12#issuecomment-520695575
|
float tcxoVoltage = SX126X_DIO3_TCXO_VOLTAGE;
|
||||||
float tcxoVoltage = 1.8;
|
LOG_DEBUG("SX126X_DIO3_TCXO_VOLTAGE defined, using DIO3 as TCXO reference voltage at %f V\n", SX126X_DIO3_TCXO_VOLTAGE);
|
||||||
|
// (DIO3 is not free to be used as an IRQ)
|
||||||
#endif
|
#endif
|
||||||
|
// FIXME: May want to set depending on a definition, currently all SX126x variant files use the DC-DC regulator option
|
||||||
bool useRegulatorLDO = false; // Seems to depend on the connection to pin 9/DCC_SW - if an inductor DCDC?
|
bool useRegulatorLDO = false; // Seems to depend on the connection to pin 9/DCC_SW - if an inductor DCDC?
|
||||||
|
|
||||||
RadioLibInterface::init();
|
RadioLibInterface::init();
|
||||||
|
if (power > SX126X_MAX_POWER) // Clamp power to maximum defined level
|
||||||
if (power == 0)
|
|
||||||
power = SX126X_MAX_POWER;
|
|
||||||
|
|
||||||
if (power > SX126X_MAX_POWER) // This chip has lower power limits than some
|
|
||||||
power = SX126X_MAX_POWER;
|
power = SX126X_MAX_POWER;
|
||||||
|
|
||||||
limitPower();
|
limitPower();
|
||||||
@@ -54,49 +58,50 @@ template <typename T> bool SX126xInterface<T>::init()
|
|||||||
LOG_INFO("Bandwidth set to %f\n", bw);
|
LOG_INFO("Bandwidth set to %f\n", bw);
|
||||||
LOG_INFO("Power output set to %d\n", power);
|
LOG_INFO("Power output set to %d\n", power);
|
||||||
|
|
||||||
// current limit was removed from module' ctor
|
// Overriding current limit
|
||||||
// override default value (60 mA)
|
// (https://github.com/jgromes/RadioLib/blob/690a050ebb46e6097c5d00c371e961c1caa3b52e/src/modules/SX126x/SX126x.cpp#L85) using
|
||||||
|
// value in SX126xInterface.h (currently 140 mA) It may or may not be neccessary, depending on how RadioLib functions, from
|
||||||
|
// SX1261/2 datasheet: OCP after setting DeviceSel with SetPaConfig(): SX1261 - 60 mA, SX1262 - 140 mA For the SX1268 the IC
|
||||||
|
// defaults to 140mA no matter the set power level, but RadioLib set it lower, this would need further checking Default values
|
||||||
|
// are: SX1262, SX1268: 0x38 (140 mA), SX1261: 0x18 (60 mA)
|
||||||
|
// FIXME: Not ideal to increase SX1261 current limit above 60mA as it can only transmit max 15dBm, should probably only do it
|
||||||
|
// if using SX1262 or SX1268
|
||||||
res = lora.setCurrentLimit(currentLimit);
|
res = lora.setCurrentLimit(currentLimit);
|
||||||
LOG_DEBUG("Current limit set to %f\n", currentLimit);
|
LOG_DEBUG("Current limit set to %f\n", currentLimit);
|
||||||
LOG_DEBUG("Current limit set result %d\n", res);
|
LOG_DEBUG("Current limit set result %d\n", res);
|
||||||
|
|
||||||
#if defined(SX126X_E22)
|
#ifdef SX126X_DIO2_AS_RF_SWITCH
|
||||||
// E22 Emulation explicitly requires DIO2 as RF switch, so set it to TRUE again for good measure. In case somebody defines
|
LOG_DEBUG("Setting DIO2 as RF switch\n");
|
||||||
// SX126X_TX for an E22 Module
|
bool dio2AsRfSwitch = true;
|
||||||
if (res == RADIOLIB_ERR_NONE) {
|
#else
|
||||||
LOG_DEBUG("SX126X_E22 mode enabled. Setting DIO2 as RF Switch\n");
|
LOG_DEBUG("Setting DIO2 as not RF switch\n");
|
||||||
res = lora.setDio2AsRfSwitch(true);
|
bool dio2AsRfSwitch = false;
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
|
if (res == RADIOLIB_ERR_NONE) {
|
||||||
|
res = lora.setDio2AsRfSwitch(dio2AsRfSwitch);
|
||||||
|
}
|
||||||
|
|
||||||
#if defined(SX126X_TXEN) && (SX126X_TXEN != RADIOLIB_NC)
|
// If a pin isn't defined, we set it to RADIOLIB_NC, it is safe to always do external RF switching with RADIOLIB_NC as it has
|
||||||
// If SX126X_TXEN is connected to the MCU, we are manually controlling RX and TX.
|
// no effect
|
||||||
// But lora.begin (called above) sets Dio2 as RF switch control, which is not true here, so set it back to false.
|
#ifndef SX126X_RXEN
|
||||||
if (res == RADIOLIB_ERR_NONE) {
|
#define SX126X_RXEN RADIOLIB_NC
|
||||||
LOG_DEBUG("SX126X_TXEN pin defined. Setting RF Switch: RXEN=%i, TXEN=%i\n", SX126X_RXEN, SX126X_TXEN);
|
LOG_DEBUG("SX126X_RXEN not defined, defaulting to RADIOLIB_NC\n");
|
||||||
res = lora.setDio2AsRfSwitch(false);
|
|
||||||
lora.setRfSwitchPins(SX126X_RXEN, SX126X_TXEN);
|
|
||||||
}
|
|
||||||
#elif defined(SX126X_RXEN) && (SX126X_RXEN != RADIOLIB_NC && defined(E22_TXEN_CONNECTED_TO_DIO2))
|
|
||||||
// Otherwise, if SX126X_RXEN is connected to the MCU, and E22_TXEN_CONNECTED_TO_DIO2 is defined, we are letting the
|
|
||||||
// E22 control RX and TX via DIO2. In this configuration, the E22's TXEN and DIO2 pins are connected to each other,
|
|
||||||
// but not to the MCU.
|
|
||||||
// However, we must still connect the E22's RXEN pin to the MCU, define SX126X_RXEN accordingly, and then call
|
|
||||||
// setRfSwitchPins, otherwise RX sensitivity (observed via RSSI) is greatly diminished.
|
|
||||||
LOG_DEBUG("SX126X_RXEN and E22_TXEN_CONNECTED_TO_DIO2 are defined; value of res: %d", res);
|
|
||||||
if (res == RADIOLIB_ERR_NONE) {
|
|
||||||
LOG_DEBUG("SX126X_TXEN is RADIOLIB_NC, but SX126X_RXEN and E22_TXEN_CONNECTED_TO_DIO2 are both defined; calling "
|
|
||||||
"lora.setRfSwitchPins.");
|
|
||||||
lora.setRfSwitchPins(SX126X_RXEN, SX126X_TXEN);
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
|
#ifndef SX126X_TXEN
|
||||||
|
#define SX126X_TXEN RADIOLIB_NC
|
||||||
|
LOG_DEBUG("SX126X_TXEN not defined, defaulting to RADIOLIB_NC\n");
|
||||||
|
#endif
|
||||||
|
if (res == RADIOLIB_ERR_NONE) {
|
||||||
|
LOG_DEBUG("Using MCU pin %i as RXEN and pin %i as TXEN to control RF switching\n", SX126X_RXEN, SX126X_TXEN);
|
||||||
|
lora.setRfSwitchPins(SX126X_RXEN, SX126X_TXEN);
|
||||||
|
}
|
||||||
|
|
||||||
if (config.lora.sx126x_rx_boosted_gain) {
|
if (config.lora.sx126x_rx_boosted_gain) {
|
||||||
uint16_t result = lora.setRxBoostedGainMode(true);
|
uint16_t result = lora.setRxBoostedGainMode(true);
|
||||||
LOG_INFO("Set Rx Boosted Gain mode; result: %d\n", result);
|
LOG_INFO("Set RX gain to boosted mode; result: %d\n", result);
|
||||||
} else {
|
} else {
|
||||||
uint16_t result = lora.setRxBoostedGainMode(false);
|
uint16_t result = lora.setRxBoostedGainMode(false);
|
||||||
LOG_INFO("Set Rx Power Saving Gain mode; result: %d\n", result);
|
LOG_INFO("Set RX gain to power saving mode (boosted mode off); result: %d\n", result);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
@@ -265,7 +270,7 @@ template <typename T> bool SX126xInterface<T>::isChannelActive()
|
|||||||
/** Could we send right now (i.e. either not actively receiving or transmitting)? */
|
/** Could we send right now (i.e. either not actively receiving or transmitting)? */
|
||||||
template <typename T> bool SX126xInterface<T>::isActivelyReceiving()
|
template <typename T> bool SX126xInterface<T>::isActivelyReceiving()
|
||||||
{
|
{
|
||||||
// The IRQ status will be cleared when we start our read operation. Check if we've started a header, but haven't yet
|
// The IRQ status will be cleared when we start our read operation. Check if we've started a header, but haven't yet
|
||||||
// received and handled the interrupt for reading the packet/handling errors.
|
// received and handled the interrupt for reading the packet/handling errors.
|
||||||
|
|
||||||
uint16_t irq = lora.getIrqStatus();
|
uint16_t irq = lora.getIrqStatus();
|
||||||
@@ -296,7 +301,7 @@ template <typename T> bool SX126xInterface<T>::sleep()
|
|||||||
{
|
{
|
||||||
// Not keeping config is busted - next time nrf52 board boots lora sending fails tcxo related? - see datasheet
|
// Not keeping config is busted - next time nrf52 board boots lora sending fails tcxo related? - see datasheet
|
||||||
// \todo Display actual typename of the adapter, not just `SX126x`
|
// \todo Display actual typename of the adapter, not just `SX126x`
|
||||||
LOG_DEBUG("sx126x entering sleep mode (FIXME, don't keep config)\n");
|
LOG_DEBUG("SX126x entering sleep mode (FIXME, don't keep config)\n");
|
||||||
setStandby(); // Stop any pending operations
|
setStandby(); // Stop any pending operations
|
||||||
|
|
||||||
// turn off TCXO if it was powered
|
// turn off TCXO if it was powered
|
||||||
@@ -312,4 +317,4 @@ template <typename T> bool SX126xInterface<T>::sleep()
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
55
src/mesh/TypeConversions.cpp
Normal file
55
src/mesh/TypeConversions.cpp
Normal file
@@ -0,0 +1,55 @@
|
|||||||
|
#include "TypeConversions.h"
|
||||||
|
#include "mesh/generated/meshtastic/deviceonly.pb.h"
|
||||||
|
#include "mesh/generated/meshtastic/mesh.pb.h"
|
||||||
|
|
||||||
|
meshtastic_NodeInfo TypeConversions::ConvertToNodeInfo(const meshtastic_NodeInfoLite *lite)
|
||||||
|
{
|
||||||
|
meshtastic_NodeInfo info = meshtastic_NodeInfo_init_default;
|
||||||
|
|
||||||
|
info.num = lite->num;
|
||||||
|
info.snr = lite->snr;
|
||||||
|
info.last_heard = lite->last_heard;
|
||||||
|
info.channel = lite->channel;
|
||||||
|
|
||||||
|
if (lite->has_position) {
|
||||||
|
info.has_position = true;
|
||||||
|
info.position.latitude_i = lite->position.latitude_i;
|
||||||
|
info.position.longitude_i = lite->position.longitude_i;
|
||||||
|
info.position.altitude = lite->position.altitude;
|
||||||
|
info.position.location_source = lite->position.location_source;
|
||||||
|
info.position.time = lite->position.time;
|
||||||
|
}
|
||||||
|
if (lite->has_user) {
|
||||||
|
info.has_user = true;
|
||||||
|
info.user = lite->user;
|
||||||
|
}
|
||||||
|
if (lite->has_device_metrics) {
|
||||||
|
info.has_device_metrics = true;
|
||||||
|
info.device_metrics = lite->device_metrics;
|
||||||
|
}
|
||||||
|
return info;
|
||||||
|
}
|
||||||
|
|
||||||
|
meshtastic_PositionLite TypeConversions::ConvertToPositionLite(meshtastic_Position position)
|
||||||
|
{
|
||||||
|
meshtastic_PositionLite lite = meshtastic_PositionLite_init_default;
|
||||||
|
lite.latitude_i = position.latitude_i;
|
||||||
|
lite.longitude_i = position.longitude_i;
|
||||||
|
lite.altitude = position.altitude;
|
||||||
|
lite.location_source = position.location_source;
|
||||||
|
lite.time = position.time;
|
||||||
|
|
||||||
|
return lite;
|
||||||
|
}
|
||||||
|
|
||||||
|
meshtastic_Position TypeConversions::ConvertToPosition(meshtastic_PositionLite lite)
|
||||||
|
{
|
||||||
|
meshtastic_Position position = meshtastic_Position_init_default;
|
||||||
|
position.latitude_i = lite.latitude_i;
|
||||||
|
position.longitude_i = lite.longitude_i;
|
||||||
|
position.altitude = lite.altitude;
|
||||||
|
position.location_source = lite.location_source;
|
||||||
|
position.time = lite.time;
|
||||||
|
|
||||||
|
return position;
|
||||||
|
}
|
||||||
@@ -1,54 +1,13 @@
|
|||||||
#include "mesh/generated/meshtastic/deviceonly.pb.h"
|
#include "mesh/generated/meshtastic/deviceonly.pb.h"
|
||||||
#include "mesh/generated/meshtastic/mesh.pb.h"
|
#include "mesh/generated/meshtastic/mesh.pb.h"
|
||||||
|
|
||||||
inline static meshtastic_NodeInfo ConvertToNodeInfo(const meshtastic_NodeInfoLite *lite)
|
#pragma once
|
||||||
|
#include "NodeDB.h"
|
||||||
|
|
||||||
|
class TypeConversions
|
||||||
{
|
{
|
||||||
meshtastic_NodeInfo info = meshtastic_NodeInfo_init_default;
|
public:
|
||||||
|
static meshtastic_NodeInfo ConvertToNodeInfo(const meshtastic_NodeInfoLite *lite);
|
||||||
info.num = lite->num;
|
static meshtastic_PositionLite ConvertToPositionLite(meshtastic_Position position);
|
||||||
info.snr = lite->snr;
|
static meshtastic_Position ConvertToPosition(meshtastic_PositionLite lite);
|
||||||
info.last_heard = lite->last_heard;
|
};
|
||||||
info.channel = lite->channel;
|
|
||||||
|
|
||||||
if (lite->has_position) {
|
|
||||||
info.has_position = true;
|
|
||||||
info.position.latitude_i = lite->position.latitude_i;
|
|
||||||
info.position.longitude_i = lite->position.longitude_i;
|
|
||||||
info.position.altitude = lite->position.altitude;
|
|
||||||
info.position.location_source = lite->position.location_source;
|
|
||||||
info.position.time = lite->position.time;
|
|
||||||
}
|
|
||||||
if (lite->has_user) {
|
|
||||||
info.has_user = true;
|
|
||||||
info.user = lite->user;
|
|
||||||
}
|
|
||||||
if (lite->has_device_metrics) {
|
|
||||||
info.has_device_metrics = true;
|
|
||||||
info.device_metrics = lite->device_metrics;
|
|
||||||
}
|
|
||||||
return info;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline static meshtastic_PositionLite ConvertToPositionLite(meshtastic_Position position)
|
|
||||||
{
|
|
||||||
meshtastic_PositionLite lite = meshtastic_PositionLite_init_default;
|
|
||||||
lite.latitude_i = position.latitude_i;
|
|
||||||
lite.longitude_i = position.longitude_i;
|
|
||||||
lite.altitude = position.altitude;
|
|
||||||
lite.location_source = position.location_source;
|
|
||||||
lite.time = position.time;
|
|
||||||
|
|
||||||
return lite;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline static meshtastic_Position ConvertToPosition(meshtastic_PositionLite lite)
|
|
||||||
{
|
|
||||||
meshtastic_Position position = meshtastic_Position_init_default;
|
|
||||||
position.latitude_i = lite.latitude_i;
|
|
||||||
position.longitude_i = lite.longitude_i;
|
|
||||||
position.altitude = lite.altitude;
|
|
||||||
position.location_source = lite.location_source;
|
|
||||||
position.time = lite.time;
|
|
||||||
|
|
||||||
return position;
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -57,7 +57,9 @@ typedef enum _meshtastic_AdminMessage_ModuleConfigType {
|
|||||||
/* TODO: REPLACE */
|
/* TODO: REPLACE */
|
||||||
meshtastic_AdminMessage_ModuleConfigType_NEIGHBORINFO_CONFIG = 9,
|
meshtastic_AdminMessage_ModuleConfigType_NEIGHBORINFO_CONFIG = 9,
|
||||||
/* TODO: REPLACE */
|
/* TODO: REPLACE */
|
||||||
meshtastic_AdminMessage_ModuleConfigType_AMBIENTLIGHTING_CONFIG = 10
|
meshtastic_AdminMessage_ModuleConfigType_AMBIENTLIGHTING_CONFIG = 10,
|
||||||
|
/* TODO: REPLACE */
|
||||||
|
meshtastic_AdminMessage_ModuleConfigType_DETECTIONSENSOR_CONFIG = 11
|
||||||
} meshtastic_AdminMessage_ModuleConfigType;
|
} meshtastic_AdminMessage_ModuleConfigType;
|
||||||
|
|
||||||
/* Struct definitions */
|
/* Struct definitions */
|
||||||
@@ -176,8 +178,8 @@ extern "C" {
|
|||||||
#define _meshtastic_AdminMessage_ConfigType_ARRAYSIZE ((meshtastic_AdminMessage_ConfigType)(meshtastic_AdminMessage_ConfigType_BLUETOOTH_CONFIG+1))
|
#define _meshtastic_AdminMessage_ConfigType_ARRAYSIZE ((meshtastic_AdminMessage_ConfigType)(meshtastic_AdminMessage_ConfigType_BLUETOOTH_CONFIG+1))
|
||||||
|
|
||||||
#define _meshtastic_AdminMessage_ModuleConfigType_MIN meshtastic_AdminMessage_ModuleConfigType_MQTT_CONFIG
|
#define _meshtastic_AdminMessage_ModuleConfigType_MIN meshtastic_AdminMessage_ModuleConfigType_MQTT_CONFIG
|
||||||
#define _meshtastic_AdminMessage_ModuleConfigType_MAX meshtastic_AdminMessage_ModuleConfigType_AMBIENTLIGHTING_CONFIG
|
#define _meshtastic_AdminMessage_ModuleConfigType_MAX meshtastic_AdminMessage_ModuleConfigType_DETECTIONSENSOR_CONFIG
|
||||||
#define _meshtastic_AdminMessage_ModuleConfigType_ARRAYSIZE ((meshtastic_AdminMessage_ModuleConfigType)(meshtastic_AdminMessage_ModuleConfigType_AMBIENTLIGHTING_CONFIG+1))
|
#define _meshtastic_AdminMessage_ModuleConfigType_ARRAYSIZE ((meshtastic_AdminMessage_ModuleConfigType)(meshtastic_AdminMessage_ModuleConfigType_DETECTIONSENSOR_CONFIG+1))
|
||||||
|
|
||||||
#define meshtastic_AdminMessage_payload_variant_get_config_request_ENUMTYPE meshtastic_AdminMessage_ConfigType
|
#define meshtastic_AdminMessage_payload_variant_get_config_request_ENUMTYPE meshtastic_AdminMessage_ConfigType
|
||||||
#define meshtastic_AdminMessage_payload_variant_get_module_config_request_ENUMTYPE meshtastic_AdminMessage_ModuleConfigType
|
#define meshtastic_AdminMessage_payload_variant_get_module_config_request_ENUMTYPE meshtastic_AdminMessage_ModuleConfigType
|
||||||
|
|||||||
@@ -30,11 +30,20 @@ typedef enum _meshtastic_Config_DeviceConfig_Role {
|
|||||||
or any other packet type. They will simply rebroadcast any mesh packets on the same frequency, channel num, spread factor, and coding rate. */
|
or any other packet type. They will simply rebroadcast any mesh packets on the same frequency, channel num, spread factor, and coding rate. */
|
||||||
meshtastic_Config_DeviceConfig_Role_REPEATER = 4,
|
meshtastic_Config_DeviceConfig_Role_REPEATER = 4,
|
||||||
/* Tracker device role
|
/* Tracker device role
|
||||||
Position Mesh packets will be prioritized higher and sent more frequently by default. */
|
Position Mesh packets will be prioritized higher and sent more frequently by default.
|
||||||
|
When used in conjunction with power.is_power_saving = true, nodes will wake up,
|
||||||
|
send position, and then sleep for position.position_broadcast_secs seconds. */
|
||||||
meshtastic_Config_DeviceConfig_Role_TRACKER = 5,
|
meshtastic_Config_DeviceConfig_Role_TRACKER = 5,
|
||||||
/* Sensor device role
|
/* Sensor device role
|
||||||
Telemetry Mesh packets will be prioritized higher and sent more frequently by default. */
|
Telemetry Mesh packets will be prioritized higher and sent more frequently by default.
|
||||||
meshtastic_Config_DeviceConfig_Role_SENSOR = 6
|
When used in conjunction with power.is_power_saving = true, nodes will wake up,
|
||||||
|
send environment telemetry, and then sleep for telemetry.environment_update_interval seconds. */
|
||||||
|
meshtastic_Config_DeviceConfig_Role_SENSOR = 6,
|
||||||
|
/* TAK device role
|
||||||
|
Used for nodes dedicated for connection to an ATAK EUD.
|
||||||
|
Turns off many of the routine broadcasts to favor CoT packet stream
|
||||||
|
from the Meshtastic ATAK plugin -> IMeshService -> Node */
|
||||||
|
meshtastic_Config_DeviceConfig_Role_TAK = 7
|
||||||
} meshtastic_Config_DeviceConfig_Role;
|
} meshtastic_Config_DeviceConfig_Role;
|
||||||
|
|
||||||
/* Defines the device's behavior for how messages are rebroadcast */
|
/* Defines the device's behavior for how messages are rebroadcast */
|
||||||
@@ -51,8 +60,9 @@ typedef enum _meshtastic_Config_DeviceConfig_RebroadcastMode {
|
|||||||
} meshtastic_Config_DeviceConfig_RebroadcastMode;
|
} meshtastic_Config_DeviceConfig_RebroadcastMode;
|
||||||
|
|
||||||
/* Bit field of boolean configuration options, indicating which optional
|
/* Bit field of boolean configuration options, indicating which optional
|
||||||
fields to include when assembling POSITION messages
|
fields to include when assembling POSITION messages.
|
||||||
Longitude and latitude are always included (also time if GPS-synced)
|
Longitude, latitude, altitude, speed, heading, and DOP
|
||||||
|
are always included (also time if GPS-synced)
|
||||||
NOTE: the more fields are included, the larger the message will be -
|
NOTE: the more fields are included, the larger the message will be -
|
||||||
leading to longer airtime and a higher risk of packet loss */
|
leading to longer airtime and a higher risk of packet loss */
|
||||||
typedef enum _meshtastic_Config_PositionConfig_PositionFlags {
|
typedef enum _meshtastic_Config_PositionConfig_PositionFlags {
|
||||||
@@ -236,6 +246,8 @@ typedef struct _meshtastic_Config_DeviceConfig {
|
|||||||
/* If true, device is considered to be "managed" by a mesh administrator
|
/* If true, device is considered to be "managed" by a mesh administrator
|
||||||
Clients should then limit available configuration and administrative options inside the user interface */
|
Clients should then limit available configuration and administrative options inside the user interface */
|
||||||
bool is_managed;
|
bool is_managed;
|
||||||
|
/* Disables the triple-press of user button to enable or disable GPS */
|
||||||
|
bool disable_triple_click;
|
||||||
} meshtastic_Config_DeviceConfig;
|
} meshtastic_Config_DeviceConfig;
|
||||||
|
|
||||||
/* Position Config */
|
/* Position Config */
|
||||||
@@ -269,8 +281,10 @@ typedef struct _meshtastic_Config_PositionConfig {
|
|||||||
uint32_t tx_gpio;
|
uint32_t tx_gpio;
|
||||||
/* The minimum distance in meters traveled (since the last send) before we can send a position to the mesh if position_broadcast_smart_enabled */
|
/* The minimum distance in meters traveled (since the last send) before we can send a position to the mesh if position_broadcast_smart_enabled */
|
||||||
uint32_t broadcast_smart_minimum_distance;
|
uint32_t broadcast_smart_minimum_distance;
|
||||||
/* The minumum number of seconds (since the last send) before we can send a position to the mesh if position_broadcast_smart_enabled */
|
/* The minimum number of seconds (since the last send) before we can send a position to the mesh if position_broadcast_smart_enabled */
|
||||||
uint32_t broadcast_smart_minimum_interval_secs;
|
uint32_t broadcast_smart_minimum_interval_secs;
|
||||||
|
/* (Re)define PIN_GPS_EN for your board. */
|
||||||
|
uint32_t gps_en_gpio;
|
||||||
} meshtastic_Config_PositionConfig;
|
} meshtastic_Config_PositionConfig;
|
||||||
|
|
||||||
/* Power Config\
|
/* Power Config\
|
||||||
@@ -292,12 +306,6 @@ typedef struct _meshtastic_Config_PowerConfig {
|
|||||||
The number of seconds for to wait before turning off BLE in No Bluetooth states
|
The number of seconds for to wait before turning off BLE in No Bluetooth states
|
||||||
0 for default of 1 minute */
|
0 for default of 1 minute */
|
||||||
uint32_t wait_bluetooth_secs;
|
uint32_t wait_bluetooth_secs;
|
||||||
/* Deprecated in 2.1.X
|
|
||||||
Mesh Super Deep Sleep Timeout Seconds
|
|
||||||
While in Light Sleep if this value is exceeded we will lower into super deep sleep
|
|
||||||
for sds_secs (default 1 year) or a button press
|
|
||||||
0 for default of two hours, MAXUINT for disabled */
|
|
||||||
uint32_t mesh_sds_timeout_secs;
|
|
||||||
/* Super Deep Sleep Seconds
|
/* Super Deep Sleep Seconds
|
||||||
While in Light Sleep if mesh_sds_timeout_secs is exceeded we will lower into super deep sleep
|
While in Light Sleep if mesh_sds_timeout_secs is exceeded we will lower into super deep sleep
|
||||||
for this value (default 1 year) or a button press
|
for this value (default 1 year) or a button press
|
||||||
@@ -404,7 +412,8 @@ typedef struct _meshtastic_Config_LoRaConfig {
|
|||||||
/* The region code for the radio (US, CN, EU433, etc...) */
|
/* The region code for the radio (US, CN, EU433, etc...) */
|
||||||
meshtastic_Config_LoRaConfig_RegionCode region;
|
meshtastic_Config_LoRaConfig_RegionCode region;
|
||||||
/* Maximum number of hops. This can't be greater than 7.
|
/* Maximum number of hops. This can't be greater than 7.
|
||||||
Default of 3 */
|
Default of 3
|
||||||
|
Attempting to set a value > 7 results in the default */
|
||||||
uint32_t hop_limit;
|
uint32_t hop_limit;
|
||||||
/* Disable TX from the LoRa radio. Useful for hot-swapping antennas and other tests.
|
/* Disable TX from the LoRa radio. Useful for hot-swapping antennas and other tests.
|
||||||
Defaults to false */
|
Defaults to false */
|
||||||
@@ -470,8 +479,8 @@ extern "C" {
|
|||||||
|
|
||||||
/* Helper constants for enums */
|
/* Helper constants for enums */
|
||||||
#define _meshtastic_Config_DeviceConfig_Role_MIN meshtastic_Config_DeviceConfig_Role_CLIENT
|
#define _meshtastic_Config_DeviceConfig_Role_MIN meshtastic_Config_DeviceConfig_Role_CLIENT
|
||||||
#define _meshtastic_Config_DeviceConfig_Role_MAX meshtastic_Config_DeviceConfig_Role_SENSOR
|
#define _meshtastic_Config_DeviceConfig_Role_MAX meshtastic_Config_DeviceConfig_Role_TAK
|
||||||
#define _meshtastic_Config_DeviceConfig_Role_ARRAYSIZE ((meshtastic_Config_DeviceConfig_Role)(meshtastic_Config_DeviceConfig_Role_SENSOR+1))
|
#define _meshtastic_Config_DeviceConfig_Role_ARRAYSIZE ((meshtastic_Config_DeviceConfig_Role)(meshtastic_Config_DeviceConfig_Role_TAK+1))
|
||||||
|
|
||||||
#define _meshtastic_Config_DeviceConfig_RebroadcastMode_MIN meshtastic_Config_DeviceConfig_RebroadcastMode_ALL
|
#define _meshtastic_Config_DeviceConfig_RebroadcastMode_MIN meshtastic_Config_DeviceConfig_RebroadcastMode_ALL
|
||||||
#define _meshtastic_Config_DeviceConfig_RebroadcastMode_MAX meshtastic_Config_DeviceConfig_RebroadcastMode_LOCAL_ONLY
|
#define _meshtastic_Config_DeviceConfig_RebroadcastMode_MAX meshtastic_Config_DeviceConfig_RebroadcastMode_LOCAL_ONLY
|
||||||
@@ -535,18 +544,18 @@ extern "C" {
|
|||||||
|
|
||||||
/* Initializer values for message structs */
|
/* Initializer values for message structs */
|
||||||
#define meshtastic_Config_init_default {0, {meshtastic_Config_DeviceConfig_init_default}}
|
#define meshtastic_Config_init_default {0, {meshtastic_Config_DeviceConfig_init_default}}
|
||||||
#define meshtastic_Config_DeviceConfig_init_default {_meshtastic_Config_DeviceConfig_Role_MIN, 0, 0, 0, 0, _meshtastic_Config_DeviceConfig_RebroadcastMode_MIN, 0, 0, 0}
|
#define meshtastic_Config_DeviceConfig_init_default {_meshtastic_Config_DeviceConfig_Role_MIN, 0, 0, 0, 0, _meshtastic_Config_DeviceConfig_RebroadcastMode_MIN, 0, 0, 0, 0}
|
||||||
#define meshtastic_Config_PositionConfig_init_default {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
|
#define meshtastic_Config_PositionConfig_init_default {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
|
||||||
#define meshtastic_Config_PowerConfig_init_default {0, 0, 0, 0, 0, 0, 0, 0, 0}
|
#define meshtastic_Config_PowerConfig_init_default {0, 0, 0, 0, 0, 0, 0, 0}
|
||||||
#define meshtastic_Config_NetworkConfig_init_default {0, "", "", "", 0, _meshtastic_Config_NetworkConfig_AddressMode_MIN, false, meshtastic_Config_NetworkConfig_IpV4Config_init_default, ""}
|
#define meshtastic_Config_NetworkConfig_init_default {0, "", "", "", 0, _meshtastic_Config_NetworkConfig_AddressMode_MIN, false, meshtastic_Config_NetworkConfig_IpV4Config_init_default, ""}
|
||||||
#define meshtastic_Config_NetworkConfig_IpV4Config_init_default {0, 0, 0, 0}
|
#define meshtastic_Config_NetworkConfig_IpV4Config_init_default {0, 0, 0, 0}
|
||||||
#define meshtastic_Config_DisplayConfig_init_default {0, _meshtastic_Config_DisplayConfig_GpsCoordinateFormat_MIN, 0, 0, 0, _meshtastic_Config_DisplayConfig_DisplayUnits_MIN, _meshtastic_Config_DisplayConfig_OledType_MIN, _meshtastic_Config_DisplayConfig_DisplayMode_MIN, 0, 0}
|
#define meshtastic_Config_DisplayConfig_init_default {0, _meshtastic_Config_DisplayConfig_GpsCoordinateFormat_MIN, 0, 0, 0, _meshtastic_Config_DisplayConfig_DisplayUnits_MIN, _meshtastic_Config_DisplayConfig_OledType_MIN, _meshtastic_Config_DisplayConfig_DisplayMode_MIN, 0, 0}
|
||||||
#define meshtastic_Config_LoRaConfig_init_default {0, _meshtastic_Config_LoRaConfig_ModemPreset_MIN, 0, 0, 0, 0, _meshtastic_Config_LoRaConfig_RegionCode_MIN, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0}}
|
#define meshtastic_Config_LoRaConfig_init_default {0, _meshtastic_Config_LoRaConfig_ModemPreset_MIN, 0, 0, 0, 0, _meshtastic_Config_LoRaConfig_RegionCode_MIN, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0}}
|
||||||
#define meshtastic_Config_BluetoothConfig_init_default {0, _meshtastic_Config_BluetoothConfig_PairingMode_MIN, 0}
|
#define meshtastic_Config_BluetoothConfig_init_default {0, _meshtastic_Config_BluetoothConfig_PairingMode_MIN, 0}
|
||||||
#define meshtastic_Config_init_zero {0, {meshtastic_Config_DeviceConfig_init_zero}}
|
#define meshtastic_Config_init_zero {0, {meshtastic_Config_DeviceConfig_init_zero}}
|
||||||
#define meshtastic_Config_DeviceConfig_init_zero {_meshtastic_Config_DeviceConfig_Role_MIN, 0, 0, 0, 0, _meshtastic_Config_DeviceConfig_RebroadcastMode_MIN, 0, 0, 0}
|
#define meshtastic_Config_DeviceConfig_init_zero {_meshtastic_Config_DeviceConfig_Role_MIN, 0, 0, 0, 0, _meshtastic_Config_DeviceConfig_RebroadcastMode_MIN, 0, 0, 0, 0}
|
||||||
#define meshtastic_Config_PositionConfig_init_zero {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
|
#define meshtastic_Config_PositionConfig_init_zero {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
|
||||||
#define meshtastic_Config_PowerConfig_init_zero {0, 0, 0, 0, 0, 0, 0, 0, 0}
|
#define meshtastic_Config_PowerConfig_init_zero {0, 0, 0, 0, 0, 0, 0, 0}
|
||||||
#define meshtastic_Config_NetworkConfig_init_zero {0, "", "", "", 0, _meshtastic_Config_NetworkConfig_AddressMode_MIN, false, meshtastic_Config_NetworkConfig_IpV4Config_init_zero, ""}
|
#define meshtastic_Config_NetworkConfig_init_zero {0, "", "", "", 0, _meshtastic_Config_NetworkConfig_AddressMode_MIN, false, meshtastic_Config_NetworkConfig_IpV4Config_init_zero, ""}
|
||||||
#define meshtastic_Config_NetworkConfig_IpV4Config_init_zero {0, 0, 0, 0}
|
#define meshtastic_Config_NetworkConfig_IpV4Config_init_zero {0, 0, 0, 0}
|
||||||
#define meshtastic_Config_DisplayConfig_init_zero {0, _meshtastic_Config_DisplayConfig_GpsCoordinateFormat_MIN, 0, 0, 0, _meshtastic_Config_DisplayConfig_DisplayUnits_MIN, _meshtastic_Config_DisplayConfig_OledType_MIN, _meshtastic_Config_DisplayConfig_DisplayMode_MIN, 0, 0}
|
#define meshtastic_Config_DisplayConfig_init_zero {0, _meshtastic_Config_DisplayConfig_GpsCoordinateFormat_MIN, 0, 0, 0, _meshtastic_Config_DisplayConfig_DisplayUnits_MIN, _meshtastic_Config_DisplayConfig_OledType_MIN, _meshtastic_Config_DisplayConfig_DisplayMode_MIN, 0, 0}
|
||||||
@@ -563,6 +572,7 @@ extern "C" {
|
|||||||
#define meshtastic_Config_DeviceConfig_node_info_broadcast_secs_tag 7
|
#define meshtastic_Config_DeviceConfig_node_info_broadcast_secs_tag 7
|
||||||
#define meshtastic_Config_DeviceConfig_double_tap_as_button_press_tag 8
|
#define meshtastic_Config_DeviceConfig_double_tap_as_button_press_tag 8
|
||||||
#define meshtastic_Config_DeviceConfig_is_managed_tag 9
|
#define meshtastic_Config_DeviceConfig_is_managed_tag 9
|
||||||
|
#define meshtastic_Config_DeviceConfig_disable_triple_click_tag 10
|
||||||
#define meshtastic_Config_PositionConfig_position_broadcast_secs_tag 1
|
#define meshtastic_Config_PositionConfig_position_broadcast_secs_tag 1
|
||||||
#define meshtastic_Config_PositionConfig_position_broadcast_smart_enabled_tag 2
|
#define meshtastic_Config_PositionConfig_position_broadcast_smart_enabled_tag 2
|
||||||
#define meshtastic_Config_PositionConfig_fixed_position_tag 3
|
#define meshtastic_Config_PositionConfig_fixed_position_tag 3
|
||||||
@@ -574,11 +584,11 @@ extern "C" {
|
|||||||
#define meshtastic_Config_PositionConfig_tx_gpio_tag 9
|
#define meshtastic_Config_PositionConfig_tx_gpio_tag 9
|
||||||
#define meshtastic_Config_PositionConfig_broadcast_smart_minimum_distance_tag 10
|
#define meshtastic_Config_PositionConfig_broadcast_smart_minimum_distance_tag 10
|
||||||
#define meshtastic_Config_PositionConfig_broadcast_smart_minimum_interval_secs_tag 11
|
#define meshtastic_Config_PositionConfig_broadcast_smart_minimum_interval_secs_tag 11
|
||||||
|
#define meshtastic_Config_PositionConfig_gps_en_gpio_tag 12
|
||||||
#define meshtastic_Config_PowerConfig_is_power_saving_tag 1
|
#define meshtastic_Config_PowerConfig_is_power_saving_tag 1
|
||||||
#define meshtastic_Config_PowerConfig_on_battery_shutdown_after_secs_tag 2
|
#define meshtastic_Config_PowerConfig_on_battery_shutdown_after_secs_tag 2
|
||||||
#define meshtastic_Config_PowerConfig_adc_multiplier_override_tag 3
|
#define meshtastic_Config_PowerConfig_adc_multiplier_override_tag 3
|
||||||
#define meshtastic_Config_PowerConfig_wait_bluetooth_secs_tag 4
|
#define meshtastic_Config_PowerConfig_wait_bluetooth_secs_tag 4
|
||||||
#define meshtastic_Config_PowerConfig_mesh_sds_timeout_secs_tag 5
|
|
||||||
#define meshtastic_Config_PowerConfig_sds_secs_tag 6
|
#define meshtastic_Config_PowerConfig_sds_secs_tag 6
|
||||||
#define meshtastic_Config_PowerConfig_ls_secs_tag 7
|
#define meshtastic_Config_PowerConfig_ls_secs_tag 7
|
||||||
#define meshtastic_Config_PowerConfig_min_wake_secs_tag 8
|
#define meshtastic_Config_PowerConfig_min_wake_secs_tag 8
|
||||||
@@ -659,7 +669,8 @@ X(a, STATIC, SINGULAR, UINT32, buzzer_gpio, 5) \
|
|||||||
X(a, STATIC, SINGULAR, UENUM, rebroadcast_mode, 6) \
|
X(a, STATIC, SINGULAR, UENUM, rebroadcast_mode, 6) \
|
||||||
X(a, STATIC, SINGULAR, UINT32, node_info_broadcast_secs, 7) \
|
X(a, STATIC, SINGULAR, UINT32, node_info_broadcast_secs, 7) \
|
||||||
X(a, STATIC, SINGULAR, BOOL, double_tap_as_button_press, 8) \
|
X(a, STATIC, SINGULAR, BOOL, double_tap_as_button_press, 8) \
|
||||||
X(a, STATIC, SINGULAR, BOOL, is_managed, 9)
|
X(a, STATIC, SINGULAR, BOOL, is_managed, 9) \
|
||||||
|
X(a, STATIC, SINGULAR, BOOL, disable_triple_click, 10)
|
||||||
#define meshtastic_Config_DeviceConfig_CALLBACK NULL
|
#define meshtastic_Config_DeviceConfig_CALLBACK NULL
|
||||||
#define meshtastic_Config_DeviceConfig_DEFAULT NULL
|
#define meshtastic_Config_DeviceConfig_DEFAULT NULL
|
||||||
|
|
||||||
@@ -674,7 +685,8 @@ X(a, STATIC, SINGULAR, UINT32, position_flags, 7) \
|
|||||||
X(a, STATIC, SINGULAR, UINT32, rx_gpio, 8) \
|
X(a, STATIC, SINGULAR, UINT32, rx_gpio, 8) \
|
||||||
X(a, STATIC, SINGULAR, UINT32, tx_gpio, 9) \
|
X(a, STATIC, SINGULAR, UINT32, tx_gpio, 9) \
|
||||||
X(a, STATIC, SINGULAR, UINT32, broadcast_smart_minimum_distance, 10) \
|
X(a, STATIC, SINGULAR, UINT32, broadcast_smart_minimum_distance, 10) \
|
||||||
X(a, STATIC, SINGULAR, UINT32, broadcast_smart_minimum_interval_secs, 11)
|
X(a, STATIC, SINGULAR, UINT32, broadcast_smart_minimum_interval_secs, 11) \
|
||||||
|
X(a, STATIC, SINGULAR, UINT32, gps_en_gpio, 12)
|
||||||
#define meshtastic_Config_PositionConfig_CALLBACK NULL
|
#define meshtastic_Config_PositionConfig_CALLBACK NULL
|
||||||
#define meshtastic_Config_PositionConfig_DEFAULT NULL
|
#define meshtastic_Config_PositionConfig_DEFAULT NULL
|
||||||
|
|
||||||
@@ -683,7 +695,6 @@ X(a, STATIC, SINGULAR, BOOL, is_power_saving, 1) \
|
|||||||
X(a, STATIC, SINGULAR, UINT32, on_battery_shutdown_after_secs, 2) \
|
X(a, STATIC, SINGULAR, UINT32, on_battery_shutdown_after_secs, 2) \
|
||||||
X(a, STATIC, SINGULAR, FLOAT, adc_multiplier_override, 3) \
|
X(a, STATIC, SINGULAR, FLOAT, adc_multiplier_override, 3) \
|
||||||
X(a, STATIC, SINGULAR, UINT32, wait_bluetooth_secs, 4) \
|
X(a, STATIC, SINGULAR, UINT32, wait_bluetooth_secs, 4) \
|
||||||
X(a, STATIC, SINGULAR, UINT32, mesh_sds_timeout_secs, 5) \
|
|
||||||
X(a, STATIC, SINGULAR, UINT32, sds_secs, 6) \
|
X(a, STATIC, SINGULAR, UINT32, sds_secs, 6) \
|
||||||
X(a, STATIC, SINGULAR, UINT32, ls_secs, 7) \
|
X(a, STATIC, SINGULAR, UINT32, ls_secs, 7) \
|
||||||
X(a, STATIC, SINGULAR, UINT32, min_wake_secs, 8) \
|
X(a, STATIC, SINGULAR, UINT32, min_wake_secs, 8) \
|
||||||
@@ -775,13 +786,13 @@ extern const pb_msgdesc_t meshtastic_Config_BluetoothConfig_msg;
|
|||||||
|
|
||||||
/* Maximum encoded size of messages (where known) */
|
/* Maximum encoded size of messages (where known) */
|
||||||
#define meshtastic_Config_BluetoothConfig_size 10
|
#define meshtastic_Config_BluetoothConfig_size 10
|
||||||
#define meshtastic_Config_DeviceConfig_size 30
|
#define meshtastic_Config_DeviceConfig_size 32
|
||||||
#define meshtastic_Config_DisplayConfig_size 28
|
#define meshtastic_Config_DisplayConfig_size 28
|
||||||
#define meshtastic_Config_LoRaConfig_size 77
|
#define meshtastic_Config_LoRaConfig_size 77
|
||||||
#define meshtastic_Config_NetworkConfig_IpV4Config_size 20
|
#define meshtastic_Config_NetworkConfig_IpV4Config_size 20
|
||||||
#define meshtastic_Config_NetworkConfig_size 195
|
#define meshtastic_Config_NetworkConfig_size 195
|
||||||
#define meshtastic_Config_PositionConfig_size 54
|
#define meshtastic_Config_PositionConfig_size 60
|
||||||
#define meshtastic_Config_PowerConfig_size 46
|
#define meshtastic_Config_PowerConfig_size 40
|
||||||
#define meshtastic_Config_size 198
|
#define meshtastic_Config_size 198
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
|||||||
@@ -151,7 +151,7 @@ typedef struct _meshtastic_DeviceState {
|
|||||||
meshtastic_NodeRemoteHardwarePin node_remote_hardware_pins[12];
|
meshtastic_NodeRemoteHardwarePin node_remote_hardware_pins[12];
|
||||||
/* New lite version of NodeDB to decrease memory footprint */
|
/* New lite version of NodeDB to decrease memory footprint */
|
||||||
pb_size_t node_db_lite_count;
|
pb_size_t node_db_lite_count;
|
||||||
meshtastic_NodeInfoLite node_db_lite[80];
|
meshtastic_NodeInfoLite node_db_lite[100];
|
||||||
} meshtastic_DeviceState;
|
} meshtastic_DeviceState;
|
||||||
|
|
||||||
|
|
||||||
@@ -174,13 +174,13 @@ extern "C" {
|
|||||||
|
|
||||||
|
|
||||||
/* Initializer values for message structs */
|
/* Initializer values for message structs */
|
||||||
#define meshtastic_DeviceState_init_default {false, meshtastic_MyNodeInfo_init_default, false, meshtastic_User_init_default, 0, {meshtastic_MeshPacket_init_default}, false, meshtastic_MeshPacket_init_default, 0, 0, 0, false, meshtastic_MeshPacket_init_default, 0, {meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default}, 0, {meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default}}
|
#define meshtastic_DeviceState_init_default {false, meshtastic_MyNodeInfo_init_default, false, meshtastic_User_init_default, 0, {meshtastic_MeshPacket_init_default}, false, meshtastic_MeshPacket_init_default, 0, 0, 0, false, meshtastic_MeshPacket_init_default, 0, {meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default}, 0, {meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default, meshtastic_NodeInfoLite_init_default}}
|
||||||
#define meshtastic_NodeInfoLite_init_default {0, false, meshtastic_User_init_default, false, meshtastic_PositionLite_init_default, 0, 0, false, meshtastic_DeviceMetrics_init_default, 0}
|
#define meshtastic_NodeInfoLite_init_default {0, false, meshtastic_User_init_default, false, meshtastic_PositionLite_init_default, 0, 0, false, meshtastic_DeviceMetrics_init_default, 0}
|
||||||
#define meshtastic_PositionLite_init_default {0, 0, 0, 0, _meshtastic_Position_LocSource_MIN}
|
#define meshtastic_PositionLite_init_default {0, 0, 0, 0, _meshtastic_Position_LocSource_MIN}
|
||||||
#define meshtastic_ChannelFile_init_default {0, {meshtastic_Channel_init_default, meshtastic_Channel_init_default, meshtastic_Channel_init_default, meshtastic_Channel_init_default, meshtastic_Channel_init_default, meshtastic_Channel_init_default, meshtastic_Channel_init_default, meshtastic_Channel_init_default}, 0}
|
#define meshtastic_ChannelFile_init_default {0, {meshtastic_Channel_init_default, meshtastic_Channel_init_default, meshtastic_Channel_init_default, meshtastic_Channel_init_default, meshtastic_Channel_init_default, meshtastic_Channel_init_default, meshtastic_Channel_init_default, meshtastic_Channel_init_default}, 0}
|
||||||
#define meshtastic_OEMStore_init_default {0, 0, {0, {0}}, _meshtastic_ScreenFonts_MIN, "", {0, {0}}, false, meshtastic_LocalConfig_init_default, false, meshtastic_LocalModuleConfig_init_default}
|
#define meshtastic_OEMStore_init_default {0, 0, {0, {0}}, _meshtastic_ScreenFonts_MIN, "", {0, {0}}, false, meshtastic_LocalConfig_init_default, false, meshtastic_LocalModuleConfig_init_default}
|
||||||
#define meshtastic_NodeRemoteHardwarePin_init_default {0, false, meshtastic_RemoteHardwarePin_init_default}
|
#define meshtastic_NodeRemoteHardwarePin_init_default {0, false, meshtastic_RemoteHardwarePin_init_default}
|
||||||
#define meshtastic_DeviceState_init_zero {false, meshtastic_MyNodeInfo_init_zero, false, meshtastic_User_init_zero, 0, {meshtastic_MeshPacket_init_zero}, false, meshtastic_MeshPacket_init_zero, 0, 0, 0, false, meshtastic_MeshPacket_init_zero, 0, {meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero}, 0, {meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero}}
|
#define meshtastic_DeviceState_init_zero {false, meshtastic_MyNodeInfo_init_zero, false, meshtastic_User_init_zero, 0, {meshtastic_MeshPacket_init_zero}, false, meshtastic_MeshPacket_init_zero, 0, 0, 0, false, meshtastic_MeshPacket_init_zero, 0, {meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero}, 0, {meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero, meshtastic_NodeInfoLite_init_zero}}
|
||||||
#define meshtastic_NodeInfoLite_init_zero {0, false, meshtastic_User_init_zero, false, meshtastic_PositionLite_init_zero, 0, 0, false, meshtastic_DeviceMetrics_init_zero, 0}
|
#define meshtastic_NodeInfoLite_init_zero {0, false, meshtastic_User_init_zero, false, meshtastic_PositionLite_init_zero, 0, 0, false, meshtastic_DeviceMetrics_init_zero, 0}
|
||||||
#define meshtastic_PositionLite_init_zero {0, 0, 0, 0, _meshtastic_Position_LocSource_MIN}
|
#define meshtastic_PositionLite_init_zero {0, 0, 0, 0, _meshtastic_Position_LocSource_MIN}
|
||||||
#define meshtastic_ChannelFile_init_zero {0, {meshtastic_Channel_init_zero, meshtastic_Channel_init_zero, meshtastic_Channel_init_zero, meshtastic_Channel_init_zero, meshtastic_Channel_init_zero, meshtastic_Channel_init_zero, meshtastic_Channel_init_zero, meshtastic_Channel_init_zero}, 0}
|
#define meshtastic_ChannelFile_init_zero {0, {meshtastic_Channel_init_zero, meshtastic_Channel_init_zero, meshtastic_Channel_init_zero, meshtastic_Channel_init_zero, meshtastic_Channel_init_zero, meshtastic_Channel_init_zero, meshtastic_Channel_init_zero, meshtastic_Channel_init_zero}, 0}
|
||||||
@@ -313,10 +313,10 @@ extern const pb_msgdesc_t meshtastic_NodeRemoteHardwarePin_msg;
|
|||||||
|
|
||||||
/* Maximum encoded size of messages (where known) */
|
/* Maximum encoded size of messages (where known) */
|
||||||
#define meshtastic_ChannelFile_size 638
|
#define meshtastic_ChannelFile_size 638
|
||||||
#define meshtastic_DeviceState_size 13774
|
#define meshtastic_DeviceState_size 16854
|
||||||
#define meshtastic_NodeInfoLite_size 151
|
#define meshtastic_NodeInfoLite_size 151
|
||||||
#define meshtastic_NodeRemoteHardwarePin_size 29
|
#define meshtastic_NodeRemoteHardwarePin_size 29
|
||||||
#define meshtastic_OEMStore_size 3154
|
#define meshtastic_OEMStore_size 3218
|
||||||
#define meshtastic_PositionLite_size 28
|
#define meshtastic_PositionLite_size 28
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
|||||||
@@ -75,6 +75,12 @@ typedef struct _meshtastic_LocalModuleConfig {
|
|||||||
/* The part of the config that is specific to the Neighbor Info module */
|
/* The part of the config that is specific to the Neighbor Info module */
|
||||||
bool has_neighbor_info;
|
bool has_neighbor_info;
|
||||||
meshtastic_ModuleConfig_NeighborInfoConfig neighbor_info;
|
meshtastic_ModuleConfig_NeighborInfoConfig neighbor_info;
|
||||||
|
/* The part of the config that is specific to the Ambient Lighting module */
|
||||||
|
bool has_ambient_lighting;
|
||||||
|
meshtastic_ModuleConfig_AmbientLightingConfig ambient_lighting;
|
||||||
|
/* The part of the config that is specific to the Detection Sensor module */
|
||||||
|
bool has_detection_sensor;
|
||||||
|
meshtastic_ModuleConfig_DetectionSensorConfig detection_sensor;
|
||||||
} meshtastic_LocalModuleConfig;
|
} meshtastic_LocalModuleConfig;
|
||||||
|
|
||||||
|
|
||||||
@@ -84,9 +90,9 @@ extern "C" {
|
|||||||
|
|
||||||
/* Initializer values for message structs */
|
/* Initializer values for message structs */
|
||||||
#define meshtastic_LocalConfig_init_default {false, meshtastic_Config_DeviceConfig_init_default, false, meshtastic_Config_PositionConfig_init_default, false, meshtastic_Config_PowerConfig_init_default, false, meshtastic_Config_NetworkConfig_init_default, false, meshtastic_Config_DisplayConfig_init_default, false, meshtastic_Config_LoRaConfig_init_default, false, meshtastic_Config_BluetoothConfig_init_default, 0}
|
#define meshtastic_LocalConfig_init_default {false, meshtastic_Config_DeviceConfig_init_default, false, meshtastic_Config_PositionConfig_init_default, false, meshtastic_Config_PowerConfig_init_default, false, meshtastic_Config_NetworkConfig_init_default, false, meshtastic_Config_DisplayConfig_init_default, false, meshtastic_Config_LoRaConfig_init_default, false, meshtastic_Config_BluetoothConfig_init_default, 0}
|
||||||
#define meshtastic_LocalModuleConfig_init_default {false, meshtastic_ModuleConfig_MQTTConfig_init_default, false, meshtastic_ModuleConfig_SerialConfig_init_default, false, meshtastic_ModuleConfig_ExternalNotificationConfig_init_default, false, meshtastic_ModuleConfig_StoreForwardConfig_init_default, false, meshtastic_ModuleConfig_RangeTestConfig_init_default, false, meshtastic_ModuleConfig_TelemetryConfig_init_default, false, meshtastic_ModuleConfig_CannedMessageConfig_init_default, 0, false, meshtastic_ModuleConfig_AudioConfig_init_default, false, meshtastic_ModuleConfig_RemoteHardwareConfig_init_default, false, meshtastic_ModuleConfig_NeighborInfoConfig_init_default}
|
#define meshtastic_LocalModuleConfig_init_default {false, meshtastic_ModuleConfig_MQTTConfig_init_default, false, meshtastic_ModuleConfig_SerialConfig_init_default, false, meshtastic_ModuleConfig_ExternalNotificationConfig_init_default, false, meshtastic_ModuleConfig_StoreForwardConfig_init_default, false, meshtastic_ModuleConfig_RangeTestConfig_init_default, false, meshtastic_ModuleConfig_TelemetryConfig_init_default, false, meshtastic_ModuleConfig_CannedMessageConfig_init_default, 0, false, meshtastic_ModuleConfig_AudioConfig_init_default, false, meshtastic_ModuleConfig_RemoteHardwareConfig_init_default, false, meshtastic_ModuleConfig_NeighborInfoConfig_init_default, false, meshtastic_ModuleConfig_AmbientLightingConfig_init_default, false, meshtastic_ModuleConfig_DetectionSensorConfig_init_default}
|
||||||
#define meshtastic_LocalConfig_init_zero {false, meshtastic_Config_DeviceConfig_init_zero, false, meshtastic_Config_PositionConfig_init_zero, false, meshtastic_Config_PowerConfig_init_zero, false, meshtastic_Config_NetworkConfig_init_zero, false, meshtastic_Config_DisplayConfig_init_zero, false, meshtastic_Config_LoRaConfig_init_zero, false, meshtastic_Config_BluetoothConfig_init_zero, 0}
|
#define meshtastic_LocalConfig_init_zero {false, meshtastic_Config_DeviceConfig_init_zero, false, meshtastic_Config_PositionConfig_init_zero, false, meshtastic_Config_PowerConfig_init_zero, false, meshtastic_Config_NetworkConfig_init_zero, false, meshtastic_Config_DisplayConfig_init_zero, false, meshtastic_Config_LoRaConfig_init_zero, false, meshtastic_Config_BluetoothConfig_init_zero, 0}
|
||||||
#define meshtastic_LocalModuleConfig_init_zero {false, meshtastic_ModuleConfig_MQTTConfig_init_zero, false, meshtastic_ModuleConfig_SerialConfig_init_zero, false, meshtastic_ModuleConfig_ExternalNotificationConfig_init_zero, false, meshtastic_ModuleConfig_StoreForwardConfig_init_zero, false, meshtastic_ModuleConfig_RangeTestConfig_init_zero, false, meshtastic_ModuleConfig_TelemetryConfig_init_zero, false, meshtastic_ModuleConfig_CannedMessageConfig_init_zero, 0, false, meshtastic_ModuleConfig_AudioConfig_init_zero, false, meshtastic_ModuleConfig_RemoteHardwareConfig_init_zero, false, meshtastic_ModuleConfig_NeighborInfoConfig_init_zero}
|
#define meshtastic_LocalModuleConfig_init_zero {false, meshtastic_ModuleConfig_MQTTConfig_init_zero, false, meshtastic_ModuleConfig_SerialConfig_init_zero, false, meshtastic_ModuleConfig_ExternalNotificationConfig_init_zero, false, meshtastic_ModuleConfig_StoreForwardConfig_init_zero, false, meshtastic_ModuleConfig_RangeTestConfig_init_zero, false, meshtastic_ModuleConfig_TelemetryConfig_init_zero, false, meshtastic_ModuleConfig_CannedMessageConfig_init_zero, 0, false, meshtastic_ModuleConfig_AudioConfig_init_zero, false, meshtastic_ModuleConfig_RemoteHardwareConfig_init_zero, false, meshtastic_ModuleConfig_NeighborInfoConfig_init_zero, false, meshtastic_ModuleConfig_AmbientLightingConfig_init_zero, false, meshtastic_ModuleConfig_DetectionSensorConfig_init_zero}
|
||||||
|
|
||||||
/* Field tags (for use in manual encoding/decoding) */
|
/* Field tags (for use in manual encoding/decoding) */
|
||||||
#define meshtastic_LocalConfig_device_tag 1
|
#define meshtastic_LocalConfig_device_tag 1
|
||||||
@@ -108,6 +114,8 @@ extern "C" {
|
|||||||
#define meshtastic_LocalModuleConfig_audio_tag 9
|
#define meshtastic_LocalModuleConfig_audio_tag 9
|
||||||
#define meshtastic_LocalModuleConfig_remote_hardware_tag 10
|
#define meshtastic_LocalModuleConfig_remote_hardware_tag 10
|
||||||
#define meshtastic_LocalModuleConfig_neighbor_info_tag 11
|
#define meshtastic_LocalModuleConfig_neighbor_info_tag 11
|
||||||
|
#define meshtastic_LocalModuleConfig_ambient_lighting_tag 12
|
||||||
|
#define meshtastic_LocalModuleConfig_detection_sensor_tag 13
|
||||||
|
|
||||||
/* Struct field encoding specification for nanopb */
|
/* Struct field encoding specification for nanopb */
|
||||||
#define meshtastic_LocalConfig_FIELDLIST(X, a) \
|
#define meshtastic_LocalConfig_FIELDLIST(X, a) \
|
||||||
@@ -140,7 +148,9 @@ X(a, STATIC, OPTIONAL, MESSAGE, canned_message, 7) \
|
|||||||
X(a, STATIC, SINGULAR, UINT32, version, 8) \
|
X(a, STATIC, SINGULAR, UINT32, version, 8) \
|
||||||
X(a, STATIC, OPTIONAL, MESSAGE, audio, 9) \
|
X(a, STATIC, OPTIONAL, MESSAGE, audio, 9) \
|
||||||
X(a, STATIC, OPTIONAL, MESSAGE, remote_hardware, 10) \
|
X(a, STATIC, OPTIONAL, MESSAGE, remote_hardware, 10) \
|
||||||
X(a, STATIC, OPTIONAL, MESSAGE, neighbor_info, 11)
|
X(a, STATIC, OPTIONAL, MESSAGE, neighbor_info, 11) \
|
||||||
|
X(a, STATIC, OPTIONAL, MESSAGE, ambient_lighting, 12) \
|
||||||
|
X(a, STATIC, OPTIONAL, MESSAGE, detection_sensor, 13)
|
||||||
#define meshtastic_LocalModuleConfig_CALLBACK NULL
|
#define meshtastic_LocalModuleConfig_CALLBACK NULL
|
||||||
#define meshtastic_LocalModuleConfig_DEFAULT NULL
|
#define meshtastic_LocalModuleConfig_DEFAULT NULL
|
||||||
#define meshtastic_LocalModuleConfig_mqtt_MSGTYPE meshtastic_ModuleConfig_MQTTConfig
|
#define meshtastic_LocalModuleConfig_mqtt_MSGTYPE meshtastic_ModuleConfig_MQTTConfig
|
||||||
@@ -153,6 +163,8 @@ X(a, STATIC, OPTIONAL, MESSAGE, neighbor_info, 11)
|
|||||||
#define meshtastic_LocalModuleConfig_audio_MSGTYPE meshtastic_ModuleConfig_AudioConfig
|
#define meshtastic_LocalModuleConfig_audio_MSGTYPE meshtastic_ModuleConfig_AudioConfig
|
||||||
#define meshtastic_LocalModuleConfig_remote_hardware_MSGTYPE meshtastic_ModuleConfig_RemoteHardwareConfig
|
#define meshtastic_LocalModuleConfig_remote_hardware_MSGTYPE meshtastic_ModuleConfig_RemoteHardwareConfig
|
||||||
#define meshtastic_LocalModuleConfig_neighbor_info_MSGTYPE meshtastic_ModuleConfig_NeighborInfoConfig
|
#define meshtastic_LocalModuleConfig_neighbor_info_MSGTYPE meshtastic_ModuleConfig_NeighborInfoConfig
|
||||||
|
#define meshtastic_LocalModuleConfig_ambient_lighting_MSGTYPE meshtastic_ModuleConfig_AmbientLightingConfig
|
||||||
|
#define meshtastic_LocalModuleConfig_detection_sensor_MSGTYPE meshtastic_ModuleConfig_DetectionSensorConfig
|
||||||
|
|
||||||
extern const pb_msgdesc_t meshtastic_LocalConfig_msg;
|
extern const pb_msgdesc_t meshtastic_LocalConfig_msg;
|
||||||
extern const pb_msgdesc_t meshtastic_LocalModuleConfig_msg;
|
extern const pb_msgdesc_t meshtastic_LocalModuleConfig_msg;
|
||||||
@@ -162,8 +174,8 @@ extern const pb_msgdesc_t meshtastic_LocalModuleConfig_msg;
|
|||||||
#define meshtastic_LocalModuleConfig_fields &meshtastic_LocalModuleConfig_msg
|
#define meshtastic_LocalModuleConfig_fields &meshtastic_LocalModuleConfig_msg
|
||||||
|
|
||||||
/* Maximum encoded size of messages (where known) */
|
/* Maximum encoded size of messages (where known) */
|
||||||
#define meshtastic_LocalConfig_size 461
|
#define meshtastic_LocalConfig_size 463
|
||||||
#define meshtastic_LocalModuleConfig_size 547
|
#define meshtastic_LocalModuleConfig_size 609
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
} /* extern "C" */
|
} /* extern "C" */
|
||||||
|
|||||||
@@ -61,6 +61,8 @@ typedef enum _meshtastic_HardwareModel {
|
|||||||
meshtastic_HardwareModel_NANO_G1_EXPLORER = 17,
|
meshtastic_HardwareModel_NANO_G1_EXPLORER = 17,
|
||||||
/* B&Q Consulting Nano G2 Ultra: https://wiki.uniteng.com/en/meshtastic/nano-g2-ultra */
|
/* B&Q Consulting Nano G2 Ultra: https://wiki.uniteng.com/en/meshtastic/nano-g2-ultra */
|
||||||
meshtastic_HardwareModel_NANO_G2_ULTRA = 18,
|
meshtastic_HardwareModel_NANO_G2_ULTRA = 18,
|
||||||
|
/* LoRAType device: https://loratype.org/ */
|
||||||
|
meshtastic_HardwareModel_LORA_TYPE = 19,
|
||||||
/* B&Q Consulting Station Edition G1: https://uniteng.com/wiki/doku.php?id=meshtastic:station */
|
/* B&Q Consulting Station Edition G1: https://uniteng.com/wiki/doku.php?id=meshtastic:station */
|
||||||
meshtastic_HardwareModel_STATION_G1 = 25,
|
meshtastic_HardwareModel_STATION_G1 = 25,
|
||||||
/* RAK11310 (RP2040 + SX1262) */
|
/* RAK11310 (RP2040 + SX1262) */
|
||||||
@@ -109,6 +111,10 @@ typedef enum _meshtastic_HardwareModel {
|
|||||||
meshtastic_HardwareModel_T_WATCH_S3 = 51,
|
meshtastic_HardwareModel_T_WATCH_S3 = 51,
|
||||||
/* Bobricius Picomputer with ESP32-S3 CPU, Keyboard and IPS display */
|
/* Bobricius Picomputer with ESP32-S3 CPU, Keyboard and IPS display */
|
||||||
meshtastic_HardwareModel_PICOMPUTER_S3 = 52,
|
meshtastic_HardwareModel_PICOMPUTER_S3 = 52,
|
||||||
|
/* Heltec HT-CT62 with ESP32-C3 CPU and SX1262 LoRa */
|
||||||
|
meshtastic_HardwareModel_HELTEC_HT62 = 53,
|
||||||
|
/* EBYTE SPI LoRa module and ESP32-S3 */
|
||||||
|
meshtastic_HardwareModel_EBYTE_ESP32_S3 = 54,
|
||||||
/* ------------------------------------------------------------------------------------------------------------------------------------------
|
/* ------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
Reserved ID For developing private Ports. These will show up in live traffic sparsely, so we can use a high number. Keep it within 8 bits.
|
Reserved ID For developing private Ports. These will show up in live traffic sparsely, so we can use a high number. Keep it within 8 bits.
|
||||||
------------------------------------------------------------------------------------------------------------------------------------------ */
|
------------------------------------------------------------------------------------------------------------------------------------------ */
|
||||||
@@ -151,7 +157,7 @@ typedef enum _meshtastic_CriticalErrorCode {
|
|||||||
/* Radio transmit hardware failure. We sent data to the radio chip, but it didn't
|
/* Radio transmit hardware failure. We sent data to the radio chip, but it didn't
|
||||||
reply with an interrupt. */
|
reply with an interrupt. */
|
||||||
meshtastic_CriticalErrorCode_TRANSMIT_FAILED = 8,
|
meshtastic_CriticalErrorCode_TRANSMIT_FAILED = 8,
|
||||||
/* We detected that the main CPU voltage dropped below the minumum acceptable value */
|
/* We detected that the main CPU voltage dropped below the minimum acceptable value */
|
||||||
meshtastic_CriticalErrorCode_BROWNOUT = 9,
|
meshtastic_CriticalErrorCode_BROWNOUT = 9,
|
||||||
/* Selftest of SX1262 radio chip failed */
|
/* Selftest of SX1262 radio chip failed */
|
||||||
meshtastic_CriticalErrorCode_SX1262_FAILURE = 10,
|
meshtastic_CriticalErrorCode_SX1262_FAILURE = 10,
|
||||||
@@ -295,9 +301,8 @@ typedef struct _meshtastic_Position {
|
|||||||
/* In meters above MSL (but see issue #359) */
|
/* In meters above MSL (but see issue #359) */
|
||||||
int32_t altitude;
|
int32_t altitude;
|
||||||
/* This is usually not sent over the mesh (to save space), but it is sent
|
/* This is usually not sent over the mesh (to save space), but it is sent
|
||||||
from the phone so that the local device can set its RTC If it is sent over
|
from the phone so that the local device can set its time if it is sent over
|
||||||
the mesh (because there are devices on the mesh without GPS), it will only
|
the mesh (because there are devices on the mesh without GPS or RTC).
|
||||||
be sent by devices which has a hardware GPS clock.
|
|
||||||
seconds since 1970 */
|
seconds since 1970 */
|
||||||
uint32_t time;
|
uint32_t time;
|
||||||
/* TODO: REPLACE */
|
/* TODO: REPLACE */
|
||||||
|
|||||||
@@ -18,6 +18,9 @@ PB_BIND(meshtastic_ModuleConfig_RemoteHardwareConfig, meshtastic_ModuleConfig_Re
|
|||||||
PB_BIND(meshtastic_ModuleConfig_NeighborInfoConfig, meshtastic_ModuleConfig_NeighborInfoConfig, AUTO)
|
PB_BIND(meshtastic_ModuleConfig_NeighborInfoConfig, meshtastic_ModuleConfig_NeighborInfoConfig, AUTO)
|
||||||
|
|
||||||
|
|
||||||
|
PB_BIND(meshtastic_ModuleConfig_DetectionSensorConfig, meshtastic_ModuleConfig_DetectionSensorConfig, AUTO)
|
||||||
|
|
||||||
|
|
||||||
PB_BIND(meshtastic_ModuleConfig_AudioConfig, meshtastic_ModuleConfig_AudioConfig, AUTO)
|
PB_BIND(meshtastic_ModuleConfig_AudioConfig, meshtastic_ModuleConfig_AudioConfig, AUTO)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -125,6 +125,33 @@ typedef struct _meshtastic_ModuleConfig_NeighborInfoConfig {
|
|||||||
uint32_t update_interval;
|
uint32_t update_interval;
|
||||||
} meshtastic_ModuleConfig_NeighborInfoConfig;
|
} meshtastic_ModuleConfig_NeighborInfoConfig;
|
||||||
|
|
||||||
|
/* Detection Sensor Module Config */
|
||||||
|
typedef struct _meshtastic_ModuleConfig_DetectionSensorConfig {
|
||||||
|
/* Whether the Module is enabled */
|
||||||
|
bool enabled;
|
||||||
|
/* Interval in seconds of how often we can send a message to the mesh when a state change is detected */
|
||||||
|
uint32_t minimum_broadcast_secs;
|
||||||
|
/* Interval in seconds of how often we should send a message to the mesh with the current state regardless of changes
|
||||||
|
When set to 0, only state changes will be broadcasted
|
||||||
|
Works as a sort of status heartbeat for peace of mind */
|
||||||
|
uint32_t state_broadcast_secs;
|
||||||
|
/* Send ASCII bell with alert message
|
||||||
|
Useful for triggering ext. notification on bell */
|
||||||
|
bool send_bell;
|
||||||
|
/* Friendly name used to format message sent to mesh
|
||||||
|
Example: A name "Motion" would result in a message "Motion detected"
|
||||||
|
Maximum length of 20 characters */
|
||||||
|
char name[20];
|
||||||
|
/* GPIO pin to monitor for state changes */
|
||||||
|
uint8_t monitor_pin;
|
||||||
|
/* Whether or not the GPIO pin state detection is triggered on HIGH (1)
|
||||||
|
Otherwise LOW (0) */
|
||||||
|
bool detection_triggered_high;
|
||||||
|
/* Whether or not use INPUT_PULLUP mode for GPIO pin
|
||||||
|
Only applicable if the board uses pull-up resistors on the pin */
|
||||||
|
bool use_pullup;
|
||||||
|
} meshtastic_ModuleConfig_DetectionSensorConfig;
|
||||||
|
|
||||||
/* Audio Config for codec2 voice */
|
/* Audio Config for codec2 voice */
|
||||||
typedef struct _meshtastic_ModuleConfig_AudioConfig {
|
typedef struct _meshtastic_ModuleConfig_AudioConfig {
|
||||||
/* Whether Audio is enabled */
|
/* Whether Audio is enabled */
|
||||||
@@ -286,13 +313,14 @@ Initially created for the RAK14001 RGB LED module. */
|
|||||||
typedef struct _meshtastic_ModuleConfig_AmbientLightingConfig {
|
typedef struct _meshtastic_ModuleConfig_AmbientLightingConfig {
|
||||||
/* Sets LED to on or off. */
|
/* Sets LED to on or off. */
|
||||||
bool led_state;
|
bool led_state;
|
||||||
/* Sets the overall current for the LED, firmware side range for the RAK14001 is 1-31, but users should be given a range of 0-100% */
|
/* Sets the current for the LED output. Default is 10. */
|
||||||
uint8_t current;
|
uint8_t current;
|
||||||
uint8_t red; /* Red level */
|
/* Sets the red LED level. Values are 0-255. */
|
||||||
/* Sets the green level of the LED, firmware side values are 0-255, but users should be given a range of 0-100% */
|
uint8_t red;
|
||||||
uint8_t green; /* Green level */
|
/* Sets the green LED level. Values are 0-255. */
|
||||||
/* Sets the blue level of the LED, firmware side values are 0-255, but users should be given a range of 0-100% */
|
uint8_t green;
|
||||||
uint8_t blue; /* Blue level */
|
/* Sets the blue LED level. Values are 0-255. */
|
||||||
|
uint8_t blue;
|
||||||
} meshtastic_ModuleConfig_AmbientLightingConfig;
|
} meshtastic_ModuleConfig_AmbientLightingConfig;
|
||||||
|
|
||||||
/* A GPIO pin definition for remote hardware module */
|
/* A GPIO pin definition for remote hardware module */
|
||||||
@@ -342,6 +370,8 @@ typedef struct _meshtastic_ModuleConfig {
|
|||||||
meshtastic_ModuleConfig_NeighborInfoConfig neighbor_info;
|
meshtastic_ModuleConfig_NeighborInfoConfig neighbor_info;
|
||||||
/* TODO: REPLACE */
|
/* TODO: REPLACE */
|
||||||
meshtastic_ModuleConfig_AmbientLightingConfig ambient_lighting;
|
meshtastic_ModuleConfig_AmbientLightingConfig ambient_lighting;
|
||||||
|
/* TODO: REPLACE */
|
||||||
|
meshtastic_ModuleConfig_DetectionSensorConfig detection_sensor;
|
||||||
} payload_variant;
|
} payload_variant;
|
||||||
} meshtastic_ModuleConfig;
|
} meshtastic_ModuleConfig;
|
||||||
|
|
||||||
@@ -375,6 +405,7 @@ extern "C" {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#define meshtastic_ModuleConfig_AudioConfig_bitrate_ENUMTYPE meshtastic_ModuleConfig_AudioConfig_Audio_Baud
|
#define meshtastic_ModuleConfig_AudioConfig_bitrate_ENUMTYPE meshtastic_ModuleConfig_AudioConfig_Audio_Baud
|
||||||
|
|
||||||
#define meshtastic_ModuleConfig_SerialConfig_baud_ENUMTYPE meshtastic_ModuleConfig_SerialConfig_Serial_Baud
|
#define meshtastic_ModuleConfig_SerialConfig_baud_ENUMTYPE meshtastic_ModuleConfig_SerialConfig_Serial_Baud
|
||||||
@@ -397,6 +428,7 @@ extern "C" {
|
|||||||
#define meshtastic_ModuleConfig_MQTTConfig_init_default {0, "", "", "", 0, 0, 0, "", 0}
|
#define meshtastic_ModuleConfig_MQTTConfig_init_default {0, "", "", "", 0, 0, 0, "", 0}
|
||||||
#define meshtastic_ModuleConfig_RemoteHardwareConfig_init_default {0, 0, 0, {meshtastic_RemoteHardwarePin_init_default, meshtastic_RemoteHardwarePin_init_default, meshtastic_RemoteHardwarePin_init_default, meshtastic_RemoteHardwarePin_init_default}}
|
#define meshtastic_ModuleConfig_RemoteHardwareConfig_init_default {0, 0, 0, {meshtastic_RemoteHardwarePin_init_default, meshtastic_RemoteHardwarePin_init_default, meshtastic_RemoteHardwarePin_init_default, meshtastic_RemoteHardwarePin_init_default}}
|
||||||
#define meshtastic_ModuleConfig_NeighborInfoConfig_init_default {0, 0}
|
#define meshtastic_ModuleConfig_NeighborInfoConfig_init_default {0, 0}
|
||||||
|
#define meshtastic_ModuleConfig_DetectionSensorConfig_init_default {0, 0, 0, 0, "", 0, 0, 0}
|
||||||
#define meshtastic_ModuleConfig_AudioConfig_init_default {0, 0, _meshtastic_ModuleConfig_AudioConfig_Audio_Baud_MIN, 0, 0, 0, 0}
|
#define meshtastic_ModuleConfig_AudioConfig_init_default {0, 0, _meshtastic_ModuleConfig_AudioConfig_Audio_Baud_MIN, 0, 0, 0, 0}
|
||||||
#define meshtastic_ModuleConfig_SerialConfig_init_default {0, 0, 0, 0, _meshtastic_ModuleConfig_SerialConfig_Serial_Baud_MIN, 0, _meshtastic_ModuleConfig_SerialConfig_Serial_Mode_MIN, 0}
|
#define meshtastic_ModuleConfig_SerialConfig_init_default {0, 0, 0, 0, _meshtastic_ModuleConfig_SerialConfig_Serial_Baud_MIN, 0, _meshtastic_ModuleConfig_SerialConfig_Serial_Mode_MIN, 0}
|
||||||
#define meshtastic_ModuleConfig_ExternalNotificationConfig_init_default {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
|
#define meshtastic_ModuleConfig_ExternalNotificationConfig_init_default {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
|
||||||
@@ -410,6 +442,7 @@ extern "C" {
|
|||||||
#define meshtastic_ModuleConfig_MQTTConfig_init_zero {0, "", "", "", 0, 0, 0, "", 0}
|
#define meshtastic_ModuleConfig_MQTTConfig_init_zero {0, "", "", "", 0, 0, 0, "", 0}
|
||||||
#define meshtastic_ModuleConfig_RemoteHardwareConfig_init_zero {0, 0, 0, {meshtastic_RemoteHardwarePin_init_zero, meshtastic_RemoteHardwarePin_init_zero, meshtastic_RemoteHardwarePin_init_zero, meshtastic_RemoteHardwarePin_init_zero}}
|
#define meshtastic_ModuleConfig_RemoteHardwareConfig_init_zero {0, 0, 0, {meshtastic_RemoteHardwarePin_init_zero, meshtastic_RemoteHardwarePin_init_zero, meshtastic_RemoteHardwarePin_init_zero, meshtastic_RemoteHardwarePin_init_zero}}
|
||||||
#define meshtastic_ModuleConfig_NeighborInfoConfig_init_zero {0, 0}
|
#define meshtastic_ModuleConfig_NeighborInfoConfig_init_zero {0, 0}
|
||||||
|
#define meshtastic_ModuleConfig_DetectionSensorConfig_init_zero {0, 0, 0, 0, "", 0, 0, 0}
|
||||||
#define meshtastic_ModuleConfig_AudioConfig_init_zero {0, 0, _meshtastic_ModuleConfig_AudioConfig_Audio_Baud_MIN, 0, 0, 0, 0}
|
#define meshtastic_ModuleConfig_AudioConfig_init_zero {0, 0, _meshtastic_ModuleConfig_AudioConfig_Audio_Baud_MIN, 0, 0, 0, 0}
|
||||||
#define meshtastic_ModuleConfig_SerialConfig_init_zero {0, 0, 0, 0, _meshtastic_ModuleConfig_SerialConfig_Serial_Baud_MIN, 0, _meshtastic_ModuleConfig_SerialConfig_Serial_Mode_MIN, 0}
|
#define meshtastic_ModuleConfig_SerialConfig_init_zero {0, 0, 0, 0, _meshtastic_ModuleConfig_SerialConfig_Serial_Baud_MIN, 0, _meshtastic_ModuleConfig_SerialConfig_Serial_Mode_MIN, 0}
|
||||||
#define meshtastic_ModuleConfig_ExternalNotificationConfig_init_zero {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
|
#define meshtastic_ModuleConfig_ExternalNotificationConfig_init_zero {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
|
||||||
@@ -432,6 +465,14 @@ extern "C" {
|
|||||||
#define meshtastic_ModuleConfig_MQTTConfig_proxy_to_client_enabled_tag 9
|
#define meshtastic_ModuleConfig_MQTTConfig_proxy_to_client_enabled_tag 9
|
||||||
#define meshtastic_ModuleConfig_NeighborInfoConfig_enabled_tag 1
|
#define meshtastic_ModuleConfig_NeighborInfoConfig_enabled_tag 1
|
||||||
#define meshtastic_ModuleConfig_NeighborInfoConfig_update_interval_tag 2
|
#define meshtastic_ModuleConfig_NeighborInfoConfig_update_interval_tag 2
|
||||||
|
#define meshtastic_ModuleConfig_DetectionSensorConfig_enabled_tag 1
|
||||||
|
#define meshtastic_ModuleConfig_DetectionSensorConfig_minimum_broadcast_secs_tag 2
|
||||||
|
#define meshtastic_ModuleConfig_DetectionSensorConfig_state_broadcast_secs_tag 3
|
||||||
|
#define meshtastic_ModuleConfig_DetectionSensorConfig_send_bell_tag 4
|
||||||
|
#define meshtastic_ModuleConfig_DetectionSensorConfig_name_tag 5
|
||||||
|
#define meshtastic_ModuleConfig_DetectionSensorConfig_monitor_pin_tag 6
|
||||||
|
#define meshtastic_ModuleConfig_DetectionSensorConfig_detection_triggered_high_tag 7
|
||||||
|
#define meshtastic_ModuleConfig_DetectionSensorConfig_use_pullup_tag 8
|
||||||
#define meshtastic_ModuleConfig_AudioConfig_codec2_enabled_tag 1
|
#define meshtastic_ModuleConfig_AudioConfig_codec2_enabled_tag 1
|
||||||
#define meshtastic_ModuleConfig_AudioConfig_ptt_pin_tag 2
|
#define meshtastic_ModuleConfig_AudioConfig_ptt_pin_tag 2
|
||||||
#define meshtastic_ModuleConfig_AudioConfig_bitrate_tag 3
|
#define meshtastic_ModuleConfig_AudioConfig_bitrate_tag 3
|
||||||
@@ -509,6 +550,7 @@ extern "C" {
|
|||||||
#define meshtastic_ModuleConfig_remote_hardware_tag 9
|
#define meshtastic_ModuleConfig_remote_hardware_tag 9
|
||||||
#define meshtastic_ModuleConfig_neighbor_info_tag 10
|
#define meshtastic_ModuleConfig_neighbor_info_tag 10
|
||||||
#define meshtastic_ModuleConfig_ambient_lighting_tag 11
|
#define meshtastic_ModuleConfig_ambient_lighting_tag 11
|
||||||
|
#define meshtastic_ModuleConfig_detection_sensor_tag 12
|
||||||
|
|
||||||
/* Struct field encoding specification for nanopb */
|
/* Struct field encoding specification for nanopb */
|
||||||
#define meshtastic_ModuleConfig_FIELDLIST(X, a) \
|
#define meshtastic_ModuleConfig_FIELDLIST(X, a) \
|
||||||
@@ -522,7 +564,8 @@ X(a, STATIC, ONEOF, MESSAGE, (payload_variant,canned_message,payload_varia
|
|||||||
X(a, STATIC, ONEOF, MESSAGE, (payload_variant,audio,payload_variant.audio), 8) \
|
X(a, STATIC, ONEOF, MESSAGE, (payload_variant,audio,payload_variant.audio), 8) \
|
||||||
X(a, STATIC, ONEOF, MESSAGE, (payload_variant,remote_hardware,payload_variant.remote_hardware), 9) \
|
X(a, STATIC, ONEOF, MESSAGE, (payload_variant,remote_hardware,payload_variant.remote_hardware), 9) \
|
||||||
X(a, STATIC, ONEOF, MESSAGE, (payload_variant,neighbor_info,payload_variant.neighbor_info), 10) \
|
X(a, STATIC, ONEOF, MESSAGE, (payload_variant,neighbor_info,payload_variant.neighbor_info), 10) \
|
||||||
X(a, STATIC, ONEOF, MESSAGE, (payload_variant,ambient_lighting,payload_variant.ambient_lighting), 11)
|
X(a, STATIC, ONEOF, MESSAGE, (payload_variant,ambient_lighting,payload_variant.ambient_lighting), 11) \
|
||||||
|
X(a, STATIC, ONEOF, MESSAGE, (payload_variant,detection_sensor,payload_variant.detection_sensor), 12)
|
||||||
#define meshtastic_ModuleConfig_CALLBACK NULL
|
#define meshtastic_ModuleConfig_CALLBACK NULL
|
||||||
#define meshtastic_ModuleConfig_DEFAULT NULL
|
#define meshtastic_ModuleConfig_DEFAULT NULL
|
||||||
#define meshtastic_ModuleConfig_payload_variant_mqtt_MSGTYPE meshtastic_ModuleConfig_MQTTConfig
|
#define meshtastic_ModuleConfig_payload_variant_mqtt_MSGTYPE meshtastic_ModuleConfig_MQTTConfig
|
||||||
@@ -536,6 +579,7 @@ X(a, STATIC, ONEOF, MESSAGE, (payload_variant,ambient_lighting,payload_var
|
|||||||
#define meshtastic_ModuleConfig_payload_variant_remote_hardware_MSGTYPE meshtastic_ModuleConfig_RemoteHardwareConfig
|
#define meshtastic_ModuleConfig_payload_variant_remote_hardware_MSGTYPE meshtastic_ModuleConfig_RemoteHardwareConfig
|
||||||
#define meshtastic_ModuleConfig_payload_variant_neighbor_info_MSGTYPE meshtastic_ModuleConfig_NeighborInfoConfig
|
#define meshtastic_ModuleConfig_payload_variant_neighbor_info_MSGTYPE meshtastic_ModuleConfig_NeighborInfoConfig
|
||||||
#define meshtastic_ModuleConfig_payload_variant_ambient_lighting_MSGTYPE meshtastic_ModuleConfig_AmbientLightingConfig
|
#define meshtastic_ModuleConfig_payload_variant_ambient_lighting_MSGTYPE meshtastic_ModuleConfig_AmbientLightingConfig
|
||||||
|
#define meshtastic_ModuleConfig_payload_variant_detection_sensor_MSGTYPE meshtastic_ModuleConfig_DetectionSensorConfig
|
||||||
|
|
||||||
#define meshtastic_ModuleConfig_MQTTConfig_FIELDLIST(X, a) \
|
#define meshtastic_ModuleConfig_MQTTConfig_FIELDLIST(X, a) \
|
||||||
X(a, STATIC, SINGULAR, BOOL, enabled, 1) \
|
X(a, STATIC, SINGULAR, BOOL, enabled, 1) \
|
||||||
@@ -564,6 +608,18 @@ X(a, STATIC, SINGULAR, UINT32, update_interval, 2)
|
|||||||
#define meshtastic_ModuleConfig_NeighborInfoConfig_CALLBACK NULL
|
#define meshtastic_ModuleConfig_NeighborInfoConfig_CALLBACK NULL
|
||||||
#define meshtastic_ModuleConfig_NeighborInfoConfig_DEFAULT NULL
|
#define meshtastic_ModuleConfig_NeighborInfoConfig_DEFAULT NULL
|
||||||
|
|
||||||
|
#define meshtastic_ModuleConfig_DetectionSensorConfig_FIELDLIST(X, a) \
|
||||||
|
X(a, STATIC, SINGULAR, BOOL, enabled, 1) \
|
||||||
|
X(a, STATIC, SINGULAR, UINT32, minimum_broadcast_secs, 2) \
|
||||||
|
X(a, STATIC, SINGULAR, UINT32, state_broadcast_secs, 3) \
|
||||||
|
X(a, STATIC, SINGULAR, BOOL, send_bell, 4) \
|
||||||
|
X(a, STATIC, SINGULAR, STRING, name, 5) \
|
||||||
|
X(a, STATIC, SINGULAR, UINT32, monitor_pin, 6) \
|
||||||
|
X(a, STATIC, SINGULAR, BOOL, detection_triggered_high, 7) \
|
||||||
|
X(a, STATIC, SINGULAR, BOOL, use_pullup, 8)
|
||||||
|
#define meshtastic_ModuleConfig_DetectionSensorConfig_CALLBACK NULL
|
||||||
|
#define meshtastic_ModuleConfig_DetectionSensorConfig_DEFAULT NULL
|
||||||
|
|
||||||
#define meshtastic_ModuleConfig_AudioConfig_FIELDLIST(X, a) \
|
#define meshtastic_ModuleConfig_AudioConfig_FIELDLIST(X, a) \
|
||||||
X(a, STATIC, SINGULAR, BOOL, codec2_enabled, 1) \
|
X(a, STATIC, SINGULAR, BOOL, codec2_enabled, 1) \
|
||||||
X(a, STATIC, SINGULAR, UINT32, ptt_pin, 2) \
|
X(a, STATIC, SINGULAR, UINT32, ptt_pin, 2) \
|
||||||
@@ -667,6 +723,7 @@ extern const pb_msgdesc_t meshtastic_ModuleConfig_msg;
|
|||||||
extern const pb_msgdesc_t meshtastic_ModuleConfig_MQTTConfig_msg;
|
extern const pb_msgdesc_t meshtastic_ModuleConfig_MQTTConfig_msg;
|
||||||
extern const pb_msgdesc_t meshtastic_ModuleConfig_RemoteHardwareConfig_msg;
|
extern const pb_msgdesc_t meshtastic_ModuleConfig_RemoteHardwareConfig_msg;
|
||||||
extern const pb_msgdesc_t meshtastic_ModuleConfig_NeighborInfoConfig_msg;
|
extern const pb_msgdesc_t meshtastic_ModuleConfig_NeighborInfoConfig_msg;
|
||||||
|
extern const pb_msgdesc_t meshtastic_ModuleConfig_DetectionSensorConfig_msg;
|
||||||
extern const pb_msgdesc_t meshtastic_ModuleConfig_AudioConfig_msg;
|
extern const pb_msgdesc_t meshtastic_ModuleConfig_AudioConfig_msg;
|
||||||
extern const pb_msgdesc_t meshtastic_ModuleConfig_SerialConfig_msg;
|
extern const pb_msgdesc_t meshtastic_ModuleConfig_SerialConfig_msg;
|
||||||
extern const pb_msgdesc_t meshtastic_ModuleConfig_ExternalNotificationConfig_msg;
|
extern const pb_msgdesc_t meshtastic_ModuleConfig_ExternalNotificationConfig_msg;
|
||||||
@@ -682,6 +739,7 @@ extern const pb_msgdesc_t meshtastic_RemoteHardwarePin_msg;
|
|||||||
#define meshtastic_ModuleConfig_MQTTConfig_fields &meshtastic_ModuleConfig_MQTTConfig_msg
|
#define meshtastic_ModuleConfig_MQTTConfig_fields &meshtastic_ModuleConfig_MQTTConfig_msg
|
||||||
#define meshtastic_ModuleConfig_RemoteHardwareConfig_fields &meshtastic_ModuleConfig_RemoteHardwareConfig_msg
|
#define meshtastic_ModuleConfig_RemoteHardwareConfig_fields &meshtastic_ModuleConfig_RemoteHardwareConfig_msg
|
||||||
#define meshtastic_ModuleConfig_NeighborInfoConfig_fields &meshtastic_ModuleConfig_NeighborInfoConfig_msg
|
#define meshtastic_ModuleConfig_NeighborInfoConfig_fields &meshtastic_ModuleConfig_NeighborInfoConfig_msg
|
||||||
|
#define meshtastic_ModuleConfig_DetectionSensorConfig_fields &meshtastic_ModuleConfig_DetectionSensorConfig_msg
|
||||||
#define meshtastic_ModuleConfig_AudioConfig_fields &meshtastic_ModuleConfig_AudioConfig_msg
|
#define meshtastic_ModuleConfig_AudioConfig_fields &meshtastic_ModuleConfig_AudioConfig_msg
|
||||||
#define meshtastic_ModuleConfig_SerialConfig_fields &meshtastic_ModuleConfig_SerialConfig_msg
|
#define meshtastic_ModuleConfig_SerialConfig_fields &meshtastic_ModuleConfig_SerialConfig_msg
|
||||||
#define meshtastic_ModuleConfig_ExternalNotificationConfig_fields &meshtastic_ModuleConfig_ExternalNotificationConfig_msg
|
#define meshtastic_ModuleConfig_ExternalNotificationConfig_fields &meshtastic_ModuleConfig_ExternalNotificationConfig_msg
|
||||||
@@ -696,6 +754,7 @@ extern const pb_msgdesc_t meshtastic_RemoteHardwarePin_msg;
|
|||||||
#define meshtastic_ModuleConfig_AmbientLightingConfig_size 14
|
#define meshtastic_ModuleConfig_AmbientLightingConfig_size 14
|
||||||
#define meshtastic_ModuleConfig_AudioConfig_size 19
|
#define meshtastic_ModuleConfig_AudioConfig_size 19
|
||||||
#define meshtastic_ModuleConfig_CannedMessageConfig_size 49
|
#define meshtastic_ModuleConfig_CannedMessageConfig_size 49
|
||||||
|
#define meshtastic_ModuleConfig_DetectionSensorConfig_size 44
|
||||||
#define meshtastic_ModuleConfig_ExternalNotificationConfig_size 40
|
#define meshtastic_ModuleConfig_ExternalNotificationConfig_size 40
|
||||||
#define meshtastic_ModuleConfig_MQTTConfig_size 222
|
#define meshtastic_ModuleConfig_MQTTConfig_size 222
|
||||||
#define meshtastic_ModuleConfig_NeighborInfoConfig_size 8
|
#define meshtastic_ModuleConfig_NeighborInfoConfig_size 8
|
||||||
|
|||||||
@@ -69,6 +69,9 @@ typedef enum _meshtastic_PortNum {
|
|||||||
NOTE: audio frames contain a 3 byte header (0xc0 0xde 0xc2) and a one byte marker for the decompressed bitrate.
|
NOTE: audio frames contain a 3 byte header (0xc0 0xde 0xc2) and a one byte marker for the decompressed bitrate.
|
||||||
This marker comes from the 'moduleConfig.audio.bitrate' enum minus one. */
|
This marker comes from the 'moduleConfig.audio.bitrate' enum minus one. */
|
||||||
meshtastic_PortNum_AUDIO_APP = 9,
|
meshtastic_PortNum_AUDIO_APP = 9,
|
||||||
|
/* Same as Text Message but originating from Detection Sensor Module.
|
||||||
|
NOTE: This portnum traffic is not sent to the public MQTT starting at firmware version 2.2.9 */
|
||||||
|
meshtastic_PortNum_DETECTION_SENSOR_APP = 10,
|
||||||
/* Provides a 'ping' service that replies to any packet it receives.
|
/* Provides a 'ping' service that replies to any packet it receives.
|
||||||
Also serves as a small example module.
|
Also serves as a small example module.
|
||||||
ENCODING: ASCII Plaintext */
|
ENCODING: ASCII Plaintext */
|
||||||
@@ -88,7 +91,8 @@ typedef enum _meshtastic_PortNum {
|
|||||||
ENCODING: Protobuf */
|
ENCODING: Protobuf */
|
||||||
meshtastic_PortNum_STORE_FORWARD_APP = 65,
|
meshtastic_PortNum_STORE_FORWARD_APP = 65,
|
||||||
/* Optional port for messages for the range test module.
|
/* Optional port for messages for the range test module.
|
||||||
ENCODING: ASCII Plaintext */
|
ENCODING: ASCII Plaintext
|
||||||
|
NOTE: This portnum traffic is not sent to the public MQTT starting at firmware version 2.2.9 */
|
||||||
meshtastic_PortNum_RANGE_TEST_APP = 66,
|
meshtastic_PortNum_RANGE_TEST_APP = 66,
|
||||||
/* Provides a format to send and receive telemetry data from the Meshtastic network.
|
/* Provides a format to send and receive telemetry data from the Meshtastic network.
|
||||||
Maintained by Charles Crossan (crossan007) : crossan007@gmail.com
|
Maintained by Charles Crossan (crossan007) : crossan007@gmail.com
|
||||||
|
|||||||
@@ -101,11 +101,7 @@ typedef struct _meshtastic_AirQualityMetrics {
|
|||||||
|
|
||||||
/* Types of Measurements the telemetry module is equipped to handle */
|
/* Types of Measurements the telemetry module is equipped to handle */
|
||||||
typedef struct _meshtastic_Telemetry {
|
typedef struct _meshtastic_Telemetry {
|
||||||
/* This is usually not sent over the mesh (to save space), but it is sent
|
/* Seconds since 1970 - or 0 for unknown/unset */
|
||||||
from the phone so that the local device can set its RTC If it is sent over
|
|
||||||
the mesh (because there are devices on the mesh without GPS), it will only
|
|
||||||
be sent by devices which has a hardware GPS clock (IE Mobile Phone).
|
|
||||||
seconds since 1970 */
|
|
||||||
uint32_t time;
|
uint32_t time;
|
||||||
pb_size_t which_variant;
|
pb_size_t which_variant;
|
||||||
union {
|
union {
|
||||||
|
|||||||
@@ -402,7 +402,6 @@ void handleStatic(HTTPRequest *req, HTTPResponse *res)
|
|||||||
"href=/admin>admin</a>");
|
"href=/admin>admin</a>");
|
||||||
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
res->setHeader("Content-Encoding", "gzip");
|
res->setHeader("Content-Encoding", "gzip");
|
||||||
}
|
}
|
||||||
@@ -438,7 +437,6 @@ void handleStatic(HTTPRequest *req, HTTPResponse *res)
|
|||||||
file.close();
|
file.close();
|
||||||
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
LOG_ERROR("This should not have happened...\n");
|
LOG_ERROR("This should not have happened...\n");
|
||||||
res->println("ERROR: This should not have happened...");
|
res->println("ERROR: This should not have happened...");
|
||||||
@@ -467,7 +465,7 @@ void handleFormUpload(HTTPRequest *req, HTTPResponse *res)
|
|||||||
// first semicolon, if one exists:
|
// first semicolon, if one exists:
|
||||||
size_t semicolonPos = contentType.find(";");
|
size_t semicolonPos = contentType.find(";");
|
||||||
if (semicolonPos != std::string::npos) {
|
if (semicolonPos != std::string::npos) {
|
||||||
contentType = contentType.substr(0, semicolonPos);
|
contentType.resize(semicolonPos);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Now, we can decide based on the content type:
|
// Now, we can decide based on the content type:
|
||||||
@@ -581,7 +579,6 @@ void handleReport(HTTPRequest *req, HTTPResponse *res)
|
|||||||
res->setHeader("Content-Type", "application/json");
|
res->setHeader("Content-Type", "application/json");
|
||||||
res->setHeader("Access-Control-Allow-Origin", "*");
|
res->setHeader("Access-Control-Allow-Origin", "*");
|
||||||
res->setHeader("Access-Control-Allow-Methods", "GET");
|
res->setHeader("Access-Control-Allow-Methods", "GET");
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
res->setHeader("Content-Type", "text/html");
|
res->setHeader("Content-Type", "text/html");
|
||||||
res->println("<pre>");
|
res->println("<pre>");
|
||||||
@@ -857,4 +854,4 @@ void handleScanNetworks(HTTPRequest *req, HTTPResponse *res)
|
|||||||
JSONValue *value = new JSONValue(jsonObjOuter);
|
JSONValue *value = new JSONValue(jsonObjOuter);
|
||||||
res->print(value->Stringify().c_str());
|
res->print(value->Stringify().c_str());
|
||||||
delete value;
|
delete value;
|
||||||
}
|
}
|
||||||
@@ -25,7 +25,7 @@ bool pb_decode_from_bytes(const uint8_t *srcbuf, size_t srcbufsize, const pb_msg
|
|||||||
{
|
{
|
||||||
pb_istream_t stream = pb_istream_from_buffer(srcbuf, srcbufsize);
|
pb_istream_t stream = pb_istream_from_buffer(srcbuf, srcbufsize);
|
||||||
if (!pb_decode(&stream, fields, dest_struct)) {
|
if (!pb_decode(&stream, fields, dest_struct)) {
|
||||||
LOG_ERROR("Can't decode protobuf reason='%s', pb_msgdesc 0x%p\n", PB_GET_ERROR(&stream), fields);
|
LOG_ERROR("Can't decode protobuf reason='%s', pb_msgdesc %p\n", PB_GET_ERROR(&stream), fields);
|
||||||
return false;
|
return false;
|
||||||
} else {
|
} else {
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
58
src/meshUtils.cpp
Normal file
58
src/meshUtils.cpp
Normal file
@@ -0,0 +1,58 @@
|
|||||||
|
#include "meshUtils.h"
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Find the first occurrence of find in s, where the search is limited to the
|
||||||
|
* first slen characters of s.
|
||||||
|
* -
|
||||||
|
* Copyright (c) 2001 Mike Barcroft <mike@FreeBSD.org>
|
||||||
|
* Copyright (c) 1990, 1993
|
||||||
|
* The Regents of the University of California. All rights reserved.
|
||||||
|
*
|
||||||
|
* This code is derived from software contributed to Berkeley by
|
||||||
|
* Chris Torek.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. Neither the name of the University nor the names of its contributors
|
||||||
|
* may be used to endorse or promote products derived from this software
|
||||||
|
* without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
char *strnstr(const char *s, const char *find, size_t slen)
|
||||||
|
{
|
||||||
|
char c, sc;
|
||||||
|
size_t len;
|
||||||
|
|
||||||
|
if ((c = *find++) != '\0') {
|
||||||
|
len = strlen(find);
|
||||||
|
do {
|
||||||
|
do {
|
||||||
|
if (slen-- < 1 || (sc = *s++) == '\0')
|
||||||
|
return (NULL);
|
||||||
|
} while (sc != c);
|
||||||
|
if (len > slen)
|
||||||
|
return (NULL);
|
||||||
|
} while (strncmp(s, find, len) != 0);
|
||||||
|
s--;
|
||||||
|
}
|
||||||
|
return ((char *)s);
|
||||||
|
}
|
||||||
@@ -4,4 +4,9 @@
|
|||||||
template <class T> constexpr const T &clamp(const T &v, const T &lo, const T &hi)
|
template <class T> constexpr const T &clamp(const T &v, const T &lo, const T &hi)
|
||||||
{
|
{
|
||||||
return (v < lo) ? lo : (hi < v) ? hi : v;
|
return (v < lo) ? lo : (hi < v) ? hi : v;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if (defined(ARCH_PORTDUINO) && !defined(STRNSTR))
|
||||||
|
#define STRNSTR
|
||||||
|
char *strnstr(const char *s, const char *find, size_t slen);
|
||||||
|
#endif
|
||||||
@@ -373,6 +373,11 @@ void AdminModule::handleSetModuleConfig(const meshtastic_ModuleConfig &c)
|
|||||||
moduleConfig.has_neighbor_info = true;
|
moduleConfig.has_neighbor_info = true;
|
||||||
moduleConfig.neighbor_info = c.payload_variant.neighbor_info;
|
moduleConfig.neighbor_info = c.payload_variant.neighbor_info;
|
||||||
break;
|
break;
|
||||||
|
case meshtastic_ModuleConfig_detection_sensor_tag:
|
||||||
|
LOG_INFO("Setting module config: Detection Sensor\n");
|
||||||
|
moduleConfig.has_detection_sensor = true;
|
||||||
|
moduleConfig.detection_sensor = c.payload_variant.detection_sensor;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
saveChanges(SEGMENT_MODULECONFIG);
|
saveChanges(SEGMENT_MODULECONFIG);
|
||||||
@@ -513,6 +518,11 @@ void AdminModule::handleGetModuleConfig(const meshtastic_MeshPacket &req, const
|
|||||||
res.get_module_config_response.which_payload_variant = meshtastic_ModuleConfig_neighbor_info_tag;
|
res.get_module_config_response.which_payload_variant = meshtastic_ModuleConfig_neighbor_info_tag;
|
||||||
res.get_module_config_response.payload_variant.neighbor_info = moduleConfig.neighbor_info;
|
res.get_module_config_response.payload_variant.neighbor_info = moduleConfig.neighbor_info;
|
||||||
break;
|
break;
|
||||||
|
case meshtastic_AdminMessage_ModuleConfigType_DETECTIONSENSOR_CONFIG:
|
||||||
|
LOG_INFO("Getting module config: Detection Sensor\n");
|
||||||
|
res.get_module_config_response.which_payload_variant = meshtastic_ModuleConfig_detection_sensor_tag;
|
||||||
|
res.get_module_config_response.payload_variant.detection_sensor = moduleConfig.detection_sensor;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// NOTE: The phone app needs to know the ls_secsvalue so it can properly expect sleep behavior.
|
// NOTE: The phone app needs to know the ls_secsvalue so it can properly expect sleep behavior.
|
||||||
|
|||||||
@@ -63,10 +63,10 @@ CannedMessageModule *cannedMessageModule;
|
|||||||
CannedMessageModule::CannedMessageModule()
|
CannedMessageModule::CannedMessageModule()
|
||||||
: SinglePortModule("canned", meshtastic_PortNum_TEXT_MESSAGE_APP), concurrency::OSThread("CannedMessageModule")
|
: SinglePortModule("canned", meshtastic_PortNum_TEXT_MESSAGE_APP), concurrency::OSThread("CannedMessageModule")
|
||||||
{
|
{
|
||||||
if (moduleConfig.canned_message.enabled) {
|
if (moduleConfig.canned_message.enabled || CANNED_MESSAGE_MODULE_ENABLE) {
|
||||||
this->loadProtoForModule();
|
this->loadProtoForModule();
|
||||||
if ((this->splitConfiguredMessages() <= 0) && (cardkb_found.address != CARDKB_ADDR) &&
|
if ((this->splitConfiguredMessages() <= 0) && (cardkb_found.address == 0x00) && !INPUTBROKER_MATRIX_TYPE &&
|
||||||
(cardkb_found.address != TDECK_KB_ADDR) && !INPUTBROKER_MATRIX_TYPE) {
|
!CANNED_MESSAGE_MODULE_ENABLE) {
|
||||||
LOG_INFO("CannedMessageModule: No messages are configured. Module is disabled\n");
|
LOG_INFO("CannedMessageModule: No messages are configured. Module is disabled\n");
|
||||||
this->runState = CANNED_MESSAGE_RUN_STATE_DISABLED;
|
this->runState = CANNED_MESSAGE_RUN_STATE_DISABLED;
|
||||||
disable();
|
disable();
|
||||||
@@ -141,12 +141,12 @@ int CannedMessageModule::handleInputEvent(const InputEvent *event)
|
|||||||
|
|
||||||
bool validEvent = false;
|
bool validEvent = false;
|
||||||
if (event->inputEvent == static_cast<char>(meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_UP)) {
|
if (event->inputEvent == static_cast<char>(meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_UP)) {
|
||||||
LOG_DEBUG("Canned message event UP\n");
|
// LOG_DEBUG("Canned message event UP\n");
|
||||||
this->runState = CANNED_MESSAGE_RUN_STATE_ACTION_UP;
|
this->runState = CANNED_MESSAGE_RUN_STATE_ACTION_UP;
|
||||||
validEvent = true;
|
validEvent = true;
|
||||||
}
|
}
|
||||||
if (event->inputEvent == static_cast<char>(meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_DOWN)) {
|
if (event->inputEvent == static_cast<char>(meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_DOWN)) {
|
||||||
LOG_DEBUG("Canned message event DOWN\n");
|
// LOG_DEBUG("Canned message event DOWN\n");
|
||||||
this->runState = CANNED_MESSAGE_RUN_STATE_ACTION_DOWN;
|
this->runState = CANNED_MESSAGE_RUN_STATE_ACTION_DOWN;
|
||||||
validEvent = true;
|
validEvent = true;
|
||||||
}
|
}
|
||||||
@@ -170,7 +170,7 @@ int CannedMessageModule::handleInputEvent(const InputEvent *event)
|
|||||||
if ((event->inputEvent == static_cast<char>(meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_BACK)) ||
|
if ((event->inputEvent == static_cast<char>(meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_BACK)) ||
|
||||||
(event->inputEvent == static_cast<char>(meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_LEFT)) ||
|
(event->inputEvent == static_cast<char>(meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_LEFT)) ||
|
||||||
(event->inputEvent == static_cast<char>(meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_RIGHT))) {
|
(event->inputEvent == static_cast<char>(meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_RIGHT))) {
|
||||||
LOG_DEBUG("Canned message event (%x)\n", event->kbchar);
|
// LOG_DEBUG("Canned message event (%x)\n", event->kbchar);
|
||||||
// tweak for left/right events generated via trackball/touch with empty kbchar
|
// tweak for left/right events generated via trackball/touch with empty kbchar
|
||||||
if (!event->kbchar) {
|
if (!event->kbchar) {
|
||||||
if (event->inputEvent == static_cast<char>(meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_LEFT)) {
|
if (event->inputEvent == static_cast<char>(meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_LEFT)) {
|
||||||
@@ -195,6 +195,7 @@ int CannedMessageModule::handleInputEvent(const InputEvent *event)
|
|||||||
this->runState = CANNED_MESSAGE_RUN_STATE_FREETEXT;
|
this->runState = CANNED_MESSAGE_RUN_STATE_FREETEXT;
|
||||||
}
|
}
|
||||||
// pass the pressed key
|
// pass the pressed key
|
||||||
|
// LOG_DEBUG("Canned message ANYKEY (%x)\n", event->kbchar);
|
||||||
this->payload = event->kbchar;
|
this->payload = event->kbchar;
|
||||||
this->lastTouchMillis = millis();
|
this->lastTouchMillis = millis();
|
||||||
validEvent = true;
|
validEvent = true;
|
||||||
@@ -237,8 +238,8 @@ void CannedMessageModule::sendText(NodeNum dest, const char *message, bool wantR
|
|||||||
|
|
||||||
int32_t CannedMessageModule::runOnce()
|
int32_t CannedMessageModule::runOnce()
|
||||||
{
|
{
|
||||||
if ((!moduleConfig.canned_message.enabled) || (this->runState == CANNED_MESSAGE_RUN_STATE_DISABLED) ||
|
if (((!moduleConfig.canned_message.enabled) && !CANNED_MESSAGE_MODULE_ENABLE) ||
|
||||||
(this->runState == CANNED_MESSAGE_RUN_STATE_INACTIVE)) {
|
(this->runState == CANNED_MESSAGE_RUN_STATE_DISABLED) || (this->runState == CANNED_MESSAGE_RUN_STATE_INACTIVE)) {
|
||||||
return INT32_MAX;
|
return INT32_MAX;
|
||||||
}
|
}
|
||||||
// LOG_DEBUG("Check status\n");
|
// LOG_DEBUG("Check status\n");
|
||||||
@@ -454,7 +455,7 @@ const char *CannedMessageModule::getNodeName(NodeNum node)
|
|||||||
|
|
||||||
bool CannedMessageModule::shouldDraw()
|
bool CannedMessageModule::shouldDraw()
|
||||||
{
|
{
|
||||||
if (!moduleConfig.canned_message.enabled) {
|
if (!moduleConfig.canned_message.enabled && !CANNED_MESSAGE_MODULE_ENABLE) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return (currentMessageIndex != -1) || (this->runState != CANNED_MESSAGE_RUN_STATE_INACTIVE);
|
return (currentMessageIndex != -1) || (this->runState != CANNED_MESSAGE_RUN_STATE_INACTIVE);
|
||||||
@@ -649,4 +650,4 @@ String CannedMessageModule::drawWithCursor(String text, int cursor)
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -20,6 +20,10 @@ enum cannedMessageModuleRunState {
|
|||||||
*/
|
*/
|
||||||
#define CANNED_MESSAGE_MODULE_MESSAGES_SIZE 800
|
#define CANNED_MESSAGE_MODULE_MESSAGES_SIZE 800
|
||||||
|
|
||||||
|
#ifndef CANNED_MESSAGE_MODULE_ENABLE
|
||||||
|
#define CANNED_MESSAGE_MODULE_ENABLE 0
|
||||||
|
#endif
|
||||||
|
|
||||||
class CannedMessageModule : public SinglePortModule, public Observable<const UIFrameEvent *>, private concurrency::OSThread
|
class CannedMessageModule : public SinglePortModule, public Observable<const UIFrameEvent *>, private concurrency::OSThread
|
||||||
{
|
{
|
||||||
CallbackObserver<CannedMessageModule, const InputEvent *> inputObserver =
|
CallbackObserver<CannedMessageModule, const InputEvent *> inputObserver =
|
||||||
|
|||||||
102
src/modules/DetectionSensorModule.cpp
Normal file
102
src/modules/DetectionSensorModule.cpp
Normal file
@@ -0,0 +1,102 @@
|
|||||||
|
#include "DetectionSensorModule.h"
|
||||||
|
#include "MeshService.h"
|
||||||
|
#include "NodeDB.h"
|
||||||
|
#include "PowerFSM.h"
|
||||||
|
#include "configuration.h"
|
||||||
|
#include "main.h"
|
||||||
|
|
||||||
|
DetectionSensorModule *detectionSensorModule;
|
||||||
|
|
||||||
|
#define GPIO_POLLING_INTERVAL 100
|
||||||
|
#define DELAYED_INTERVAL 1000
|
||||||
|
|
||||||
|
int32_t DetectionSensorModule::runOnce()
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
Uncomment the preferences below if you want to use the module
|
||||||
|
without having to configure it from the PythonAPI or WebUI.
|
||||||
|
*/
|
||||||
|
// moduleConfig.detection_sensor.enabled = true;
|
||||||
|
// moduleConfig.detection_sensor.monitor_pin = 10; // WisBlock PIR IO6
|
||||||
|
// moduleConfig.detection_sensor.monitor_pin = 21; // WisBlock RAK12013 Radar IO6
|
||||||
|
// moduleConfig.detection_sensor.minimum_broadcast_secs = 30;
|
||||||
|
// moduleConfig.detection_sensor.state_broadcast_secs = 120;
|
||||||
|
// moduleConfig.detection_sensor.detection_triggered_high = true;
|
||||||
|
// strcpy(moduleConfig.detection_sensor.name, "Motion");
|
||||||
|
|
||||||
|
if (moduleConfig.detection_sensor.enabled == false)
|
||||||
|
return disable();
|
||||||
|
|
||||||
|
if (firstTime) {
|
||||||
|
// This is the first time the OSThread library has called this function, so do some setup
|
||||||
|
firstTime = false;
|
||||||
|
if (moduleConfig.detection_sensor.monitor_pin > 0) {
|
||||||
|
pinMode(moduleConfig.detection_sensor.monitor_pin, moduleConfig.detection_sensor.use_pullup ? INPUT_PULLUP : INPUT);
|
||||||
|
} else {
|
||||||
|
LOG_WARN("Detection Sensor Module: Set to enabled but no monitor pin is set. Disabling module...\n");
|
||||||
|
return disable();
|
||||||
|
}
|
||||||
|
LOG_INFO("Detection Sensor Module: Initializing\n");
|
||||||
|
|
||||||
|
return DELAYED_INTERVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
// LOG_DEBUG("Detection Sensor Module: Current pin state: %i\n", digitalRead(moduleConfig.detection_sensor.monitor_pin));
|
||||||
|
|
||||||
|
if ((millis() - lastSentToMesh) >= getConfiguredOrDefaultMs(moduleConfig.detection_sensor.minimum_broadcast_secs) &&
|
||||||
|
hasDetectionEvent()) {
|
||||||
|
sendDetectionMessage();
|
||||||
|
return DELAYED_INTERVAL;
|
||||||
|
}
|
||||||
|
// Even if we haven't detected an event, broadcast our current state to the mesh on the scheduled interval as a sort
|
||||||
|
// of heartbeat. We only do this if the minimum broadcast interval is greater than zero, otherwise we'll only broadcast state
|
||||||
|
// change detections.
|
||||||
|
else if (moduleConfig.detection_sensor.state_broadcast_secs > 0 &&
|
||||||
|
(millis() - lastSentToMesh) >= getConfiguredOrDefaultMs(moduleConfig.detection_sensor.state_broadcast_secs)) {
|
||||||
|
sendCurrentStateMessage();
|
||||||
|
return DELAYED_INTERVAL;
|
||||||
|
}
|
||||||
|
return GPIO_POLLING_INTERVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DetectionSensorModule::sendDetectionMessage()
|
||||||
|
{
|
||||||
|
LOG_DEBUG("Detected event observed. Sending message\n");
|
||||||
|
char *message = new char[40];
|
||||||
|
sprintf(message, "%s detected", moduleConfig.detection_sensor.name);
|
||||||
|
meshtastic_MeshPacket *p = allocDataPacket();
|
||||||
|
p->want_ack = false;
|
||||||
|
p->decoded.payload.size = strlen(message);
|
||||||
|
memcpy(p->decoded.payload.bytes, message, p->decoded.payload.size);
|
||||||
|
if (moduleConfig.detection_sensor.send_bell && p->decoded.payload.size < meshtastic_Constants_DATA_PAYLOAD_LEN) {
|
||||||
|
p->decoded.payload.bytes[p->decoded.payload.size] = 7; // Bell character
|
||||||
|
p->decoded.payload.bytes[p->decoded.payload.size + 1] = '\0'; // Bell character
|
||||||
|
p->decoded.payload.size++;
|
||||||
|
}
|
||||||
|
LOG_INFO("Sending message id=%d, dest=%x, msg=%.*s\n", p->id, p->to, p->decoded.payload.size, p->decoded.payload.bytes);
|
||||||
|
lastSentToMesh = millis();
|
||||||
|
service.sendToMesh(p);
|
||||||
|
delete[] message;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DetectionSensorModule::sendCurrentStateMessage()
|
||||||
|
{
|
||||||
|
char *message = new char[40];
|
||||||
|
sprintf(message, "%s state: %i", moduleConfig.detection_sensor.name, hasDetectionEvent());
|
||||||
|
|
||||||
|
meshtastic_MeshPacket *p = allocDataPacket();
|
||||||
|
p->want_ack = false;
|
||||||
|
p->decoded.payload.size = strlen(message);
|
||||||
|
memcpy(p->decoded.payload.bytes, message, p->decoded.payload.size);
|
||||||
|
LOG_INFO("Sending message id=%d, dest=%x, msg=%.*s\n", p->id, p->to, p->decoded.payload.size, p->decoded.payload.bytes);
|
||||||
|
lastSentToMesh = millis();
|
||||||
|
service.sendToMesh(p);
|
||||||
|
delete[] message;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool DetectionSensorModule::hasDetectionEvent()
|
||||||
|
{
|
||||||
|
bool currentState = digitalRead(moduleConfig.detection_sensor.monitor_pin);
|
||||||
|
// LOG_DEBUG("Detection Sensor Module: Current state: %i\n", currentState);
|
||||||
|
return moduleConfig.detection_sensor.detection_triggered_high ? currentState : !currentState;
|
||||||
|
}
|
||||||
23
src/modules/DetectionSensorModule.h
Normal file
23
src/modules/DetectionSensorModule.h
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
#pragma once
|
||||||
|
#include "SinglePortModule.h"
|
||||||
|
|
||||||
|
class DetectionSensorModule : public SinglePortModule, private concurrency::OSThread
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
DetectionSensorModule()
|
||||||
|
: SinglePortModule("detection", meshtastic_PortNum_DETECTION_SENSOR_APP), OSThread("DetectionSensorModule")
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual int32_t runOnce() override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool firstTime = true;
|
||||||
|
uint32_t lastSentToMesh = 0;
|
||||||
|
void sendDetectionMessage();
|
||||||
|
void sendCurrentStateMessage();
|
||||||
|
bool hasDetectionEvent();
|
||||||
|
};
|
||||||
|
|
||||||
|
extern DetectionSensorModule *detectionSensorModule;
|
||||||
@@ -27,7 +27,6 @@
|
|||||||
|
|
||||||
#ifdef HAS_NCP5623
|
#ifdef HAS_NCP5623
|
||||||
#include <graphics/RAKled.h>
|
#include <graphics/RAKled.h>
|
||||||
NCP5623 rgb;
|
|
||||||
|
|
||||||
uint8_t red = 0;
|
uint8_t red = 0;
|
||||||
uint8_t green = 0;
|
uint8_t green = 0;
|
||||||
@@ -128,6 +127,11 @@ int32_t ExternalNotificationModule::runOnce()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool ExternalNotificationModule::wantPacket(const meshtastic_MeshPacket *p)
|
||||||
|
{
|
||||||
|
return MeshService::isTextPayload(p);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the external notification on for the specified index.
|
* Sets the external notification on for the specified index.
|
||||||
*
|
*
|
||||||
@@ -212,8 +216,8 @@ void ExternalNotificationModule::stopNow()
|
|||||||
}
|
}
|
||||||
|
|
||||||
ExternalNotificationModule::ExternalNotificationModule()
|
ExternalNotificationModule::ExternalNotificationModule()
|
||||||
: SinglePortModule("ExternalNotificationModule", meshtastic_PortNum_TEXT_MESSAGE_APP), concurrency::OSThread(
|
: SinglePortModule("ExternalNotificationModule", meshtastic_PortNum_TEXT_MESSAGE_APP),
|
||||||
"ExternalNotificationModule")
|
concurrency::OSThread("ExternalNotificationModule")
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
Uncomment the preferences below if you want to use the module
|
Uncomment the preferences below if you want to use the module
|
||||||
|
|||||||
@@ -52,6 +52,8 @@ class ExternalNotificationModule : public SinglePortModule, private concurrency:
|
|||||||
|
|
||||||
virtual int32_t runOnce() override;
|
virtual int32_t runOnce() override;
|
||||||
|
|
||||||
|
virtual bool wantPacket(const meshtastic_MeshPacket *p) override;
|
||||||
|
|
||||||
bool isNagging = false;
|
bool isNagging = false;
|
||||||
|
|
||||||
virtual AdminMessageHandleResult handleAdminMessageForModule(const meshtastic_MeshPacket &mp,
|
virtual AdminMessageHandleResult handleAdminMessageForModule(const meshtastic_MeshPacket &mp,
|
||||||
@@ -59,4 +61,4 @@ class ExternalNotificationModule : public SinglePortModule, private concurrency:
|
|||||||
meshtastic_AdminMessage *response) override;
|
meshtastic_AdminMessage *response) override;
|
||||||
};
|
};
|
||||||
|
|
||||||
extern ExternalNotificationModule *externalNotificationModule;
|
extern ExternalNotificationModule *externalNotificationModule;
|
||||||
@@ -7,6 +7,7 @@
|
|||||||
#include "input/kbMatrixImpl.h"
|
#include "input/kbMatrixImpl.h"
|
||||||
#include "modules/AdminModule.h"
|
#include "modules/AdminModule.h"
|
||||||
#include "modules/CannedMessageModule.h"
|
#include "modules/CannedMessageModule.h"
|
||||||
|
#include "modules/DetectionSensorModule.h"
|
||||||
#include "modules/NeighborInfoModule.h"
|
#include "modules/NeighborInfoModule.h"
|
||||||
#include "modules/NodeInfoModule.h"
|
#include "modules/NodeInfoModule.h"
|
||||||
#include "modules/PositionModule.h"
|
#include "modules/PositionModule.h"
|
||||||
@@ -30,7 +31,7 @@
|
|||||||
#if defined(ARCH_ESP32) || defined(ARCH_NRF52) || defined(ARCH_RP2040)
|
#if defined(ARCH_ESP32) || defined(ARCH_NRF52) || defined(ARCH_RP2040)
|
||||||
#include "modules/ExternalNotificationModule.h"
|
#include "modules/ExternalNotificationModule.h"
|
||||||
#include "modules/RangeTestModule.h"
|
#include "modules/RangeTestModule.h"
|
||||||
#if (defined(ARCH_ESP32) || defined(ARCH_NRF52)) && !defined(CONFIG_IDF_TARGET_ESP32S2)
|
#if (defined(ARCH_ESP32) || defined(ARCH_NRF52) || defined(ARCH_RP2040)) && !defined(CONFIG_IDF_TARGET_ESP32S2)
|
||||||
#include "modules/SerialModule.h"
|
#include "modules/SerialModule.h"
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
@@ -50,6 +51,7 @@ void setupModules()
|
|||||||
textMessageModule = new TextMessageModule();
|
textMessageModule = new TextMessageModule();
|
||||||
traceRouteModule = new TraceRouteModule();
|
traceRouteModule = new TraceRouteModule();
|
||||||
neighborInfoModule = new NeighborInfoModule();
|
neighborInfoModule = new NeighborInfoModule();
|
||||||
|
detectionSensorModule = new DetectionSensorModule();
|
||||||
|
|
||||||
// Note: if the rest of meshtastic doesn't need to explicitly use your module, you do not need to assign the instance
|
// Note: if the rest of meshtastic doesn't need to explicitly use your module, you do not need to assign the instance
|
||||||
// to a global variable.
|
// to a global variable.
|
||||||
@@ -58,9 +60,15 @@ void setupModules()
|
|||||||
new ReplyModule();
|
new ReplyModule();
|
||||||
#if HAS_BUTTON
|
#if HAS_BUTTON
|
||||||
rotaryEncoderInterruptImpl1 = new RotaryEncoderInterruptImpl1();
|
rotaryEncoderInterruptImpl1 = new RotaryEncoderInterruptImpl1();
|
||||||
rotaryEncoderInterruptImpl1->init();
|
if (!rotaryEncoderInterruptImpl1->init()) {
|
||||||
|
delete rotaryEncoderInterruptImpl1;
|
||||||
|
rotaryEncoderInterruptImpl1 = nullptr;
|
||||||
|
}
|
||||||
upDownInterruptImpl1 = new UpDownInterruptImpl1();
|
upDownInterruptImpl1 = new UpDownInterruptImpl1();
|
||||||
upDownInterruptImpl1->init();
|
if (!upDownInterruptImpl1->init()) {
|
||||||
|
delete upDownInterruptImpl1;
|
||||||
|
upDownInterruptImpl1 = nullptr;
|
||||||
|
}
|
||||||
cardKbI2cImpl = new CardKbI2cImpl();
|
cardKbI2cImpl = new CardKbI2cImpl();
|
||||||
cardKbI2cImpl->init();
|
cardKbI2cImpl->init();
|
||||||
#ifdef INPUTBROKER_MATRIX_TYPE
|
#ifdef INPUTBROKER_MATRIX_TYPE
|
||||||
@@ -80,11 +88,12 @@ void setupModules()
|
|||||||
#endif
|
#endif
|
||||||
#if HAS_SENSOR
|
#if HAS_SENSOR
|
||||||
new EnvironmentTelemetryModule();
|
new EnvironmentTelemetryModule();
|
||||||
if (nodeTelemetrySensorsMap[meshtastic_TelemetrySensorType_PMSA003I] > 0) {
|
if (nodeTelemetrySensorsMap[meshtastic_TelemetrySensorType_PMSA003I].first > 0) {
|
||||||
new AirQualityTelemetryModule();
|
new AirQualityTelemetryModule();
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
#if (defined(ARCH_ESP32) || defined(ARCH_NRF52)) && !defined(CONFIG_IDF_TARGET_ESP32S2) && !defined(CONFIG_IDF_TARGET_ESP32C3)
|
#if (defined(ARCH_ESP32) || defined(ARCH_NRF52) || defined(ARCH_RP2040)) && !defined(CONFIG_IDF_TARGET_ESP32S2) && \
|
||||||
|
!defined(CONFIG_IDF_TARGET_ESP32C3)
|
||||||
new SerialModule();
|
new SerialModule();
|
||||||
#endif
|
#endif
|
||||||
#ifdef ARCH_ESP32
|
#ifdef ARCH_ESP32
|
||||||
|
|||||||
@@ -15,12 +15,12 @@ NOTE: For debugging only
|
|||||||
*/
|
*/
|
||||||
void NeighborInfoModule::printNeighborInfo(const char *header, const meshtastic_NeighborInfo *np)
|
void NeighborInfoModule::printNeighborInfo(const char *header, const meshtastic_NeighborInfo *np)
|
||||||
{
|
{
|
||||||
LOG_DEBUG("%s NEIGHBORINFO PACKET from Node %d to Node %d (last sent by %d)\n", header, np->node_id, nodeDB.getNodeNum(),
|
LOG_DEBUG("%s NEIGHBORINFO PACKET from Node 0x%x to Node 0x%x (last sent by 0x%x)\n", header, np->node_id,
|
||||||
np->last_sent_by_id);
|
nodeDB.getNodeNum(), np->last_sent_by_id);
|
||||||
LOG_DEBUG("----------------\n");
|
LOG_DEBUG("----------------\n");
|
||||||
LOG_DEBUG("Packet contains %d neighbors\n", np->neighbors_count);
|
LOG_DEBUG("Packet contains %d neighbors\n", np->neighbors_count);
|
||||||
for (int i = 0; i < np->neighbors_count; i++) {
|
for (int i = 0; i < np->neighbors_count; i++) {
|
||||||
LOG_DEBUG("Neighbor %d: node_id=%d, snr=%.2f\n", i, np->neighbors[i].node_id, np->neighbors[i].snr);
|
LOG_DEBUG("Neighbor %d: node_id=0x%x, snr=%.2f\n", i, np->neighbors[i].node_id, np->neighbors[i].snr);
|
||||||
}
|
}
|
||||||
LOG_DEBUG("----------------\n");
|
LOG_DEBUG("----------------\n");
|
||||||
}
|
}
|
||||||
@@ -31,12 +31,12 @@ NOTE: for debugging only
|
|||||||
void NeighborInfoModule::printNodeDBNodes(const char *header)
|
void NeighborInfoModule::printNodeDBNodes(const char *header)
|
||||||
{
|
{
|
||||||
int num_nodes = nodeDB.getNumMeshNodes();
|
int num_nodes = nodeDB.getNumMeshNodes();
|
||||||
LOG_DEBUG("%s NODEDB SELECTION from Node %d:\n", header, nodeDB.getNodeNum());
|
LOG_DEBUG("%s NODEDB SELECTION from Node 0x%x:\n", header, nodeDB.getNodeNum());
|
||||||
LOG_DEBUG("----------------\n");
|
LOG_DEBUG("----------------\n");
|
||||||
LOG_DEBUG("DB contains %d nodes\n", num_nodes);
|
LOG_DEBUG("DB contains %d nodes\n", num_nodes);
|
||||||
for (int i = 0; i < num_nodes; i++) {
|
for (int i = 0; i < num_nodes; i++) {
|
||||||
meshtastic_NodeInfoLite *dbEntry = nodeDB.getMeshNodeByIndex(i);
|
const meshtastic_NodeInfoLite *dbEntry = nodeDB.getMeshNodeByIndex(i);
|
||||||
LOG_DEBUG(" Node %d: node_id=%d, snr=%.2f\n", i, dbEntry->num, dbEntry->snr);
|
LOG_DEBUG(" Node %d: node_id=0x%x, snr=%.2f\n", i, dbEntry->num, dbEntry->snr);
|
||||||
}
|
}
|
||||||
LOG_DEBUG("----------------\n");
|
LOG_DEBUG("----------------\n");
|
||||||
}
|
}
|
||||||
@@ -48,12 +48,12 @@ NOTE: for debugging only
|
|||||||
void NeighborInfoModule::printNodeDBNeighbors(const char *header)
|
void NeighborInfoModule::printNodeDBNeighbors(const char *header)
|
||||||
{
|
{
|
||||||
int num_neighbors = getNumNeighbors();
|
int num_neighbors = getNumNeighbors();
|
||||||
LOG_DEBUG("%s NODEDB SELECTION from Node %d:\n", header, nodeDB.getNodeNum());
|
LOG_DEBUG("%s NODEDB SELECTION from Node 0x%x:\n", header, nodeDB.getNodeNum());
|
||||||
LOG_DEBUG("----------------\n");
|
LOG_DEBUG("----------------\n");
|
||||||
LOG_DEBUG("DB contains %d neighbors\n", num_neighbors);
|
LOG_DEBUG("DB contains %d neighbors\n", num_neighbors);
|
||||||
for (int i = 0; i < num_neighbors; i++) {
|
for (int i = 0; i < num_neighbors; i++) {
|
||||||
meshtastic_Neighbor *dbEntry = getNeighborByIndex(i);
|
const meshtastic_Neighbor *dbEntry = getNeighborByIndex(i);
|
||||||
LOG_DEBUG(" Node %d: node_id=%d, snr=%.2f\n", i, dbEntry->node_id, dbEntry->snr);
|
LOG_DEBUG(" Node %d: node_id=0x%x, snr=%.2f\n", i, dbEntry->node_id, dbEntry->snr);
|
||||||
}
|
}
|
||||||
LOG_DEBUG("----------------\n");
|
LOG_DEBUG("----------------\n");
|
||||||
}
|
}
|
||||||
@@ -66,7 +66,7 @@ NOTE: For debugging only
|
|||||||
void NeighborInfoModule::printNodeDBSelection(const char *header, const meshtastic_NeighborInfo *np)
|
void NeighborInfoModule::printNodeDBSelection(const char *header, const meshtastic_NeighborInfo *np)
|
||||||
{
|
{
|
||||||
int num_neighbors = getNumNeighbors();
|
int num_neighbors = getNumNeighbors();
|
||||||
LOG_DEBUG("%s NODEDB SELECTION from Node %d:\n", header, nodeDB.getNodeNum());
|
LOG_DEBUG("%s NODEDB SELECTION from Node 0x%x:\n", header, nodeDB.getNodeNum());
|
||||||
LOG_DEBUG("----------------\n");
|
LOG_DEBUG("----------------\n");
|
||||||
LOG_DEBUG("Selected %d neighbors of %d DB neighbors\n", np->neighbors_count, num_neighbors);
|
LOG_DEBUG("Selected %d neighbors of %d DB neighbors\n", np->neighbors_count, num_neighbors);
|
||||||
for (int i = 0; i < num_neighbors; i++) {
|
for (int i = 0; i < num_neighbors; i++) {
|
||||||
@@ -78,9 +78,9 @@ void NeighborInfoModule::printNodeDBSelection(const char *header, const meshtast
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!chosen) {
|
if (!chosen) {
|
||||||
LOG_DEBUG(" Node %d: neighbor=%d, snr=%.2f\n", i, dbEntry->node_id, dbEntry->snr);
|
LOG_DEBUG(" Node %d: neighbor=0x%x, snr=%.2f\n", i, dbEntry->node_id, dbEntry->snr);
|
||||||
} else {
|
} else {
|
||||||
LOG_DEBUG("---> Node %d: neighbor=%d, snr=%.2f\n", i, dbEntry->node_id, dbEntry->snr);
|
LOG_DEBUG("---> Node %d: neighbor=0x%x, snr=%.2f\n", i, dbEntry->node_id, dbEntry->snr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
LOG_DEBUG("----------------\n");
|
LOG_DEBUG("----------------\n");
|
||||||
@@ -88,9 +88,9 @@ void NeighborInfoModule::printNodeDBSelection(const char *header, const meshtast
|
|||||||
|
|
||||||
/* Send our initial owner announcement 35 seconds after we start (to give network time to setup) */
|
/* Send our initial owner announcement 35 seconds after we start (to give network time to setup) */
|
||||||
NeighborInfoModule::NeighborInfoModule()
|
NeighborInfoModule::NeighborInfoModule()
|
||||||
: neighbors(neighborState.neighbors), numNeighbors(&neighborState.neighbors_count),
|
: ProtobufModule("neighborinfo", meshtastic_PortNum_NEIGHBORINFO_APP, &meshtastic_NeighborInfo_msg),
|
||||||
ProtobufModule("neighborinfo", meshtastic_PortNum_NEIGHBORINFO_APP, &meshtastic_NeighborInfo_msg), concurrency::OSThread(
|
concurrency::OSThread("NeighborInfoModule"), neighbors(neighborState.neighbors),
|
||||||
"NeighborInfoModule")
|
numNeighbors(&neighborState.neighbors_count)
|
||||||
{
|
{
|
||||||
ourPortNum = meshtastic_PortNum_NEIGHBORINFO_APP;
|
ourPortNum = meshtastic_PortNum_NEIGHBORINFO_APP;
|
||||||
|
|
||||||
@@ -103,16 +103,6 @@ NeighborInfoModule::NeighborInfoModule()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
Allocate a zeroed neighbor info packet
|
|
||||||
*/
|
|
||||||
meshtastic_NeighborInfo *NeighborInfoModule::allocateNeighborInfoPacket()
|
|
||||||
{
|
|
||||||
meshtastic_NeighborInfo *neighborInfo = (meshtastic_NeighborInfo *)malloc(sizeof(meshtastic_NeighborInfo));
|
|
||||||
memset(neighborInfo, 0, sizeof(meshtastic_NeighborInfo));
|
|
||||||
return neighborInfo;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Collect neighbor info from the nodeDB's history, capping at a maximum number of entries and max time
|
Collect neighbor info from the nodeDB's history, capping at a maximum number of entries and max time
|
||||||
Assumes that the neighborInfo packet has been allocated
|
Assumes that the neighborInfo packet has been allocated
|
||||||
@@ -120,7 +110,7 @@ Assumes that the neighborInfo packet has been allocated
|
|||||||
*/
|
*/
|
||||||
uint32_t NeighborInfoModule::collectNeighborInfo(meshtastic_NeighborInfo *neighborInfo)
|
uint32_t NeighborInfoModule::collectNeighborInfo(meshtastic_NeighborInfo *neighborInfo)
|
||||||
{
|
{
|
||||||
int my_node_id = nodeDB.getNodeNum();
|
uint my_node_id = nodeDB.getNodeNum();
|
||||||
neighborInfo->node_id = my_node_id;
|
neighborInfo->node_id = my_node_id;
|
||||||
neighborInfo->last_sent_by_id = my_node_id;
|
neighborInfo->last_sent_by_id = my_node_id;
|
||||||
neighborInfo->node_broadcast_interval_secs = moduleConfig.neighbor_info.update_interval;
|
neighborInfo->node_broadcast_interval_secs = moduleConfig.neighbor_info.update_interval;
|
||||||
@@ -164,7 +154,7 @@ size_t NeighborInfoModule::cleanUpNeighbors()
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Update the neighbor list
|
// Update the neighbor list
|
||||||
for (int i = 0; i < indices_to_remove.size(); i++) {
|
for (uint i = 0; i < indices_to_remove.size(); i++) {
|
||||||
int index = indices_to_remove[i];
|
int index = indices_to_remove[i];
|
||||||
LOG_DEBUG("Removing neighbor with node ID 0x%x\n", neighbors[index].node_id);
|
LOG_DEBUG("Removing neighbor with node ID 0x%x\n", neighbors[index].node_id);
|
||||||
for (int j = index; j < num_neighbors - 1; j++) {
|
for (int j = index; j < num_neighbors - 1; j++) {
|
||||||
@@ -184,14 +174,14 @@ size_t NeighborInfoModule::cleanUpNeighbors()
|
|||||||
/* Send neighbor info to the mesh */
|
/* Send neighbor info to the mesh */
|
||||||
void NeighborInfoModule::sendNeighborInfo(NodeNum dest, bool wantReplies)
|
void NeighborInfoModule::sendNeighborInfo(NodeNum dest, bool wantReplies)
|
||||||
{
|
{
|
||||||
meshtastic_NeighborInfo *neighborInfo = allocateNeighborInfoPacket();
|
meshtastic_NeighborInfo neighborInfo = meshtastic_NeighborInfo_init_zero;
|
||||||
collectNeighborInfo(neighborInfo);
|
collectNeighborInfo(&neighborInfo);
|
||||||
meshtastic_MeshPacket *p = allocDataProtobuf(*neighborInfo);
|
meshtastic_MeshPacket *p = allocDataProtobuf(neighborInfo);
|
||||||
// send regardless of whether or not we have neighbors in our DB,
|
// send regardless of whether or not we have neighbors in our DB,
|
||||||
// because we want to get neighbors for the next cycle
|
// because we want to get neighbors for the next cycle
|
||||||
p->to = dest;
|
p->to = dest;
|
||||||
p->decoded.want_response = wantReplies;
|
p->decoded.want_response = wantReplies;
|
||||||
printNeighborInfo("SENDING", neighborInfo);
|
printNeighborInfo("SENDING", &neighborInfo);
|
||||||
service.sendToMesh(p, RX_SRC_LOCAL, true);
|
service.sendToMesh(p, RX_SRC_LOCAL, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -212,8 +202,10 @@ Pass it to an upper client; do not persist this data on the mesh
|
|||||||
*/
|
*/
|
||||||
bool NeighborInfoModule::handleReceivedProtobuf(const meshtastic_MeshPacket &mp, meshtastic_NeighborInfo *np)
|
bool NeighborInfoModule::handleReceivedProtobuf(const meshtastic_MeshPacket &mp, meshtastic_NeighborInfo *np)
|
||||||
{
|
{
|
||||||
printNeighborInfo("RECEIVED", np);
|
if (enabled) {
|
||||||
updateNeighbors(mp, np);
|
printNeighborInfo("RECEIVED", np);
|
||||||
|
updateNeighbors(mp, np);
|
||||||
|
}
|
||||||
// Allow others to handle this packet
|
// Allow others to handle this packet
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -245,7 +237,7 @@ void NeighborInfoModule::resetNeighbors()
|
|||||||
saveProtoForModule();
|
saveProtoForModule();
|
||||||
}
|
}
|
||||||
|
|
||||||
void NeighborInfoModule::updateNeighbors(const meshtastic_MeshPacket &mp, meshtastic_NeighborInfo *np)
|
void NeighborInfoModule::updateNeighbors(const meshtastic_MeshPacket &mp, const meshtastic_NeighborInfo *np)
|
||||||
{
|
{
|
||||||
// The last sent ID will be 0 if the packet is from the phone, which we don't count as
|
// The last sent ID will be 0 if the packet is from the phone, which we don't count as
|
||||||
// an edge. So we assume that if it's zero, then this packet is from our node.
|
// an edge. So we assume that if it's zero, then this packet is from our node.
|
||||||
@@ -255,7 +247,7 @@ void NeighborInfoModule::updateNeighbors(const meshtastic_MeshPacket &mp, meshta
|
|||||||
}
|
}
|
||||||
|
|
||||||
meshtastic_Neighbor *NeighborInfoModule::getOrCreateNeighbor(NodeNum originalSender, NodeNum n,
|
meshtastic_Neighbor *NeighborInfoModule::getOrCreateNeighbor(NodeNum originalSender, NodeNum n,
|
||||||
uint32_t node_broadcast_interval_secs, int snr)
|
uint32_t node_broadcast_interval_secs, float snr)
|
||||||
{
|
{
|
||||||
// our node and the phone are the same node (not neighbors)
|
// our node and the phone are the same node (not neighbors)
|
||||||
if (n == 0) {
|
if (n == 0) {
|
||||||
@@ -277,7 +269,7 @@ meshtastic_Neighbor *NeighborInfoModule::getOrCreateNeighbor(NodeNum originalSen
|
|||||||
}
|
}
|
||||||
// otherwise, allocate one and assign data to it
|
// otherwise, allocate one and assign data to it
|
||||||
// TODO: max memory for the database should take neighbors into account, but currently doesn't
|
// TODO: max memory for the database should take neighbors into account, but currently doesn't
|
||||||
if (*numNeighbors < MAX_NUM_NODES) {
|
if (*numNeighbors < MAX_NUM_NEIGHBORS) {
|
||||||
(*numNeighbors)++;
|
(*numNeighbors)++;
|
||||||
}
|
}
|
||||||
meshtastic_Neighbor *new_nbr = &neighbors[((*numNeighbors) - 1)];
|
meshtastic_Neighbor *new_nbr = &neighbors[((*numNeighbors) - 1)];
|
||||||
|
|||||||
@@ -49,7 +49,7 @@ class NeighborInfoModule : public ProtobufModule<meshtastic_NeighborInfo>, priva
|
|||||||
meshtastic_NeighborInfo *allocateNeighborInfoPacket();
|
meshtastic_NeighborInfo *allocateNeighborInfoPacket();
|
||||||
|
|
||||||
// Find a neighbor in our DB, create an empty neighbor if missing
|
// Find a neighbor in our DB, create an empty neighbor if missing
|
||||||
meshtastic_Neighbor *getOrCreateNeighbor(NodeNum originalSender, NodeNum n, uint32_t node_broadcast_interval_secs, int snr);
|
meshtastic_Neighbor *getOrCreateNeighbor(NodeNum originalSender, NodeNum n, uint32_t node_broadcast_interval_secs, float snr);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Send info on our node's neighbors into the mesh
|
* Send info on our node's neighbors into the mesh
|
||||||
@@ -65,7 +65,7 @@ class NeighborInfoModule : public ProtobufModule<meshtastic_NeighborInfo>, priva
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* update neighbors with subpacket sniffed from network */
|
/* update neighbors with subpacket sniffed from network */
|
||||||
void updateNeighbors(const meshtastic_MeshPacket &mp, meshtastic_NeighborInfo *np);
|
void updateNeighbors(const meshtastic_MeshPacket &mp, const meshtastic_NeighborInfo *np);
|
||||||
|
|
||||||
/* update a NeighborInfo packet with our NodeNum as last_sent_by_id */
|
/* update a NeighborInfo packet with our NodeNum as last_sent_by_id */
|
||||||
void updateLastSentById(meshtastic_MeshPacket *p);
|
void updateLastSentById(meshtastic_MeshPacket *p);
|
||||||
|
|||||||
@@ -40,7 +40,9 @@ void NodeInfoModule::sendOurNodeInfo(NodeNum dest, bool wantReplies, uint8_t cha
|
|||||||
meshtastic_MeshPacket *p = allocReply();
|
meshtastic_MeshPacket *p = allocReply();
|
||||||
if (p) { // Check whether we didn't ignore it
|
if (p) { // Check whether we didn't ignore it
|
||||||
p->to = dest;
|
p->to = dest;
|
||||||
p->decoded.want_response = wantReplies;
|
p->decoded.want_response = (config.device.role != meshtastic_Config_DeviceConfig_Role_TRACKER &&
|
||||||
|
config.device.role != meshtastic_Config_DeviceConfig_Role_SENSOR) &&
|
||||||
|
wantReplies;
|
||||||
p->priority = meshtastic_MeshPacket_Priority_BACKGROUND;
|
p->priority = meshtastic_MeshPacket_Priority_BACKGROUND;
|
||||||
if (channel > 0) {
|
if (channel > 0) {
|
||||||
LOG_DEBUG("sending ourNodeInfo to channel %d\n", channel);
|
LOG_DEBUG("sending ourNodeInfo to channel %d\n", channel);
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
#include "PositionModule.h"
|
#include "PositionModule.h"
|
||||||
|
#include "GPS.h"
|
||||||
#include "MeshService.h"
|
#include "MeshService.h"
|
||||||
#include "NodeDB.h"
|
#include "NodeDB.h"
|
||||||
#include "RTC.h"
|
#include "RTC.h"
|
||||||
@@ -7,15 +8,34 @@
|
|||||||
#include "airtime.h"
|
#include "airtime.h"
|
||||||
#include "configuration.h"
|
#include "configuration.h"
|
||||||
#include "gps/GeoCoord.h"
|
#include "gps/GeoCoord.h"
|
||||||
|
#include "sleep.h"
|
||||||
|
#include "target_specific.h"
|
||||||
|
|
||||||
PositionModule *positionModule;
|
PositionModule *positionModule;
|
||||||
|
|
||||||
PositionModule::PositionModule()
|
PositionModule::PositionModule()
|
||||||
: ProtobufModule("position", meshtastic_PortNum_POSITION_APP, &meshtastic_Position_msg), concurrency::OSThread(
|
: ProtobufModule("position", meshtastic_PortNum_POSITION_APP, &meshtastic_Position_msg),
|
||||||
"PositionModule")
|
concurrency::OSThread("PositionModule")
|
||||||
{
|
{
|
||||||
isPromiscuous = true; // We always want to update our nodedb, even if we are sniffing on others
|
isPromiscuous = true; // We always want to update our nodedb, even if we are sniffing on others
|
||||||
setIntervalFromNow(60 * 1000); // Send our initial position 60 seconds after we start (to give GPS time to setup)
|
if (config.device.role != meshtastic_Config_DeviceConfig_Role_TRACKER)
|
||||||
|
setIntervalFromNow(60 * 1000);
|
||||||
|
|
||||||
|
// Power saving trackers should clear their position on startup to avoid waking up and sending a stale position
|
||||||
|
if (config.device.role == meshtastic_Config_DeviceConfig_Role_TRACKER && config.power.is_power_saving) {
|
||||||
|
clearPosition();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void PositionModule::clearPosition()
|
||||||
|
{
|
||||||
|
LOG_DEBUG("Clearing position on startup for sleepy tracker (ー。ー) zzz\n");
|
||||||
|
meshtastic_NodeInfoLite *node = nodeDB.getMeshNode(nodeDB.getNodeNum());
|
||||||
|
node->position.latitude_i = 0;
|
||||||
|
node->position.longitude_i = 0;
|
||||||
|
node->position.altitude = 0;
|
||||||
|
node->position.time = 0;
|
||||||
|
nodeDB.setLocalPosition(meshtastic_Position_init_default);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool PositionModule::handleReceivedProtobuf(const meshtastic_MeshPacket &mp, meshtastic_Position *pptr)
|
bool PositionModule::handleReceivedProtobuf(const meshtastic_MeshPacket &mp, meshtastic_Position *pptr)
|
||||||
@@ -27,18 +47,19 @@ bool PositionModule::handleReceivedProtobuf(const meshtastic_MeshPacket &mp, mes
|
|||||||
|
|
||||||
// FIXME this can in fact happen with packets sent from EUD (src=RX_SRC_USER)
|
// FIXME this can in fact happen with packets sent from EUD (src=RX_SRC_USER)
|
||||||
// to set fixed location, EUD-GPS location or just the time (see also issue #900)
|
// to set fixed location, EUD-GPS location or just the time (see also issue #900)
|
||||||
|
bool isLocal = false;
|
||||||
if (nodeDB.getNodeNum() == getFrom(&mp)) {
|
if (nodeDB.getNodeNum() == getFrom(&mp)) {
|
||||||
LOG_DEBUG("Incoming update from MYSELF\n");
|
LOG_DEBUG("Incoming update from MYSELF\n");
|
||||||
// LOG_DEBUG("Ignored an incoming update from MYSELF\n");
|
isLocal = true;
|
||||||
// return false;
|
nodeDB.setLocalPosition(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Log packet size and list of fields
|
// Log packet size and data fields
|
||||||
LOG_INFO("POSITION node=%08x l=%d %s%s%s%s%s%s%s%s%s%s%s%s%s\n", getFrom(&mp), mp.decoded.payload.size,
|
LOG_INFO("POSITION node=%08x l=%d latI=%d lonI=%d msl=%d hae=%d geo=%d pdop=%d hdop=%d vdop=%d siv=%d fxq=%d fxt=%d pts=%d "
|
||||||
p.latitude_i ? "LAT " : "", p.longitude_i ? "LON " : "", p.altitude ? "MSL " : "", p.altitude_hae ? "HAE " : "",
|
"time=%d\n",
|
||||||
p.altitude_geoidal_separation ? "GEO " : "", p.PDOP ? "PDOP " : "", p.HDOP ? "HDOP " : "", p.VDOP ? "VDOP " : "",
|
getFrom(&mp), mp.decoded.payload.size, p.latitude_i, p.longitude_i, p.altitude, p.altitude_hae,
|
||||||
p.sats_in_view ? "SIV " : "", p.fix_quality ? "FXQ " : "", p.fix_type ? "FXT " : "", p.timestamp ? "PTS " : "",
|
p.altitude_geoidal_separation, p.PDOP, p.HDOP, p.VDOP, p.sats_in_view, p.fix_quality, p.fix_type, p.timestamp,
|
||||||
p.time ? "TIME " : "");
|
p.time);
|
||||||
|
|
||||||
if (p.time) {
|
if (p.time) {
|
||||||
struct timeval tv;
|
struct timeval tv;
|
||||||
@@ -47,7 +68,8 @@ bool PositionModule::handleReceivedProtobuf(const meshtastic_MeshPacket &mp, mes
|
|||||||
tv.tv_sec = secs;
|
tv.tv_sec = secs;
|
||||||
tv.tv_usec = 0;
|
tv.tv_usec = 0;
|
||||||
|
|
||||||
perhapsSetRTC(RTCQualityFromNet, &tv);
|
// Set from phone RTC Quality to RTCQualityNTP since it should be approximately so
|
||||||
|
perhapsSetRTC(isLocal ? RTCQualityNTP : RTCQualityFromNet, &tv);
|
||||||
}
|
}
|
||||||
|
|
||||||
nodeDB.updatePosition(getFrom(&mp), p);
|
nodeDB.updatePosition(getFrom(&mp), p);
|
||||||
@@ -65,7 +87,7 @@ bool PositionModule::handleReceivedProtobuf(const meshtastic_MeshPacket &mp, mes
|
|||||||
meshtastic_MeshPacket *PositionModule::allocReply()
|
meshtastic_MeshPacket *PositionModule::allocReply()
|
||||||
{
|
{
|
||||||
if (ignoreRequest) {
|
if (ignoreRequest) {
|
||||||
return NULL;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
meshtastic_NodeInfoLite *node = service.refreshLocalMeshNode(); // should guarantee there is now a position
|
meshtastic_NodeInfoLite *node = service.refreshLocalMeshNode(); // should guarantee there is now a position
|
||||||
@@ -77,8 +99,9 @@ meshtastic_MeshPacket *PositionModule::allocReply()
|
|||||||
|
|
||||||
// Populate a Position struct with ONLY the requested fields
|
// Populate a Position struct with ONLY the requested fields
|
||||||
meshtastic_Position p = meshtastic_Position_init_default; // Start with an empty structure
|
meshtastic_Position p = meshtastic_Position_init_default; // Start with an empty structure
|
||||||
|
// if localPosition is totally empty, put our last saved position (lite) in there
|
||||||
if (localPosition.latitude_i == 0 && localPosition.longitude_i == 0) {
|
if (localPosition.latitude_i == 0 && localPosition.longitude_i == 0) {
|
||||||
localPosition = ConvertToPosition(node->position);
|
nodeDB.setLocalPosition(TypeConversions::ConvertToPosition(node->position));
|
||||||
}
|
}
|
||||||
localPosition.seq_number++;
|
localPosition.seq_number++;
|
||||||
|
|
||||||
@@ -142,8 +165,13 @@ void PositionModule::sendOurPosition(NodeNum dest, bool wantReplies, uint8_t cha
|
|||||||
service.cancelSending(prevPacketId);
|
service.cancelSending(prevPacketId);
|
||||||
|
|
||||||
meshtastic_MeshPacket *p = allocReply();
|
meshtastic_MeshPacket *p = allocReply();
|
||||||
|
if (p == nullptr) {
|
||||||
|
LOG_WARN("allocReply returned a nullptr");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
p->to = dest;
|
p->to = dest;
|
||||||
p->decoded.want_response = wantReplies;
|
p->decoded.want_response = config.device.role == meshtastic_Config_DeviceConfig_Role_TRACKER ? false : wantReplies;
|
||||||
if (config.device.role == meshtastic_Config_DeviceConfig_Role_TRACKER)
|
if (config.device.role == meshtastic_Config_DeviceConfig_Role_TRACKER)
|
||||||
p->priority = meshtastic_MeshPacket_Priority_RELIABLE;
|
p->priority = meshtastic_MeshPacket_Priority_RELIABLE;
|
||||||
else
|
else
|
||||||
@@ -154,75 +182,142 @@ void PositionModule::sendOurPosition(NodeNum dest, bool wantReplies, uint8_t cha
|
|||||||
p->channel = channel;
|
p->channel = channel;
|
||||||
|
|
||||||
service.sendToMesh(p, RX_SRC_LOCAL, true);
|
service.sendToMesh(p, RX_SRC_LOCAL, true);
|
||||||
|
|
||||||
|
if (config.device.role == meshtastic_Config_DeviceConfig_Role_TRACKER && config.power.is_power_saving) {
|
||||||
|
LOG_DEBUG("Starting next execution in 5 seconds and then going to sleep.\n");
|
||||||
|
sleepOnNextExecution = true;
|
||||||
|
setIntervalFromNow(5000);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define RUNONCE_INTERVAL 5000;
|
||||||
|
|
||||||
int32_t PositionModule::runOnce()
|
int32_t PositionModule::runOnce()
|
||||||
{
|
{
|
||||||
|
if (sleepOnNextExecution == true) {
|
||||||
|
sleepOnNextExecution = false;
|
||||||
|
uint32_t nightyNightMs = getConfiguredOrDefaultMs(config.position.position_broadcast_secs);
|
||||||
|
LOG_DEBUG("Sleeping for %ims, then awaking to send position again.\n", nightyNightMs);
|
||||||
|
doDeepSleep(nightyNightMs, false);
|
||||||
|
}
|
||||||
|
|
||||||
meshtastic_NodeInfoLite *node = nodeDB.getMeshNode(nodeDB.getNodeNum());
|
meshtastic_NodeInfoLite *node = nodeDB.getMeshNode(nodeDB.getNodeNum());
|
||||||
|
|
||||||
// We limit our GPS broadcasts to a max rate
|
// We limit our GPS broadcasts to a max rate
|
||||||
uint32_t now = millis();
|
uint32_t now = millis();
|
||||||
uint32_t intervalMs = getConfiguredOrDefaultMs(config.position.position_broadcast_secs, default_broadcast_interval_secs);
|
uint32_t intervalMs = getConfiguredOrDefaultMs(config.position.position_broadcast_secs, default_broadcast_interval_secs);
|
||||||
uint32_t msSinceLastSend = now - lastGpsSend;
|
uint32_t msSinceLastSend = now - lastGpsSend;
|
||||||
|
// Only send packets if the channel util. is less than 25% utilized or we're a tracker with less than 40% utilized.
|
||||||
|
if (!airTime->isTxAllowedChannelUtil(config.device.role != meshtastic_Config_DeviceConfig_Role_TRACKER)) {
|
||||||
|
return RUNONCE_INTERVAL;
|
||||||
|
}
|
||||||
|
|
||||||
if (lastGpsSend == 0 || msSinceLastSend >= intervalMs) {
|
if (lastGpsSend == 0 || msSinceLastSend >= intervalMs) {
|
||||||
// Only send packets if the channel is less than 40% utilized.
|
if (hasValidPosition(node)) {
|
||||||
if (airTime->isTxAllowedChannelUtil()) {
|
lastGpsSend = now;
|
||||||
if (hasValidPosition(node)) {
|
|
||||||
lastGpsSend = now;
|
|
||||||
|
|
||||||
lastGpsLatitude = node->position.latitude_i;
|
lastGpsLatitude = node->position.latitude_i;
|
||||||
lastGpsLongitude = node->position.longitude_i;
|
lastGpsLongitude = node->position.longitude_i;
|
||||||
|
|
||||||
// If we changed channels, ask everyone else for their latest info
|
// If we changed channels, ask everyone else for their latest info
|
||||||
|
bool requestReplies = currentGeneration != radioGeneration;
|
||||||
|
currentGeneration = radioGeneration;
|
||||||
|
|
||||||
|
LOG_INFO("Sending pos@%x:6 to mesh (wantReplies=%d)\n", localPosition.timestamp, requestReplies);
|
||||||
|
sendOurPosition(NODENUM_BROADCAST, requestReplies);
|
||||||
|
}
|
||||||
|
} else if (config.position.position_broadcast_smart_enabled) {
|
||||||
|
const meshtastic_NodeInfoLite *node2 = service.refreshLocalMeshNode(); // should guarantee there is now a position
|
||||||
|
|
||||||
|
if (hasValidPosition(node2)) {
|
||||||
|
// The minimum time (in seconds) that would pass before we are able to send a new position packet.
|
||||||
|
const uint32_t minimumTimeThreshold =
|
||||||
|
getConfiguredOrDefaultMs(config.position.broadcast_smart_minimum_interval_secs, 30);
|
||||||
|
|
||||||
|
auto smartPosition = getDistanceTraveledSinceLastSend(node->position);
|
||||||
|
|
||||||
|
if (smartPosition.hasTraveledOverThreshold && msSinceLastSend >= minimumTimeThreshold) {
|
||||||
bool requestReplies = currentGeneration != radioGeneration;
|
bool requestReplies = currentGeneration != radioGeneration;
|
||||||
currentGeneration = radioGeneration;
|
currentGeneration = radioGeneration;
|
||||||
|
|
||||||
LOG_INFO("Sending pos@%x:6 to mesh (wantReplies=%d)\n", localPosition.timestamp, requestReplies);
|
LOG_INFO("Sending smart pos@%x:6 to mesh (distanceTraveled=%fm, minDistanceThreshold=%im, timeElapsed=%ims, "
|
||||||
|
"minTimeInterval=%ims)\n",
|
||||||
|
localPosition.timestamp, smartPosition.distanceTraveled, smartPosition.distanceThreshold,
|
||||||
|
msSinceLastSend, minimumTimeThreshold);
|
||||||
sendOurPosition(NODENUM_BROADCAST, requestReplies);
|
sendOurPosition(NODENUM_BROADCAST, requestReplies);
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if (config.position.position_broadcast_smart_enabled) {
|
|
||||||
// Only send packets if the channel is less than 25% utilized or we're a tracker.
|
|
||||||
if (airTime->isTxAllowedChannelUtil(config.device.role != meshtastic_Config_DeviceConfig_Role_TRACKER)) {
|
|
||||||
meshtastic_NodeInfoLite *node2 = service.refreshLocalMeshNode(); // should guarantee there is now a position
|
|
||||||
|
|
||||||
if (hasValidPosition(node2)) {
|
// Set the current coords as our last ones, after we've compared distance with current and decided to send
|
||||||
// The minimum distance to travel before we are able to send a new position packet.
|
lastGpsLatitude = node->position.latitude_i;
|
||||||
const uint32_t distanceTravelThreshold =
|
lastGpsLongitude = node->position.longitude_i;
|
||||||
config.position.broadcast_smart_minimum_distance > 0 ? config.position.broadcast_smart_minimum_distance : 100;
|
|
||||||
|
|
||||||
// The minimum time (in seconds) that would pass before we are able to send a new position packet.
|
/* Update lastGpsSend to now. This means if the device is stationary, then
|
||||||
const uint32_t minimumTimeThreshold =
|
getPref_position_broadcast_secs will still apply.
|
||||||
getConfiguredOrDefaultMs(config.position.broadcast_smart_minimum_interval_secs, 30);
|
*/
|
||||||
|
lastGpsSend = now;
|
||||||
// Determine the distance in meters between two points on the globe
|
|
||||||
float distanceTraveledSinceLastSend =
|
|
||||||
GeoCoord::latLongToMeter(lastGpsLatitude * 1e-7, lastGpsLongitude * 1e-7, node->position.latitude_i * 1e-7,
|
|
||||||
node->position.longitude_i * 1e-7);
|
|
||||||
|
|
||||||
if ((abs(distanceTraveledSinceLastSend) >= distanceTravelThreshold) && msSinceLastSend >= minimumTimeThreshold) {
|
|
||||||
bool requestReplies = currentGeneration != radioGeneration;
|
|
||||||
currentGeneration = radioGeneration;
|
|
||||||
|
|
||||||
LOG_INFO("Sending smart pos@%x:6 to mesh (distanceTraveled=%fm, minDistanceThreshold=%im, timeElapsed=%ims, "
|
|
||||||
"minTimeInterval=%ims)\n",
|
|
||||||
localPosition.timestamp, abs(distanceTraveledSinceLastSend), distanceTravelThreshold,
|
|
||||||
msSinceLastSend, minimumTimeThreshold);
|
|
||||||
sendOurPosition(NODENUM_BROADCAST, requestReplies);
|
|
||||||
|
|
||||||
// Set the current coords as our last ones, after we've compared distance with current and decided to send
|
|
||||||
lastGpsLatitude = node->position.latitude_i;
|
|
||||||
lastGpsLongitude = node->position.longitude_i;
|
|
||||||
|
|
||||||
/* Update lastGpsSend to now. This means if the device is stationary, then
|
|
||||||
getPref_position_broadcast_secs will still apply.
|
|
||||||
*/
|
|
||||||
lastGpsSend = now;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return 5000; // to save power only wake for our callback occasionally
|
return RUNONCE_INTERVAL; // to save power only wake for our callback occasionally
|
||||||
|
}
|
||||||
|
|
||||||
|
struct SmartPosition PositionModule::getDistanceTraveledSinceLastSend(meshtastic_PositionLite currentPosition)
|
||||||
|
{
|
||||||
|
// The minimum distance to travel before we are able to send a new position packet.
|
||||||
|
const uint32_t distanceTravelThreshold = getConfiguredOrDefault(config.position.broadcast_smart_minimum_distance, 100);
|
||||||
|
|
||||||
|
// Determine the distance in meters between two points on the globe
|
||||||
|
float distanceTraveledSinceLastSend = GeoCoord::latLongToMeter(
|
||||||
|
lastGpsLatitude * 1e-7, lastGpsLongitude * 1e-7, currentPosition.latitude_i * 1e-7, currentPosition.longitude_i * 1e-7);
|
||||||
|
|
||||||
|
#ifdef GPS_EXTRAVERBOSE
|
||||||
|
LOG_DEBUG("--------LAST POSITION------------------------------------\n");
|
||||||
|
LOG_DEBUG("lastGpsLatitude=%i, lastGpsLatitude=%i\n", lastGpsLatitude, lastGpsLongitude);
|
||||||
|
|
||||||
|
LOG_DEBUG("--------CURRENT POSITION---------------------------------\n");
|
||||||
|
LOG_DEBUG("currentPosition.latitude_i=%i, currentPosition.longitude_i=%i\n", lastGpsLatitude, lastGpsLongitude);
|
||||||
|
|
||||||
|
LOG_DEBUG("--------SMART POSITION-----------------------------------\n");
|
||||||
|
LOG_DEBUG("hasTraveledOverThreshold=%i, distanceTraveled=%d, distanceThreshold=% u\n",
|
||||||
|
abs(distanceTraveledSinceLastSend) >= distanceTravelThreshold, abs(distanceTraveledSinceLastSend),
|
||||||
|
distanceTravelThreshold);
|
||||||
|
|
||||||
|
if (abs(distanceTraveledSinceLastSend) >= distanceTravelThreshold) {
|
||||||
|
LOG_DEBUG("\n\n\nSMART SEEEEEEEEENDING\n\n\n");
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return SmartPosition{.distanceTraveled = abs(distanceTraveledSinceLastSend),
|
||||||
|
.distanceThreshold = distanceTravelThreshold,
|
||||||
|
.hasTraveledOverThreshold = abs(distanceTraveledSinceLastSend) >= distanceTravelThreshold};
|
||||||
|
}
|
||||||
|
|
||||||
|
void PositionModule::handleNewPosition()
|
||||||
|
{
|
||||||
|
meshtastic_NodeInfoLite *node = nodeDB.getMeshNode(nodeDB.getNodeNum());
|
||||||
|
const meshtastic_NodeInfoLite *node2 = service.refreshLocalMeshNode(); // should guarantee there is now a position
|
||||||
|
// We limit our GPS broadcasts to a max rate
|
||||||
|
uint32_t now = millis();
|
||||||
|
uint32_t msSinceLastSend = now - lastGpsSend;
|
||||||
|
|
||||||
|
if (hasValidPosition(node2)) {
|
||||||
|
auto smartPosition = getDistanceTraveledSinceLastSend(node->position);
|
||||||
|
if (smartPosition.hasTraveledOverThreshold) {
|
||||||
|
bool requestReplies = currentGeneration != radioGeneration;
|
||||||
|
currentGeneration = radioGeneration;
|
||||||
|
|
||||||
|
LOG_INFO("Sending smart pos@%x:6 to mesh (distanceTraveled=%fm, minDistanceThreshold=%im, timeElapsed=%ims)\n",
|
||||||
|
localPosition.timestamp, smartPosition.distanceTraveled, smartPosition.distanceThreshold, msSinceLastSend);
|
||||||
|
sendOurPosition(NODENUM_BROADCAST, requestReplies);
|
||||||
|
|
||||||
|
// Set the current coords as our last ones, after we've compared distance with current and decided to send
|
||||||
|
lastGpsLatitude = node->position.latitude_i;
|
||||||
|
lastGpsLongitude = node->position.longitude_i;
|
||||||
|
|
||||||
|
/* Update lastGpsSend to now. This means if the device is stationary, then
|
||||||
|
getPref_position_broadcast_secs will still apply.
|
||||||
|
*/
|
||||||
|
lastGpsSend = now;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -31,6 +31,8 @@ class PositionModule : public ProtobufModule<meshtastic_Position>, private concu
|
|||||||
*/
|
*/
|
||||||
void sendOurPosition(NodeNum dest = NODENUM_BROADCAST, bool wantReplies = false, uint8_t channel = 0);
|
void sendOurPosition(NodeNum dest = NODENUM_BROADCAST, bool wantReplies = false, uint8_t channel = 0);
|
||||||
|
|
||||||
|
void handleNewPosition();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
/** Called to handle a particular incoming message
|
/** Called to handle a particular incoming message
|
||||||
|
|
||||||
@@ -44,6 +46,18 @@ class PositionModule : public ProtobufModule<meshtastic_Position>, private concu
|
|||||||
|
|
||||||
/** Does our periodic broadcast */
|
/** Does our periodic broadcast */
|
||||||
virtual int32_t runOnce() override;
|
virtual int32_t runOnce() override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
struct SmartPosition getDistanceTraveledSinceLastSend(meshtastic_PositionLite currentPosition);
|
||||||
|
|
||||||
|
/** Only used in power saving trackers for now */
|
||||||
|
void clearPosition();
|
||||||
};
|
};
|
||||||
|
|
||||||
extern PositionModule *positionModule;
|
struct SmartPosition {
|
||||||
|
float distanceTraveled;
|
||||||
|
uint32_t distanceThreshold;
|
||||||
|
bool hasTraveledOverThreshold;
|
||||||
|
};
|
||||||
|
|
||||||
|
extern PositionModule *positionModule;
|
||||||
@@ -29,7 +29,7 @@ class RangeTestModuleRadio : public SinglePortModule
|
|||||||
uint32_t lastRxID = 0;
|
uint32_t lastRxID = 0;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
RangeTestModuleRadio() : SinglePortModule("RangeTestModuleRadio", meshtastic_PortNum_TEXT_MESSAGE_APP)
|
RangeTestModuleRadio() : SinglePortModule("RangeTestModuleRadio", meshtastic_PortNum_RANGE_TEST_APP)
|
||||||
{
|
{
|
||||||
loopbackOk = true; // Allow locally generated messages to loop back to the client
|
loopbackOk = true; // Allow locally generated messages to loop back to the client
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -44,9 +44,10 @@
|
|||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#if (defined(ARCH_ESP32) || defined(ARCH_NRF52)) && !defined(CONFIG_IDF_TARGET_ESP32S2) && !defined(CONFIG_IDF_TARGET_ESP32C3)
|
#if (defined(ARCH_ESP32) || defined(ARCH_NRF52) || defined(ARCH_RP2040)) && !defined(CONFIG_IDF_TARGET_ESP32S2) && \
|
||||||
|
!defined(CONFIG_IDF_TARGET_ESP32C3)
|
||||||
|
|
||||||
#define RX_BUFFER 128
|
#define RX_BUFFER 256
|
||||||
#define TIMEOUT 250
|
#define TIMEOUT 250
|
||||||
#define BAUD 38400
|
#define BAUD 38400
|
||||||
#define ACK 1
|
#define ACK 1
|
||||||
@@ -141,7 +142,12 @@ int32_t SerialModule::runOnce()
|
|||||||
}
|
}
|
||||||
#elif !defined(TTGO_T_ECHO)
|
#elif !defined(TTGO_T_ECHO)
|
||||||
if (moduleConfig.serial.rxd && moduleConfig.serial.txd) {
|
if (moduleConfig.serial.rxd && moduleConfig.serial.txd) {
|
||||||
|
#ifdef ARCH_RP2040
|
||||||
|
Serial2.setFIFOSize(RX_BUFFER);
|
||||||
|
Serial2.setPinout(moduleConfig.serial.txd, moduleConfig.serial.rxd);
|
||||||
|
#else
|
||||||
Serial2.setPins(moduleConfig.serial.rxd, moduleConfig.serial.txd);
|
Serial2.setPins(moduleConfig.serial.rxd, moduleConfig.serial.txd);
|
||||||
|
#endif
|
||||||
Serial2.begin(baud, SERIAL_8N1);
|
Serial2.begin(baud, SERIAL_8N1);
|
||||||
Serial2.setTimeout(moduleConfig.serial.timeout > 0 ? moduleConfig.serial.timeout : TIMEOUT);
|
Serial2.setTimeout(moduleConfig.serial.timeout > 0 ? moduleConfig.serial.timeout : TIMEOUT);
|
||||||
} else {
|
} else {
|
||||||
@@ -182,7 +188,7 @@ int32_t SerialModule::runOnce()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#ifndef TTGO_T_ECHO
|
#if !defined(TTGO_T_ECHO)
|
||||||
else {
|
else {
|
||||||
while (Serial2.available()) {
|
while (Serial2.available()) {
|
||||||
serialPayloadSize = Serial2.readBytes(serialBytes, meshtastic_Constants_DATA_PAYLOAD_LEN);
|
serialPayloadSize = Serial2.readBytes(serialBytes, meshtastic_Constants_DATA_PAYLOAD_LEN);
|
||||||
@@ -217,7 +223,7 @@ meshtastic_MeshPacket *SerialModuleRadio::allocReply()
|
|||||||
*/
|
*/
|
||||||
void SerialModuleRadio::sendPayload(NodeNum dest, bool wantReplies)
|
void SerialModuleRadio::sendPayload(NodeNum dest, bool wantReplies)
|
||||||
{
|
{
|
||||||
meshtastic_Channel *ch = (boundChannel != NULL) ? &channels.getByName(boundChannel) : NULL;
|
const meshtastic_Channel *ch = (boundChannel != NULL) ? &channels.getByName(boundChannel) : NULL;
|
||||||
meshtastic_MeshPacket *p = allocReply();
|
meshtastic_MeshPacket *p = allocReply();
|
||||||
p->to = dest;
|
p->to = dest;
|
||||||
if (ch != NULL) {
|
if (ch != NULL) {
|
||||||
|
|||||||
@@ -8,7 +8,8 @@
|
|||||||
#include <Arduino.h>
|
#include <Arduino.h>
|
||||||
#include <functional>
|
#include <functional>
|
||||||
|
|
||||||
#if (defined(ARCH_ESP32) || defined(ARCH_NRF52)) && !defined(CONFIG_IDF_TARGET_ESP32S2) && !defined(CONFIG_IDF_TARGET_ESP32C3)
|
#if (defined(ARCH_ESP32) || defined(ARCH_NRF52) || defined(ARCH_RP2040)) && !defined(CONFIG_IDF_TARGET_ESP32S2) && \
|
||||||
|
!defined(CONFIG_IDF_TARGET_ESP32C3)
|
||||||
|
|
||||||
class SerialModule : public StreamAPI, private concurrency::OSThread
|
class SerialModule : public StreamAPI, private concurrency::OSThread
|
||||||
{
|
{
|
||||||
@@ -74,4 +75,4 @@ class SerialModuleRadio : public MeshModule
|
|||||||
|
|
||||||
extern SerialModuleRadio *serialModuleRadio;
|
extern SerialModuleRadio *serialModuleRadio;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
@@ -8,6 +8,8 @@
|
|||||||
#include "configuration.h"
|
#include "configuration.h"
|
||||||
#include "main.h"
|
#include "main.h"
|
||||||
#include "power.h"
|
#include "power.h"
|
||||||
|
#include "sleep.h"
|
||||||
|
#include "target_specific.h"
|
||||||
#include <OLEDDisplay.h>
|
#include <OLEDDisplay.h>
|
||||||
#include <OLEDDisplayUi.h>
|
#include <OLEDDisplayUi.h>
|
||||||
|
|
||||||
@@ -51,6 +53,13 @@ SHT31Sensor sht31Sensor;
|
|||||||
|
|
||||||
int32_t EnvironmentTelemetryModule::runOnce()
|
int32_t EnvironmentTelemetryModule::runOnce()
|
||||||
{
|
{
|
||||||
|
if (sleepOnNextExecution == true) {
|
||||||
|
sleepOnNextExecution = false;
|
||||||
|
uint32_t nightyNightMs = getConfiguredOrDefaultMs(moduleConfig.telemetry.environment_update_interval);
|
||||||
|
LOG_DEBUG("Sleeping for %ims, then awaking to send metrics again.\n", nightyNightMs);
|
||||||
|
doDeepSleep(nightyNightMs, true);
|
||||||
|
}
|
||||||
|
|
||||||
uint32_t result = UINT32_MAX;
|
uint32_t result = UINT32_MAX;
|
||||||
/*
|
/*
|
||||||
Uncomment the preferences below if you want to use the module
|
Uncomment the preferences below if you want to use the module
|
||||||
@@ -266,6 +275,12 @@ bool EnvironmentTelemetryModule::sendTelemetry(NodeNum dest, bool phoneOnly)
|
|||||||
} else {
|
} else {
|
||||||
LOG_INFO("Sending packet to mesh\n");
|
LOG_INFO("Sending packet to mesh\n");
|
||||||
service.sendToMesh(p, RX_SRC_LOCAL, true);
|
service.sendToMesh(p, RX_SRC_LOCAL, true);
|
||||||
|
|
||||||
|
if (config.device.role == meshtastic_Config_DeviceConfig_Role_SENSOR && config.power.is_power_saving) {
|
||||||
|
LOG_DEBUG("Starting next execution in 5 seconds and then going to sleep.\n");
|
||||||
|
sleepOnNextExecution = true;
|
||||||
|
setIntervalFromNow(5000);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return valid;
|
return valid;
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ int32_t BME280Sensor::runOnce()
|
|||||||
if (!hasSensor()) {
|
if (!hasSensor()) {
|
||||||
return DEFAULT_SENSOR_MINIMUM_WAIT_TIME_BETWEEN_READS;
|
return DEFAULT_SENSOR_MINIMUM_WAIT_TIME_BETWEEN_READS;
|
||||||
}
|
}
|
||||||
status = bme280.begin(nodeTelemetrySensorsMap[sensorType]);
|
status = bme280.begin(nodeTelemetrySensorsMap[sensorType].first, nodeTelemetrySensorsMap[sensorType].second);
|
||||||
|
|
||||||
bme280.setSampling(Adafruit_BME280::MODE_FORCED,
|
bme280.setSampling(Adafruit_BME280::MODE_FORCED,
|
||||||
Adafruit_BME280::SAMPLING_X1, // Temp. oversampling
|
Adafruit_BME280::SAMPLING_X1, // Temp. oversampling
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
#include "TelemetrySensor.h"
|
#include "TelemetrySensor.h"
|
||||||
#include <Adafruit_BME280.h>
|
#include <Adafruit_BME280.h>
|
||||||
|
|
||||||
class BME280Sensor : virtual public TelemetrySensor
|
class BME280Sensor : public TelemetrySensor
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
Adafruit_BME280 bme280;
|
Adafruit_BME280 bme280;
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ int32_t BME680Sensor::runOnce()
|
|||||||
if (!hasSensor()) {
|
if (!hasSensor()) {
|
||||||
return DEFAULT_SENSOR_MINIMUM_WAIT_TIME_BETWEEN_READS;
|
return DEFAULT_SENSOR_MINIMUM_WAIT_TIME_BETWEEN_READS;
|
||||||
}
|
}
|
||||||
if (!bme680.begin(nodeTelemetrySensorsMap[sensorType], Wire))
|
if (!bme680.begin(nodeTelemetrySensorsMap[sensorType].first, *nodeTelemetrySensorsMap[sensorType].second))
|
||||||
checkStatus("begin");
|
checkStatus("begin");
|
||||||
|
|
||||||
if (bme680.status == BSEC_OK) {
|
if (bme680.status == BSEC_OK) {
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
|
|
||||||
#include "bme680_iaq_33v_3s_4d/bsec_iaq.h"
|
#include "bme680_iaq_33v_3s_4d/bsec_iaq.h"
|
||||||
|
|
||||||
class BME680Sensor : virtual public TelemetrySensor
|
class BME680Sensor : public TelemetrySensor
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
Bsec2 bme680;
|
Bsec2 bme680;
|
||||||
|
|||||||
@@ -13,7 +13,8 @@ int32_t BMP280Sensor::runOnce()
|
|||||||
if (!hasSensor()) {
|
if (!hasSensor()) {
|
||||||
return DEFAULT_SENSOR_MINIMUM_WAIT_TIME_BETWEEN_READS;
|
return DEFAULT_SENSOR_MINIMUM_WAIT_TIME_BETWEEN_READS;
|
||||||
}
|
}
|
||||||
status = bmp280.begin(nodeTelemetrySensorsMap[sensorType]);
|
bmp280 = Adafruit_BMP280(nodeTelemetrySensorsMap[sensorType].second);
|
||||||
|
status = bmp280.begin(nodeTelemetrySensorsMap[sensorType].first);
|
||||||
|
|
||||||
bmp280.setSampling(Adafruit_BMP280::MODE_FORCED,
|
bmp280.setSampling(Adafruit_BMP280::MODE_FORCED,
|
||||||
Adafruit_BMP280::SAMPLING_X1, // Temp. oversampling
|
Adafruit_BMP280::SAMPLING_X1, // Temp. oversampling
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
#include "TelemetrySensor.h"
|
#include "TelemetrySensor.h"
|
||||||
#include <Adafruit_BMP280.h>
|
#include <Adafruit_BMP280.h>
|
||||||
|
|
||||||
class BMP280Sensor : virtual public TelemetrySensor
|
class BMP280Sensor : public TelemetrySensor
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
Adafruit_BMP280 bmp280;
|
Adafruit_BMP280 bmp280;
|
||||||
|
|||||||
@@ -13,8 +13,8 @@ int32_t INA219Sensor::runOnce()
|
|||||||
return DEFAULT_SENSOR_MINIMUM_WAIT_TIME_BETWEEN_READS;
|
return DEFAULT_SENSOR_MINIMUM_WAIT_TIME_BETWEEN_READS;
|
||||||
}
|
}
|
||||||
if (!ina219.success()) {
|
if (!ina219.success()) {
|
||||||
ina219 = Adafruit_INA219(nodeTelemetrySensorsMap[sensorType]);
|
ina219 = Adafruit_INA219(nodeTelemetrySensorsMap[sensorType].first);
|
||||||
status = ina219.begin();
|
status = ina219.begin(nodeTelemetrySensorsMap[sensorType].second);
|
||||||
} else {
|
} else {
|
||||||
status = ina219.success();
|
status = ina219.success();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
#include "VoltageSensor.h"
|
#include "VoltageSensor.h"
|
||||||
#include <Adafruit_INA219.h>
|
#include <Adafruit_INA219.h>
|
||||||
|
|
||||||
class INA219Sensor : virtual public TelemetrySensor, VoltageSensor
|
class INA219Sensor : public TelemetrySensor, VoltageSensor
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
Adafruit_INA219 ina219;
|
Adafruit_INA219 ina219;
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user