Compare commits

...

161 Commits

Author SHA1 Message Date
Ben Meadors
f06c56a51b Removing release build type due to huge amount of flash utilization 2024-05-10 07:14:28 -05:00
Ben Meadors
ac22a503de Revert "Revert "Add Sensirion SHT4X sensors (#3792)" (#3845)" (#3850)
This reverts commit 5d9800b7c2.
2024-05-10 07:13:12 -05:00
Jonathan Bennett
676319a9ca Implement chunked SPI transfer for ch341 (#3847)
This seems to fix the ch341 quirk where large packets fail to send. As it can be problematic for other radios, we gate it behind "ch341_quirk" in the config.
2024-05-10 04:36:20 -05:00
Ben Meadors
5d9800b7c2 Revert "Add Sensirion SHT4X sensors (#3792)" (#3845)
This reverts commit 5371f134ba.
2024-05-09 21:25:36 -05:00
Jonathan Bennett
0c89aff0f6 Enable telemetry and power telemetry on the native target 2024-05-09 15:45:16 -05:00
todd-herbert
5e160b21c7 T-Echo screen and button performance (#3840)
* Make button timing configurable per variant

* Adjust button timing for T-Echo
Easier multi-clicks for features like "toggle backlight" (4x click)

* Fewer full-refreshes for T-Echo display
Disables ghost pixel tracking: T-Echo ghost pixels are fairly faint.
2024-05-09 08:14:58 -05:00
todd-herbert
75dc8cccec Button ISR runs thread asap (#3801) 2024-05-08 16:08:24 -05:00
Nicholas Baddorf
147de75a02 Added modifier key combination to allow keyboard shortcuts on t-deck (#3668)
* Updated kbI2cBase.cpp

Updated keyboard settings for t-deck to allow a modifier key to trigger 'tab', mute notifications, or quit. To trigger the modifier press the shift key and mic (0) button at the same time. Then press q (quit), m (mute), or t (tab).

* Update kbI2cBase.cpp

* fixed formatting issues in kbI2cBase.cpp

* Removed keyboard shortcut code that doesnt work

alt+t does not work on a t-deck so I removed it to avoid confusion.

* Updated kbI2cBase.cpp

Updated keyboard settings for t-deck to allow a modifier key to trigger 'tab', mute notifications, or quit. To trigger the modifier press the shift key and mic (0) button at the same time. Then press q (quit), m (mute), or t (tab).

* Update kbI2cBase.cpp

* fixed formatting issues in kbI2cBase.cpp

* Removed keyboard shortcut code that doesnt work

alt+t does not work on a t-deck so I removed it to avoid confusion.

* Changed modifier key to alt+c

* Added screen brightness functionality

Use modifier key with o(+) to increase brightness or i(-) to decrease.

Currently there are 4 levels of brightness, (L, ML, MH, H). I would like to add a popup message to tell you the brightness.

* Added checks to disable screen brightness changes on unsupported hardware

* Setting the brightness code to work on only applicable devices

* Added "function symbol" display to bottom right corner of screen. Now shows when mute is active or modifier key is pressed. Also fixed some other minor issues.

* commented out a log

* Reworked how modifier functions worked, added

I wasn’t  happy with my previous implementation, and I think it would have caused issues with other devices. This should work on all devices.

* Added back the function I moved causing issue with versions

* Fixed the version conflicts, everything seems to work fine now

---------

Co-authored-by: Ben Meadors <benmmeadors@gmail.com>
Co-authored-by: Thomas Göttgens <tgoettgens@gmail.com>
2024-05-08 07:37:50 -05:00
pr000t
5371f134ba Add Sensirion SHT4X sensors (#3792)
* add Sensirion SHT4X sensors

* Update platformio.ini

Fix lib version

* Delete src/mesh/generated/meshtastic/telemetry.pb.h

* Revert "Delete src/mesh/generated/meshtastic/telemetry.pb.h"

This reverts commit 8e5e6a9f6ff4e31ed32775741c03a855e663a5de.

* remove modification on generated file

* Update ScanI2CTwoWire.cpp

Fix copy/paste issue

---------

Co-authored-by: Thomas Göttgens <tgoettgens@gmail.com>
2024-05-08 07:02:53 -05:00
Max
8105c0440a New variants PROMICRO_DIY (#3788)
* New variants PROMICRO_DIY

* Renaming and cleanup

* Renaming - phase 2

* nrf52_promicro: Trunk formatting

---------

Co-authored-by: Ben Meadors <benmmeadors@gmail.com>
2024-05-08 06:53:13 -05:00
Ben Meadors
cbf20e4cee Default to new vendor ntp pool (#3819) 2024-05-07 07:57:30 -05:00
Jonathan Bennett
c009c0db1e Elimate non-text output for Portduino 2024-05-06 22:27:12 -05:00
Ben Meadors
2c99f11073 Revert "set USB_CDC_ON_BOOT, udate arduinoespressif32 to 2.0.15 (#3764)" (#3809)
This reverts commit 71400103b3.
2024-05-06 17:35:38 -05:00
Ben Meadors
0d57d29cbd Send fixed position to mesh after setting it (#3803) 2024-05-06 14:51:19 -05:00
Thomas Göttgens
353c7e07d1 Wiphone (#3793)
* add wiphone, still WIP

* (very preliminary) wiphone support

* undo config changes

* revert extensions.json

* eh?
2024-05-06 06:48:57 -05:00
HarukiToreda
77a66e1dce Fix for EnvironmentTelemetry Screen (#3785)
* Update EnvironmentTelemetry.cpp

* Update EnvironmentTelemetry.cpp

Corrected lines I deleted by mistake

* trunk fmt

---------

Co-authored-by: Thomas Göttgens <tgoettgens@gmail.com>
2024-05-06 06:47:34 -05:00
Thomas Göttgens
e98c3bf5d0 Merge pull request #3802 from meshtastic/create-pull-request/patch
Changes by create-pull-request action
2024-05-06 13:39:44 +02:00
caveman99
5e9d48d0d7 [create-pull-request] automated change 2024-05-06 11:37:03 +00:00
Thomas Göttgens
8e91f895a6 Merge pull request #3800 from oseiler2/fix/RCWL9620-MESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR
Add MESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR exclusion to RCWL9620
2024-05-06 12:06:17 +02:00
Oliver Seiler
b155a5b6dc rearrange includes 2024-05-06 12:15:49 +12:00
Oliver Seiler
2c30923e3e add MESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR exclusion to RCWL9620 2024-05-06 11:25:18 +12:00
Thomas Göttgens
0afe2d459f Merge pull request #3790 from meshtastic/create-pull-request/patch
Changes by create-pull-request action
2024-05-05 17:34:07 +02:00
caveman99
0b239e618d [create-pull-request] automated change 2024-05-05 15:32:28 +00:00
Thomas Göttgens
e9ebdfeff2 Merge pull request #3787 from GUVWAF/ccToPhoneErr
Check if packet is not released before CC to phone
2024-05-05 16:47:11 +02:00
GUVWAF
6fb7d7f2d7 Check if packet is not released before CC to phone 2024-05-05 13:49:50 +02:00
tuxphone
70712d859c Enable compiling with gccnoneeabi 12.3.1 for nRF52 targets, additional small fixes (#3778)
* Fix type of nodeNum

Type of nodeNum is NodeNum, not uint

* typo

fixed typo "resumeAdverising()"

* fix missing #include "time.h"

Missing include breaks compilation with gccnoneeabi 12.3.1 for nrf52 targets on windows hosts.

* change type uint to unsigned int

uint is not a standard type. Using uint breaks compilation with gccnoneeabi 12.3.1 for nRF52 targets on windows hosts.

* fix type of channel_num

Type of channel_num should be uint32_t (as this is the type of hash() and numChannels).

Using uint non-standard type uint breaks compilation with gccnoneeabi 12.3.1 for nRF52 targets on windows hosts.

* Update nrf52.ini

Default build type should be "release" as this is the default of platformio.

* Update GPS.cpp

uint to unsigned int
2024-05-03 15:49:22 -05:00
Thomas Göttgens
4d9081b3b1 Merge pull request #3678 from meshtastic/RCWL-9620
Support radar sensor RCWL-9620 on i2c
2024-05-03 20:37:27 +02:00
Thomas Göttgens
7643a1acb1 Merge branch 'RCWL-9620' of github.com:meshtastic/firmware into RCWL-9620 2024-05-03 20:05:24 +02:00
Thomas Göttgens
61216e579e there 2024-05-03 19:25:37 +02:00
Thomas Göttgens
e31bb2d513 Merge branch 'master' into RCWL-9620 2024-05-03 16:00:08 +02:00
Thomas Göttgens
a8c38c4580 Merge pull request #3775 from lewisxhe/master
Fix the infinite restart caused by unformatted t-echo fs file system
2024-05-03 15:59:07 +02:00
Thomas Göttgens
85e0372d26 darn you, trunk. foiled my cunning plan. 2024-05-03 15:58:16 +02:00
Thomas Göttgens
53bd9de9b8 Merge branch 'master' into RCWL-9620 2024-05-03 15:12:51 +02:00
Thomas Göttgens
13ad524538 make clang-format happy again. Also fix assorted variable shrouding and logic bleeps 2024-05-03 15:10:57 +02:00
Thomas Göttgens
5f90f45ac4 trunk fmt 2024-05-03 15:04:11 +02:00
lewisxhe
dc0593c5a7 Fix the infinite restart caused by unformatted t-echo fs file system 2024-05-03 15:04:11 +02:00
Thomas Göttgens
df3cceb108 Merge pull request #3776 from oseiler2/fix/MESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR
Fix #MESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR
2024-05-03 15:02:47 +02:00
Thomas Göttgens
827dcfca4a trunk fmt 2024-05-03 14:26:57 +02:00
Thomas Göttgens
9fb6148aff Merge branch 'master' into RCWL-9620 2024-05-03 12:28:08 +02:00
Oliver Seiler
6c1377aa39 fix case statement 2024-05-03 18:59:33 +12:00
Oliver Seiler
077ca5919a MESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR refinements 2024-05-03 14:15:13 +12:00
Oliver Seiler
668b716119 move QMC5883LCompass dependency to environmental_base 2024-05-03 14:15:13 +12:00
Oliver Seiler
eaa7e21bc7 exclude AccelerometerThread when MESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR is set 2024-05-03 14:15:13 +12:00
Oliver Seiler
be0e882be1 exclude sensors when MESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR set 2024-05-03 14:15:13 +12:00
github-actions[bot]
09080d76ad [create-pull-request] automated change (#3773)
Co-authored-by: thebentern <thebentern@users.noreply.github.com>
2024-05-02 20:46:22 -05:00
Ben Meadors
d490a332a7 Update version.properties 2024-05-02 19:11:35 -05:00
todd-herbert
5dfa4b837f Ensure LED is off when disabling heartbeat (#3772) 2024-05-02 19:11:13 -05:00
github-actions[bot]
9501f3bda9 [create-pull-request] automated change (#3771)
Co-authored-by: thebentern <thebentern@users.noreply.github.com>
2024-05-02 16:17:41 -05:00
Jonathan Bennett
b69a1cada9 Portduino bump to pick up minor fix (#3770) 2024-05-02 13:54:50 -05:00
Jonathan Bennett
06e7d2b845 Track actual GPIO values, not just the enum values (#3768)
* Track actual GPIO values, not just the enum values

* trunk
2024-05-02 13:39:28 -05:00
Oliver Seiler
71400103b3 set USB_CDC_ON_BOOT, udate arduinoespressif32 to 2.0.15 (#3764) 2024-05-02 13:39:18 -05:00
Thomas Göttgens
40e361e6d0 Merge pull request #3763 from lewisxhe/master
Fix t-echo gps failure
2024-05-02 15:13:43 +02:00
lewisxhe
d1b6f11429 Fix t-echo gps failure 2024-05-02 14:39:58 +02:00
todd-herbert
0527fb10ce Init. battery voltage from ADC reading, instead of fixed value (#3761) 2024-05-02 07:14:44 -05:00
Andrew Yong
5f929a8024 Publish fixed position updates and consider changes in only altitude as an updated point (#3758)
* AdminModule: Publish fixed position updates

Enabled GPS thread when fixed position is updated, to let the GPS thread run once and publish the new fixed position.

Signed-off-by: Andrew Yong <me@ndoo.sg>

* GPS: Consider changes in only altitude as an updated point

Signed-off-by: Andrew Yong <me@ndoo.sg>

---------

Signed-off-by: Andrew Yong <me@ndoo.sg>
2024-05-02 07:13:36 -05:00
Thomas Göttgens
4f54862d63 Merge pull request #3765 from meshtastic/twc-mesh-buildfix
fix building new TWC_mesh_v4 board
2024-05-02 13:30:49 +02:00
Thomas Göttgens
0f4ac94559 fix building new TWC_mesh_v4 board 2024-05-02 12:48:50 +02:00
Jonathan Bennett
45c1b46bd0 Move native to spi_host to indicate spidev for LovyanGFX 2024-05-01 13:21:23 -05:00
Jonathan Bennett
5095efc55f Pick up support for more than 64 GPIO lines under Portduino 2024-05-01 13:21:23 -05:00
Ben Meadors
ec92f7a5a3 Remove phone nodenum warning and empty else clause (#3756) 2024-05-01 08:27:43 -05:00
Ben Meadors
57da37cfbc Position module should enforce precision for phone originated position packets (#3752) 2024-05-01 08:05:26 -05:00
github-actions[bot]
3619ac87b8 [create-pull-request] automated change (#3754)
Co-authored-by: thebentern <thebentern@users.noreply.github.com>
2024-04-30 20:14:38 -05:00
GUVWAF
e51ee91c39 Optimization: stop relaying when reply is received (#3753) 2024-04-30 20:07:15 -05:00
todd-herbert
21311bbeda T-Echo touch button no longer requires "wake on tap or motion" (#3745) 2024-04-29 08:54:57 -05:00
Ben Meadors
472db5b237 Merge branch 'master' into RCWL-9620 2024-04-28 07:05:54 -05:00
Andrew Yong
18e69a0906 Update Heltec HT-C62 variant based on HT-DEV-ESP board (#3731)
* I2C is not defined in the reference schematic nor HT-DEV-ESP board, remove definition accordingly
* There is no screen in the the reference schematic nor HT-DEV-ESP board, change definition accordingly
* BUTTON_PIN has a 10 kOhm pullup resistor on HT-DEV-ESP, turning off redundant internal pullup should save some power
* LED is connected to GPIO2 on HT-DEV-ESP and is not inverted, update definition accordingly
* Remove redundant undef lines for LoRa pins

Above changes were built and flashed to my [HT-DEV-ESP_V2 board purchased from Heltec's Taobao store](https://item.taobao.com/item.htm?id=521590063077).

Signed-off-by: Andrew Yong <me@ndoo.sg>
2024-04-28 06:49:26 -05:00
David Ellefsen
93f77ea7d2 Update TinyGPSPlus version (#3727)
Co-authored-by: Ben Meadors <benmmeadors@gmail.com>
2024-04-27 19:50:15 -05:00
Mike
ee4c4ae6c9 Allow setting hopLimit for MQTT json sendtext and sendposition (#3735)
* Fix channel name extraction

* Allow setting hopLimit for mqtt sendtext and sendposition
2024-04-27 18:15:54 -05:00
Ben Meadors
6cc7dee95c Tradunkadunk 2024-04-27 11:12:52 -05:00
HarukiToreda
38c4d35a7b Add Notification on device screen following feature toggle (#3627)
* Update CannedMessageModule.h

* Update CannedMessageModule.cpp

* Update CannedMessageModule.cpp

hopefully this fixes the errors on Trunk

* Update CannedMessageModule.cpp

Changed "Ping Broadcasted" with "Telemetry Update Sent"

* tryfix: disable tempmessage again after 2 seconds

* fix 2s showtime

* Put spelling fix back

* Fix build

---------

Co-authored-by: Thomas Göttgens <tgoettgens@gmail.com>
Co-authored-by: Ben Meadors <benmmeadors@gmail.com>
2024-04-27 11:08:25 -05:00
Ben Meadors
e683d8f552 Rebrand "send network ping" to more honest "try send position" with better output (#3737) 2024-04-27 08:55:04 -05:00
jcyrio
e66aec8223 fix typo in comment (#3726) 2024-04-27 08:54:06 -05:00
Oliver Seiler
a06a01d25e fix #if HAS_TELEMETRY when set to 0 (#3733) 2024-04-27 06:35:44 -05:00
Andrew Yong
f8c3f43ea6 Fix xiao_ble variant build error due to undefined BATTERY_SENSE_RESOLUTION_BITS (#3732)
Define BATTERY_SENSE_RESOLUTION_BITS based on [amoroz's snippet on the Meshtastic forum](https://meshtastic.discourse.group/t/new-1w-diy-variant-xiao-nrf52840-ebyte-e22-900m30s/7904/10).

Fixes following build error:

```
src/Power.cpp: In member function 'virtual uint16_t AnalogBatteryLevel::getBattVoltage()':
src/Power.cpp:224:79: error: 'BATTERY_SENSE_RESOLUTION_BITS' was not declared in this scope
             scaled = operativeAdcMultiplier * ((1000 * AREF_VOLTAGE) / pow(2, BATTERY_SENSE_RESOLUTION_BITS)) * raw;
```

Signed-off-by: Andrew Yong <me@ndoo.sg>
2024-04-27 06:17:17 -05:00
todd-herbert
dfcabba0b2 Prevent overflow when calculating timezones (#3730) 2024-04-26 20:43:09 -05:00
Thomas Göttgens
827bacdfc8 Merge pull request #3723 from meshtastic/create-pull-request/patch
Changes by create-pull-request action
2024-04-25 23:46:43 +02:00
thebentern
5806a266d3 [create-pull-request] automated change 2024-04-25 20:19:54 +00:00
Jonathan Bennett
30fbcabf84 add conffiles to .deb packaging (#3722) 2024-04-25 14:23:38 -05:00
Arkadiusz Miśkiewicz
c14043f196 Split warning into two messages, so we know which one is the case. (#3710) 2024-04-25 06:47:39 -05:00
Jonathan Bennett
e3610a2eb1 Move to lovyangfx develop for Native 2024-04-24 13:17:43 -05:00
Oleksandr Podolchak
9baccc80d8 Add SX1268 modules support for linux-native (#3702)
* Add portduino Ebyte E22 XXXM30S/XXXM33S (sx1268) module support

* Add Ebyte E22 XXXM3XS module config

* Update comment for sx1268 module

* Address review comments

---------

Co-authored-by: Ben Meadors <benmmeadors@gmail.com>
2024-04-24 08:41:01 -05:00
Gareth Coleman
ac16ccf40c fix for unPhone hangs during boot without sd card present (#3709)
* work around sd card hang if not present

* comment out the define for HAS_SDCARD
2024-04-24 06:41:05 -05:00
Ben Meadors
1c0227f90c Merge branch 'master' into RCWL-9620 2024-04-23 14:19:08 -05:00
Jonathan Bennett
57d296e0db Add better support for the Adafruit PiTFT 2.8 for Native (#3704)
* Add better support for the Adafruit PiTFT 2.8 for Native

* native: Make touch i2c address configurable

* Bump portduino to pick up I2C features

---------

Co-authored-by: Ben Meadors <benmmeadors@gmail.com>
2024-04-23 14:18:51 -05:00
SCWhite
9c9d126f6b [BOARD] Add new variant: TWC_Mesh (#3705)
* add new variant: TWC_mesh_v4

* fix trunk format

* fix format under wsl

* change board to TWC_mesh_v4

* change platformio & variant.h properly

---------

Co-authored-by: Ben Meadors <benmmeadors@gmail.com>
2024-04-23 14:09:28 -05:00
github-actions[bot]
27f0e42d2f [create-pull-request] automated change (#3708)
Co-authored-by: thebentern <thebentern@users.noreply.github.com>
2024-04-23 13:32:33 -05:00
todd-herbert
4599534616 Terminate an async-full-refresh when caught by determineMode() instead of onNotify() (#3706) 2024-04-23 12:00:48 -05:00
Tom Fifield
7acaec8ef5 Add power limit for TW region (#3701)
The TW region had now power limit set, so defaulted to 16dBm.

The relevant regulation is section 5.8.1 of the Low-power Radio-frequency Devices Technical Regulations, which notes the limits of  0.5W (27dBM) indoor or coastal, 1.0W (30dBM) outdoor.

This patch updates the power limit to 27dbM, using the the lower limit specified in the regulations to be conservative.

Regulation references:
https://www.ncc.gov.tw/english/files/23070/102_5190_230703_1_doc_C.PDF (latest English version)
https://gazette.nat.gov.tw/egFront/e_detail.do?metaid=147283 (latest Chinese version, February 2024)
2024-04-23 07:11:22 -05:00
Nicholas Baddorf
d0e81b9151 Fixed node and channel selection for t-deck (#3695)
This enables the node and channel selection to be accessed by pressing the tab shortcut and then swiping between nodes or pressing tab again to change channels.

(To access the tab function look at my other pull request https://github.com/meshtastic/firmware/pull/3668)

Co-authored-by: Ben Meadors <benmmeadors@gmail.com>
2024-04-23 07:09:26 -05:00
Thomas Göttgens
c6e940af81 Merge branch 'master' into RCWL-9620 2024-04-23 14:04:22 +02:00
Thomas Göttgens
3302fbcc53 Merge pull request #3647 from garethhcoleman/RGBLED
Support for generic 4pin RGB LEDs (both CC and CA) and NeoPixels, also RGB LED and vibration notification support for unPhone
2024-04-23 13:57:23 +02:00
Gareth Coleman
ccbf635eef corrected a bit of overzealous tidying 2024-04-22 17:21:41 +01:00
Gareth Coleman
6669b22db3 tidied up, prob broke everything 2024-04-22 16:37:05 +01:00
Gareth Coleman
ec2b854ea2 oops missed the extern enabling little chap 2024-04-22 14:44:59 +01:00
Gareth Coleman
378a2d723e Merge branch 'RGBLED' of github.com:garethhcoleman/firmware into RGBLED 2024-04-22 14:43:07 +01:00
Gareth Coleman
5dd08e9533 added NeoPixel support using Adafruit library 2024-04-22 14:42:52 +01:00
Gareth Coleman
125add9792 Merge branch 'master' into RGBLED 2024-04-22 14:42:14 +01:00
Andrew Yong
250cf16bf8 Add ability to turn off heartbeat LED blinking (#3674)
* Add ability to turn off status LED blinking

Fixes #3635 and depends on [protobufs PR #485](https://github.com/meshtastic/protobufs/pull/485)

Signed-off-by: Andrew Yong <me@ndoo.sg>

* led_heartbeat_disabled

* trunk

---------

Signed-off-by: Andrew Yong <me@ndoo.sg>
Co-authored-by: Ben Meadors <benmmeadors@gmail.com>
2024-04-22 08:21:50 -05:00
Thomas Göttgens
8b5fad21b0 Merge pull request #3693 from titan098/updates_for_esp32s2_build
Updates for esp32s2 builds
2024-04-22 13:56:14 +02:00
David Ellefsen
30d4c3a945 Updates for esp32s2 build 2024-04-22 11:01:13 +02:00
Gareth Coleman
45fd5e25ac Merge branch 'master' into RGBLED 2024-04-22 09:15:44 +01:00
Thomas Göttgens
ac6a668362 Merge pull request #3697 from meshtastic/nrf52-signfix
fix signedness warnings of NRF52 toolchain
2024-04-22 10:13:38 +02:00
Thomas Göttgens
f47b40cf68 fix signedness warnings of NRF52 toolchain 2024-04-22 09:49:06 +02:00
quimnut
fd9461505f adjust adc for rak11310 devices (#3698) 2024-04-21 19:51:02 -05:00
Ben Meadors
84edaabfe9 Merge branch 'master' into RGBLED 2024-04-21 14:46:18 -05:00
Ben Meadors
048f0a1601 Merge branch 'master' into RCWL-9620 2024-04-21 14:41:49 -05:00
Nicholas Baddorf
4a48a3fb52 Fixed bug making t-deck reboot when muted (#3694) 2024-04-21 14:41:22 -05:00
Ben Meadors
39bbf0d352 Added more clear RTC handling and quality logging (#3691)
* Also refresh timestamp for "timeonly" fixed position nodes

* Added more clear RTC quality handling

* Fix clock drift from Phone GPS / NTP too
2024-04-21 14:40:47 -05:00
Ben Meadors
675d8fe089 Merge branch 'master' into RCWL-9620 2024-04-21 12:37:38 -05:00
Mictronics
0406be82d2 Use correct format specifier and fixed typo. (#3696)
* Fix LED pinout for T-Echo board marked v1.0, date 2021-6-28

* Merge PR #420

* Fixed double and missing Default class.

* Use correct format specifier and fixed typo.

---------

Co-authored-by: Ben Meadors <benmmeadors@gmail.com>
2024-04-21 12:36:37 -05:00
Ric In New Mexico
679e068e19 Missing break in INA3221 i2c scan (#3692)
* INA3221 Mis-identification fix

* Missing break in INA3221 i2c scan
2024-04-21 12:35:42 -05:00
Thomas Göttgens
952393ca0f Merge branch 'master' into RCWL-9620 2024-04-21 18:34:40 +02:00
Thomas Göttgens
a231cd2ad0 derp... 2024-04-21 16:35:41 +02:00
Ben Meadors
ac87c0065f Also refresh timestamp for "timeonly" fixed position nodes (#3689) 2024-04-21 08:45:36 -05:00
S5NC
9822a85274 Add board and variant definitions for EBYTE_ESP32-S3 (#2882)
* Create ESP32-S3-WROOM-1-N4.json

* Create pins_arduino.h

* Create platformio.ini

* Create variant.h

* Update mesh.pb.h

* Update architecture.h

* Update mesh.pb.h

* Update variant.h

* Update variant.h

Add example schematic

* Update architecture.h

* Revert update architecture.h

* Create variant.h

* Create pins_arduino.h

* Create platformio.ini

* Delete variants/E22-900M_S3 directory

* Update architecture.h

* Update variant.h

* Update platformio.ini

* Update variant.h

* Update variant.h

* Update architecture.h

* Update platformio.ini

* Update architecture.h

* Update ESP32-S3-WROOM-1-N4.json

* Update platformio.ini

* Update ESP32-S3-WROOM-1-N4.json

* Update variant.h

* Update variant.h

* Update variant.h

* Update variant.h

* Update pins_arduino.h

* Update architecture.h

* add SX1268 allow

* GPS

* Commit

* Whitespace

* Update variant.h

* Update variant.h

* trunk

---------

Co-authored-by: Ben Meadors <benmmeadors@gmail.com>
Co-authored-by: Thomas Göttgens <tgoettgens@gmail.com>
Co-authored-by: S5NC <>
2024-04-21 08:40:23 -05:00
Thomas Göttgens
a957065fe8 Merge branch 'master' into RCWL-9620 2024-04-21 14:47:29 +02:00
Ben Meadors
41f3557491 Refactor smart position to use throttle helper (#3671)
* Added one minute throttling to NodeDB

* Derp

* Refactor smart-position to use throttle
2024-04-21 07:42:36 -05:00
Thomas Göttgens
402b0d7e0b ditch that no-good m5 dependancy and do it ourself 2024-04-21 14:39:55 +02:00
Thomas Göttgens
13ebda6b2f Merge branch 'RCWL-9620' of github.com:meshtastic/firmware into RCWL-9620 2024-04-21 14:35:32 +02:00
Ben Meadors
1dd19cec6e Merge branch 'master' into RCWL-9620 2024-04-21 07:34:11 -05:00
Ben Meadors
df718ab294 Merge branch 'master' into RGBLED 2024-04-21 07:31:54 -05:00
todd-herbert
dfc43bae18 Fix crash on shutdown, if Bluetooth not enabled (#3686)
Previously attempted to call deinit method for a nullptr
2024-04-21 07:25:58 -05:00
todd-herbert
f6cfdfe881 (ESP-32S) Fix "critical error 3" after deep-sleep (#3685) 2024-04-21 07:25:12 -05:00
S5NC
820c5dc8c5 Update architecture.h (#3688) 2024-04-21 07:24:39 -05:00
Thomas Göttgens
1f9c295c9e Merge branch 'RCWL-9620' of github.com:meshtastic/firmware into RCWL-9620 2024-04-21 13:48:08 +02:00
Thomas Göttgens
5218aaafcf Change name 2024-04-21 11:41:52 +02:00
Thomas Göttgens
c480f0870c Support radar sensor RCWL-9620 on i2c 2024-04-21 11:41:52 +02:00
Gareth Coleman
9e4ef92e6d lets just define it without guards! 2024-04-21 09:16:50 +01:00
Gareth Coleman
cf65661c7c another silly error 2024-04-21 08:59:40 +01:00
Gareth Coleman
fb7a878d94 tweaked guards to allow various combinations of RGB leds 2024-04-21 08:24:51 +01:00
github-actions[bot]
e72792afc8 [create-pull-request] automated change (#3683)
Co-authored-by: thebentern <thebentern@users.noreply.github.com>
2024-04-20 15:58:42 -05:00
Ric In New Mexico
ec39e1136a INA3221 Mis-identification fix (#3681) 2024-04-20 15:58:21 -05:00
Thomas Göttgens
94e1f016e5 Change name 2024-04-20 20:49:57 +02:00
Thomas Göttgens
9170fe0580 Support radar sensor RCWL-9620 on i2c 2024-04-20 20:30:22 +02:00
Thomas Göttgens
ef9808cdd6 Merge pull request #3680 from meshtastic/create-pull-request/patch
Changes by create-pull-request action
2024-04-20 20:25:14 +02:00
caveman99
0972a8dccb [create-pull-request] automated change 2024-04-20 18:24:40 +00:00
github-actions[bot]
419eb13968 [create-pull-request] automated change (#3679)
Co-authored-by: thebentern <thebentern@users.noreply.github.com>
2024-04-20 09:56:55 -05:00
github-actions[bot]
e7828c4c64 [create-pull-request] automated change (#3676)
Co-authored-by: thebentern <thebentern@users.noreply.github.com>
2024-04-20 07:36:53 -05:00
Manuel
44aa248099 added new display parameters (#3670) 2024-04-19 19:27:13 -05:00
Gareth Coleman
e0513d4078 ahem, another minor edit to have another go at CI 2024-04-19 09:27:10 +01:00
Gareth Coleman
2100f3135e minor edit to have another go at CI 2024-04-19 09:25:38 +01:00
Gareth Coleman
2f36d4990e Merge branch 'master' into RGBLED 2024-04-19 08:12:13 +01:00
github-actions[bot]
65bde8538f [create-pull-request] automated change (#3663)
Co-authored-by: thebentern <thebentern@users.noreply.github.com>
2024-04-18 20:33:23 -05:00
Gareth Coleman
4a471ded79 Merge branch 'RGBLED' of github.com:garethhcoleman/firmware into RGBLED 2024-04-19 00:28:39 +01:00
Gareth Coleman
eea85d26ca oh god the bugs, they are everywhere, I feel so dirty... 2024-04-19 00:28:20 +01:00
Gareth Coleman
8ac308e73b Merge branch 'master' into RGBLED 2024-04-18 23:12:08 +01:00
Gareth Coleman
0ae7674982 I'm sure there's a cleverer way to do this, but I'm stupid and I didn't find it after a few minutes of searching stack overflow 2024-04-18 22:18:50 +01:00
Gareth Coleman
7d77b23eb6 support for generic 4 pin CC and CA RGB LEDS 2024-04-18 22:00:33 +01:00
Gareth Coleman
a149999cec tidy up first 2024-04-18 20:57:03 +01:00
Ben Meadors
78d915b454 Merge branch 'master' into RGBLED 2024-04-18 14:44:53 -05:00
Ben Meadors
2e13aeeacb Merge branch 'master' into RGBLED 2024-04-18 07:32:25 -05:00
Gareth Coleman
4b5549be8f added vibration notifications 2024-04-18 09:22:31 +01:00
Gareth Coleman
172d271b0b Merge branch 'master' into RGBLED 2024-04-18 07:11:49 +01:00
Ben Meadors
2cd877d2eb Merge branch 'master' into RGBLED 2024-04-16 20:37:02 -05:00
Gareth Coleman
afb4de21d9 yet another random edit, think i'm brushing the touchpad or perhaps my computer is possessed by the devil determined to make me look foolish 2024-04-16 22:37:57 +01:00
Gareth Coleman
86223d8806 Merge branch 'RGBLED' of github.com:garethhcoleman/firmware into RGBLED 2024-04-16 21:41:57 +01:00
Gareth Coleman
0632b96fcb just tiny tweak to minimise changes 2024-04-16 21:40:13 +01:00
Gareth Coleman
dcfc9c9f03 Merge branch 'meshtastic:master' into RGBLED 2024-04-16 21:29:12 +01:00
Gareth Coleman
8a3322fbcb rgb led support for unPhone 2024-04-16 21:28:12 +01:00
Gareth Coleman
385d7296fe strange extra edits removed wtf 2024-04-15 17:37:39 +01:00
Gareth Coleman
d1cd686644 Fixed XPT2046 syntax and using unPhone library to clean up main and TFTDisplay. 2024-04-15 17:24:08 +01:00
148 changed files with 2651 additions and 756 deletions

View File

@@ -45,6 +45,7 @@ jobs:
- name: build .debpkg
run: |
mkdir -p .debpkg/debian
mkdir -p .debpkg/usr/share/doc/meshtasticd/web
mkdir -p .debpkg/usr/sbin
mkdir -p .debpkg/etc/meshtasticd
@@ -55,6 +56,7 @@ jobs:
cp bin/config-dist.yaml .debpkg/etc/meshtasticd/config.yaml
chmod +x .debpkg/usr/sbin/meshtasticd
cp bin/meshtasticd.service .debpkg/usr/lib/systemd/system/meshtasticd.service
echo "etc/meshtasticd/config.yaml" > .debpkg/debian/conffiles
- uses: jiro4989/build-deb-action@v3
with:

View File

@@ -2,14 +2,17 @@
extends = esp32_base
build_src_filter =
${esp32_base.build_src_filter} -<nimble/> -<mesh/raspihttp>
${esp32_base.build_src_filter} - <libpax/> -<nimble/> -<mesh/raspihttp>
monitor_speed = 115200
build_flags =
${esp32_base.build_flags}
-DHAS_BLUETOOTH=0
-DMESHTASTIC_EXCLUDE_PAXCOUNTER
-DMESHTASTIC_EXCLUDE_BLUETOOTH
lib_ignore =
${esp32_base.lib_ignore}
NimBLE-Arduino
NimBLE-Arduino
libpax

View File

@@ -3,7 +3,7 @@
platform = platformio/nordicnrf52@^10.4.0
extends = arduino_base
build_type = debug ; I'm debugging with ICE a lot now
build_type = debug
build_flags =
${arduino_base.build_flags}
-DSERIAL_BUFFER_SIZE=1024

View File

@@ -1,6 +1,6 @@
; The Portduino based sim environment on top of any host OS, all hardware will be simulated
[portduino_base]
platform = https://github.com/meshtastic/platform-native.git#6fb39b6f94ece9c042141edb4afb91aca94dcaab
platform = https://github.com/meshtastic/platform-native.git#9881bf3721d610cccacf5ae8e3a07839cce75d63
framework = arduino
build_src_filter =
@@ -24,7 +24,7 @@ lib_deps =
${env.lib_deps}
${networking_base.lib_deps}
rweather/Crypto@^0.4.0
lovyan03/LovyanGFX@^1.1.12
https://github.com/lovyan03/LovyanGFX.git#5a39989aa2c9492572255b22f033843ec8900233
build_flags =
${arduino_base.build_flags}

View File

@@ -38,11 +38,22 @@ Lora:
# Busy: 20
# Reset: 18
# Module: sx1268 # SX1268-based modules, tested with Ebyte E22 400M33S
# CS: 21
# IRQ: 16
# Busy: 20
# Reset: 18
# TXen: 6
# RXen: 12
# DIO3_TCXO_VOLTAGE: true
# DIO3_TCXO_VOLTAGE: true # the Waveshare Core1262 and others are known to need this setting
# TXen: x # TX and RX enable pins
# RXen: x
# ch341_quirk: true # Uncomment this to use the chunked SPI transfer that seems to fix the ch341
### Set gpio chip to use in /dev/. Defaults to 0.
### Notably the Raspberry Pi 5 puts the GPIO header on gpiochip4
# gpiochip: 4
@@ -96,17 +107,21 @@ Display:
# Panel: ILI9341
# CS: 8
# DC: 25
# Backlight: 2
# Width: 320
# Height: 240
# Width: 240
# Height: 320
# Rotate: true
Touchscreen:
### Note, at least for now, the touchscreen must have a CS pin defined, even if you let Linux manage the CS switching.
# Module: STMPE610
# Module: STMPE610 # Option 1 for Adafruit PiTFT 2.8
# CS: 7
# IRQ: 24
# Module: FT5x06 # Option 2 for Adafruit PiTFT 2.8
# IRQ: 24
# I2CAddr: 0x38
# Module: XPT2046 # Waveshare 2.8inch
# CS: 7
# IRQ: 17

View File

@@ -0,0 +1,39 @@
{
"build": {
"arduino": {
"ldscript": "esp32s3_out.ld"
},
"core": "esp32",
"extra_flags": [
"-D ARDUINO_USB_CDC_ON_BOOT=0",
"-D ARDUINO_USB_MSC_ON_BOOT=0",
"-D ARDUINO_USB_DFU_ON_BOOT=0",
"-D ARDUINO_USB_MODE=0",
"-D ARDUINO_RUNNING_CORE=1",
"-D ARDUINO_EVENT_RUNNING_CORE=1"
],
"f_cpu": "240000000L",
"f_flash": "80000000L",
"flash_mode": "qio",
"hwids": [["0x303A", "0x1001"]],
"mcu": "esp32s3",
"variant": "ESP32-S3-WROOM-1-N4"
},
"connectivity": ["wifi"],
"debug": {
"default_tool": "esp-builtin",
"onboard_tools": ["esp-builtin"],
"openocd_target": "esp32s3.cfg"
},
"frameworks": ["arduino", "espidf"],
"name": "ESP32-S3-WROOM-1-N4 (4 MB Flash, No PSRAM)",
"upload": {
"flash_size": "4MB",
"maximum_ram_size": 524288,
"maximum_size": 4194304,
"require_upload_port": true,
"speed": 921600
},
"url": "https://www.espressif.com/sites/default/files/documentation/esp32-s3-wroom-1_wroom-1u_datasheet_en.pdf",
"vendor": "Espressif"
}

View File

@@ -0,0 +1,52 @@
{
"build": {
"arduino": {
"ldscript": "nrf52840_s140_v6.ld"
},
"core": "nRF5",
"cpu": "cortex-m4",
"extra_flags": "-DARDUINO_NRF52840_FEATHER -DNRF52840_XXAA",
"f_cpu": "64000000L",
"hwids": [
["0x239A", "0x00B3"],
["0x239A", "0x8029"],
["0x239A", "0x0029"],
["0x239A", "0x002A"],
["0x239A", "0x802A"]
],
"usb_product": "ProMicro compatible nRF52840",
"mcu": "nrf52840",
"variant": "promicro_diy",
"bsp": {
"name": "adafruit"
},
"softdevice": {
"sd_flags": "-DS140",
"sd_name": "s140",
"sd_version": "6.1.1",
"sd_fwid": "0x00B6"
},
"bootloader": {
"settings_addr": "0xFF000"
}
},
"connectivity": ["bluetooth"],
"debug": {
"jlink_device": "nRF52840_xxAA",
"svd_path": "nrf52840.svd"
},
"frameworks": ["arduino"],
"name": "ProMicro compatible nRF52840",
"upload": {
"maximum_ram_size": 248832,
"maximum_size": 815104,
"speed": 115200,
"protocol": "nrfutil",
"protocols": ["nrfutil", "jlink", "nrfjprog", "stlink"],
"use_1200bps_touch": true,
"require_upload_port": true,
"wait_for_upload_port": true
},
"url": "https://www.nologo.tech/product/otherboard/NRF52840.html",
"vendor": "Nologo"
}

34
boards/wiphone.json Normal file
View File

@@ -0,0 +1,34 @@
{
"build": {
"arduino": {
"ldscript": "esp32_out.ld",
"partitions": "default_16MB.csv"
},
"core": "esp32",
"extra_flags": [
"-DARDUINO_WIPHONE14",
"-DBOARD_HAS_PSRAM",
"-mfix-esp32-psram-cache-issue",
"-mfix-esp32-psram-cache-strategy=memw"
],
"f_cpu": "240000000L",
"f_flash": "40000000L",
"flash_mode": "dio",
"mcu": "esp32",
"variant": "wiphone",
"board": "WiPhone"
},
"connectivity": ["wifi", "bluetooth"],
"frameworks": ["arduino", "espidf"],
"name": "WIPhone Integrated 1.4",
"upload": {
"flash_size": "16MB",
"maximum_ram_size": 532480,
"maximum_size": 6553600,
"maximum_data_size": 4521984,
"require_upload_port": true,
"speed": 921600
},
"url": "https://www.wiphone.io/",
"vendor": "HackEDA"
}

View File

@@ -78,7 +78,7 @@ lib_deps =
https://github.com/meshtastic/esp8266-oled-ssd1306.git#ee628ee6c9588d4c56c9e3da35f0fc9448ad54a8 ; ESP8266_SSD1306
mathertel/OneButton@^2.5.0 ; OneButton library for non-blocking button debounce
https://github.com/meshtastic/arduino-fsm.git#7db3702bf0cfe97b783d6c72595e3f38e0b19159
https://github.com/meshtastic/TinyGPSPlus.git#964f75a72cccd6b53cd74e4add1f7a42c6f7344d
https://github.com/meshtastic/TinyGPSPlus.git#71a82db35f3b973440044c476d4bcdc673b104f4
https://github.com/meshtastic/ArduinoThread.git#1ae8778c85d0a2a729f989e0b1e7d7c4dc84eef0
nanopb/Nanopb@^0.4.7
erriez/ErriezCRC32@^1.0.1
@@ -96,7 +96,6 @@ check_flags =
framework = arduino
lib_deps =
${env.lib_deps}
mprograms/QMC5883LCompass@^1.2.0
end2endzone/NonBlockingRTTTL@^1.3.0
https://github.com/meshtastic/SparkFun_ATECCX08a_Arduino_Library.git#5cf62b36c6f30bc72a07bdb2c11fc9a22d1e31da
@@ -132,4 +131,6 @@ lib_deps =
adafruit/Adafruit MPU6050@^2.2.4
adafruit/Adafruit LIS3DH@^1.2.4
https://github.com/lewisxhe/SensorLib#27fd0f721e20cd09e1f81383f0ba58a54fe84a17
adafruit/Adafruit LSM6DS@^4.7.2
adafruit/Adafruit LSM6DS@^4.7.2
mprograms/QMC5883LCompass@^1.2.0
https://github.com/Sensirion/arduino-i2c-sht4x#1.1.0

View File

@@ -1,6 +1,9 @@
#include "configuration.h"
#if !MESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR
#include "PowerFSM.h"
#include "concurrency/OSThread.h"
#include "configuration.h"
#include "main.h"
#include "power.h"
@@ -172,4 +175,6 @@ class AccelerometerThread : public concurrency::OSThread
Adafruit_LSM6DS3TRC lsm;
};
} // namespace concurrency
} // namespace concurrency
#endif

View File

@@ -5,6 +5,16 @@
NCP5623 rgb;
#endif
#ifdef HAS_NEOPIXEL
#include <graphics/NeoPixel.h>
Adafruit_NeoPixel pixels(NEOPIXEL_COUNT, NEOPIXEL_DATA, NEOPIXEL_TYPE);
#endif
#ifdef UNPHONE
#include "unPhone.h"
extern unPhone unphone;
#endif
namespace concurrency
{
class AmbientLightingThread : public concurrency::OSThread
@@ -27,15 +37,31 @@ class AmbientLightingThread : public concurrency::OSThread
disable();
return;
}
#endif
#if defined(HAS_NCP5623) || defined(RGBLED_RED) || defined(HAS_NEOPIXEL) || defined(UNPHONE)
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");
#ifdef HAS_NCP5623
if (_type == ScanI2C::NCP5623) {
rgb.begin();
#endif
#ifdef RGBLED_RED
pinMode(RGBLED_RED, OUTPUT);
pinMode(RGBLED_GREEN, OUTPUT);
pinMode(RGBLED_BLUE, OUTPUT);
#endif
#ifdef HAS_NEOPIXEL
pixels.begin(); // Initialise the pixel(s)
pixels.clear(); // Set all pixel colors to 'off'
pixels.setBrightness(moduleConfig.ambient_lighting.current);
#endif
setLighting();
#endif
#ifdef HAS_NCP5623
}
#endif
}
@@ -43,16 +69,17 @@ class AmbientLightingThread : public concurrency::OSThread
protected:
int32_t runOnce() override
{
#if defined(HAS_NCP5623) || defined(RGBLED_RED) || defined(HAS_NEOPIXEL) || defined(UNPHONE)
#ifdef HAS_NCP5623
if (_type == ScanI2C::NCP5623 && moduleConfig.ambient_lighting.led_state) {
#endif
setLighting();
return 30000; // 30 seconds to reset from any animations that may have been running from Ext. Notification
} else {
return disable();
#ifdef HAS_NCP5623
}
#else
return disable();
#endif
#endif
return disable();
}
private:
@@ -65,9 +92,36 @@ class AmbientLightingThread : public concurrency::OSThread
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",
LOG_DEBUG("Initializing NCP5623 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
#ifdef HAS_NEOPIXEL
pixels.fill(pixels.Color(moduleConfig.ambient_lighting.red, moduleConfig.ambient_lighting.green,
moduleConfig.ambient_lighting.blue),
0, NEOPIXEL_COUNT);
pixels.show();
LOG_DEBUG("Initializing NeoPixel Ambient lighting w/ brightness(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
#ifdef RGBLED_CA
analogWrite(RGBLED_RED, 255 - moduleConfig.ambient_lighting.red);
analogWrite(RGBLED_GREEN, 255 - moduleConfig.ambient_lighting.green);
analogWrite(RGBLED_BLUE, 255 - moduleConfig.ambient_lighting.blue);
LOG_DEBUG("Initializing Ambient lighting RGB Common Anode w/ red=%d, green=%d, blue=%d\n",
moduleConfig.ambient_lighting.red, moduleConfig.ambient_lighting.green, moduleConfig.ambient_lighting.blue);
#elif defined(RGBLED_RED)
analogWrite(RGBLED_RED, moduleConfig.ambient_lighting.red);
analogWrite(RGBLED_GREEN, moduleConfig.ambient_lighting.green);
analogWrite(RGBLED_BLUE, moduleConfig.ambient_lighting.blue);
LOG_DEBUG("Initializing Ambient lighting RGB Common Cathode w/ red=%d, green=%d, blue=%d\n",
moduleConfig.ambient_lighting.red, moduleConfig.ambient_lighting.green, moduleConfig.ambient_lighting.blue);
#endif
#ifdef UNPHONE
unphone.rgb(moduleConfig.ambient_lighting.red, moduleConfig.ambient_lighting.green, moduleConfig.ambient_lighting.blue);
LOG_DEBUG("Initializing unPhone Ambient lighting w/ red=%d, green=%d, blue=%d\n", moduleConfig.ambient_lighting.red,
moduleConfig.ambient_lighting.green, moduleConfig.ambient_lighting.blue);
#endif
}
};

View File

@@ -52,8 +52,8 @@ ButtonThread::ButtonThread() : OSThread("Button")
#if defined(BUTTON_PIN) || defined(ARCH_PORTDUINO)
userButton.attachClick(userButtonPressed);
userButton.setClickMs(250);
userButton.setPressMs(c_longPressTime);
userButton.setClickMs(BUTTON_CLICK_MS);
userButton.setPressMs(BUTTON_LONGPRESS_MS);
userButton.setDebounceMs(1);
userButton.attachDoubleClick(userButtonDoublePressed);
userButton.attachMultiClick(userButtonMultiPressed, this); // Reference to instance: get click count from non-static OneButton
@@ -70,8 +70,8 @@ ButtonThread::ButtonThread() : OSThread("Button")
pinMode(BUTTON_PIN_ALT, INPUT_PULLUP_SENSE);
#endif
userButtonAlt.attachClick(userButtonPressed);
userButtonAlt.setClickMs(250);
userButtonAlt.setPressMs(c_longPressTime);
userButtonAlt.setClickMs(BUTTON_CLICK_MS);
userButtonAlt.setPressMs(BUTTON_LONGPRESS_MS);
userButtonAlt.setDebounceMs(1);
userButtonAlt.attachDoubleClick(userButtonDoublePressed);
userButtonAlt.attachLongPressStart(userButtonPressedLongStart);
@@ -80,7 +80,7 @@ ButtonThread::ButtonThread() : OSThread("Button")
#ifdef BUTTON_PIN_TOUCH
userButtonTouch = OneButton(BUTTON_PIN_TOUCH, true, true);
userButtonTouch.setPressMs(400);
userButtonTouch.setPressMs(BUTTON_TOUCH_MS);
userButtonTouch.attachLongPressStart(touchPressedLongStart); // Better handling with longpress than click?
#endif
@@ -136,9 +136,12 @@ int32_t ButtonThread::runOnce()
case BUTTON_EVENT_DOUBLE_PRESSED: {
LOG_BUTTON("Double press!\n");
service.refreshLocalMeshNode();
service.sendNetworkPing(NODENUM_BROADCAST, true);
auto sentPosition = service.trySendPosition(NODENUM_BROADCAST, true);
if (screen) {
screen->print("Sent ad-hoc ping\n");
if (sentPosition)
screen->print("Sent ad-hoc position\n");
else
screen->print("Sent ad-hoc nodeinfo\n");
screen->forceDisplay(true); // Force a new UI frame, then force an EInk update
}
break;
@@ -193,15 +196,13 @@ int32_t ButtonThread::runOnce()
#ifdef BUTTON_PIN_TOUCH
case BUTTON_EVENT_TOUCH_LONG_PRESSED: {
LOG_BUTTON("Touch press!\n");
if (config.display.wake_on_tap_or_motion) {
if (screen) {
// Wake if asleep
if (powerFSM.getState() == &stateDARK)
powerFSM.trigger(EVENT_PRESS);
if (screen) {
// Wake if asleep
if (powerFSM.getState() == &stateDARK)
powerFSM.trigger(EVENT_PRESS);
// Update display (legacy behaviour)
screen->forceDisplay();
}
// Update display (legacy behaviour)
screen->forceDisplay();
}
break;
}
@@ -213,6 +214,7 @@ int32_t ButtonThread::runOnce()
btnEvent = BUTTON_EVENT_NONE;
}
runASAP = false;
return 50;
}
@@ -233,6 +235,7 @@ void ButtonThread::attachButtonInterrupts()
BaseType_t higherWake = 0;
mainDelay.interruptFromISR(&higherWake);
ButtonThread::userButton.tick();
runASAP = true;
},
CHANGE);
#endif
@@ -279,6 +282,7 @@ void ButtonThread::wakeOnIrq(int irq, int mode)
[] {
BaseType_t higherWake = 0;
mainDelay.interruptFromISR(&higherWake);
runASAP = true;
},
FALLING);
}

View File

@@ -4,11 +4,22 @@
#include "concurrency/OSThread.h"
#include "configuration.h"
#ifndef BUTTON_CLICK_MS
#define BUTTON_CLICK_MS 250
#endif
#ifndef BUTTON_LONGPRESS_MS
#define BUTTON_LONGPRESS_MS 5000
#endif
#ifndef BUTTON_TOUCH_MS
#define BUTTON_TOCH_MS 400
#endif
class ButtonThread : public concurrency::OSThread
{
public:
static const uint32_t c_longPressTime = 5000; // shutdown after 5s
static const uint32_t c_holdOffTime = 30000; // hold off 30s after boot
static const uint32_t c_holdOffTime = 30000; // hold off 30s after boot
enum ButtonEventType {
BUTTON_EVENT_NONE,

View File

@@ -212,8 +212,23 @@ void fsInit()
LOG_ERROR("Filesystem mount Failed.\n");
// assert(0); This auto-formats the partition, so no need to fail here.
}
#ifdef ARCH_ESP32
#if defined(ARCH_ESP32)
LOG_DEBUG("Filesystem files (%d/%d Bytes):\n", FSCom.usedBytes(), FSCom.totalBytes());
#elif defined(ARCH_NRF52)
/*
* nRF52840 has a certain chance of automatic formatting failure.
* Try to create a file after initializing the file system. If the creation fails,
* it means that the file system is not working properly. Please format it manually again.
* */
Adafruit_LittleFS_Namespace::File file(FSCom);
const char *filename = "/meshtastic.txt";
if (!file.open(filename, FILE_O_WRITE)) {
LOG_DEBUG("Format ....");
FSCom.format();
FSCom.begin();
} else {
file.close();
}
#else
LOG_DEBUG("Filesystem files:\n");
#endif

View File

@@ -69,7 +69,7 @@ static const uint8_t ext_chrg_detect_value = EXT_CHRG_DETECT_VALUE;
#endif
#endif
#if HAS_TELEMETRY && !defined(ARCH_PORTDUINO)
#if HAS_TELEMETRY && !MESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR && !defined(ARCH_PORTDUINO)
INA260Sensor ina260Sensor;
INA219Sensor ina219Sensor;
INA3221Sensor ina3221Sensor;
@@ -184,7 +184,7 @@ class AnalogBatteryLevel : public HasBatteryLevel
virtual uint16_t getBattVoltage() override
{
#if defined(HAS_TELEMETRY) && !defined(ARCH_PORTDUINO) && !defined(HAS_PMU)
#if HAS_TELEMETRY && !defined(ARCH_PORTDUINO) && !defined(HAS_PMU) && !MESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR
if (hasINA()) {
LOG_DEBUG("Using INA on I2C addr 0x%x for device battery voltage\n", config.power.device_battery_ina_address);
return getINAVoltage();
@@ -223,7 +223,17 @@ class AnalogBatteryLevel : public HasBatteryLevel
raw = raw / BATTERY_SENSE_SAMPLES;
scaled = operativeAdcMultiplier * ((1000 * AREF_VOLTAGE) / pow(2, BATTERY_SENSE_RESOLUTION_BITS)) * raw;
#endif
last_read_value += (scaled - last_read_value) * 0.5; // Virtual LPF
if (!initial_read_done) {
// Flush the smoothing filter with an ADC reading, if the reading is plausibly correct
if (scaled > last_read_value)
last_read_value = scaled;
initial_read_done = true;
} else {
// Already initialized - filter this reading
last_read_value += (scaled - last_read_value) * 0.5; // Virtual LPF
}
// LOG_DEBUG("battery gpio %d raw val=%u scaled=%u filtered=%u\n", BATTERY_PIN, raw, (uint32_t)(scaled), (uint32_t)
// (last_read_value));
}
@@ -357,10 +367,12 @@ class AnalogBatteryLevel : public HasBatteryLevel
const float noBatVolt = (OCV[NUM_OCV_POINTS - 1] - 500) * NUM_CELLS;
// Start value from minimum voltage for the filter to not start from 0
// that could trigger some events.
// This value is over-written by the first ADC reading, it the voltage seems reasonable.
bool initial_read_done = false;
float last_read_value = (OCV[NUM_OCV_POINTS - 1] * NUM_CELLS);
uint32_t last_read_time_ms = 0;
#if defined(HAS_TELEMETRY) && !defined(ARCH_PORTDUINO)
#if HAS_TELEMETRY && !MESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR && !defined(ARCH_PORTDUINO)
uint16_t getINAVoltage()
{
if (nodeTelemetrySensorsMap[meshtastic_TelemetrySensorType_INA219].first == config.power.device_battery_ina_address) {

View File

@@ -2,6 +2,7 @@
#include "NodeDB.h"
#include "PowerFSM.h"
#include "configuration.h"
#include "time.h"
#ifdef RP2040_SLOW_CLOCK
#define Port Serial2
@@ -50,7 +51,9 @@ SerialConsole::SerialConsole() : StreamAPI(&Port), RedirectablePrint(&Port), con
}
}
#endif
#if !ARCH_PORTDUINO
emitRebooted();
#endif
}
int32_t SerialConsole::runOnce()

View File

@@ -126,8 +126,9 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#define SHTC3_ADDR 0x70
#define LPS22HB_ADDR 0x5C
#define LPS22HB_ADDR_ALT 0x5D
#define SHT31_ADDR 0x44
#define SHT31_4x_ADDR 0x44
#define PMSA0031_ADDR 0x12
#define RCWL9620_ADDR 0x57
// -----------------------------------------------------------------------------
// ACCELEROMETER

View File

@@ -29,6 +29,7 @@ class ScanI2C
INA3221,
MCP9808,
SHT31,
SHT4X,
SHTC3,
LPS22HB,
QMC6310,
@@ -41,9 +42,8 @@ class ScanI2C
BQ24295,
LSM6DS3,
TCA9555,
#ifdef HAS_NCP5623
RCWL9620,
NCP5623,
#endif
} DeviceType;
// typedef uint8_t DeviceAddress;

View File

@@ -271,8 +271,14 @@ void ScanI2CTwoWire::scanPort(I2CPort port)
}
break;
case INA3221_ADDR:
LOG_INFO("INA3221 sensor found at address 0x%x\n", (uint8_t)addr.address);
type = INA3221;
registerValue = getRegisterValue(ScanI2CTwoWire::RegisterLocation(addr, 0xFE), 2);
LOG_DEBUG("Register MFG_UID: 0x%x\n", registerValue);
if (registerValue == 0x5449) {
LOG_INFO("INA3221 sensor found at address 0x%x\n", (uint8_t)addr.address);
type = INA3221;
} else { // Unknown device
LOG_INFO("No INA3221 found at address 0x%x\n", (uint8_t)addr.address);
}
break;
case MCP9808_ADDR:
registerValue = getRegisterValue(ScanI2CTwoWire::RegisterLocation(addr, 0x07), 2);
@@ -286,8 +292,20 @@ void ScanI2CTwoWire::scanPort(I2CPort port)
break;
SCAN_SIMPLE_CASE(SHT31_ADDR, SHT31, "SHT31 sensor found\n")
case SHT31_4x_ADDR:
registerValue = getRegisterValue(ScanI2CTwoWire::RegisterLocation(addr, 0x89), 2);
if (registerValue == 0x11a2) {
type = SHT4X;
LOG_INFO("SHT4X sensor found\n");
} else {
type = SHT31;
LOG_INFO("SHT31 sensor found\n");
}
break;
SCAN_SIMPLE_CASE(SHTC3_ADDR, SHTC3, "SHTC3 sensor found\n")
SCAN_SIMPLE_CASE(RCWL9620_ADDR, RCWL9620, "RCWL9620 sensor found\n")
case LPS22HB_ADDR_ALT:
SCAN_SIMPLE_CASE(LPS22HB_ADDR, LPS22HB, "LPS22HB sensor found\n")
@@ -350,4 +368,4 @@ TwoWire *ScanI2CTwoWire::fetchI2CBus(ScanI2C::DeviceAddress address) const
size_t ScanI2CTwoWire::countDevices() const
{
return foundDevices.size();
}
}

View File

@@ -62,10 +62,10 @@ void GPS::CASChecksum(uint8_t *message, size_t length)
// Iterate over the payload as a series of uint32_t's and
// accumulate the cksum
uint32_t *payload = (uint32_t *)(message + 6);
uint32_t const *payload = (uint32_t *)(message + 6);
for (size_t i = 0; i < (length - 10) / 4; i++) {
uint32_t p = payload[i];
cksum += p;
uint32_t pl = payload[i];
cksum += pl;
}
// Place the checksum values in the message
@@ -452,7 +452,7 @@ bool GPS::setup()
// Set the NEMA output messages
// Ask for only RMC and GGA
uint8_t fields[] = {CAS_NEMA_RMC, CAS_NEMA_GGA};
for (int i = 0; i < sizeof(fields); i++) {
for (unsigned int i = 0; i < sizeof(fields); i++) {
// Construct a CAS-CFG-MSG packet
uint8_t cas_cfg_msg_packet[] = {0x4e, fields[i], 0x01, 0x00};
msglen = makeCASPacket(0x06, 0x01, sizeof(cas_cfg_msg_packet), cas_cfg_msg_packet);
@@ -1467,7 +1467,7 @@ bool GPS::lookForLocation()
#endif // GPS_EXTRAVERBOSE
// Is this a new point or are we re-reading the previous one?
if (!reader.location.isUpdated())
if (!reader.location.isUpdated() && !reader.altitude.isUpdated())
return false;
// check if a complete GPS solution set is available for reading
@@ -1584,7 +1584,7 @@ bool GPS::hasFlow()
bool GPS::whileIdle()
{
int charsInBuf = 0;
unsigned int charsInBuf = 0;
bool isValid = false;
if (!isAwake) {
clearBuffer();

View File

@@ -104,13 +104,15 @@ bool perhapsSetRTC(RTCQuality q, const struct timeval *tv)
bool shouldSet;
if (q > currentQuality) {
shouldSet = true;
LOG_DEBUG("Upgrading time to quality %d\n", q);
} 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
LOG_DEBUG("Upgrading time to quality %s\n", RtcName(q));
} else if (q >= RTCQualityNTP && (now - lastSetMsec) > (12 * 60 * 60 * 1000UL)) {
// Every 12 hrs we will slam in a new GPS or Phone GPS / NTP time, to correct for local RTC clock drift
shouldSet = true;
LOG_DEBUG("Reapplying external time to correct clock drift %ld secs\n", tv->tv_sec);
} else
} else {
shouldSet = false;
LOG_DEBUG("Current RTC quality: %s. Ignoring time of RTC quality of %s\n", RtcName(currentQuality), RtcName(q));
}
if (shouldSet) {
currentQuality = q;
@@ -162,6 +164,24 @@ bool perhapsSetRTC(RTCQuality q, const struct timeval *tv)
}
}
const char *RtcName(RTCQuality quality)
{
switch (quality) {
case RTCQualityNone:
return "None";
case RTCQualityDevice:
return "Device";
case RTCQualityFromNet:
return "Net";
case RTCQualityNTP:
return "NTP";
case RTCQualityGPS:
return "GPS";
default:
return "Unknown";
}
}
/**
* Sets the RTC time if the provided time is of higher quality than the current RTC time.
*
@@ -203,7 +223,7 @@ int32_t getTZOffset()
now = time(NULL);
gmt = gmtime(&now);
gmt->tm_isdst = -1;
return (int16_t)difftime(now, mktime(gmt));
return (int32_t)difftime(now, mktime(gmt));
}
/**

View File

@@ -28,6 +28,9 @@ RTCQuality getRTCQuality();
bool perhapsSetRTC(RTCQuality q, const struct timeval *tv);
bool perhapsSetRTC(RTCQuality q, struct tm &t);
/// Return a string name for the quality
const char *RtcName(RTCQuality quality);
/// Return time since 1970 in secs. While quality is RTCQualityNone we will be returning time based at zero
uint32_t getTime(bool local = false);

View File

@@ -534,6 +534,10 @@ void EInkDynamicDisplay::checkBusyAsyncRefresh()
return;
}
// Async refresh appears to have stopped, but wasn't caught by onNotify()
else
pollAsyncRefresh(); // Check (and terminate) the async refresh manually
}
// Hold control while an async refresh runs

4
src/graphics/NeoPixel.h Normal file
View File

@@ -0,0 +1,4 @@
#ifdef HAS_NEOPIXEL
#include <Adafruit_NeoPixel.h>
extern Adafruit_NeoPixel pixels;
#endif

View File

@@ -94,6 +94,11 @@ std::vector<MeshModule *> moduleFrames;
// Stores the last 4 of our hardware ID, to make finding the device for pairing easier
static char ourId[5];
// vector where symbols (string) are displayed in bottom corner of display.
std::vector<std::string> functionSymbals;
// string displayed in bottom right corner of display. Created from elements in functionSymbals vector
std::string functionSymbalString = "";
#if HAS_GPS
// GeoCoord object for the screen
GeoCoord geoCoord;
@@ -260,6 +265,18 @@ static void drawWelcomeScreen(OLEDDisplay *display, OLEDDisplayUiState *state, i
#endif
}
// draw overlay in bottom right corner of screen to show when notifications are muted or modifier key is active
static void drawFunctionOverlay(OLEDDisplay *display, OLEDDisplayUiState *state)
{
// LOG_DEBUG("Drawing function overlay\n");
if (functionSymbals.begin() != functionSymbals.end()) {
char buf[64];
display->setFont(FONT_SMALL);
snprintf(buf, sizeof(buf), "%s", functionSymbalString.c_str());
display->drawString(SCREEN_WIDTH - display->getStringWidth(buf), SCREEN_HEIGHT - FONT_HEIGHT_SMALL, buf);
}
}
#ifdef USE_EINK
/// Used on eink displays while in deep sleep
static void drawDeepSleepScreen(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y)
@@ -1023,7 +1040,14 @@ void Screen::handleSetOn(bool on, FrameCallback einkScreensaver)
#if !ARCH_PORTDUINO
dispdev->displayOn();
#endif
#if defined(ST7789_CS) && \
!defined(M5STACK) // set display brightness when turning on screens. Just moved function from TFTDisplay to here.
static_cast<TFTDisplay *>(dispdev)->setDisplayBrightness(brightness);
#endif
dispdev->displayOn();
enabled = true;
setInterval(0); // Draw ASAP
runASAP = true;
@@ -1490,6 +1514,11 @@ void Screen::setFrames()
ui->setFrames(normalFrames, numframes);
ui->enableAllIndicators();
// Add function overlay here. This can show when notifications muted, modifier key is active etc
static OverlayCallback functionOverlay[] = {drawFunctionOverlay};
static const int functionOverlayCount = sizeof(functionOverlay) / sizeof(functionOverlay[0]);
ui->setOverlays(functionOverlay, functionOverlayCount);
prevFrame = -1; // Force drawNodeInfo to pick a new node (because our list
// just changed)
@@ -1573,9 +1602,55 @@ void Screen::blink()
delay(50);
count = count - 1;
}
// The dispdev->setBrightness does not work for t-deck display, it seems to run the setBrightness function in OLEDDisplay.
dispdev->setBrightness(brightness);
}
void Screen::increaseBrightness()
{
brightness = ((brightness + 62) > 254) ? brightness : (brightness + 62);
#if defined(ST7789_CS)
// run the setDisplayBrightness function. This works on t-decks
static_cast<TFTDisplay *>(dispdev)->setDisplayBrightness(brightness);
#endif
/* TO DO: add little popup in center of screen saying what brightness level it is set to*/
}
void Screen::decreaseBrightness()
{
brightness = (brightness < 70) ? brightness : (brightness - 62);
#if defined(ST7789_CS)
static_cast<TFTDisplay *>(dispdev)->setDisplayBrightness(brightness);
#endif
/* TO DO: add little popup in center of screen saying what brightness level it is set to*/
}
void Screen::setFunctionSymbal(std::string sym)
{
if (std::find(functionSymbals.begin(), functionSymbals.end(), sym) == functionSymbals.end()) {
functionSymbals.push_back(sym);
functionSymbalString = "";
for (auto symbol : functionSymbals) {
functionSymbalString = symbol + " " + functionSymbalString;
}
setFastFramerate();
}
}
void Screen::removeFunctionSymbal(std::string sym)
{
functionSymbals.erase(std::remove(functionSymbals.begin(), functionSymbals.end(), sym), functionSymbals.end());
functionSymbalString = "";
for (auto symbol : functionSymbals) {
functionSymbalString = symbol + " " + functionSymbalString;
}
setFastFramerate();
}
std::string Screen::drawTimeDelta(uint32_t days, uint32_t hours, uint32_t minutes, uint32_t seconds)
{
std::string uptime;
@@ -1998,4 +2073,4 @@ int Screen::handleInputEvent(const InputEvent *event)
} // namespace graphics
#else
graphics::Screen::Screen(ScanI2C::DeviceAddress, meshtastic_Config_DisplayConfig_OledType, OLEDDISPLAY_GEOMETRY) {}
#endif // HAS_SCREEN
#endif // HAS_SCREEN

View File

@@ -166,9 +166,6 @@ class Screen : public concurrency::OSThread
void showPrevFrame() { enqueueCmd(ScreenCmd{.cmd = Cmd::SHOW_PREV_FRAME}); }
void showNextFrame() { enqueueCmd(ScreenCmd{.cmd = Cmd::SHOW_NEXT_FRAME}); }
// Implementation to Adjust Brightness
uint8_t brightness = BRIGHTNESS_DEFAULT;
/// Starts showing the Bluetooth PIN screen.
//
// Switches over to a static frame showing the Bluetooth pairing screen
@@ -202,6 +199,13 @@ class Screen : public concurrency::OSThread
enqueueCmd(cmd);
}
// functions for display brightness
void increaseBrightness();
void decreaseBrightness();
void setFunctionSymbal(std::string sym);
void removeFunctionSymbal(std::string sym);
/// Stops showing the bluetooth PIN screen.
void stopBluetoothPinScreen() { enqueueCmd(ScreenCmd{.cmd = Cmd::STOP_BLUETOOTH_PIN_SCREEN}); }
@@ -395,6 +399,9 @@ class Screen : public concurrency::OSThread
// Bluetooth PIN screen)
bool showingNormalScreen = false;
// Implementation to Adjust Brightness
uint8_t brightness = BRIGHTNESS_DEFAULT; // H = 254, MH = 192, ML = 130 L = 103
/// Holds state for debug information
DebugInfo debugInfo;

View File

@@ -1,7 +1,6 @@
#include "configuration.h"
#include "main.h"
#if ARCH_PORTDUINO
#include "mesh_bus_spi.h"
#include "platform/portduino/PortduinoGlue.h"
#endif
@@ -9,6 +8,12 @@
#define TFT_BACKLIGHT_ON HIGH
#endif
#ifdef GPIO_EXTENDER
#include <SparkFunSX1509.h>
#include <Wire.h>
extern SX1509 gpioExtender;
#endif
#ifndef TFT_MESH
#define TFT_MESH COLOR565(0x67, 0xEA, 0x94)
#endif
@@ -340,7 +345,7 @@ static TFT_eSPI *tft = nullptr; // Invoke library, pins defined in User_Setup.h
class LGFX : public lgfx::LGFX_Device
{
lgfx::Panel_LCD *_panel_instance;
lgfx::Mesh_Bus_SPI _bus_instance;
lgfx::Bus_SPI _bus_instance;
lgfx::ITouch *_touch_instance;
@@ -357,7 +362,7 @@ class LGFX : public lgfx::LGFX_Device
_panel_instance = new lgfx::Panel_ILI9341;
auto buscfg = _bus_instance.config();
buscfg.spi_mode = 0;
_bus_instance.spi_device(DisplaySPI, settingsStrings[displayspidev]);
buscfg.spi_host = settingsMap[displayspidev];
buscfg.pin_dc = settingsMap[displayDC]; // Set SPI DC pin number (-1 = disable)
@@ -383,6 +388,8 @@ class LGFX : public lgfx::LGFX_Device
_touch_instance = new lgfx::Touch_XPT2046;
} else if (settingsMap[touchscreenModule] == stmpe610) {
_touch_instance = new lgfx::Touch_STMPE610;
} else if (settingsMap[touchscreenModule] == ft5x06) {
_touch_instance = new lgfx::Touch_FT5x06;
}
auto touch_cfg = _touch_instance->config();
@@ -394,6 +401,11 @@ class LGFX : public lgfx::LGFX_Device
touch_cfg.pin_int = settingsMap[touchscreenIRQ];
touch_cfg.bus_shared = true;
touch_cfg.offset_rotation = 1;
if (settingsMap[touchscreenI2CAddr] != -1) {
touch_cfg.i2c_addr = settingsMap[touchscreenI2CAddr];
} else {
touch_cfg.spi_host = settingsMap[touchscreenspidev];
}
_touch_instance->config(touch_cfg);
_panel_instance->setTouch(_touch_instance);
@@ -584,7 +596,7 @@ void TFTDisplay::sendCommand(uint8_t com)
unphone.backlight(true); // using unPhone library
#endif
#ifdef RAK14014
#elif !defined(M5STACK)
#elif !defined(M5STACK) && !defined(ST7789_CS) // T-Deck gets brightness set in Screen.cpp in the handleSetOn function
tft->setBrightness(172);
#endif
break;
@@ -628,6 +640,12 @@ void TFTDisplay::sendCommand(uint8_t com)
// Drop all other commands to device (we just update the buffer)
}
void TFTDisplay::setDisplayBrightness(uint8_t _brightness)
{
tft->setBrightness(_brightness);
LOG_DEBUG("Brightness is set to value: %i \n", _brightness);
}
void TFTDisplay::flipScreenVertically()
{
#if defined(T_WATCH_S3)
@@ -711,4 +729,4 @@ bool TFTDisplay::connect()
return true;
}
#endif
#endif

View File

@@ -30,6 +30,9 @@ class TFTDisplay : public OLEDDisplay
static bool hasTouch(void);
static bool getTouch(int16_t *x, int16_t *y);
// Functions for changing display brightness
void setDisplayBrightness(uint8_t);
/**
* shim to make the abstraction happy
*

View File

@@ -1,188 +0,0 @@
// This code has been copied from LovyanGFX to make the SPI device selectable for touchscreens.
// Ideally this could eventually be an inherited class from BUS_SPI,
// but currently too many internal objects are set private.
#include "configuration.h"
#if ARCH_PORTDUINO
#include "lgfx/v1/misc/pixelcopy.hpp"
#include "main.h"
#include "mesh_bus_spi.h"
#include <Arduino.h>
#include <SPI.h>
namespace lgfx
{
inline namespace v1
{
//----------------------------------------------------------------------------
void Mesh_Bus_SPI::config(const config_t &config)
{
_cfg = config;
if (_cfg.pin_dc >= 0) {
pinMode(_cfg.pin_dc, pin_mode_t::output);
gpio_hi(_cfg.pin_dc);
}
}
bool Mesh_Bus_SPI::init(void)
{
dc_h();
pinMode(_cfg.pin_dc, pin_mode_t::output);
if (SPIName != "")
PrivateSPI->begin(SPIName.c_str());
else
PrivateSPI->begin();
return true;
}
void Mesh_Bus_SPI::release(void)
{
PrivateSPI->end();
}
void Mesh_Bus_SPI::spi_device(HardwareSPI *newSPI, std::string newSPIName)
{
PrivateSPI = newSPI;
SPIName = newSPIName;
}
void Mesh_Bus_SPI::beginTransaction(void)
{
dc_h();
SPISettings setting(_cfg.freq_write, MSBFIRST, _cfg.spi_mode);
PrivateSPI->beginTransaction(setting);
}
void Mesh_Bus_SPI::endTransaction(void)
{
PrivateSPI->endTransaction();
dc_h();
}
void Mesh_Bus_SPI::beginRead(void)
{
PrivateSPI->endTransaction();
// SPISettings setting(_cfg.freq_read, BitOrder::MSBFIRST, _cfg.spi_mode, false);
SPISettings setting(_cfg.freq_read, MSBFIRST, _cfg.spi_mode);
PrivateSPI->beginTransaction(setting);
}
void Mesh_Bus_SPI::endRead(void)
{
PrivateSPI->endTransaction();
beginTransaction();
}
void Mesh_Bus_SPI::wait(void) {}
bool Mesh_Bus_SPI::busy(void) const
{
return false;
}
bool Mesh_Bus_SPI::writeCommand(uint32_t data, uint_fast8_t bit_length)
{
dc_l();
PrivateSPI->transfer((uint8_t *)&data, bit_length >> 3);
dc_h();
return true;
}
void Mesh_Bus_SPI::writeData(uint32_t data, uint_fast8_t bit_length)
{
PrivateSPI->transfer((uint8_t *)&data, bit_length >> 3);
}
void Mesh_Bus_SPI::writeDataRepeat(uint32_t data, uint_fast8_t bit_length, uint32_t length)
{
const uint8_t dst_bytes = bit_length >> 3;
uint32_t limit = (dst_bytes == 3) ? 12 : 16;
auto buf = _flip_buffer.getBuffer(512);
size_t fillpos = 0;
reinterpret_cast<uint32_t *>(buf)[0] = data;
fillpos += dst_bytes;
uint32_t len;
do {
len = ((length - 1) % limit) + 1;
if (limit <= 64)
limit <<= 1;
while (fillpos < len * dst_bytes) {
memcpy(&buf[fillpos], buf, fillpos);
fillpos += fillpos;
}
PrivateSPI->transfer(buf, len * dst_bytes);
} while (length -= len);
}
void Mesh_Bus_SPI::writePixels(pixelcopy_t *param, uint32_t length)
{
const uint8_t dst_bytes = param->dst_bits >> 3;
uint32_t limit = (dst_bytes == 3) ? 12 : 16;
uint32_t len;
do {
len = ((length - 1) % limit) + 1;
if (limit <= 32)
limit <<= 1;
auto buf = _flip_buffer.getBuffer(len * dst_bytes);
param->fp_copy(buf, 0, len, param);
PrivateSPI->transfer(buf, len * dst_bytes);
} while (length -= len);
}
void Mesh_Bus_SPI::writeBytes(const uint8_t *data, uint32_t length, bool dc, bool use_dma)
{
if (dc)
dc_h();
else
dc_l();
PrivateSPI->transfer(const_cast<uint8_t *>(data), length);
if (!dc)
dc_h();
}
uint32_t Mesh_Bus_SPI::readData(uint_fast8_t bit_length)
{
uint32_t res = 0;
bit_length >>= 3;
if (!bit_length)
return res;
int idx = 0;
do {
res |= PrivateSPI->transfer(0) << idx;
idx += 8;
} while (--bit_length);
return res;
}
bool Mesh_Bus_SPI::readBytes(uint8_t *dst, uint32_t length, bool use_dma)
{
do {
dst[0] = PrivateSPI->transfer(0);
++dst;
} while (--length);
return true;
}
void Mesh_Bus_SPI::readPixels(void *dst, pixelcopy_t *param, uint32_t length)
{
uint32_t bytes = param->src_bits >> 3;
uint32_t dstindex = 0;
uint32_t len = 4;
uint8_t buf[24];
param->src_data = buf;
do {
if (len > length)
len = length;
readBytes((uint8_t *)buf, len * bytes, true);
param->src_x = 0;
dstindex = param->fp_copy(dst, dstindex, dstindex + len, param);
length -= len;
} while (length);
}
} // namespace v1
} // namespace lgfx
#endif

View File

@@ -1,100 +0,0 @@
#if ARCH_PORTDUINO
/*----------------------------------------------------------------------------/
Lovyan GFX - Graphics library for embedded devices.
Original Source:
https://github.com/lovyan03/LovyanGFX/
Licence:
[FreeBSD](https://github.com/lovyan03/LovyanGFX/blob/master/license.txt)
Author:
[lovyan03](https://twitter.com/lovyan03)
Contributors:
[ciniml](https://github.com/ciniml)
[mongonta0716](https://github.com/mongonta0716)
[tobozo](https://github.com/tobozo)
/----------------------------------------------------------------------------*/
#pragma once
#include <stdint.h>
#include "lgfx/v1/Bus.hpp"
#include "lgfx/v1/platforms/common.hpp"
namespace lgfx
{
inline namespace v1
{
//----------------------------------------------------------------------------
class Mesh_Bus_SPI : public IBus
{
public:
struct config_t {
uint32_t freq_write = 16000000;
uint32_t freq_read = 8000000;
// bool spi_3wire = true;
// bool use_lock = true;
int16_t pin_sclk = -1;
int16_t pin_miso = -1;
int16_t pin_mosi = -1;
int16_t pin_dc = -1;
uint8_t spi_mode = 0;
};
const config_t &config(void) const { return _cfg; }
void config(const config_t &config);
bus_type_t busType(void) const override { return bus_type_t::bus_spi; }
bool init(void) override;
void release(void) override;
void spi_device(HardwareSPI *newSPI, std::string newSPIName);
void beginTransaction(void) override;
void endTransaction(void) override;
void wait(void) override;
bool busy(void) const override;
bool writeCommand(uint32_t data, uint_fast8_t bit_length) override;
void writeData(uint32_t data, uint_fast8_t bit_length) override;
void writeDataRepeat(uint32_t data, uint_fast8_t bit_length, uint32_t count) override;
void writePixels(pixelcopy_t *param, uint32_t length) override;
void writeBytes(const uint8_t *data, uint32_t length, bool dc, bool use_dma) override;
void initDMA(void) {}
void flush(void) {}
void addDMAQueue(const uint8_t *data, uint32_t length) override { writeBytes(data, length, true, true); }
void execDMAQueue(void) {}
uint8_t *getDMABuffer(uint32_t length) override { return _flip_buffer.getBuffer(length); }
void beginRead(void) override;
void endRead(void) override;
uint32_t readData(uint_fast8_t bit_length) override;
bool readBytes(uint8_t *dst, uint32_t length, bool use_dma) override;
void readPixels(void *dst, pixelcopy_t *param, uint32_t length) override;
private:
HardwareSPI *PrivateSPI;
std::string SPIName;
__attribute__((always_inline)) inline void dc_h(void) { gpio_hi(_cfg.pin_dc); }
__attribute__((always_inline)) inline void dc_l(void) { gpio_lo(_cfg.pin_dc); }
config_t _cfg;
FlipBuffer _flip_buffer;
bool _need_wait;
uint32_t _mask_reg_dc;
uint32_t _last_apb_freq = -1;
uint32_t _clkdiv_write;
uint32_t _clkdiv_read;
volatile uint32_t *_gpio_reg_dc_h;
volatile uint32_t *_gpio_reg_dc_l;
};
//----------------------------------------------------------------------------
} // namespace v1
} // namespace lgfx
#endif

View File

@@ -3,6 +3,7 @@
#include "InputBroker.h"
#include "concurrency/OSThread.h"
#include "mesh/NodeDB.h"
#include "time.h"
typedef struct _TouchEvent {
const char *source;

View File

@@ -1,5 +1,4 @@
#include "kbI2cBase.h"
#include "configuration.h"
#include "detect/ScanI2C.h"
@@ -138,6 +137,9 @@ int32_t KbI2cBase::runOnce()
break;
case 0x13: // Code scanner says the SYM key is 0x13
is_sym = !is_sym;
e.inputEvent = ANYKEY;
e.kbchar =
is_sym ? 0xf1 : 0xf2; // send 0xf1 to tell CannedMessages to display that the modifier key is active
break;
case 0x0a: // apparently Enter on Q10 is a line feed instead of carriage return
e.inputEvent = meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_SELECT;
@@ -193,6 +195,75 @@ int32_t KbI2cBase::runOnce()
e.inputEvent = meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_NONE;
e.source = this->_originName;
switch (c) {
case 0x71: // This is the button q. If modifier and q pressed, it cancels the input
if (is_sym) {
is_sym = false;
e.inputEvent = meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_CANCEL;
} else {
e.inputEvent = ANYKEY;
e.kbchar = c;
}
break;
case 0x74: // letter t. if modifier and t pressed call 'tab'
if (is_sym) {
is_sym = false;
e.inputEvent = ANYKEY;
e.kbchar = 0x09; // TAB Scancode
} else {
e.inputEvent = ANYKEY;
e.kbchar = c;
}
break;
case 0x6d: // letter m. Modifier makes it mute notifications
if (is_sym) {
is_sym = false;
e.inputEvent = ANYKEY;
e.kbchar = 0xac; // mute notifications
} else {
e.inputEvent = ANYKEY;
e.kbchar = c;
}
break;
case 0x6f: // letter o(+). Modifier makes screen increase in brightness
if (is_sym) {
is_sym = false;
e.inputEvent = ANYKEY;
e.kbchar = 0x11; // Increase Brightness code
} else {
e.inputEvent = ANYKEY;
e.kbchar = c;
}
break;
case 0x69: // letter i(-). Modifier makes screen decrease in brightness
if (is_sym) {
is_sym = false;
e.inputEvent = ANYKEY;
e.kbchar = 0x12; // Decrease Brightness code
} else {
e.inputEvent = ANYKEY;
e.kbchar = c;
}
break;
case 0x20: // Space. Send network ping like double press does
if (is_sym) {
is_sym = false;
e.inputEvent = ANYKEY;
e.kbchar = 0xaf; // (fn + space)
} else {
e.inputEvent = ANYKEY;
e.kbchar = c;
}
break;
case 0x67: // letter g. toggle gps
if (is_sym) {
is_sym = false;
e.inputEvent = ANYKEY;
e.kbchar = 0x9e;
} else {
e.inputEvent = ANYKEY;
e.kbchar = c;
}
break;
case 0x1b: // ESC
e.inputEvent = meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_CANCEL;
break;
@@ -216,6 +287,12 @@ int32_t KbI2cBase::runOnce()
e.inputEvent = meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_RIGHT;
e.kbchar = 0xb7;
break;
case 0xc: // Modifier key: 0xc is alt+c (Other options could be: 0xea = shift+mic button or 0x4 shift+$(speaker))
// toggle moddifiers button.
is_sym = !is_sym;
e.inputEvent = ANYKEY;
e.kbchar = is_sym ? 0xf1 : 0xf2; // send 0xf1 to tell CannedMessages to display that the modifier key is active
break;
case 0x90: // fn+r
case 0x91: // fn+t
case 0x9b: // fn+s
@@ -239,6 +316,7 @@ int32_t KbI2cBase::runOnce()
}
e.inputEvent = ANYKEY;
e.kbchar = c;
is_sym = false;
break;
}

View File

@@ -179,6 +179,11 @@ const char *getDeviceName()
static int32_t ledBlinker()
{
// Still set up the blinking (heartbeat) interval but skip code path below, so LED will blink if
// config.device.led_heartbeat_disabled is changed
if (config.device.led_heartbeat_disabled)
return 1000;
static bool ledOn;
ledOn ^= 1;
@@ -192,7 +197,9 @@ uint32_t timeLastPowered = 0;
static Periodic *ledPeriodic;
static OSThread *powerFSMthread;
#if !MESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR
static OSThread *accelerometerThread;
#endif
static OSThread *ambientLightingThread;
SPISettings spiSettings(4000000, MSBFIRST, SPI_MODE0);
@@ -337,7 +344,7 @@ void setup()
Wire.begin(I2C_SDA, I2C_SCL);
#elif defined(ARCH_PORTDUINO)
if (settingsStrings[i2cdev] != "") {
LOG_INFO("Using %s as I2C device.\n", settingsStrings[i2cdev]);
LOG_INFO("Using %s as I2C device.\n", settingsStrings[i2cdev].c_str());
Wire.begin(settingsStrings[i2cdev].c_str());
} else {
LOG_INFO("No I2C device configured, skipping.\n");
@@ -533,6 +540,8 @@ void setup()
SCANNER_TO_SENSORS_MAP(ScanI2C::DeviceType::QMI8658, meshtastic_TelemetrySensorType_QMI8658)
SCANNER_TO_SENSORS_MAP(ScanI2C::DeviceType::QMC5883L, meshtastic_TelemetrySensorType_QMC5883L)
SCANNER_TO_SENSORS_MAP(ScanI2C::DeviceType::PMSA0031, meshtastic_TelemetrySensorType_PMSA003I)
SCANNER_TO_SENSORS_MAP(ScanI2C::DeviceType::RCWL9620, meshtastic_TelemetrySensorType_RCWL9620)
SCANNER_TO_SENSORS_MAP(ScanI2C::DeviceType::SHT4X, meshtastic_TelemetrySensorType_SHT4X)
i2cScanner.reset();
@@ -599,7 +608,7 @@ void setup()
screen_model = meshtastic_Config_DisplayConfig_OledType_OLED_SH1107; // keep dimension of 128x64
#endif
#if !defined(ARCH_PORTDUINO) && !defined(ARCH_STM32WL)
#if !defined(ARCH_PORTDUINO) && !defined(ARCH_STM32WL) && !MESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR
if (acc_info.type != ScanI2C::DeviceType::NONE) {
config.display.wake_on_tap_or_motion = true;
moduleConfig.external_notification.enabled = true;
@@ -607,7 +616,9 @@ void setup()
}
#endif
#if !defined(ARCH_PORTDUINO) && !defined(ARCH_STM32WL)
#if defined(HAS_NEOPIXEL) || defined(UNPHONE) || defined(RGBLED_RED)
ambientLightingThread = new AmbientLightingThread(ScanI2C::DeviceType::NONE);
#elif !defined(ARCH_PORTDUINO) && !defined(ARCH_STM32WL)
if (rgb_found.type != ScanI2C::DeviceType::NONE) {
ambientLightingThread = new AmbientLightingThread(rgb_found.type);
}
@@ -686,6 +697,12 @@ void setup()
// Now that the mesh service is created, create any modules
setupModules();
#ifdef LED_PIN
// Turn LED off after boot, if heartbeat by config
if (config.device.led_heartbeat_disabled)
digitalWrite(LED_PIN, LOW ^ LED_INVERTED);
#endif
// Do this after service.init (because that clears error_code)
#ifdef HAS_PMU
if (!pmu_found)
@@ -722,7 +739,8 @@ void setup()
if (settingsMap[use_sx1262]) {
if (!rIf) {
LOG_DEBUG("Attempting to activate sx1262 radio on SPI port %s\n", settingsStrings[spidev].c_str());
LockingArduinoHal *RadioLibHAL = new LockingArduinoHal(*LoraSPI, spiSettings);
LockingArduinoHal *RadioLibHAL =
new LockingArduinoHal(SPI, spiSettings, (settingsMap[ch341Quirk] ? settingsMap[busy] : RADIOLIB_NC));
rIf = new SX1262Interface((LockingArduinoHal *)RadioLibHAL, settingsMap[cs], settingsMap[irq], settingsMap[reset],
settingsMap[busy]);
if (!rIf->init()) {
@@ -736,7 +754,8 @@ void setup()
} else if (settingsMap[use_rf95]) {
if (!rIf) {
LOG_DEBUG("Attempting to activate rf95 radio on SPI port %s\n", settingsStrings[spidev].c_str());
LockingArduinoHal *RadioLibHAL = new LockingArduinoHal(*LoraSPI, spiSettings);
LockingArduinoHal *RadioLibHAL =
new LockingArduinoHal(SPI, spiSettings, (settingsMap[ch341Quirk] ? settingsMap[busy] : RADIOLIB_NC));
rIf = new RF95Interface((LockingArduinoHal *)RadioLibHAL, settingsMap[cs], settingsMap[irq], settingsMap[reset],
settingsMap[busy]);
if (!rIf->init()) {
@@ -751,7 +770,7 @@ void setup()
} else if (settingsMap[use_sx1280]) {
if (!rIf) {
LOG_DEBUG("Attempting to activate sx1280 radio on SPI port %s\n", settingsStrings[spidev].c_str());
LockingArduinoHal *RadioLibHAL = new LockingArduinoHal(*LoraSPI, spiSettings);
LockingArduinoHal *RadioLibHAL = new LockingArduinoHal(SPI, spiSettings);
rIf = new SX1280Interface((LockingArduinoHal *)RadioLibHAL, settingsMap[cs], settingsMap[irq], settingsMap[reset],
settingsMap[busy]);
if (!rIf->init()) {
@@ -763,6 +782,21 @@ void setup()
LOG_INFO("SX1280 Radio init succeeded, using SX1280 radio\n");
}
}
} else if (settingsMap[use_sx1268]) {
if (!rIf) {
LOG_DEBUG("Attempting to activate sx1268 radio on SPI port %s\n", settingsStrings[spidev].c_str());
LockingArduinoHal *RadioLibHAL = new LockingArduinoHal(SPI, spiSettings);
rIf = new SX1268Interface((LockingArduinoHal *)RadioLibHAL, settingsMap[cs], settingsMap[irq], settingsMap[reset],
settingsMap[busy]);
if (!rIf->init()) {
LOG_ERROR("Failed to find SX1268 radio\n");
delete rIf;
rIf = NULL;
exit(EXIT_FAILURE);
} else {
LOG_INFO("SX1268 Radio init succeeded, using SX1268 radio\n");
}
}
}
#elif defined(HW_SPI1_DEVICE)

View File

@@ -35,11 +35,10 @@ bool FloodingRouter::shouldFilterReceived(const meshtastic_MeshPacket *p)
void FloodingRouter::sniffReceived(const meshtastic_MeshPacket *p, const meshtastic_Routing *c)
{
bool isAck =
((c && c->error_reason == meshtastic_Routing_Error_NONE)); // consider only ROUTING_APP message without error as ACK
if (isAck && p->to != getNodeNum()) {
// do not flood direct message that is ACKed
LOG_DEBUG("Receiving an ACK not for me, but don't need to rebroadcast this direct message anymore.\n");
bool isAckorReply = (p->which_payload_variant == meshtastic_MeshPacket_decoded_tag) && (p->decoded.request_id != 0);
if (isAckorReply && p->to != getNodeNum() && p->to != NODENUM_BROADCAST) {
// do not flood direct message that is ACKed or replied to
LOG_DEBUG("Receiving an ACK or reply not for me, but don't need to rebroadcast this direct message anymore.\n");
Router::cancelSending(p->to, p->decoded.request_id); // cancel rebroadcast for this DM
}
if ((p->to != getNodeNum()) && (p->hop_limit > 0) && (getFrom(p) != getNodeNum())) {

View File

@@ -192,12 +192,7 @@ void MeshService::handleToRadio(meshtastic_MeshPacket &p)
return;
}
#endif
if (p.from != 0) { // We don't let phones assign nodenums to their sent messages
LOG_WARN("phone tried to pick a nodenum, we don't allow that.\n");
p.from = 0;
} else {
// p.from = nodeDB->getNodeNum();
}
p.from = 0; // We don't let phones assign nodenums to their sent messages
if (p.id == 0)
p.id = generatePacketId(); // If the phone didn't supply one, then pick one
@@ -262,12 +257,12 @@ void MeshService::sendToMesh(meshtastic_MeshPacket *p, RxSource src, bool ccToPh
LOG_DEBUG("Can't send status to phone");
}
if (ccToPhone) {
if (res == ERRNO_OK && ccToPhone) { // Check if p is not released in case it couldn't be sent
sendToPhone(packetPool.allocCopy(*p));
}
}
void MeshService::sendNetworkPing(NodeNum dest, bool wantReplies)
bool MeshService::trySendPosition(NodeNum dest, bool wantReplies)
{
meshtastic_NodeInfoLite *node = nodeDB->getMeshNode(nodeDB->getNodeNum());
@@ -278,6 +273,7 @@ void MeshService::sendNetworkPing(NodeNum dest, bool wantReplies)
if (positionModule) {
LOG_INFO("Sending position ping to 0x%x, wantReplies=%d, channel=%d\n", dest, wantReplies, node->channel);
positionModule->sendOurPosition(dest, wantReplies, node->channel);
return true;
}
} else {
#endif
@@ -286,6 +282,7 @@ void MeshService::sendNetworkPing(NodeNum dest, bool wantReplies)
nodeInfoModule->sendOurNodeInfo(dest, wantReplies, node->channel);
}
}
return false;
}
void MeshService::sendToPhone(meshtastic_MeshPacket *p)

View File

@@ -108,8 +108,9 @@ class MeshService
void reloadOwner(bool shouldSave = true);
/// Called when the user wakes up our GUI, normally sends our latest location to the mesh (if we have it), otherwise at least
/// sends our owner
void sendNetworkPing(NodeNum dest, bool wantReplies = false);
/// sends our nodeinfo
/// returns true if we sent a position
bool trySendPosition(NodeNum dest, bool wantReplies = false);
/// Send a packet into the mesh - note p must have been allocated from packetPool. We will return it to that pool after
/// sending. This is the ONLY function you should use for sending messages into the mesh, because it also updates the nodedb

View File

@@ -56,7 +56,7 @@ meshtastic_OEMStore oemStore;
bool meshtastic_DeviceState_callback(pb_istream_t *istream, pb_ostream_t *ostream, const pb_field_iter_t *field)
{
if (ostream) {
std::vector<meshtastic_NodeInfoLite> *vec = (std::vector<meshtastic_NodeInfoLite> *)field->pData;
std::vector<meshtastic_NodeInfoLite> const *vec = (std::vector<meshtastic_NodeInfoLite> *)field->pData;
for (auto item : *vec) {
if (!pb_encode_tag_for_field(ostream, field))
return false;
@@ -269,7 +269,7 @@ void NodeDB::installDefaultConfig()
config.device.node_info_broadcast_secs = default_node_info_broadcast_secs;
config.device.serial_enabled = true;
resetRadioConfig();
strncpy(config.network.ntp_server, "0.pool.ntp.org", 32);
strncpy(config.network.ntp_server, "meshtastic.pool.ntp.org", 32);
// FIXME: Default to bluetooth capability of platform as default
config.bluetooth.enabled = true;
config.bluetooth.fixed_pin = defaultBLEPin;
@@ -352,9 +352,6 @@ void NodeDB::installDefaultModuleConfig()
moduleConfig.external_notification.alert_message = true;
moduleConfig.external_notification.output_ms = 100;
moduleConfig.external_notification.active = true;
#endif
#ifdef TTGO_T_ECHO
config.display.wake_on_tap_or_motion = true; // Enable touch button for screen-on / refresh
#endif
moduleConfig.has_canned_message = true;
@@ -452,7 +449,7 @@ void NodeDB::resetNodes()
neighborInfoModule->resetNeighbors();
}
void NodeDB::removeNodeByNum(uint nodeNum)
void NodeDB::removeNodeByNum(NodeNum nodeNum)
{
int newPos = 0, removed = 0;
for (int i = 0; i < numMeshNodes; i++) {

View File

@@ -124,7 +124,7 @@ class NodeDB
*/
size_t getNumOnlineMeshNodes(bool localOnly = false);
void initConfigIntervals(), initModuleConfigIntervals(), resetNodes(), removeNodeByNum(uint nodeNum);
void initConfigIntervals(), initModuleConfigIntervals(), resetNodes(), removeNodeByNum(NodeNum nodeNum);
bool factoryReset();
@@ -150,12 +150,13 @@ class NodeDB
void setLocalPosition(meshtastic_Position position, bool timeOnly = false)
{
if (timeOnly) {
LOG_DEBUG("Setting local position time only: time=%i\n", position.time);
LOG_DEBUG("Setting local position time only: time=%u timestamp=%u\n", position.time, position.timestamp);
localPosition.time = position.time;
localPosition.timestamp = position.timestamp > 0 ? position.timestamp : position.time;
return;
}
LOG_DEBUG("Setting local position: latitude=%i, longitude=%i, time=%i\n", position.latitude_i, position.longitude_i,
position.time);
LOG_DEBUG("Setting local position: latitude=%i, longitude=%i, time=%u, timestamp=%u\n", position.latitude_i,
position.longitude_i, position.time, position.timestamp);
localPosition = position;
}

View File

@@ -95,12 +95,11 @@ template <class T> class ProtobufModule : protected SinglePortModule
*/
virtual void alterReceived(meshtastic_MeshPacket &mp) override
{
auto &p = mp.decoded;
T scratch;
T *decoded = NULL;
if (mp.which_payload_variant == meshtastic_MeshPacket_decoded_tag && mp.decoded.portnum == ourPortNum) {
memset(&scratch, 0, sizeof(scratch));
auto &p = mp.decoded;
if (pb_decode_from_bytes(p.payload.bytes, p.payload.size, fields, &scratch)) {
decoded = &scratch;
} else {

View File

@@ -76,9 +76,12 @@ const RegionInfo regions[] = {
RDEF(KR, 920.0f, 923.0f, 100, 0, 0, true, false, false),
/*
???
Taiwan, 920-925Mhz, limited to 0.5W indoor or coastal, 1.0W outdoor.
5.8.1 in the Low-power Radio-frequency Devices Technical Regulations
https://www.ncc.gov.tw/english/files/23070/102_5190_230703_1_doc_C.PDF
https://gazette.nat.gov.tw/egFront/e_detail.do?metaid=147283
*/
RDEF(TW, 920.0f, 925.0f, 100, 0, 0, true, false, false),
RDEF(TW, 920.0f, 925.0f, 100, 0, 27, true, false, false),
/*
https://lora-alliance.org/wp-content/uploads/2020/11/lorawan_regional_parameters_v1.0.3reva_0.pdf
@@ -492,7 +495,7 @@ void RadioInterface::applyModemConfig()
// If user has manually specified a channel num, then use that, otherwise generate one by hashing the name
const char *channelName = channels.getName(channels.getPrimaryIndex());
// channel_num is actually (channel_num - 1), since modulus (%) returns values from 0 to (numChannels - 1)
int channel_num = (loraConfig.channel_num ? loraConfig.channel_num - 1 : hash(channelName)) % numChannels;
uint32_t channel_num = (loraConfig.channel_num ? loraConfig.channel_num - 1 : hash(channelName)) % numChannels;
// Check if we use the default frequency slot
RadioInterface::uses_default_frequency_slot =
@@ -586,4 +589,4 @@ size_t RadioInterface::beginSending(meshtastic_MeshPacket *p)
sendingPacket = p;
return p->encrypted.size + sizeof(PacketHeader);
}
}

View File

@@ -25,7 +25,31 @@ void LockingArduinoHal::spiEndTransaction()
#if ARCH_PORTDUINO
void LockingArduinoHal::spiTransfer(uint8_t *out, size_t len, uint8_t *in)
{
spi->transfer(out, in, len);
if (busy == RADIOLIB_NC) {
spi->transfer(out, in, len);
} else {
uint16_t offset = 0;
while (len) {
uint8_t block_size = (len < 20 ? len : 20);
spi->transfer((out != NULL ? out + offset : NULL), (in != NULL ? in + offset : NULL), block_size);
if (block_size == len)
return;
// ensure GPIO is low
uint32_t start = millis();
while (digitalRead(busy)) {
if (millis() - start >= 2000) {
LOG_ERROR("GPIO mid-transfer timeout, is it connected?");
return;
}
}
offset += block_size;
len -= block_size;
}
}
}
#endif
@@ -414,4 +438,4 @@ void RadioLibInterface::startSend(meshtastic_MeshPacket *txp)
// bits
enableInterrupt(isrTxLevel0);
}
}
}

View File

@@ -21,12 +21,20 @@
class LockingArduinoHal : public ArduinoHal
{
public:
LockingArduinoHal(SPIClass &spi, SPISettings spiSettings) : ArduinoHal(spi, spiSettings){};
LockingArduinoHal(SPIClass &spi, SPISettings spiSettings, RADIOLIB_PIN_TYPE _busy = RADIOLIB_NC)
: ArduinoHal(spi, spiSettings)
{
#if ARCH_PORTDUINO
busy = _busy;
#endif
};
void spiBeginTransaction() override;
void spiEndTransaction() override;
#if ARCH_PORTDUINO
RADIOLIB_PIN_TYPE busy;
void spiTransfer(uint8_t *out, size_t len, uint8_t *in) override;
#endif
};
@@ -179,4 +187,4 @@ class RadioLibInterface : public RadioInterface, protected concurrency::Notified
virtual void addReceiveMetadata(meshtastic_MeshPacket *mp) = 0;
virtual void setStandby() = 0;
};
};

View File

@@ -55,7 +55,7 @@ extern const pb_msgdesc_t meshtastic_ChannelSet_msg;
/* Maximum encoded size of messages (where known) */
#define MESHTASTIC_MESHTASTIC_APPONLY_PB_H_MAX_SIZE meshtastic_ChannelSet_size
#define meshtastic_ChannelSet_size 658
#define meshtastic_ChannelSet_size 674
#ifdef __cplusplus
} /* extern "C" */

View File

@@ -34,6 +34,9 @@ typedef enum _meshtastic_Channel_Role {
typedef struct _meshtastic_ModuleSettings {
/* Bits of precision for the location sent in position packets. */
uint32_t position_precision;
/* Controls whether or not the phone / clients should mute the current channel
Useful for noisy public channels you don't necessarily want to disable */
bool is_client_muted;
} meshtastic_ModuleSettings;
typedef PB_BYTES_ARRAY_T(32) meshtastic_ChannelSettings_psk_t;
@@ -126,14 +129,15 @@ extern "C" {
/* Initializer values for message structs */
#define meshtastic_ChannelSettings_init_default {0, {0, {0}}, "", 0, 0, 0, false, meshtastic_ModuleSettings_init_default}
#define meshtastic_ModuleSettings_init_default {0}
#define meshtastic_ModuleSettings_init_default {0, 0}
#define meshtastic_Channel_init_default {0, false, meshtastic_ChannelSettings_init_default, _meshtastic_Channel_Role_MIN}
#define meshtastic_ChannelSettings_init_zero {0, {0, {0}}, "", 0, 0, 0, false, meshtastic_ModuleSettings_init_zero}
#define meshtastic_ModuleSettings_init_zero {0}
#define meshtastic_ModuleSettings_init_zero {0, 0}
#define meshtastic_Channel_init_zero {0, false, meshtastic_ChannelSettings_init_zero, _meshtastic_Channel_Role_MIN}
/* Field tags (for use in manual encoding/decoding) */
#define meshtastic_ModuleSettings_position_precision_tag 1
#define meshtastic_ModuleSettings_is_client_muted_tag 2
#define meshtastic_ChannelSettings_channel_num_tag 1
#define meshtastic_ChannelSettings_psk_tag 2
#define meshtastic_ChannelSettings_name_tag 3
@@ -159,7 +163,8 @@ X(a, STATIC, OPTIONAL, MESSAGE, module_settings, 7)
#define meshtastic_ChannelSettings_module_settings_MSGTYPE meshtastic_ModuleSettings
#define meshtastic_ModuleSettings_FIELDLIST(X, a) \
X(a, STATIC, SINGULAR, UINT32, position_precision, 1)
X(a, STATIC, SINGULAR, UINT32, position_precision, 1) \
X(a, STATIC, SINGULAR, BOOL, is_client_muted, 2)
#define meshtastic_ModuleSettings_CALLBACK NULL
#define meshtastic_ModuleSettings_DEFAULT NULL
@@ -182,9 +187,9 @@ extern const pb_msgdesc_t meshtastic_Channel_msg;
/* Maximum encoded size of messages (where known) */
#define MESHTASTIC_MESHTASTIC_CHANNEL_PB_H_MAX_SIZE meshtastic_Channel_size
#define meshtastic_ChannelSettings_size 70
#define meshtastic_Channel_size 85
#define meshtastic_ModuleSettings_size 6
#define meshtastic_ChannelSettings_size 72
#define meshtastic_Channel_size 87
#define meshtastic_ModuleSettings_size 8
#ifdef __cplusplus
} /* extern "C" */

View File

@@ -283,6 +283,8 @@ typedef struct _meshtastic_Config_DeviceConfig {
bool disable_triple_click;
/* POSIX Timezone definition string from https://github.com/nayarsystems/posix_tz_db/blob/master/zones.csv. */
char tzdef[65];
/* If true, disable the default blinking LED (LED_PIN) behavior on the device */
bool led_heartbeat_disabled;
} meshtastic_Config_DeviceConfig;
/* Position Config */
@@ -580,7 +582,7 @@ extern "C" {
/* Initializer values for message structs */
#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, 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, "", 0}
#define meshtastic_Config_PositionConfig_init_default {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, _meshtastic_Config_PositionConfig_GpsMode_MIN}
#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, ""}
@@ -589,7 +591,7 @@ extern "C" {
#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}, 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_DeviceConfig_init_zero {_meshtastic_Config_DeviceConfig_Role_MIN, 0, 0, 0, 0, _meshtastic_Config_DeviceConfig_RebroadcastMode_MIN, 0, 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, "", 0}
#define meshtastic_Config_PositionConfig_init_zero {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, _meshtastic_Config_PositionConfig_GpsMode_MIN}
#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, ""}
@@ -610,6 +612,7 @@ extern "C" {
#define meshtastic_Config_DeviceConfig_is_managed_tag 9
#define meshtastic_Config_DeviceConfig_disable_triple_click_tag 10
#define meshtastic_Config_DeviceConfig_tzdef_tag 11
#define meshtastic_Config_DeviceConfig_led_heartbeat_disabled_tag 12
#define meshtastic_Config_PositionConfig_position_broadcast_secs_tag 1
#define meshtastic_Config_PositionConfig_position_broadcast_smart_enabled_tag 2
#define meshtastic_Config_PositionConfig_fixed_position_tag 3
@@ -710,7 +713,8 @@ 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, is_managed, 9) \
X(a, STATIC, SINGULAR, BOOL, disable_triple_click, 10) \
X(a, STATIC, SINGULAR, STRING, tzdef, 11)
X(a, STATIC, SINGULAR, STRING, tzdef, 11) \
X(a, STATIC, SINGULAR, BOOL, led_heartbeat_disabled, 12)
#define meshtastic_Config_DeviceConfig_CALLBACK NULL
#define meshtastic_Config_DeviceConfig_DEFAULT NULL
@@ -829,7 +833,7 @@ extern const pb_msgdesc_t meshtastic_Config_BluetoothConfig_msg;
/* Maximum encoded size of messages (where known) */
#define MESHTASTIC_MESHTASTIC_CONFIG_PB_H_MAX_SIZE meshtastic_Config_size
#define meshtastic_Config_BluetoothConfig_size 10
#define meshtastic_Config_DeviceConfig_size 98
#define meshtastic_Config_DeviceConfig_size 100
#define meshtastic_Config_DisplayConfig_size 28
#define meshtastic_Config_LoRaConfig_size 80
#define meshtastic_Config_NetworkConfig_IpV4Config_size 20

View File

@@ -306,9 +306,9 @@ extern const pb_msgdesc_t meshtastic_OEMStore_msg;
/* Maximum encoded size of messages (where known) */
/* meshtastic_DeviceState_size depends on runtime parameters */
#define MESHTASTIC_MESHTASTIC_DEVICEONLY_PB_H_MAX_SIZE meshtastic_OEMStore_size
#define meshtastic_ChannelFile_size 702
#define meshtastic_ChannelFile_size 718
#define meshtastic_NodeInfoLite_size 166
#define meshtastic_OEMStore_size 3344
#define meshtastic_OEMStore_size 3346
#define meshtastic_PositionLite_size 28
#ifdef __cplusplus

View File

@@ -181,7 +181,7 @@ extern const pb_msgdesc_t meshtastic_LocalModuleConfig_msg;
/* Maximum encoded size of messages (where known) */
#define MESHTASTIC_MESHTASTIC_LOCALONLY_PB_H_MAX_SIZE meshtastic_LocalModuleConfig_size
#define meshtastic_LocalConfig_size 535
#define meshtastic_LocalConfig_size 537
#define meshtastic_LocalModuleConfig_size 663
#ifdef __cplusplus

View File

@@ -63,6 +63,8 @@ typedef enum _meshtastic_HardwareModel {
meshtastic_HardwareModel_NANO_G2_ULTRA = 18,
/* LoRAType device: https://loratype.org/ */
meshtastic_HardwareModel_LORA_TYPE = 19,
/* wiphone https://www.wiphone.io/ */
meshtastic_HardwareModel_WIPHONE = 20,
/* B&Q Consulting Station Edition G1: https://uniteng.com/wiki/doku.php?id=meshtastic:station */
meshtastic_HardwareModel_STATION_G1 = 25,
/* RAK11310 (RP2040 + SX1262) */
@@ -148,6 +150,12 @@ typedef enum _meshtastic_HardwareModel {
meshtastic_HardwareModel_TD_LORAC = 60,
/* CDEBYTE EoRa-S3 board using their own MM modules, clone of LILYGO T3S3 */
meshtastic_HardwareModel_CDEBYTE_EORA_S3 = 61,
/* TWC_MESH_V4
Adafruit NRF52840 feather express with SX1262, SSD1306 OLED and NEO6M GPS */
meshtastic_HardwareModel_TWC_MESH_V4 = 62,
/* NRF52_PROMICRO_DIY
Promicro NRF52840 with SX1262/LLCC68, SSD1306 OLED and NEO6M GPS */
meshtastic_HardwareModel_NRF52_PROMICRO_DIY = 63,
/* ------------------------------------------------------------------------------------------------------------------------------------------
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.
------------------------------------------------------------------------------------------------------------------------------------------ */

View File

@@ -43,7 +43,11 @@ typedef enum _meshtastic_TelemetrySensorType {
/* INA3221 3 Channel Voltage / Current Sensor */
meshtastic_TelemetrySensorType_INA3221 = 14,
/* BMP085/BMP180 High accuracy temperature and pressure (older Version of BMP280) */
meshtastic_TelemetrySensorType_BMP085 = 15
meshtastic_TelemetrySensorType_BMP085 = 15,
/* RCWL-9620 Doppler Radar Distance Sensor, used for water level detection */
meshtastic_TelemetrySensorType_RCWL9620 = 16,
/* Sensirion High accuracy temperature and humidity */
meshtastic_TelemetrySensorType_SHT4X = 17
} meshtastic_TelemetrySensorType;
/* Struct definitions */
@@ -78,6 +82,8 @@ typedef struct _meshtastic_EnvironmentMetrics {
/* relative scale IAQ value as measured by Bosch BME680 . value 0-500.
Belongs to Air Quality but is not particle but VOC measurement. Other VOC values can also be put in here. */
uint16_t iaq;
/* RCWL9620 Doppler Radar Distance Sensor, used for water level detection. Float value in mm. */
float distance;
} meshtastic_EnvironmentMetrics;
/* Power Metrics (voltage / current / etc) */
@@ -148,8 +154,8 @@ extern "C" {
/* Helper constants for enums */
#define _meshtastic_TelemetrySensorType_MIN meshtastic_TelemetrySensorType_SENSOR_UNSET
#define _meshtastic_TelemetrySensorType_MAX meshtastic_TelemetrySensorType_BMP085
#define _meshtastic_TelemetrySensorType_ARRAYSIZE ((meshtastic_TelemetrySensorType)(meshtastic_TelemetrySensorType_BMP085+1))
#define _meshtastic_TelemetrySensorType_MAX meshtastic_TelemetrySensorType_SHT4X
#define _meshtastic_TelemetrySensorType_ARRAYSIZE ((meshtastic_TelemetrySensorType)(meshtastic_TelemetrySensorType_SHT4X+1))
@@ -159,12 +165,12 @@ extern "C" {
/* Initializer values for message structs */
#define meshtastic_DeviceMetrics_init_default {0, 0, 0, 0, 0}
#define meshtastic_EnvironmentMetrics_init_default {0, 0, 0, 0, 0, 0, 0}
#define meshtastic_EnvironmentMetrics_init_default {0, 0, 0, 0, 0, 0, 0, 0}
#define meshtastic_PowerMetrics_init_default {0, 0, 0, 0, 0, 0}
#define meshtastic_AirQualityMetrics_init_default {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
#define meshtastic_Telemetry_init_default {0, 0, {meshtastic_DeviceMetrics_init_default}}
#define meshtastic_DeviceMetrics_init_zero {0, 0, 0, 0, 0}
#define meshtastic_EnvironmentMetrics_init_zero {0, 0, 0, 0, 0, 0, 0}
#define meshtastic_EnvironmentMetrics_init_zero {0, 0, 0, 0, 0, 0, 0, 0}
#define meshtastic_PowerMetrics_init_zero {0, 0, 0, 0, 0, 0}
#define meshtastic_AirQualityMetrics_init_zero {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
#define meshtastic_Telemetry_init_zero {0, 0, {meshtastic_DeviceMetrics_init_zero}}
@@ -182,6 +188,7 @@ extern "C" {
#define meshtastic_EnvironmentMetrics_voltage_tag 5
#define meshtastic_EnvironmentMetrics_current_tag 6
#define meshtastic_EnvironmentMetrics_iaq_tag 7
#define meshtastic_EnvironmentMetrics_distance_tag 8
#define meshtastic_PowerMetrics_ch1_voltage_tag 1
#define meshtastic_PowerMetrics_ch1_current_tag 2
#define meshtastic_PowerMetrics_ch2_voltage_tag 3
@@ -223,7 +230,8 @@ X(a, STATIC, SINGULAR, FLOAT, barometric_pressure, 3) \
X(a, STATIC, SINGULAR, FLOAT, gas_resistance, 4) \
X(a, STATIC, SINGULAR, FLOAT, voltage, 5) \
X(a, STATIC, SINGULAR, FLOAT, current, 6) \
X(a, STATIC, SINGULAR, UINT32, iaq, 7)
X(a, STATIC, SINGULAR, UINT32, iaq, 7) \
X(a, STATIC, SINGULAR, FLOAT, distance, 8)
#define meshtastic_EnvironmentMetrics_CALLBACK NULL
#define meshtastic_EnvironmentMetrics_DEFAULT NULL
@@ -283,7 +291,7 @@ extern const pb_msgdesc_t meshtastic_Telemetry_msg;
#define MESHTASTIC_MESHTASTIC_TELEMETRY_PB_H_MAX_SIZE meshtastic_Telemetry_size
#define meshtastic_AirQualityMetrics_size 72
#define meshtastic_DeviceMetrics_size 27
#define meshtastic_EnvironmentMetrics_size 34
#define meshtastic_EnvironmentMetrics_size 39
#define meshtastic_PowerMetrics_size 30
#define meshtastic_Telemetry_size 79

View File

@@ -23,6 +23,10 @@
#include "mqtt/MQTT.h"
#endif
#if !MESHTASTIC_EXCLUDE_GPS
#include "GPS.h"
#endif
AdminModule *adminModule;
bool hasOpenEditTransaction;
@@ -217,6 +221,12 @@ bool AdminModule::handleReceivedProtobuf(const meshtastic_MeshPacket &mp, meshta
nodeDB->setLocalPosition(r->set_fixed_position);
config.position.fixed_position = true;
saveChanges(SEGMENT_DEVICESTATE | SEGMENT_CONFIG, false);
// Send our new fixed position to the mesh for good measure
positionModule->sendOurPosition();
#if !MESHTASTIC_EXCLUDE_GPS
if (gps != nullptr)
gps->enable();
#endif
}
break;
}

View File

@@ -161,10 +161,10 @@ int CannedMessageModule::handleInputEvent(const InputEvent *event)
if (!event->kbchar) {
if (event->inputEvent == static_cast<char>(meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_LEFT)) {
this->payload = 0xb4;
this->destSelect = CANNED_MESSAGE_DESTINATION_TYPE_NODE;
// this->destSelect = CANNED_MESSAGE_DESTINATION_TYPE_NODE;
} else if (event->inputEvent == static_cast<char>(meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_RIGHT)) {
this->payload = 0xb7;
this->destSelect = CANNED_MESSAGE_DESTINATION_TYPE_NODE;
// this->destSelect = CANNED_MESSAGE_DESTINATION_TYPE_NODE;
}
} else {
// pass the pressed key
@@ -180,11 +180,75 @@ int CannedMessageModule::handleInputEvent(const InputEvent *event)
(this->runState == CANNED_MESSAGE_RUN_STATE_DISABLED)) {
this->runState = CANNED_MESSAGE_RUN_STATE_FREETEXT;
}
// pass the pressed key
// LOG_DEBUG("Canned message ANYKEY (%x)\n", event->kbchar);
this->payload = event->kbchar;
this->lastTouchMillis = millis();
validEvent = true;
validEvent = false; // If key is normal than it will be set to true.
// Run modifier key code below, (doesnt inturrupt typing or reset to start screen page)
switch (event->kbchar) {
case 0x11: // make screen brighter
if (screen)
screen->increaseBrightness();
LOG_DEBUG("increasing Screen Brightness\n");
break;
case 0x12: // make screen dimmer
if (screen)
screen->decreaseBrightness();
LOG_DEBUG("Decreasing Screen Brightness\n");
break;
case 0xf1: // draw modifier (function) symbal
if (screen)
screen->setFunctionSymbal("Fn");
break;
case 0xf2: // remove modifier (function) symbal
if (screen)
screen->removeFunctionSymbal("Fn");
break;
// mute (switch off/toggle) external notifications on fn+m
case 0xac:
if (moduleConfig.external_notification.enabled == true) {
if (externalNotificationModule->getMute()) {
externalNotificationModule->setMute(false);
showTemporaryMessage("Notifications \nEnabled");
if (screen)
screen->removeFunctionSymbal("M"); // remove the mute symbol from the bottom right corner
} else {
externalNotificationModule->stopNow(); // this will turn off all GPIO and sounds and idle the loop
externalNotificationModule->setMute(true);
showTemporaryMessage("Notifications \nDisabled");
if (screen)
screen->setFunctionSymbal("M"); // add the mute symbol to the bottom right corner
}
}
break;
case 0x9e: // toggle GPS like triple press does
#if !MESHTASTIC_EXCLUDE_GPS
if (gps != nullptr) {
gps->toggleGpsMode();
}
if (screen)
screen->forceDisplay();
showTemporaryMessage("GPS Toggled");
#endif
break;
case 0xaf: // fn+space send network ping like double press does
service.refreshLocalMeshNode();
if (service.trySendPosition(NODENUM_BROADCAST, true)) {
showTemporaryMessage("Position \nUpdate Sent");
} else {
showTemporaryMessage("Node Info \nUpdate Sent");
}
break;
default:
// pass the pressed key
// LOG_DEBUG("Canned message ANYKEY (%x)\n", event->kbchar);
this->payload = event->kbchar;
this->lastTouchMillis = millis();
validEvent = true;
break;
}
if (screen && (event->kbchar != 0xf1)) {
screen->removeFunctionSymbal("Fn"); // remove modifier (function) symbal
}
}
if (event->inputEvent == static_cast<char>(MATRIXKEY)) {
LOG_DEBUG("Canned message event Matrix key pressed\n");
@@ -233,14 +297,16 @@ int32_t CannedMessageModule::runOnce()
{
if (((!moduleConfig.canned_message.enabled) && !CANNED_MESSAGE_MODULE_ENABLE) ||
(this->runState == CANNED_MESSAGE_RUN_STATE_DISABLED) || (this->runState == CANNED_MESSAGE_RUN_STATE_INACTIVE)) {
temporaryMessage = "";
return INT32_MAX;
}
// LOG_DEBUG("Check status\n");
UIFrameEvent e = {false, true};
if ((this->runState == CANNED_MESSAGE_RUN_STATE_SENDING_ACTIVE) ||
(this->runState == CANNED_MESSAGE_RUN_STATE_ACK_NACK_RECEIVED)) {
// TODO: might have some feedback of sendig state
(this->runState == CANNED_MESSAGE_RUN_STATE_ACK_NACK_RECEIVED) || (this->runState == CANNED_MESSAGE_RUN_STATE_MESSAGE)) {
// TODO: might have some feedback of sending state
this->runState = CANNED_MESSAGE_RUN_STATE_INACTIVE;
temporaryMessage = "";
e.frameChanged = true;
this->currentMessageIndex = -1;
this->freetext = ""; // clear freetext
@@ -388,8 +454,9 @@ int32_t CannedMessageModule::runOnce()
}
if (this->runState == CANNED_MESSAGE_RUN_STATE_FREETEXT) {
e.frameChanged = true;
switch (this->payload) {
case 0x08: // backspace
switch (this->payload) { // code below all trigger the freetext window (where you type to send a message) or reset the
// display back to the default window
case 0x08: // backspace
if (this->freetext.length() > 0) {
if (this->cursor == this->freetext.length()) {
this->freetext = this->freetext.substring(0, this->freetext.length() - 1);
@@ -401,7 +468,6 @@ int32_t CannedMessageModule::runOnce()
}
break;
case 0x09: // tab
case 0x91: // alt+t for T-Deck that doesn't have a tab key
if (this->destSelect == CANNED_MESSAGE_DESTINATION_TYPE_CHANNEL) {
this->destSelect = CANNED_MESSAGE_DESTINATION_TYPE_NONE;
} else if (this->destSelect == CANNED_MESSAGE_DESTINATION_TYPE_NODE) {
@@ -414,7 +480,7 @@ int32_t CannedMessageModule::runOnce()
case 0xb7: // right
// already handled above
break;
// handle fn+s for shutdown
// handle fn+s for shutdown
case 0x9b:
if (screen)
screen->startShutdownScreen();
@@ -428,33 +494,6 @@ int32_t CannedMessageModule::runOnce()
rebootAtMsec = millis() + DEFAULT_REBOOT_SECONDS * 1000;
runState = CANNED_MESSAGE_RUN_STATE_INACTIVE;
break;
case 0x9e: // toggle GPS like triple press does
if (gps != nullptr) {
gps->toggleGpsMode();
}
if (screen)
screen->forceDisplay();
runState = CANNED_MESSAGE_RUN_STATE_INACTIVE;
break;
// mute (switch off/toggle) external notifications on fn+m
case 0xac:
if (moduleConfig.external_notification.enabled == true) {
if (externalNotificationModule->getMute()) {
externalNotificationModule->setMute(false);
runState = CANNED_MESSAGE_RUN_STATE_INACTIVE;
} else {
externalNotificationModule->stopNow(); // this will turn off all GPIO and sounds and idle the loop
externalNotificationModule->setMute(true);
runState = CANNED_MESSAGE_RUN_STATE_INACTIVE;
}
}
break;
case 0xaf: // fn+space send network ping like double press does
service.refreshLocalMeshNode();
service.sendNetworkPing(NODENUM_BROADCAST, true);
runState = CANNED_MESSAGE_RUN_STATE_INACTIVE;
break;
default:
if (this->cursor == this->freetext.length()) {
this->freetext += this->payload;
@@ -470,6 +509,8 @@ int32_t CannedMessageModule::runOnce()
}
break;
}
if (screen)
screen->removeFunctionSymbal("Fn");
}
this->lastTouchMillis = millis();
@@ -542,12 +583,27 @@ int CannedMessageModule::getPrevIndex()
return this->currentMessageIndex - 1;
}
}
void CannedMessageModule::showTemporaryMessage(const String &message)
{
temporaryMessage = message;
UIFrameEvent e = {false, true};
e.frameChanged = true;
notifyObservers(&e);
runState = CANNED_MESSAGE_RUN_STATE_MESSAGE;
// run this loop again in 2 seconds, next iteration will clear the display
setIntervalFromNow(2000);
}
void CannedMessageModule::drawFrame(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y)
{
char buffer[50];
if (cannedMessageModule->runState == CANNED_MESSAGE_RUN_STATE_ACK_NACK_RECEIVED) {
if (temporaryMessage.length() != 0) {
LOG_DEBUG("Drawing temporary message: %s", temporaryMessage.c_str());
display->setTextAlignment(TEXT_ALIGN_CENTER);
display->setFont(FONT_MEDIUM);
display->drawString(display->getWidth() / 2 + x, 0 + y + 12, temporaryMessage);
} else if (cannedMessageModule->runState == CANNED_MESSAGE_RUN_STATE_ACK_NACK_RECEIVED) {
display->setTextAlignment(TEXT_ALIGN_CENTER);
display->setFont(FONT_MEDIUM);
String displayString;

View File

@@ -10,6 +10,7 @@ enum cannedMessageModuleRunState {
CANNED_MESSAGE_RUN_STATE_FREETEXT,
CANNED_MESSAGE_RUN_STATE_SENDING_ACTIVE,
CANNED_MESSAGE_RUN_STATE_ACK_NACK_RECEIVED,
CANNED_MESSAGE_RUN_STATE_MESSAGE,
CANNED_MESSAGE_RUN_STATE_ACTION_SELECT,
CANNED_MESSAGE_RUN_STATE_ACTION_UP,
CANNED_MESSAGE_RUN_STATE_ACTION_DOWN,
@@ -51,6 +52,8 @@ class CannedMessageModule : public SinglePortModule, public Observable<const UIF
void handleGetCannedMessageModuleMessages(const meshtastic_MeshPacket &req, meshtastic_AdminMessage *response);
void handleSetCannedMessageModuleMessages(const char *from_msg);
void showTemporaryMessage(const String &message);
String drawWithCursor(String text, int cursor);
/*
@@ -112,7 +115,8 @@ class CannedMessageModule : public SinglePortModule, public Observable<const UIF
char *messages[CANNED_MESSAGE_MODULE_MESSAGE_MAX_COUNT];
int messagesCount = 0;
unsigned long lastTouchMillis = 0;
String temporaryMessage;
};
extern CannedMessageModule *cannedMessageModule;
#endif
#endif

View File

@@ -26,7 +26,18 @@
#ifdef HAS_NCP5623
#include <graphics/RAKled.h>
#endif
#ifdef HAS_NEOPIXEL
#include <graphics/NeoPixel.h>
#endif
#ifdef UNPHONE
#include "unPhone.h"
extern unPhone unphone;
#endif
#if defined(HAS_NCP5623) || defined(RGBLED_RED) || defined(HAS_NEOPIXEL) || defined(UNPHONE)
uint8_t red = 0;
uint8_t green = 0;
uint8_t blue = 0;
@@ -108,27 +119,44 @@ int32_t ExternalNotificationModule::runOnce()
millis()) {
getExternal(2) ? setExternalOff(2) : setExternalOn(2);
}
#if defined(HAS_NCP5623) || defined(RGBLED_RED) || defined(HAS_NEOPIXEL) || defined(UNPHONE)
red = (colorState & 4) ? brightnessValues[brightnessIndex] : 0; // Red enabled on colorState = 4,5,6,7
green = (colorState & 2) ? brightnessValues[brightnessIndex] : 0; // Green enabled on colorState = 2,3,6,7
blue = (colorState & 1) ? (brightnessValues[brightnessIndex] * 1.5) : 0; // Blue enabled on colorState = 1,3,5,7
#ifdef HAS_NCP5623
if (rgb_found.type == ScanI2C::NCP5623) {
red = (colorState & 4) ? brightnessValues[brightnessIndex] : 0; // Red enabled on colorState = 4,5,6,7
green = (colorState & 2) ? brightnessValues[brightnessIndex] : 0; // Green enabled on colorState = 2,3,6,7
blue = (colorState & 1) ? (brightnessValues[brightnessIndex] * 1.5) : 0; // Blue enabled on colorState = 1,3,5,7
rgb.setColor(red, green, blue);
if (ascending) { // fade in
brightnessIndex++;
if (brightnessIndex == (sizeof(brightnessValues) - 1)) {
ascending = false;
}
} else {
brightnessIndex--; // fade out
}
#endif
#ifdef RGBLED_CA
analogWrite(RGBLED_RED, 255 - red); // CA type needs reverse logic
analogWrite(RGBLED_GREEN, 255 - green);
analogWrite(RGBLED_BLUE, 255 - blue);
#elif defined(RGBLED_RED)
analogWrite(RGBLED_RED, red);
analogWrite(RGBLED_GREEN, green);
analogWrite(RGBLED_BLUE, blue);
#endif
#ifdef HAS_NEOPIXEL
pixels.fill(pixels.Color(red, green, blue), 0, NEOPIXEL_COUNT);
pixels.show();
#endif
#ifdef UNPHONE
unphone.rgb(red, green, blue);
#endif
if (ascending) { // fade in
brightnessIndex++;
if (brightnessIndex == (sizeof(brightnessValues) - 1)) {
ascending = false;
}
if (brightnessIndex == 0) {
ascending = true;
colorState++; // next color
if (colorState > 7) {
colorState = 1;
}
} else {
brightnessIndex--; // fade out
}
if (brightnessIndex == 0) {
ascending = true;
colorState++; // next color
if (colorState > 7) {
colorState = 1;
}
}
#endif
@@ -179,6 +207,9 @@ void ExternalNotificationModule::setExternalOn(uint8_t index)
switch (index) {
case 1:
#ifdef UNPHONE
unphone.vibe(true); // the unPhone's vibration motor is on a i2c GPIO expander
#endif
if (moduleConfig.external_notification.output_vibra)
digitalWrite(moduleConfig.external_notification.output_vibra, true);
break;
@@ -197,6 +228,22 @@ void ExternalNotificationModule::setExternalOn(uint8_t index)
rgb.setColor(red, green, blue);
}
#endif
#ifdef RGBLED_CA
analogWrite(RGBLED_RED, 255 - red); // CA type needs reverse logic
analogWrite(RGBLED_GREEN, 255 - green);
analogWrite(RGBLED_BLUE, 255 - blue);
#elif defined(RGBLED_RED)
analogWrite(RGBLED_RED, red);
analogWrite(RGBLED_GREEN, green);
analogWrite(RGBLED_BLUE, blue);
#endif
#ifdef HAS_NEOPIXEL
pixels.fill(pixels.Color(red, green, blue), 0, NEOPIXEL_COUNT);
pixels.show();
#endif
#ifdef UNPHONE
unphone.rgb(red, green, blue);
#endif
#ifdef T_WATCH_S3
drv.go();
#endif
@@ -209,6 +256,9 @@ void ExternalNotificationModule::setExternalOff(uint8_t index)
switch (index) {
case 1:
#ifdef UNPHONE
unphone.vibe(false); // the unPhone's vibration motor is on a i2c GPIO expander
#endif
if (moduleConfig.external_notification.output_vibra)
digitalWrite(moduleConfig.external_notification.output_vibra, false);
break;
@@ -222,14 +272,33 @@ void ExternalNotificationModule::setExternalOff(uint8_t index)
break;
}
#if defined(HAS_NCP5623) || defined(RGBLED_RED) || defined(HAS_NEOPIXEL) || defined(UNPHONE)
red = 0;
green = 0;
blue = 0;
#ifdef HAS_NCP5623
if (rgb_found.type == ScanI2C::NCP5623) {
red = 0;
green = 0;
blue = 0;
rgb.setColor(red, green, blue);
}
#endif
#ifdef RGBLED_CA
analogWrite(RGBLED_RED, 255 - red); // CA type needs reverse logic
analogWrite(RGBLED_GREEN, 255 - green);
analogWrite(RGBLED_BLUE, 255 - blue);
#elif defined(RGBLED_RED)
analogWrite(RGBLED_RED, red);
analogWrite(RGBLED_GREEN, green);
analogWrite(RGBLED_BLUE, blue);
#endif
#ifdef HAS_NEOPIXEL
pixels.fill(pixels.Color(red, green, blue), 0, NEOPIXEL_COUNT);
pixels.show();
#endif
#ifdef UNPHONE
unphone.rgb(red, green, blue);
#endif
#endif
#ifdef T_WATCH_S3
drv.stop();
#endif
@@ -244,7 +313,8 @@ void ExternalNotificationModule::stopNow()
{
rtttl::stop();
#ifdef HAS_I2S
audioThread->stop();
if (audioThread->isPlaying())
audioThread->stop();
#endif
nagCycleCutoff = 1; // small value
isNagging = false;
@@ -327,6 +397,21 @@ ExternalNotificationModule::ExternalNotificationModule()
rgb.begin();
rgb.setCurrent(10);
}
#endif
#ifdef RGBLED_RED
pinMode(RGBLED_RED, OUTPUT); // set up the RGB led pins
pinMode(RGBLED_GREEN, OUTPUT);
pinMode(RGBLED_BLUE, OUTPUT);
#endif
#ifdef RGBLED_CA
analogWrite(RGBLED_RED, 255); // with a common anode type, logic is reversed
analogWrite(RGBLED_GREEN, 255); // so we want to initialise with lights off
analogWrite(RGBLED_BLUE, 255);
#endif
#ifdef HAS_NEOPIXEL
pixels.begin(); // Initialise the pixel(s)
pixels.clear(); // Set all pixel colors to 'off'
pixels.setBrightness(moduleConfig.ambient_lighting.current);
#endif
} else {
LOG_INFO("External Notification Module Disabled\n");
@@ -508,4 +593,4 @@ void ExternalNotificationModule::handleSetRingtone(const char *from_msg)
if (changed) {
nodeDB->saveProto(rtttlConfigFile, meshtastic_RTTTLConfig_size, &meshtastic_RTTTLConfig_msg, &rtttlConfig);
}
}
}

View File

@@ -45,7 +45,7 @@
#include "modules/Telemetry/AirQualityTelemetry.h"
#include "modules/Telemetry/EnvironmentTelemetry.h"
#endif
#if HAS_TELEMETRY && !defined(ARCH_PORTDUINO) && !MESHTASTIC_EXCLUDE_POWER_TELEMETRY
#if HAS_TELEMETRY && !MESHTASTIC_EXCLUDE_POWER_TELEMETRY
#include "modules/Telemetry/PowerTelemetry.h"
#endif
#ifdef ARCH_ESP32
@@ -137,7 +137,7 @@ void setupModules()
#if HAS_SCREEN && !MESHTASTIC_EXCLUDE_CANNEDMESSAGES
cannedMessageModule = new CannedMessageModule();
#endif
#if HAS_TELEMETRY && !defined(ARCH_PORTDUINO)
#if HAS_TELEMETRY
new DeviceTelemetryModule();
#endif
#if HAS_SENSOR && !MESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR
@@ -146,7 +146,7 @@ void setupModules()
new AirQualityTelemetryModule();
}
#endif
#if HAS_TELEMETRY && !defined(ARCH_PORTDUINO) && !MESHTASTIC_EXCLUDE_POWER_TELEMETRY
#if HAS_TELEMETRY && !MESHTASTIC_EXCLUDE_POWER_TELEMETRY && !MESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR
new PowerTelemetryModule();
#endif
#if (defined(ARCH_ESP32) || defined(ARCH_NRF52) || defined(ARCH_RP2040)) && !defined(CONFIG_IDF_TARGET_ESP32S2) && \

View File

@@ -116,9 +116,8 @@ Will be used for broadcast.
*/
int32_t NeighborInfoModule::runOnce()
{
bool requestReplies = false;
if (airTime->isTxAllowedChannelUtil(true) && airTime->isTxAllowedAirUtil()) {
sendNeighborInfo(NODENUM_BROADCAST, requestReplies);
sendNeighborInfo(NODENUM_BROADCAST, false);
}
return Default::getConfiguredOrDefaultMs(moduleConfig.neighbor_info.update_interval, default_broadcast_interval_secs);
}

View File

@@ -17,6 +17,7 @@
extern "C" {
#include "mesh/compression/unishox2.h"
#include <Throttle.h>
}
PositionModule *positionModule;
@@ -63,21 +64,15 @@ bool PositionModule::handleReceivedProtobuf(const meshtastic_MeshPacket &mp, mes
}
// Log packet size and data fields
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 "
"time=%d\n",
getFrom(&mp), mp.decoded.payload.size, p.latitude_i, p.longitude_i, p.altitude, p.altitude_hae,
p.altitude_geoidal_separation, p.PDOP, p.HDOP, p.VDOP, p.sats_in_view, p.fix_quality, p.fix_type, p.timestamp,
p.time);
LOG_DEBUG("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 "
"time=%d\n",
getFrom(&mp), mp.decoded.payload.size, p.latitude_i, p.longitude_i, p.altitude, p.altitude_hae,
p.altitude_geoidal_separation, p.PDOP, p.HDOP, p.VDOP, p.sats_in_view, p.fix_quality, p.fix_type, p.timestamp,
p.time);
if (p.time && channels.getByIndex(mp.channel).role == meshtastic_Channel_Role_PRIMARY) {
struct timeval tv;
uint32_t secs = p.time;
tv.tv_sec = secs;
tv.tv_usec = 0;
// Set from phone RTC Quality to RTCQualityNTP since it should be approximately so
perhapsSetRTC(isLocal ? RTCQualityNTP : RTCQualityFromNet, &tv);
trySetRtc(p, isLocal);
}
nodeDB->updatePosition(getFrom(&mp), p);
@@ -92,6 +87,33 @@ bool PositionModule::handleReceivedProtobuf(const meshtastic_MeshPacket &mp, mes
return false; // Let others look at this message also if they want
}
void PositionModule::alterReceivedProtobuf(meshtastic_MeshPacket &mp, meshtastic_Position *p)
{
// Phone position packets need to be truncated to the channel precision
if (nodeDB->getNodeNum() == getFrom(&mp) && (precision < 32 && precision > 0)) {
LOG_DEBUG("Truncating phone position to channel precision %i\n", precision);
p->latitude_i = p->latitude_i & (UINT32_MAX << (32 - precision));
p->longitude_i = p->longitude_i & (UINT32_MAX << (32 - precision));
// We want the imprecise position to be the middle of the possible location, not
p->latitude_i += (1 << (31 - precision));
p->longitude_i += (1 << (31 - precision));
mp.decoded.payload.size =
pb_encode_to_bytes(mp.decoded.payload.bytes, sizeof(mp.decoded.payload.bytes), &meshtastic_Position_msg, p);
}
}
void PositionModule::trySetRtc(meshtastic_Position p, bool isLocal)
{
struct timeval tv;
uint32_t secs = p.time;
tv.tv_sec = secs;
tv.tv_usec = 0;
perhapsSetRTC(isLocal ? RTCQualityNTP : RTCQualityFromNet, &tv);
}
meshtastic_MeshPacket *PositionModule::allocReply()
{
if (precision == 0) {
@@ -222,6 +244,16 @@ meshtastic_MeshPacket *PositionModule::allocAtakPli()
return mp;
}
void PositionModule::sendOurPosition()
{
bool requestReplies = currentGeneration != radioGeneration;
currentGeneration = radioGeneration;
// If we changed channels, ask everyone else for their latest info
LOG_INFO("Sending pos@%x:6 to mesh (wantReplies=%d)\n", localPosition.timestamp, requestReplies);
sendOurPosition(NODENUM_BROADCAST, requestReplies);
}
void PositionModule::sendOurPosition(NodeNum dest, bool wantReplies, uint8_t channel)
{
// cancel any not yet sent (now stale) position packets
@@ -299,12 +331,7 @@ int32_t PositionModule::runOnce()
lastGpsLatitude = node->position.latitude_i;
lastGpsLongitude = node->position.longitude_i;
// 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);
sendOurPosition();
if (config.device.role == meshtastic_Config_DeviceConfig_Role_LOST_AND_FOUND) {
sendLostAndFoundText();
}
@@ -314,29 +341,23 @@ int32_t PositionModule::runOnce()
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 =
Default::getConfiguredOrDefaultMs(config.position.broadcast_smart_minimum_interval_secs, 30);
auto smartPosition = getDistanceTraveledSinceLastSend(node->position);
msSinceLastSend = now - lastGpsSend;
if (smartPosition.hasTraveledOverThreshold && msSinceLastSend >= minimumTimeThreshold) {
bool requestReplies = currentGeneration != radioGeneration;
currentGeneration = radioGeneration;
if (smartPosition.hasTraveledOverThreshold &&
Throttle::execute(
&lastGpsSend, minimumTimeThreshold, []() { positionModule->sendOurPosition(); },
[]() { LOG_DEBUG("Skipping send smart broadcast due to time throttling\n"); })) {
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);
LOG_DEBUG("Sent smart pos@%x:6 to mesh (distanceTraveled=%fm, minDistanceThreshold=%im, timeElapsed=%ims, "
"minTimeInterval=%ims)\n",
localPosition.timestamp, smartPosition.distanceTraveled, smartPosition.distanceThreshold,
msSinceLastSend, minimumTimeThreshold);
// 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;
}
}
}
@@ -396,27 +417,21 @@ 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);
uint32_t msSinceLastSend = millis() - lastGpsSend;
if (smartPosition.hasTraveledOverThreshold &&
Throttle::execute(
&lastGpsSend, minimumTimeThreshold, []() { positionModule->sendOurPosition(); },
[]() { LOG_DEBUG("Skipping send smart broadcast due to time throttling\n"); })) {
LOG_DEBUG("Sent smart pos@%x:6 to mesh (distanceTraveled=%fm, minDistanceThreshold=%im, timeElapsed=%ims, "
"minTimeInterval=%ims)\n",
localPosition.timestamp, smartPosition.distanceTraveled, smartPosition.distanceThreshold, msSinceLastSend,
minimumTimeThreshold);
// 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;
}
}
}

View File

@@ -1,4 +1,5 @@
#pragma once
#include "Default.h"
#include "ProtobufModule.h"
#include "concurrency/OSThread.h"
@@ -29,7 +30,8 @@ class PositionModule : public ProtobufModule<meshtastic_Position>, private concu
/**
* Send our position into the mesh
*/
void sendOurPosition(NodeNum dest = NODENUM_BROADCAST, bool wantReplies = false, uint8_t channel = 0);
void sendOurPosition(NodeNum dest, bool wantReplies = false, uint8_t channel = 0);
void sendOurPosition();
void handleNewPosition();
@@ -40,6 +42,8 @@ class PositionModule : public ProtobufModule<meshtastic_Position>, private concu
*/
virtual bool handleReceivedProtobuf(const meshtastic_MeshPacket &mp, meshtastic_Position *p) override;
virtual void alterReceivedProtobuf(meshtastic_MeshPacket &mp, meshtastic_Position *p) override;
/** Messages can be received that have the want_response bit set. If set, this callback will be invoked
* so that subclasses can (optionally) send a response back to the original sender. */
virtual meshtastic_MeshPacket *allocReply() override;
@@ -50,8 +54,12 @@ class PositionModule : public ProtobufModule<meshtastic_Position>, private concu
private:
struct SmartPosition getDistanceTraveledSinceLastSend(meshtastic_PositionLite currentPosition);
meshtastic_MeshPacket *allocAtakPli();
void trySetRtc(meshtastic_Position p, bool isLocal);
uint32_t precision;
void sendLostAndFoundText();
const uint32_t minimumTimeThreshold =
Default::getConfiguredOrDefaultMs(config.position.broadcast_smart_minimum_interval_secs, 30);
};
struct SmartPosition {

View File

@@ -51,7 +51,7 @@ uint8_t RoutingModule::getHopLimitForResponse(uint8_t hopStart, uint8_t hopLimit
uint8_t hopsUsed = hopStart < hopLimit ? config.lora.hop_limit : hopStart - hopLimit;
if (hopsUsed > config.lora.hop_limit) {
return hopsUsed; // If the request used more hops than the limit, use the same amount of hops
} else if (hopsUsed + 2 < config.lora.hop_limit) {
} else if ((uint8_t)(hopsUsed + 2) < config.lora.hop_limit) {
return hopsUsed + 2; // Use only the amount of hops needed with some margin as the way back may be different
}
}

View File

@@ -1,12 +1,15 @@
#include "AirQualityTelemetry.h"
#include "configuration.h"
#if !MESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR
#include "../mesh/generated/meshtastic/telemetry.pb.h"
#include "AirQualityTelemetry.h"
#include "Default.h"
#include "MeshService.h"
#include "NodeDB.h"
#include "PowerFSM.h"
#include "RTC.h"
#include "Router.h"
#include "configuration.h"
#include "main.h"
int32_t AirQualityTelemetryModule::runOnce()
@@ -130,3 +133,5 @@ bool AirQualityTelemetryModule::sendTelemetry(NodeNum dest, bool phoneOnly)
}
return true;
}
#endif

View File

@@ -1,3 +1,7 @@
#include "configuration.h"
#if !MESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR
#pragma once
#include "../mesh/generated/meshtastic/telemetry.pb.h"
#include "Adafruit_PM25AQI.h"
@@ -35,3 +39,5 @@ class AirQualityTelemetryModule : private concurrency::OSThread, public Protobuf
uint32_t sendToPhoneIntervalMs = SECONDS_IN_MINUTE * 1000; // Send to phone every minute
uint32_t lastSentToMesh = 0;
};
#endif

View File

@@ -1,12 +1,15 @@
#include "EnvironmentTelemetry.h"
#include "configuration.h"
#if !MESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR
#include "../mesh/generated/meshtastic/telemetry.pb.h"
#include "Default.h"
#include "EnvironmentTelemetry.h"
#include "MeshService.h"
#include "NodeDB.h"
#include "PowerFSM.h"
#include "RTC.h"
#include "Router.h"
#include "configuration.h"
#include "main.h"
#include "power.h"
#include "sleep.h"
@@ -21,7 +24,9 @@
#include "Sensor/BMP280Sensor.h"
#include "Sensor/LPS22HBSensor.h"
#include "Sensor/MCP9808Sensor.h"
#include "Sensor/RCWL9620Sensor.h"
#include "Sensor/SHT31Sensor.h"
#include "Sensor/SHT4XSensor.h"
#include "Sensor/SHTC3Sensor.h"
BMP085Sensor bmp085Sensor;
@@ -32,6 +37,8 @@ MCP9808Sensor mcp9808Sensor;
SHTC3Sensor shtc3Sensor;
LPS22HBSensor lps22hbSensor;
SHT31Sensor sht31Sensor;
SHT4XSensor sht4xSensor;
RCWL9620Sensor rcwl9620Sensor;
#define FAILED_STATE_SENSOR_READ_MULTIPLIER 10
#define DISPLAY_RECEIVEID_MEASUREMENTS_ON_SCREEN true
@@ -86,10 +93,14 @@ int32_t EnvironmentTelemetryModule::runOnce()
result = lps22hbSensor.runOnce();
if (sht31Sensor.hasSensor())
result = sht31Sensor.runOnce();
if (sht4xSensor.hasSensor())
result = sht4xSensor.runOnce();
if (ina219Sensor.hasSensor())
result = ina219Sensor.runOnce();
if (ina260Sensor.hasSensor())
result = ina260Sensor.runOnce();
if (rcwl9620Sensor.hasSensor())
result = rcwl9620Sensor.runOnce();
}
return result;
} else {
@@ -144,45 +155,56 @@ uint32_t GetTimeSinceMeshPacket(const meshtastic_MeshPacket *mp)
void EnvironmentTelemetryModule::drawFrame(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y)
{
display->setTextAlignment(TEXT_ALIGN_LEFT);
display->setFont(FONT_MEDIUM);
display->drawString(x, y, "Environment");
display->setFont(FONT_SMALL);
if (lastMeasurementPacket == nullptr) {
display->setFont(FONT_SMALL);
display->drawString(x, y += fontHeight(FONT_MEDIUM), "No measurement");
// If there's no valid packet, display "Environment"
display->drawString(x, y, "Environment");
display->drawString(x, y += fontHeight(FONT_SMALL), "No measurement");
return;
}
// Decode the last measurement packet
meshtastic_Telemetry lastMeasurement;
uint32_t agoSecs = GetTimeSinceMeshPacket(lastMeasurementPacket);
const char *lastSender = getSenderShortName(*lastMeasurementPacket);
auto &p = lastMeasurementPacket->decoded;
if (!pb_decode_from_bytes(p.payload.bytes, p.payload.size, &meshtastic_Telemetry_msg, &lastMeasurement)) {
display->setFont(FONT_SMALL);
display->drawString(x, y += fontHeight(FONT_MEDIUM), "Measurement Error");
display->drawString(x, y, "Measurement Error");
LOG_ERROR("Unable to decode last packet");
return;
}
display->setFont(FONT_SMALL);
// Display "Env. From: ..." on its own
display->drawString(x, y, "Env. From: " + String(lastSender) + "(" + String(agoSecs) + "s)");
String last_temp = String(lastMeasurement.variant.environment_metrics.temperature, 0) + "°C";
if (moduleConfig.telemetry.environment_display_fahrenheit) {
last_temp = String(CelsiusToFahrenheit(lastMeasurement.variant.environment_metrics.temperature), 0) + "°F";
}
display->drawString(x, y += fontHeight(FONT_MEDIUM) - 2, "From: " + String(lastSender) + "(" + String(agoSecs) + "s)");
display->drawString(x, y += fontHeight(FONT_SMALL) - 2,
// Continue with the remaining details
display->drawString(x, y += fontHeight(FONT_SMALL),
"Temp/Hum: " + last_temp + " / " +
String(lastMeasurement.variant.environment_metrics.relative_humidity, 0) + "%");
if (lastMeasurement.variant.environment_metrics.barometric_pressure != 0)
if (lastMeasurement.variant.environment_metrics.barometric_pressure != 0) {
display->drawString(x, y += fontHeight(FONT_SMALL),
"Press: " + String(lastMeasurement.variant.environment_metrics.barometric_pressure, 0) + "hPA");
if (lastMeasurement.variant.environment_metrics.voltage != 0)
}
if (lastMeasurement.variant.environment_metrics.voltage != 0) {
display->drawString(x, y += fontHeight(FONT_SMALL),
"Volt/Cur: " + String(lastMeasurement.variant.environment_metrics.voltage, 0) + "V / " +
String(lastMeasurement.variant.environment_metrics.current, 0) + "mA");
if (lastMeasurement.variant.environment_metrics.iaq != 0)
}
if (lastMeasurement.variant.environment_metrics.iaq != 0) {
display->drawString(x, y += fontHeight(FONT_SMALL), "IAQ: " + String(lastMeasurement.variant.environment_metrics.iaq));
}
if (lastMeasurement.variant.environment_metrics.distance != 0)
display->drawString(x, y += fontHeight(FONT_SMALL),
"Water Level: " + String(lastMeasurement.variant.environment_metrics.distance, 0) + "mm");
}
bool EnvironmentTelemetryModule::handleReceivedProtobuf(const meshtastic_MeshPacket &mp, meshtastic_Telemetry *t)
@@ -192,10 +214,13 @@ bool EnvironmentTelemetryModule::handleReceivedProtobuf(const meshtastic_MeshPac
const char *sender = getSenderShortName(mp);
LOG_INFO("(Received from %s): barometric_pressure=%f, current=%f, gas_resistance=%f, relative_humidity=%f, "
"temperature=%f, voltage=%f\n",
"temperature=%f\n",
sender, t->variant.environment_metrics.barometric_pressure, t->variant.environment_metrics.current,
t->variant.environment_metrics.gas_resistance, t->variant.environment_metrics.relative_humidity,
t->variant.environment_metrics.temperature, t->variant.environment_metrics.voltage);
t->variant.environment_metrics.temperature);
LOG_INFO("(Received from %s): voltage=%f, IAQ=%d, distance=%f\n", sender, t->variant.environment_metrics.voltage,
t->variant.environment_metrics.iaq, t->variant.environment_metrics.distance);
#endif
// release previous packet before occupying a new spot
if (lastMeasurementPacket != nullptr)
@@ -220,9 +245,13 @@ bool EnvironmentTelemetryModule::sendTelemetry(NodeNum dest, bool phoneOnly)
m.variant.environment_metrics.relative_humidity = 0;
m.variant.environment_metrics.temperature = 0;
m.variant.environment_metrics.voltage = 0;
m.variant.environment_metrics.iaq = 0;
m.variant.environment_metrics.distance = 0;
if (sht31Sensor.hasSensor())
valid = sht31Sensor.getMetrics(&m);
if (sht4xSensor.hasSensor())
valid = sht4xSensor.getMetrics(&m);
if (lps22hbSensor.hasSensor())
valid = lps22hbSensor.getMetrics(&m);
if (shtc3Sensor.hasSensor())
@@ -241,13 +270,16 @@ bool EnvironmentTelemetryModule::sendTelemetry(NodeNum dest, bool phoneOnly)
valid = ina219Sensor.getMetrics(&m);
if (ina260Sensor.hasSensor())
valid = ina260Sensor.getMetrics(&m);
if (rcwl9620Sensor.hasSensor())
valid = rcwl9620Sensor.getMetrics(&m);
if (valid) {
LOG_INFO("(Sending): barometric_pressure=%f, current=%f, gas_resistance=%f, relative_humidity=%f, temperature=%f, "
"voltage=%f\n",
LOG_INFO("(Sending): barometric_pressure=%f, current=%f, gas_resistance=%f, relative_humidity=%f, temperature=%f\n",
m.variant.environment_metrics.barometric_pressure, m.variant.environment_metrics.current,
m.variant.environment_metrics.gas_resistance, m.variant.environment_metrics.relative_humidity,
m.variant.environment_metrics.temperature, m.variant.environment_metrics.voltage);
m.variant.environment_metrics.temperature);
LOG_INFO("(Sending): voltage=%f, IAQ=%d, distance=%f\n", m.variant.environment_metrics.voltage,
m.variant.environment_metrics.iaq, m.variant.environment_metrics.distance);
sensor_read_error_count = 0;
@@ -278,4 +310,6 @@ bool EnvironmentTelemetryModule::sendTelemetry(NodeNum dest, bool phoneOnly)
}
}
return valid;
}
}
#endif

View File

@@ -1,3 +1,7 @@
#include "configuration.h"
#if !MESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR
#pragma once
#include "../mesh/generated/meshtastic/telemetry.pb.h"
#include "NodeDB.h"
@@ -42,3 +46,5 @@ class EnvironmentTelemetryModule : private concurrency::OSThread, public Protobu
uint32_t lastSentToPhone = 0;
uint32_t sensor_read_error_count = 0;
};
#endif

View File

@@ -1,12 +1,15 @@
#include "PowerTelemetry.h"
#include "configuration.h"
#if !MESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR
#include "../mesh/generated/meshtastic/telemetry.pb.h"
#include "Default.h"
#include "MeshService.h"
#include "NodeDB.h"
#include "PowerFSM.h"
#include "PowerTelemetry.h"
#include "RTC.h"
#include "Router.h"
#include "configuration.h"
#include "main.h"
#include "power.h"
#include "sleep.h"
@@ -217,4 +220,6 @@ bool PowerTelemetryModule::sendTelemetry(NodeNum dest, bool phoneOnly)
}
}
return valid;
}
}
#endif

View File

@@ -1,4 +1,9 @@
#pragma once
#include "configuration.h"
#if !MESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR
#include "../mesh/generated/meshtastic/telemetry.pb.h"
#include "NodeDB.h"
#include "ProtobufModule.h"
@@ -41,3 +46,5 @@ class PowerTelemetryModule : private concurrency::OSThread, public ProtobufModul
uint32_t lastSentToPhone = 0;
uint32_t sensor_read_error_count = 0;
};
#endif

View File

@@ -1,7 +1,10 @@
#include "BME280Sensor.h"
#include "../mesh/generated/meshtastic/telemetry.pb.h"
#include "TelemetrySensor.h"
#include "configuration.h"
#if !MESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR
#include "../mesh/generated/meshtastic/telemetry.pb.h"
#include "BME280Sensor.h"
#include "TelemetrySensor.h"
#include <Adafruit_BME280.h>
#include <typeinfo>
@@ -35,4 +38,5 @@ bool BME280Sensor::getMetrics(meshtastic_Telemetry *measurement)
measurement->variant.environment_metrics.barometric_pressure = bme280.readPressure() / 100.0F;
return true;
}
}
#endif

View File

@@ -1,3 +1,7 @@
#include "configuration.h"
#if !MESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR
#include "../mesh/generated/meshtastic/telemetry.pb.h"
#include "TelemetrySensor.h"
#include <Adafruit_BME280.h>
@@ -14,4 +18,6 @@ class BME280Sensor : public TelemetrySensor
BME280Sensor();
virtual int32_t runOnce() override;
virtual bool getMetrics(meshtastic_Telemetry *measurement) override;
};
};
#endif

View File

@@ -1,8 +1,11 @@
#include "BME680Sensor.h"
#include "configuration.h"
#if !MESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR
#include "../mesh/generated/meshtastic/telemetry.pb.h"
#include "BME680Sensor.h"
#include "FSCommon.h"
#include "TelemetrySensor.h"
#include "configuration.h"
BME680Sensor::BME680Sensor() : TelemetrySensor(meshtastic_TelemetrySensorType_BME680, "BME680") {}
@@ -134,3 +137,5 @@ void BME680Sensor::checkStatus(String functionName)
else if (bme680.sensor.status > BME68X_OK)
LOG_WARN("%s BME68X code: %s\n", functionName.c_str(), String(bme680.sensor.status).c_str());
}
#endif

View File

@@ -1,3 +1,7 @@
#include "configuration.h"
#if !MESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR
#include "../mesh/generated/meshtastic/telemetry.pb.h"
#include "TelemetrySensor.h"
#include <bsec2.h>
@@ -35,4 +39,6 @@ class BME680Sensor : public TelemetrySensor
int32_t runTrigger();
virtual int32_t runOnce() override;
virtual bool getMetrics(meshtastic_Telemetry *measurement) override;
};
};
#endif

View File

@@ -1,7 +1,10 @@
#include "BMP085Sensor.h"
#include "../mesh/generated/meshtastic/telemetry.pb.h"
#include "TelemetrySensor.h"
#include "configuration.h"
#if !MESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR
#include "../mesh/generated/meshtastic/telemetry.pb.h"
#include "BMP085Sensor.h"
#include "TelemetrySensor.h"
#include <Adafruit_BMP085.h>
#include <typeinfo>
@@ -29,3 +32,5 @@ bool BMP085Sensor::getMetrics(meshtastic_Telemetry *measurement)
return true;
}
#endif

View File

@@ -1,3 +1,7 @@
#include "configuration.h"
#if !MESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR
#include "../mesh/generated/meshtastic/telemetry.pb.h"
#include "TelemetrySensor.h"
#include <Adafruit_BMP085.h>
@@ -14,4 +18,6 @@ class BMP085Sensor : public TelemetrySensor
BMP085Sensor();
virtual int32_t runOnce() override;
virtual bool getMetrics(meshtastic_Telemetry *measurement) override;
};
};
#endif

View File

@@ -1,7 +1,10 @@
#include "BMP280Sensor.h"
#include "../mesh/generated/meshtastic/telemetry.pb.h"
#include "TelemetrySensor.h"
#include "configuration.h"
#if !MESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR
#include "../mesh/generated/meshtastic/telemetry.pb.h"
#include "BMP280Sensor.h"
#include "TelemetrySensor.h"
#include <Adafruit_BMP280.h>
#include <typeinfo>
@@ -35,3 +38,5 @@ bool BMP280Sensor::getMetrics(meshtastic_Telemetry *measurement)
return true;
}
#endif

View File

@@ -1,3 +1,7 @@
#include "configuration.h"
#if !MESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR
#include "../mesh/generated/meshtastic/telemetry.pb.h"
#include "TelemetrySensor.h"
#include <Adafruit_BMP280.h>
@@ -14,4 +18,6 @@ class BMP280Sensor : public TelemetrySensor
BMP280Sensor();
virtual int32_t runOnce() override;
virtual bool getMetrics(meshtastic_Telemetry *measurement) override;
};
};
#endif

View File

@@ -1,7 +1,10 @@
#include "INA219Sensor.h"
#include "../mesh/generated/meshtastic/telemetry.pb.h"
#include "TelemetrySensor.h"
#include "configuration.h"
#if HAS_TELEMETRY && !MESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR
#include "../mesh/generated/meshtastic/telemetry.pb.h"
#include "INA219Sensor.h"
#include "TelemetrySensor.h"
#include <Adafruit_INA219.h>
#ifndef INA219_MULTIPLIER
@@ -37,4 +40,6 @@ bool INA219Sensor::getMetrics(meshtastic_Telemetry *measurement)
uint16_t INA219Sensor::getBusVoltageMv()
{
return lround(ina219.getBusVoltage_V() * 1000);
}
}
#endif

View File

@@ -1,3 +1,7 @@
#include "configuration.h"
#if HAS_TELEMETRY && !MESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR
#include "../mesh/generated/meshtastic/telemetry.pb.h"
#include "TelemetrySensor.h"
#include "VoltageSensor.h"
@@ -16,4 +20,6 @@ class INA219Sensor : public TelemetrySensor, VoltageSensor
virtual int32_t runOnce() override;
virtual bool getMetrics(meshtastic_Telemetry *measurement) override;
virtual uint16_t getBusVoltageMv() override;
};
};
#endif

View File

@@ -1,7 +1,10 @@
#include "INA260Sensor.h"
#include "../mesh/generated/meshtastic/telemetry.pb.h"
#include "TelemetrySensor.h"
#include "configuration.h"
#if HAS_TELEMETRY && !MESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR
#include "../mesh/generated/meshtastic/telemetry.pb.h"
#include "INA260Sensor.h"
#include "TelemetrySensor.h"
#include <Adafruit_INA260.h>
INA260Sensor::INA260Sensor() : TelemetrySensor(meshtastic_TelemetrySensorType_INA260, "INA260") {}
@@ -32,4 +35,6 @@ bool INA260Sensor::getMetrics(meshtastic_Telemetry *measurement)
uint16_t INA260Sensor::getBusVoltageMv()
{
return lround(ina260.readBusVoltage());
}
}
#endif

View File

@@ -1,3 +1,7 @@
#include "configuration.h"
#if HAS_TELEMETRY && !MESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR
#include "../mesh/generated/meshtastic/telemetry.pb.h"
#include "TelemetrySensor.h"
#include "VoltageSensor.h"
@@ -16,4 +20,6 @@ class INA260Sensor : public TelemetrySensor, VoltageSensor
virtual int32_t runOnce() override;
virtual bool getMetrics(meshtastic_Telemetry *measurement) override;
virtual uint16_t getBusVoltageMv() override;
};
};
#endif

View File

@@ -1,7 +1,10 @@
#include "INA3221Sensor.h"
#include "../mesh/generated/meshtastic/telemetry.pb.h"
#include "TelemetrySensor.h"
#include "configuration.h"
#if HAS_TELEMETRY && !MESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR
#include "../mesh/generated/meshtastic/telemetry.pb.h"
#include "INA3221Sensor.h"
#include "TelemetrySensor.h"
#include <INA3221.h>
INA3221Sensor::INA3221Sensor() : TelemetrySensor(meshtastic_TelemetrySensorType_INA3221, "INA3221"){};
@@ -41,4 +44,6 @@ bool INA3221Sensor::getMetrics(meshtastic_Telemetry *measurement)
uint16_t INA3221Sensor::getBusVoltageMv()
{
return lround(ina3221.getVoltage(INA3221_CH1) * 1000);
}
}
#endif

View File

@@ -1,3 +1,7 @@
#include "configuration.h"
#if HAS_TELEMETRY && !MESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR
#include "../mesh/generated/meshtastic/telemetry.pb.h"
#include "TelemetrySensor.h"
#include "VoltageSensor.h"
@@ -16,4 +20,6 @@ class INA3221Sensor : public TelemetrySensor, VoltageSensor
int32_t runOnce() override;
bool getMetrics(meshtastic_Telemetry *measurement) override;
virtual uint16_t getBusVoltageMv() override;
};
};
#endif

View File

@@ -1,7 +1,10 @@
#include "LPS22HBSensor.h"
#include "../mesh/generated/meshtastic/telemetry.pb.h"
#include "TelemetrySensor.h"
#include "configuration.h"
#if !MESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR
#include "../mesh/generated/meshtastic/telemetry.pb.h"
#include "LPS22HBSensor.h"
#include "TelemetrySensor.h"
#include <Adafruit_LPS2X.h>
#include <Adafruit_Sensor.h>
@@ -32,4 +35,6 @@ bool LPS22HBSensor::getMetrics(meshtastic_Telemetry *measurement)
measurement->variant.environment_metrics.barometric_pressure = pressure.pressure;
return true;
}
}
#endif

View File

@@ -1,3 +1,7 @@
#include "configuration.h"
#if !MESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR
#include "../mesh/generated/meshtastic/telemetry.pb.h"
#include "TelemetrySensor.h"
#include <Adafruit_LPS2X.h>
@@ -15,4 +19,6 @@ class LPS22HBSensor : public TelemetrySensor
LPS22HBSensor();
virtual int32_t runOnce() override;
virtual bool getMetrics(meshtastic_Telemetry *measurement) override;
};
};
#endif

View File

@@ -1,7 +1,10 @@
#include "MCP9808Sensor.h"
#include "../mesh/generated/meshtastic/telemetry.pb.h"
#include "TelemetrySensor.h"
#include "configuration.h"
#if !MESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR
#include "../mesh/generated/meshtastic/telemetry.pb.h"
#include "MCP9808Sensor.h"
#include "TelemetrySensor.h"
#include <Adafruit_MCP9808.h>
MCP9808Sensor::MCP9808Sensor() : TelemetrySensor(meshtastic_TelemetrySensorType_MCP9808, "MCP9808") {}
@@ -26,4 +29,6 @@ bool MCP9808Sensor::getMetrics(meshtastic_Telemetry *measurement)
LOG_DEBUG("MCP9808Sensor::getMetrics\n");
measurement->variant.environment_metrics.temperature = mcp9808.readTempC();
return true;
}
}
#endif

View File

@@ -1,3 +1,7 @@
#include "configuration.h"
#if !MESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR
#include "../mesh/generated/meshtastic/telemetry.pb.h"
#include "TelemetrySensor.h"
#include <Adafruit_MCP9808.h>
@@ -14,4 +18,6 @@ class MCP9808Sensor : public TelemetrySensor
MCP9808Sensor();
virtual int32_t runOnce() override;
virtual bool getMetrics(meshtastic_Telemetry *measurement) override;
};
};
#endif

View File

@@ -0,0 +1,65 @@
#include "configuration.h"
#if !MESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR
#include "../mesh/generated/meshtastic/telemetry.pb.h"
#include "RCWL9620Sensor.h"
#include "TelemetrySensor.h"
RCWL9620Sensor::RCWL9620Sensor() : TelemetrySensor(meshtastic_TelemetrySensorType_RCWL9620, "RCWL9620") {}
int32_t RCWL9620Sensor::runOnce()
{
LOG_INFO("Init sensor: %s\n", sensorName);
if (!hasSensor()) {
return DEFAULT_SENSOR_MINIMUM_WAIT_TIME_BETWEEN_READS;
}
status = 1;
begin(nodeTelemetrySensorsMap[sensorType].second, nodeTelemetrySensorsMap[sensorType].first);
return initI2CSensor();
}
void RCWL9620Sensor::setup() {}
bool RCWL9620Sensor::getMetrics(meshtastic_Telemetry *measurement)
{
LOG_DEBUG("RCWL9620Sensor::getMetrics\n");
measurement->variant.environment_metrics.distance = getDistance();
return true;
}
void RCWL9620Sensor::begin(TwoWire *wire, uint8_t addr, uint8_t sda, uint8_t scl, uint32_t speed)
{
_wire = wire;
_addr = addr;
_sda = sda;
_scl = scl;
_speed = speed;
_wire->begin();
}
float RCWL9620Sensor::getDistance()
{
uint32_t data;
_wire->beginTransmission(_addr); // Transfer data to addr.
_wire->write(0x01);
_wire->endTransmission(); // Stop data transmission with the Ultrasonic
// Unit.
_wire->requestFrom(_addr,
(uint8_t)3); // Request 3 bytes from Ultrasonic Unit.
data = _wire->read();
data <<= 8;
data |= _wire->read();
data <<= 8;
data |= _wire->read();
float Distance = float(data) / 1000;
if (Distance > 4500.00) {
return 4500.00;
} else {
return Distance;
}
}
#endif

View File

@@ -0,0 +1,29 @@
#include "configuration.h"
#if !MESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR
#include "../mesh/generated/meshtastic/telemetry.pb.h"
#include "TelemetrySensor.h"
#include <Wire.h>
class RCWL9620Sensor : public TelemetrySensor
{
private:
uint8_t _addr = 0x57;
TwoWire *_wire = &Wire;
uint8_t _scl = -1;
uint8_t _sda = -1;
uint32_t _speed = 200000UL;
protected:
virtual void setup() override;
void begin(TwoWire *wire = &Wire, uint8_t addr = 0x57, uint8_t sda = -1, uint8_t scl = -1, uint32_t speed = 200000UL);
float getDistance();
public:
RCWL9620Sensor();
virtual int32_t runOnce() override;
virtual bool getMetrics(meshtastic_Telemetry *measurement) override;
};
#endif

View File

@@ -1,7 +1,10 @@
#include "SHT31Sensor.h"
#include "../mesh/generated/meshtastic/telemetry.pb.h"
#include "TelemetrySensor.h"
#include "configuration.h"
#if !MESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR
#include "../mesh/generated/meshtastic/telemetry.pb.h"
#include "SHT31Sensor.h"
#include "TelemetrySensor.h"
#include <Adafruit_SHT31.h>
SHT31Sensor::SHT31Sensor() : TelemetrySensor(meshtastic_TelemetrySensorType_SHT31, "SHT31") {}
@@ -29,3 +32,5 @@ bool SHT31Sensor::getMetrics(meshtastic_Telemetry *measurement)
return true;
}
#endif

View File

@@ -1,3 +1,7 @@
#include "configuration.h"
#if !MESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR
#include "../mesh/generated/meshtastic/telemetry.pb.h"
#include "TelemetrySensor.h"
#include <Adafruit_SHT31.h>
@@ -15,3 +19,5 @@ class SHT31Sensor : public TelemetrySensor
virtual int32_t runOnce() override;
virtual bool getMetrics(meshtastic_Telemetry *measurement) override;
};
#endif

View File

@@ -0,0 +1,63 @@
#include "configuration.h"
#if !MESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR
#include "../mesh/generated/meshtastic/telemetry.pb.h"
#include "SHT4XSensor.h"
#include "TelemetrySensor.h"
#include <SensirionI2cSht4x.h>
// macro definitions
// make sure that we use the proper definition of NO_ERROR
#ifdef NO_ERROR
#undef NO_ERROR
#endif
#define NO_ERROR 0
static char errorMessage[64];
static int16_t error;
SHT4XSensor::SHT4XSensor() : TelemetrySensor(meshtastic_TelemetrySensorType_SHT4X, "SHT4X") {}
int32_t SHT4XSensor::runOnce()
{
LOG_INFO("Init sensor: %s\n", sensorName);
if (!hasSensor()) {
return DEFAULT_SENSOR_MINIMUM_WAIT_TIME_BETWEEN_READS;
}
uint32_t serialNumber = 0;
sht4x.begin(*nodeTelemetrySensorsMap[sensorType].second, 0x44);
error = sht4x.serialNumber(serialNumber);
LOG_DEBUG("serialNumber : %x\n", serialNumber);
if (error != NO_ERROR) {
LOG_DEBUG("Error trying to execute serialNumber(): ");
errorToString(error, errorMessage, sizeof errorMessage);
LOG_DEBUG(errorMessage);
status = 0;
} else {
status = 1;
}
return initI2CSensor();
}
void SHT4XSensor::setup()
{
// Set up oversampling and filter initialization
}
bool SHT4XSensor::getMetrics(meshtastic_Telemetry *measurement)
{
float aTemperature = 0.0;
float aHumidity = 0.0;
sht4x.measureLowestPrecision(aTemperature, aHumidity);
measurement->variant.environment_metrics.temperature = aTemperature;
measurement->variant.environment_metrics.relative_humidity = aHumidity;
return true;
}
#endif

View File

@@ -0,0 +1,23 @@
#include "configuration.h"
#if !MESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR
#include "../mesh/generated/meshtastic/telemetry.pb.h"
#include "TelemetrySensor.h"
#include <SensirionI2cSht4x.h>
class SHT4XSensor : public TelemetrySensor
{
private:
SensirionI2cSht4x sht4x;
protected:
virtual void setup() override;
public:
SHT4XSensor();
virtual int32_t runOnce() override;
virtual bool getMetrics(meshtastic_Telemetry *measurement) override;
};
#endif

View File

@@ -1,7 +1,10 @@
#include "SHTC3Sensor.h"
#include "../mesh/generated/meshtastic/telemetry.pb.h"
#include "TelemetrySensor.h"
#include "configuration.h"
#if !MESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR
#include "../mesh/generated/meshtastic/telemetry.pb.h"
#include "SHTC3Sensor.h"
#include "TelemetrySensor.h"
#include <Adafruit_SHTC3.h>
SHTC3Sensor::SHTC3Sensor() : TelemetrySensor(meshtastic_TelemetrySensorType_SHTC3, "SHTC3") {}
@@ -30,4 +33,6 @@ bool SHTC3Sensor::getMetrics(meshtastic_Telemetry *measurement)
measurement->variant.environment_metrics.relative_humidity = humidity.relative_humidity;
return true;
}
}
#endif

View File

@@ -1,3 +1,7 @@
#include "configuration.h"
#if !MESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR
#include "../mesh/generated/meshtastic/telemetry.pb.h"
#include "TelemetrySensor.h"
#include <Adafruit_SHTC3.h>
@@ -14,4 +18,6 @@ class SHTC3Sensor : public TelemetrySensor
SHTC3Sensor();
virtual int32_t runOnce() override;
virtual bool getMetrics(meshtastic_Telemetry *measurement) override;
};
};
#endif

View File

@@ -1,4 +1,10 @@
#include "TelemetrySensor.h"
#include "configuration.h"
#if !MESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR
#include "../mesh/generated/meshtastic/telemetry.pb.h"
#include "NodeDB.h"
#include "TelemetrySensor.h"
#include "main.h"
#endif

View File

@@ -1,3 +1,7 @@
#include "configuration.h"
#if !MESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR
#pragma once
#include "../mesh/generated/meshtastic/telemetry.pb.h"
#include "NodeDB.h"
@@ -45,4 +49,6 @@ class TelemetrySensor
virtual bool isRunning() { return status > 0; }
virtual bool getMetrics(meshtastic_Telemetry *measurement) = 0;
};
};
#endif

View File

@@ -1,7 +1,13 @@
#include "configuration.h"
#if !MESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR
#pragma once
class VoltageSensor
{
public:
virtual uint16_t getBusVoltageMv() = 0;
};
};
#endif

View File

@@ -1,3 +1,5 @@
#if !MESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR
#include "bsec_iaq.h"
const uint8_t bsec_config_iaq[1974] = {
@@ -80,3 +82,5 @@ const uint8_t bsec_config_iaq[1974] = {
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 44, 1, 0, 5, 10, 5,
0, 2, 0, 10, 0, 30, 0, 5, 0, 5, 0, 5, 0, 5, 0, 5, 0, 5, 0, 64, 1, 100, 0, 100, 0,
100, 0, 200, 0, 200, 0, 200, 0, 64, 1, 64, 1, 64, 1, 10, 0, 0, 0, 0, 0, 21, 122, 0, 0};
#endif

View File

@@ -1,3 +1,7 @@
#if !MESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR
#include <stdint.h>
extern const uint8_t bsec_config_iaq[1974];
#endif

View File

@@ -1,5 +1,5 @@
#include "configuration.h"
#if defined(ARCH_ESP32)
#if defined(ARCH_ESP32) && !MESHTASTIC_EXCLUDE_PAXCOUNTER
#include "Default.h"
#include "MeshService.h"
#include "PaxcounterModule.h"

View File

@@ -368,9 +368,9 @@ JSONValue::JSONValue(int m_integer_value)
*
* @access public
*
* @param uint m_integer_value The number to use as the value
* @param unsigned int m_integer_value The number to use as the value
*/
JSONValue::JSONValue(uint m_integer_value)
JSONValue::JSONValue(unsigned int m_integer_value)
{
type = JSONType_Number;
number_value = (double)m_integer_value;

View File

@@ -45,7 +45,7 @@ class JSONValue
JSONValue(bool m_bool_value);
JSONValue(double m_number_value);
JSONValue(int m_integer_value);
JSONValue(uint m_integer_value);
JSONValue(unsigned int m_integer_value);
JSONValue(const JSONArray &m_array_value);
JSONValue(const JSONObject &m_object_value);
JSONValue(const JSONValue &m_source);

View File

@@ -54,9 +54,9 @@ void MQTT::onReceive(char *topic, byte *payload, size_t length)
JSONObject json;
json = json_value->AsObject();
// parse the channel name from the topic string by looking for "json/"
const char *jsonSlash = "json/";
char *ptr = strstr(topic, jsonSlash) + sizeof(jsonSlash) + 1; // set pointer to after "json/"
// parse the channel name from the topic string
// the topic has been checked above for having jsonTopic prefix, so just move past it
char *ptr = topic + jsonTopic.length();
ptr = strtok(ptr, "/") ? strtok(ptr, "/") : ptr; // if another "/" was added, parse string up to that character
meshtastic_Channel sendChannel = channels.getByName(ptr);
// We allow downlink JSON packets only on a channel named "mqtt"
@@ -76,6 +76,8 @@ void MQTT::onReceive(char *topic, byte *payload, size_t length)
p->channel = json["channel"]->AsNumber();
if (json.find("to") != json.end() && json["to"]->IsNumber())
p->to = json["to"]->AsNumber();
if (json.find("hopLimit") != json.end() && json["hopLimit"]->IsNumber())
p->hop_limit = json["hopLimit"]->AsNumber();
if (jsonPayloadStr.length() <= sizeof(p->decoded.payload.bytes)) {
memcpy(p->decoded.payload.bytes, jsonPayloadStr.c_str(), jsonPayloadStr.length());
p->decoded.payload.size = jsonPayloadStr.length();
@@ -105,6 +107,8 @@ void MQTT::onReceive(char *topic, byte *payload, size_t length)
p->channel = json["channel"]->AsNumber();
if (json.find("to") != json.end() && json["to"]->IsNumber())
p->to = json["to"]->AsNumber();
if (json.find("hopLimit") != json.end() && json["hopLimit"]->IsNumber())
p->hop_limit = json["hopLimit"]->AsNumber();
p->decoded.payload.size =
pb_encode_to_bytes(p->decoded.payload.bytes, sizeof(p->decoded.payload.bytes),
&meshtastic_Position_msg, &pos); // make the Data protobuf from position
@@ -548,7 +552,10 @@ void MQTT::perhapsReportToMap()
} else {
if (map_position_precision == 0 || (localPosition.latitude_i == 0 && localPosition.longitude_i == 0)) {
last_report_to_map = millis();
LOG_WARN("MQTT Map reporting is enabled, but precision is 0 or no position available.\n");
if (map_position_precision == 0)
LOG_WARN("MQTT Map reporting is enabled, but precision is 0\n");
if (localPosition.latitude_i == 0 && localPosition.longitude_i == 0)
LOG_WARN("MQTT Map reporting is enabled, but no position available.\n");
return;
}
@@ -652,11 +659,11 @@ std::string MQTT::meshPacketToJson(meshtastic_MeshPacket *mp)
if (pb_decode_from_bytes(mp->decoded.payload.bytes, mp->decoded.payload.size, &meshtastic_Telemetry_msg, &scratch)) {
decoded = &scratch;
if (decoded->which_variant == meshtastic_Telemetry_device_metrics_tag) {
msgPayload["battery_level"] = new JSONValue((uint)decoded->variant.device_metrics.battery_level);
msgPayload["battery_level"] = new JSONValue((unsigned int)decoded->variant.device_metrics.battery_level);
msgPayload["voltage"] = new JSONValue(decoded->variant.device_metrics.voltage);
msgPayload["channel_utilization"] = new JSONValue(decoded->variant.device_metrics.channel_utilization);
msgPayload["air_util_tx"] = new JSONValue(decoded->variant.device_metrics.air_util_tx);
msgPayload["uptime_seconds"] = new JSONValue((uint)decoded->variant.device_metrics.uptime_seconds);
msgPayload["uptime_seconds"] = new JSONValue((unsigned int)decoded->variant.device_metrics.uptime_seconds);
} else if (decoded->which_variant == meshtastic_Telemetry_environment_metrics_tag) {
msgPayload["temperature"] = new JSONValue(decoded->variant.environment_metrics.temperature);
msgPayload["relative_humidity"] = new JSONValue(decoded->variant.environment_metrics.relative_humidity);
@@ -703,10 +710,10 @@ std::string MQTT::meshPacketToJson(meshtastic_MeshPacket *mp)
if (pb_decode_from_bytes(mp->decoded.payload.bytes, mp->decoded.payload.size, &meshtastic_Position_msg, &scratch)) {
decoded = &scratch;
if ((int)decoded->time) {
msgPayload["time"] = new JSONValue((uint)decoded->time);
msgPayload["time"] = new JSONValue((unsigned int)decoded->time);
}
if ((int)decoded->timestamp) {
msgPayload["timestamp"] = new JSONValue((uint)decoded->timestamp);
msgPayload["timestamp"] = new JSONValue((unsigned int)decoded->timestamp);
}
msgPayload["latitude_i"] = new JSONValue((int)decoded->latitude_i);
msgPayload["longitude_i"] = new JSONValue((int)decoded->longitude_i);
@@ -714,13 +721,13 @@ std::string MQTT::meshPacketToJson(meshtastic_MeshPacket *mp)
msgPayload["altitude"] = new JSONValue((int)decoded->altitude);
}
if ((int)decoded->ground_speed) {
msgPayload["ground_speed"] = new JSONValue((uint)decoded->ground_speed);
msgPayload["ground_speed"] = new JSONValue((unsigned int)decoded->ground_speed);
}
if (int(decoded->ground_track)) {
msgPayload["ground_track"] = new JSONValue((uint)decoded->ground_track);
msgPayload["ground_track"] = new JSONValue((unsigned int)decoded->ground_track);
}
if (int(decoded->sats_in_view)) {
msgPayload["sats_in_view"] = new JSONValue((uint)decoded->sats_in_view);
msgPayload["sats_in_view"] = new JSONValue((unsigned int)decoded->sats_in_view);
}
if ((int)decoded->PDOP) {
msgPayload["PDOP"] = new JSONValue((int)decoded->PDOP);
@@ -747,11 +754,11 @@ std::string MQTT::meshPacketToJson(meshtastic_MeshPacket *mp)
memset(&scratch, 0, sizeof(scratch));
if (pb_decode_from_bytes(mp->decoded.payload.bytes, mp->decoded.payload.size, &meshtastic_Waypoint_msg, &scratch)) {
decoded = &scratch;
msgPayload["id"] = new JSONValue((uint)decoded->id);
msgPayload["id"] = new JSONValue((unsigned int)decoded->id);
msgPayload["name"] = new JSONValue(decoded->name);
msgPayload["description"] = new JSONValue(decoded->description);
msgPayload["expire"] = new JSONValue((uint)decoded->expire);
msgPayload["locked_to"] = new JSONValue((uint)decoded->locked_to);
msgPayload["expire"] = new JSONValue((unsigned int)decoded->expire);
msgPayload["locked_to"] = new JSONValue((unsigned int)decoded->locked_to);
msgPayload["latitude_i"] = new JSONValue((int)decoded->latitude_i);
msgPayload["longitude_i"] = new JSONValue((int)decoded->longitude_i);
jsonObj["payload"] = new JSONValue(msgPayload);
@@ -768,14 +775,14 @@ std::string MQTT::meshPacketToJson(meshtastic_MeshPacket *mp)
if (pb_decode_from_bytes(mp->decoded.payload.bytes, mp->decoded.payload.size, &meshtastic_NeighborInfo_msg,
&scratch)) {
decoded = &scratch;
msgPayload["node_id"] = new JSONValue((uint)decoded->node_id);
msgPayload["node_broadcast_interval_secs"] = new JSONValue((uint)decoded->node_broadcast_interval_secs);
msgPayload["last_sent_by_id"] = new JSONValue((uint)decoded->last_sent_by_id);
msgPayload["node_id"] = new JSONValue((unsigned int)decoded->node_id);
msgPayload["node_broadcast_interval_secs"] = new JSONValue((unsigned int)decoded->node_broadcast_interval_secs);
msgPayload["last_sent_by_id"] = new JSONValue((unsigned int)decoded->last_sent_by_id);
msgPayload["neighbors_count"] = new JSONValue(decoded->neighbors_count);
JSONArray neighbors;
for (uint8_t i = 0; i < decoded->neighbors_count; i++) {
JSONObject neighborObj;
neighborObj["node_id"] = new JSONValue((uint)decoded->neighbors[i].node_id);
neighborObj["node_id"] = new JSONValue((unsigned int)decoded->neighbors[i].node_id);
neighborObj["snr"] = new JSONValue((int)decoded->neighbors[i].snr);
neighbors.push_back(new JSONValue(neighborObj));
}
@@ -836,9 +843,9 @@ std::string MQTT::meshPacketToJson(meshtastic_MeshPacket *mp)
memset(&scratch, 0, sizeof(scratch));
if (pb_decode_from_bytes(mp->decoded.payload.bytes, mp->decoded.payload.size, &meshtastic_Paxcount_msg, &scratch)) {
decoded = &scratch;
msgPayload["wifi_count"] = new JSONValue((uint)decoded->wifi);
msgPayload["ble_count"] = new JSONValue((uint)decoded->ble);
msgPayload["uptime"] = new JSONValue((uint)decoded->uptime);
msgPayload["wifi_count"] = new JSONValue((unsigned int)decoded->wifi);
msgPayload["ble_count"] = new JSONValue((unsigned int)decoded->ble);
msgPayload["uptime"] = new JSONValue((unsigned int)decoded->uptime);
jsonObj["payload"] = new JSONValue(msgPayload);
} else {
LOG_ERROR("Error decoding protobuf for Paxcount message!\n");
@@ -855,12 +862,12 @@ std::string MQTT::meshPacketToJson(meshtastic_MeshPacket *mp)
decoded = &scratch;
if (decoded->type == meshtastic_HardwareMessage_Type_GPIOS_CHANGED) {
msgType = "gpios_changed";
msgPayload["gpio_value"] = new JSONValue((uint)decoded->gpio_value);
msgPayload["gpio_value"] = new JSONValue((unsigned int)decoded->gpio_value);
jsonObj["payload"] = new JSONValue(msgPayload);
} else if (decoded->type == meshtastic_HardwareMessage_Type_READ_GPIOS_REPLY) {
msgType = "gpios_read_reply";
msgPayload["gpio_value"] = new JSONValue((uint)decoded->gpio_value);
msgPayload["gpio_mask"] = new JSONValue((uint)decoded->gpio_mask);
msgPayload["gpio_value"] = new JSONValue((unsigned int)decoded->gpio_value);
msgPayload["gpio_mask"] = new JSONValue((unsigned int)decoded->gpio_mask);
jsonObj["payload"] = new JSONValue(msgPayload);
}
} else {
@@ -876,11 +883,11 @@ std::string MQTT::meshPacketToJson(meshtastic_MeshPacket *mp)
LOG_WARN("Couldn't convert encrypted payload of MeshPacket to JSON\n");
}
jsonObj["id"] = new JSONValue((uint)mp->id);
jsonObj["timestamp"] = new JSONValue((uint)mp->rx_time);
jsonObj["to"] = new JSONValue((uint)mp->to);
jsonObj["from"] = new JSONValue((uint)mp->from);
jsonObj["channel"] = new JSONValue((uint)mp->channel);
jsonObj["id"] = new JSONValue((unsigned int)mp->id);
jsonObj["timestamp"] = new JSONValue((unsigned int)mp->rx_time);
jsonObj["to"] = new JSONValue((unsigned int)mp->to);
jsonObj["from"] = new JSONValue((unsigned int)mp->from);
jsonObj["channel"] = new JSONValue((unsigned int)mp->channel);
jsonObj["type"] = new JSONValue(msgType.c_str());
jsonObj["sender"] = new JSONValue(owner.id);
if (mp->rx_rssi != 0)
@@ -888,7 +895,7 @@ std::string MQTT::meshPacketToJson(meshtastic_MeshPacket *mp)
if (mp->rx_snr != 0)
jsonObj["snr"] = new JSONValue((float)mp->rx_snr);
if (mp->hop_start != 0 && mp->hop_limit <= mp->hop_start)
jsonObj["hops_away"] = new JSONValue((uint)(mp->hop_start - mp->hop_limit));
jsonObj["hops_away"] = new JSONValue((unsigned int)(mp->hop_start - mp->hop_limit));
// serialize and write it to the stream
JSONValue *value = new JSONValue(jsonObj);
@@ -904,6 +911,7 @@ bool MQTT::isValidJsonEnvelope(JSONObject &json)
{
// if "sender" is provided, avoid processing packets we uplinked
return (json.find("sender") != json.end() ? (json["sender"]->AsString().compare(owner.id) != 0) : true) &&
(json.find("hopLimit") != json.end() ? json["hopLimit"]->IsNumber() : true) && // hop limit should be a number
(json.find("from") != json.end()) && json["from"]->IsNumber() &&
(json["from"]->AsNumber() == nodeDB->getNodeNum()) && // only accept message if the "from" is us
(json.find("type") != json.end()) && json["type"]->IsString() && // should specify a type

Some files were not shown because too many files have changed in this diff Show More