diff --git a/.github/ISSUE_TEMPLATE/feature.yml b/.github/ISSUE_TEMPLATE/feature.yml
index 2b6ffce0a..b027a36cc 100644
--- a/.github/ISSUE_TEMPLATE/feature.yml
+++ b/.github/ISSUE_TEMPLATE/feature.yml
@@ -16,6 +16,9 @@ body:
options:
- NRF52
- ESP32
+ - RP2040
+ - Linux Native
+ - other
validations:
required: true
- type: textarea
diff --git a/.github/workflows/package_raspbian.yml b/.github/workflows/package_raspbian.yml
index dd4133dab..81ff6ee25 100644
--- a/.github/workflows/package_raspbian.yml
+++ b/.github/workflows/package_raspbian.yml
@@ -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:
diff --git a/arch/nrf52/nrf52.ini b/arch/nrf52/nrf52.ini
index 2505fe315..f41ef0edc 100644
--- a/arch/nrf52/nrf52.ini
+++ b/arch/nrf52/nrf52.ini
@@ -3,12 +3,13 @@
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
-Wno-unused-variable
-Isrc/platform/nrf52
+ -DLFS_NO_ASSERT ; Disable LFS assertions , see https://github.com/meshtastic/firmware/pull/3818
build_src_filter =
${arduino_base.build_src_filter} - - - - - - - - - -
diff --git a/arch/portduino/portduino.ini b/arch/portduino/portduino.ini
index 53f06c9f3..63f5576b6 100644
--- a/arch/portduino/portduino.ini
+++ b/arch/portduino/portduino.ini
@@ -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}
diff --git a/bin/config-dist.yaml b/bin/config-dist.yaml
index f729f1ac7..333d6eadc 100644
--- a/bin/config-dist.yaml
+++ b/bin/config-dist.yaml
@@ -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
diff --git a/boards/promicro-nrf52840.json b/boards/promicro-nrf52840.json
new file mode 100644
index 000000000..99ae3f01e
--- /dev/null
+++ b/boards/promicro-nrf52840.json
@@ -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"
+}
diff --git a/boards/wiphone.json b/boards/wiphone.json
new file mode 100644
index 000000000..bb01f425f
--- /dev/null
+++ b/boards/wiphone.json
@@ -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"
+}
diff --git a/platformio.ini b/platformio.ini
index a1082a84a..9d7c76fbf 100644
--- a/platformio.ini
+++ b/platformio.ini
@@ -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
\ No newline at end of file
+ adafruit/Adafruit LSM6DS@^4.7.2
+ mprograms/QMC5883LCompass@^1.2.0
+ https://github.com/Sensirion/arduino-i2c-sht4x#1.1.0
diff --git a/protobufs b/protobufs
index eade2c6be..1bfe0354d 160000
--- a/protobufs
+++ b/protobufs
@@ -1 +1 @@
-Subproject commit eade2c6befb65a9c46c5d28ae1e8e24c37a1a3d0
+Subproject commit 1bfe0354d101a6a71ea1354ea158e59193671a0b
diff --git a/src/AccelerometerThread.h b/src/AccelerometerThread.h
index fa5acdaae..66e5624f1 100644
--- a/src/AccelerometerThread.h
+++ b/src/AccelerometerThread.h
@@ -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
\ No newline at end of file
+} // namespace concurrency
+
+#endif
\ No newline at end of file
diff --git a/src/AmbientLightingThread.h b/src/AmbientLightingThread.h
index 98ccedde4..6b3360b1f 100644
--- a/src/AmbientLightingThread.h
+++ b/src/AmbientLightingThread.h
@@ -5,6 +5,16 @@
NCP5623 rgb;
#endif
+#ifdef HAS_NEOPIXEL
+#include
+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
}
};
diff --git a/src/ButtonThread.cpp b/src/ButtonThread.cpp
index 206bb7239..aaead62be 100644
--- a/src/ButtonThread.cpp
+++ b/src/ButtonThread.cpp
@@ -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);
}
diff --git a/src/ButtonThread.h b/src/ButtonThread.h
index 07c7ccff7..d7a9201a3 100644
--- a/src/ButtonThread.h
+++ b/src/ButtonThread.h
@@ -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,
diff --git a/src/DebugConfiguration.h b/src/DebugConfiguration.h
index f0686b811..ca908197e 100644
--- a/src/DebugConfiguration.h
+++ b/src/DebugConfiguration.h
@@ -36,7 +36,7 @@
#define LOG_CRIT(...) SEGGER_RTT_printf(0, __VA_ARGS__)
#define LOG_TRACE(...) SEGGER_RTT_printf(0, __VA_ARGS__)
#else
-#ifdef DEBUG_PORT
+#if defined(DEBUG_PORT) && !defined(DEBUG_MUTE)
#define LOG_DEBUG(...) DEBUG_PORT.log(MESHTASTIC_LOG_LEVEL_DEBUG, __VA_ARGS__)
#define LOG_INFO(...) DEBUG_PORT.log(MESHTASTIC_LOG_LEVEL_INFO, __VA_ARGS__)
#define LOG_WARN(...) DEBUG_PORT.log(MESHTASTIC_LOG_LEVEL_WARN, __VA_ARGS__)
diff --git a/src/FSCommon.cpp b/src/FSCommon.cpp
index e7760c575..96aad1a9a 100644
--- a/src/FSCommon.cpp
+++ b/src/FSCommon.cpp
@@ -205,6 +205,62 @@ void rmDir(const char *dirname)
#endif
}
+bool fsCheck()
+{
+#if defined(ARCH_NRF52)
+ size_t write_size = 0;
+ size_t read_size = 0;
+ char buf[32] = {0};
+
+ Adafruit_LittleFS_Namespace::File file(FSCom);
+ const char *text = "meshtastic fs test";
+ size_t text_length = strlen(text);
+ const char *filename = "/meshtastic.txt";
+
+ LOG_DEBUG("Try create file .\n");
+ if (file.open(filename, FILE_O_WRITE)) {
+ write_size = file.write(text);
+ } else {
+ LOG_DEBUG("Open file failed .\n");
+ goto FORMAT_FS;
+ }
+
+ if (write_size != text_length) {
+ LOG_DEBUG("Text bytes do not match .\n");
+ file.close();
+ goto FORMAT_FS;
+ }
+
+ file.close();
+
+ if (!file.open(filename, FILE_O_READ)) {
+ LOG_DEBUG("Open file failed .\n");
+ goto FORMAT_FS;
+ }
+
+ read_size = file.readBytes(buf, text_length);
+ if (read_size != text_length) {
+ LOG_DEBUG("Text bytes do not match .\n");
+ file.close();
+ goto FORMAT_FS;
+ }
+
+ if (memcmp(buf, text, text_length) != 0) {
+ LOG_DEBUG("The written bytes do not match the read bytes .\n");
+ file.close();
+ goto FORMAT_FS;
+ }
+ return true;
+FORMAT_FS:
+ LOG_DEBUG("Format FS ....\n");
+ FSCom.format();
+ FSCom.begin();
+ return false;
+#else
+ return true;
+#endif
+}
+
void fsInit()
{
#ifdef FSCom
@@ -212,8 +268,37 @@ 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.
+ * To check the normality of the file system, you need to disable the LFS_NO_ASSERT assertion.
+ * Otherwise, the assertion will be entered at the moment of reading or opening, and the FS will not be formatted.
+ * */
+ bool ret = false;
+ uint8_t retry = 3;
+
+ while (retry--) {
+ ret = fsCheck();
+ if (ret) {
+ LOG_DEBUG("File system check is OK.\n");
+ break;
+ }
+ delay(10);
+ }
+
+ // It may not be possible to reach this step.
+ // Add a loop here to prevent unpredictable situations from happening.
+ // Can add a screen to display error status later.
+ if (!ret) {
+ while (1) {
+ LOG_ERROR("The file system is damaged and cannot proceed to the next step.\n");
+ delay(1000);
+ }
+ }
#else
LOG_DEBUG("Filesystem files:\n");
#endif
diff --git a/src/Power.cpp b/src/Power.cpp
index d13fd6891..64e310b68 100644
--- a/src/Power.cpp
+++ b/src/Power.cpp
@@ -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) {
diff --git a/src/SerialConsole.cpp b/src/SerialConsole.cpp
index e17c8f99e..53ece0fa3 100644
--- a/src/SerialConsole.cpp
+++ b/src/SerialConsole.cpp
@@ -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()
diff --git a/src/configuration.h b/src/configuration.h
index 701e07a32..0d9ee5451 100644
--- a/src/configuration.h
+++ b/src/configuration.h
@@ -126,8 +126,9 @@ along with this program. If not, see .
#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
diff --git a/src/detect/ScanI2C.h b/src/detect/ScanI2C.h
index c8fcfee10..a53df11f3 100644
--- a/src/detect/ScanI2C.h
+++ b/src/detect/ScanI2C.h
@@ -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;
diff --git a/src/detect/ScanI2CTwoWire.cpp b/src/detect/ScanI2CTwoWire.cpp
index ba2820a77..58d46a58d 100644
--- a/src/detect/ScanI2CTwoWire.cpp
+++ b/src/detect/ScanI2CTwoWire.cpp
@@ -292,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")
@@ -356,4 +368,4 @@ TwoWire *ScanI2CTwoWire::fetchI2CBus(ScanI2C::DeviceAddress address) const
size_t ScanI2CTwoWire::countDevices() const
{
return foundDevices.size();
-}
\ No newline at end of file
+}
diff --git a/src/gps/GPS.cpp b/src/gps/GPS.cpp
index 17e35a4b3..eaae049b5 100644
--- a/src/gps/GPS.cpp
+++ b/src/gps/GPS.cpp
@@ -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 (uint 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()
{
- uint charsInBuf = 0;
+ unsigned int charsInBuf = 0;
bool isValid = false;
if (!isAwake) {
clearBuffer();
diff --git a/src/gps/RTC.cpp b/src/gps/RTC.cpp
index 85931900f..a2cdb5b30 100644
--- a/src/gps/RTC.cpp
+++ b/src/gps/RTC.cpp
@@ -223,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));
}
/**
diff --git a/src/graphics/EInkDynamicDisplay.cpp b/src/graphics/EInkDynamicDisplay.cpp
index b396446fa..5b97b8d48 100644
--- a/src/graphics/EInkDynamicDisplay.cpp
+++ b/src/graphics/EInkDynamicDisplay.cpp
@@ -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
diff --git a/src/graphics/NeoPixel.h b/src/graphics/NeoPixel.h
new file mode 100644
index 000000000..dde74366e
--- /dev/null
+++ b/src/graphics/NeoPixel.h
@@ -0,0 +1,4 @@
+#ifdef HAS_NEOPIXEL
+#include
+extern Adafruit_NeoPixel pixels;
+#endif
\ No newline at end of file
diff --git a/src/graphics/Screen.cpp b/src/graphics/Screen.cpp
index e5f392036..0899335e6 100644
--- a/src/graphics/Screen.cpp
+++ b/src/graphics/Screen.cpp
@@ -94,6 +94,11 @@ std::vector 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 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(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(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(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
\ No newline at end of file
diff --git a/src/graphics/Screen.h b/src/graphics/Screen.h
index 2cb1cd5a9..cfb08c0f4 100644
--- a/src/graphics/Screen.h
+++ b/src/graphics/Screen.h
@@ -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;
diff --git a/src/graphics/TFTDisplay.cpp b/src/graphics/TFTDisplay.cpp
index 12e549424..b19e402b8 100644
--- a/src/graphics/TFTDisplay.cpp
+++ b/src/graphics/TFTDisplay.cpp
@@ -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
+#include
+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
\ No newline at end of file
diff --git a/src/graphics/TFTDisplay.h b/src/graphics/TFTDisplay.h
index 3d6ea6cc6..42aa3abff 100644
--- a/src/graphics/TFTDisplay.h
+++ b/src/graphics/TFTDisplay.h
@@ -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
*
diff --git a/src/graphics/mesh_bus_spi.cpp b/src/graphics/mesh_bus_spi.cpp
deleted file mode 100644
index a9536d490..000000000
--- a/src/graphics/mesh_bus_spi.cpp
+++ /dev/null
@@ -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
-#include
-
-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(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(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
\ No newline at end of file
diff --git a/src/graphics/mesh_bus_spi.h b/src/graphics/mesh_bus_spi.h
deleted file mode 100644
index 903f7ad9d..000000000
--- a/src/graphics/mesh_bus_spi.h
+++ /dev/null
@@ -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
-
-#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
\ No newline at end of file
diff --git a/src/input/TouchScreenBase.h b/src/input/TouchScreenBase.h
index a68c23e99..0b2002551 100644
--- a/src/input/TouchScreenBase.h
+++ b/src/input/TouchScreenBase.h
@@ -3,6 +3,7 @@
#include "InputBroker.h"
#include "concurrency/OSThread.h"
#include "mesh/NodeDB.h"
+#include "time.h"
typedef struct _TouchEvent {
const char *source;
diff --git a/src/input/kbI2cBase.cpp b/src/input/kbI2cBase.cpp
index 74a6c718d..af7c96b20 100644
--- a/src/input/kbI2cBase.cpp
+++ b/src/input/kbI2cBase.cpp
@@ -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;
}
diff --git a/src/main.cpp b/src/main.cpp
index f40fd0789..93c6ef38f 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -197,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);
@@ -342,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");
@@ -538,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();
@@ -604,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;
@@ -612,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);
}
@@ -691,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)
@@ -727,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()) {
@@ -741,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()) {
@@ -756,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()) {
@@ -768,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)
@@ -1006,4 +1035,4 @@ void loop()
mainDelay.delay(delayMsec);
}
// if (didWake) LOG_DEBUG("wake!\n");
-}
+}
\ No newline at end of file
diff --git a/src/mesh/FloodingRouter.cpp b/src/mesh/FloodingRouter.cpp
index 4cfe982d8..dd547a6f1 100644
--- a/src/mesh/FloodingRouter.cpp
+++ b/src/mesh/FloodingRouter.cpp
@@ -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())) {
diff --git a/src/mesh/MeshService.cpp b/src/mesh/MeshService.cpp
index 2c1969e30..2cfb4843c 100644
--- a/src/mesh/MeshService.cpp
+++ b/src/mesh/MeshService.cpp
@@ -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)
diff --git a/src/mesh/MeshService.h b/src/mesh/MeshService.h
index 8d1434030..d777b7a01 100644
--- a/src/mesh/MeshService.h
+++ b/src/mesh/MeshService.h
@@ -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
diff --git a/src/mesh/NodeDB.cpp b/src/mesh/NodeDB.cpp
index 39422b454..b79911a3e 100644
--- a/src/mesh/NodeDB.cpp
+++ b/src/mesh/NodeDB.cpp
@@ -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 *vec = (std::vector *)field->pData;
+ std::vector const *vec = (std::vector *)field->pData;
for (auto item : *vec) {
if (!pb_encode_tag_for_field(ostream, field))
return false;
@@ -269,11 +269,11 @@ 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;
-#if defined(ST7735_CS) || defined(USE_EINK) || defined(ILI9341_DRIVER) || defined(ST7789_CS)
+#if defined(ST7735_CS) || defined(USE_EINK) || defined(ILI9341_DRIVER) || defined(ST7789_CS) || defined(HX8357_CS)
bool hasScreen = true;
#elif ARCH_PORTDUINO
bool hasScreen = false;
@@ -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++) {
diff --git a/src/mesh/NodeDB.h b/src/mesh/NodeDB.h
index 4946672ec..e9e36cc61 100644
--- a/src/mesh/NodeDB.h
+++ b/src/mesh/NodeDB.h
@@ -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();
diff --git a/src/mesh/ProtobufModule.h b/src/mesh/ProtobufModule.h
index a2e89e98a..0d3da9568 100644
--- a/src/mesh/ProtobufModule.h
+++ b/src/mesh/ProtobufModule.h
@@ -95,12 +95,11 @@ template 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 {
diff --git a/src/mesh/RadioInterface.cpp b/src/mesh/RadioInterface.cpp
index 4fa0bef7a..cc6ccca07 100644
--- a/src/mesh/RadioInterface.cpp
+++ b/src/mesh/RadioInterface.cpp
@@ -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)
- uint 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);
-}
\ No newline at end of file
+}
diff --git a/src/mesh/RadioLibInterface.cpp b/src/mesh/RadioLibInterface.cpp
index fc1563ee3..a4ceac9f1 100644
--- a/src/mesh/RadioLibInterface.cpp
+++ b/src/mesh/RadioLibInterface.cpp
@@ -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);
}
-}
+}
\ No newline at end of file
diff --git a/src/mesh/RadioLibInterface.h b/src/mesh/RadioLibInterface.h
index 62720cfc9..2c841a19e 100644
--- a/src/mesh/RadioLibInterface.h
+++ b/src/mesh/RadioLibInterface.h
@@ -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;
-};
+};
\ No newline at end of file
diff --git a/src/mesh/generated/meshtastic/apponly.pb.h b/src/mesh/generated/meshtastic/apponly.pb.h
index 54629f522..ba9f90873 100644
--- a/src/mesh/generated/meshtastic/apponly.pb.h
+++ b/src/mesh/generated/meshtastic/apponly.pb.h
@@ -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" */
diff --git a/src/mesh/generated/meshtastic/channel.pb.h b/src/mesh/generated/meshtastic/channel.pb.h
index 185a47a98..d9c7d4ffa 100644
--- a/src/mesh/generated/meshtastic/channel.pb.h
+++ b/src/mesh/generated/meshtastic/channel.pb.h
@@ -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" */
diff --git a/src/mesh/generated/meshtastic/deviceonly.pb.h b/src/mesh/generated/meshtastic/deviceonly.pb.h
index 2506ec647..b8cc80633 100644
--- a/src/mesh/generated/meshtastic/deviceonly.pb.h
+++ b/src/mesh/generated/meshtastic/deviceonly.pb.h
@@ -306,7 +306,7 @@ 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 3346
#define meshtastic_PositionLite_size 28
diff --git a/src/mesh/generated/meshtastic/mesh.pb.h b/src/mesh/generated/meshtastic/mesh.pb.h
index 67b2edd15..ffc18c30b 100644
--- a/src/mesh/generated/meshtastic/mesh.pb.h
+++ b/src/mesh/generated/meshtastic/mesh.pb.h
@@ -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.
------------------------------------------------------------------------------------------------------------------------------------------ */
diff --git a/src/mesh/generated/meshtastic/telemetry.pb.h b/src/mesh/generated/meshtastic/telemetry.pb.h
index e670dd340..b6b08f2e7 100644
--- a/src/mesh/generated/meshtastic/telemetry.pb.h
+++ b/src/mesh/generated/meshtastic/telemetry.pb.h
@@ -45,7 +45,9 @@ typedef enum _meshtastic_TelemetrySensorType {
/* BMP085/BMP180 High accuracy temperature and pressure (older Version of BMP280) */
meshtastic_TelemetrySensorType_BMP085 = 15,
/* RCWL-9620 Doppler Radar Distance Sensor, used for water level detection */
- meshtastic_TelemetrySensorType_RCWL9620 = 16
+ meshtastic_TelemetrySensorType_RCWL9620 = 16,
+ /* Sensirion High accuracy temperature and humidity */
+ meshtastic_TelemetrySensorType_SHT4X = 17
} meshtastic_TelemetrySensorType;
/* Struct definitions */
@@ -152,8 +154,8 @@ extern "C" {
/* Helper constants for enums */
#define _meshtastic_TelemetrySensorType_MIN meshtastic_TelemetrySensorType_SENSOR_UNSET
-#define _meshtastic_TelemetrySensorType_MAX meshtastic_TelemetrySensorType_RCWL9620
-#define _meshtastic_TelemetrySensorType_ARRAYSIZE ((meshtastic_TelemetrySensorType)(meshtastic_TelemetrySensorType_RCWL9620+1))
+#define _meshtastic_TelemetrySensorType_MAX meshtastic_TelemetrySensorType_SHT4X
+#define _meshtastic_TelemetrySensorType_ARRAYSIZE ((meshtastic_TelemetrySensorType)(meshtastic_TelemetrySensorType_SHT4X+1))
diff --git a/src/modules/AdminModule.cpp b/src/modules/AdminModule.cpp
index 54eb577f7..adf5620ba 100644
--- a/src/modules/AdminModule.cpp
+++ b/src/modules/AdminModule.cpp
@@ -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;
}
diff --git a/src/modules/CannedMessageModule.cpp b/src/modules/CannedMessageModule.cpp
index cbd6fee72..0f17c268b 100644
--- a/src/modules/CannedMessageModule.cpp
+++ b/src/modules/CannedMessageModule.cpp
@@ -161,10 +161,10 @@ int CannedMessageModule::handleInputEvent(const InputEvent *event)
if (!event->kbchar) {
if (event->inputEvent == static_cast(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(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(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;
diff --git a/src/modules/CannedMessageModule.h b/src/modules/CannedMessageModule.h
index 4802be078..faf1d80f3 100644
--- a/src/modules/CannedMessageModule.h
+++ b/src/modules/CannedMessageModule.h
@@ -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
+#endif
+#ifdef HAS_NEOPIXEL
+#include
+#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
@@ -328,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");
@@ -509,4 +593,4 @@ void ExternalNotificationModule::handleSetRingtone(const char *from_msg)
if (changed) {
nodeDB->saveProto(rtttlConfigFile, meshtastic_RTTTLConfig_size, &meshtastic_RTTTLConfig_msg, &rtttlConfig);
}
-}
\ No newline at end of file
+}
diff --git a/src/modules/Modules.cpp b/src/modules/Modules.cpp
index 33ae9cadc..401ae2209 100644
--- a/src/modules/Modules.cpp
+++ b/src/modules/Modules.cpp
@@ -47,7 +47,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
@@ -143,7 +143,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
@@ -152,7 +152,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) && \
diff --git a/src/modules/NeighborInfoModule.cpp b/src/modules/NeighborInfoModule.cpp
index 8c8135deb..3925bea9a 100644
--- a/src/modules/NeighborInfoModule.cpp
+++ b/src/modules/NeighborInfoModule.cpp
@@ -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);
}
diff --git a/src/modules/PositionModule.cpp b/src/modules/PositionModule.cpp
index 658b8b5a7..9986f860d 100644
--- a/src/modules/PositionModule.cpp
+++ b/src/modules/PositionModule.cpp
@@ -87,6 +87,23 @@ 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;
@@ -326,7 +343,7 @@ int32_t PositionModule::runOnce()
// The minimum time (in seconds) that would pass before we are able to send a new position packet.
auto smartPosition = getDistanceTraveledSinceLastSend(node->position);
- uint32_t msSinceLastSend = now - lastGpsSend;
+ msSinceLastSend = now - lastGpsSend;
if (smartPosition.hasTraveledOverThreshold &&
Throttle::execute(
diff --git a/src/modules/PositionModule.h b/src/modules/PositionModule.h
index 89ff50c64..1161159f7 100644
--- a/src/modules/PositionModule.h
+++ b/src/modules/PositionModule.h
@@ -42,6 +42,8 @@ class PositionModule : public ProtobufModule, 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;
diff --git a/src/modules/Telemetry/AirQualityTelemetry.cpp b/src/modules/Telemetry/AirQualityTelemetry.cpp
index a51a7cea9..e4f31ff9f 100644
--- a/src/modules/Telemetry/AirQualityTelemetry.cpp
+++ b/src/modules/Telemetry/AirQualityTelemetry.cpp
@@ -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
\ No newline at end of file
diff --git a/src/modules/Telemetry/AirQualityTelemetry.h b/src/modules/Telemetry/AirQualityTelemetry.h
index ab77d61e7..eb0355001 100644
--- a/src/modules/Telemetry/AirQualityTelemetry.h
+++ b/src/modules/Telemetry/AirQualityTelemetry.h
@@ -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
\ No newline at end of file
diff --git a/src/modules/Telemetry/EnvironmentTelemetry.cpp b/src/modules/Telemetry/EnvironmentTelemetry.cpp
index 189ab7ed0..62adc9a8c 100644
--- a/src/modules/Telemetry/EnvironmentTelemetry.cpp
+++ b/src/modules/Telemetry/EnvironmentTelemetry.cpp
@@ -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;
-}
\ No newline at end of file
+}
+
+#endif
\ No newline at end of file
diff --git a/src/modules/Telemetry/EnvironmentTelemetry.h b/src/modules/Telemetry/EnvironmentTelemetry.h
index d6cd2137f..cdd9491d4 100644
--- a/src/modules/Telemetry/EnvironmentTelemetry.h
+++ b/src/modules/Telemetry/EnvironmentTelemetry.h
@@ -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
\ No newline at end of file
diff --git a/src/modules/Telemetry/PowerTelemetry.cpp b/src/modules/Telemetry/PowerTelemetry.cpp
index 713f6aacb..e61a4e629 100644
--- a/src/modules/Telemetry/PowerTelemetry.cpp
+++ b/src/modules/Telemetry/PowerTelemetry.cpp
@@ -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;
-}
\ No newline at end of file
+}
+
+#endif
\ No newline at end of file
diff --git a/src/modules/Telemetry/PowerTelemetry.h b/src/modules/Telemetry/PowerTelemetry.h
index fc5b98875..3d6b686f2 100644
--- a/src/modules/Telemetry/PowerTelemetry.h
+++ b/src/modules/Telemetry/PowerTelemetry.h
@@ -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
\ No newline at end of file
diff --git a/src/modules/Telemetry/Sensor/BME280Sensor.cpp b/src/modules/Telemetry/Sensor/BME280Sensor.cpp
index a30614123..aea6f2c3d 100644
--- a/src/modules/Telemetry/Sensor/BME280Sensor.cpp
+++ b/src/modules/Telemetry/Sensor/BME280Sensor.cpp
@@ -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
#include
@@ -35,4 +38,5 @@ bool BME280Sensor::getMetrics(meshtastic_Telemetry *measurement)
measurement->variant.environment_metrics.barometric_pressure = bme280.readPressure() / 100.0F;
return true;
-}
\ No newline at end of file
+}
+#endif
\ No newline at end of file
diff --git a/src/modules/Telemetry/Sensor/BME280Sensor.h b/src/modules/Telemetry/Sensor/BME280Sensor.h
index 2034c0a82..eb78f79f7 100644
--- a/src/modules/Telemetry/Sensor/BME280Sensor.h
+++ b/src/modules/Telemetry/Sensor/BME280Sensor.h
@@ -1,3 +1,7 @@
+#include "configuration.h"
+
+#if !MESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR
+
#include "../mesh/generated/meshtastic/telemetry.pb.h"
#include "TelemetrySensor.h"
#include
@@ -14,4 +18,6 @@ class BME280Sensor : public TelemetrySensor
BME280Sensor();
virtual int32_t runOnce() override;
virtual bool getMetrics(meshtastic_Telemetry *measurement) override;
-};
\ No newline at end of file
+};
+
+#endif
\ No newline at end of file
diff --git a/src/modules/Telemetry/Sensor/BME680Sensor.cpp b/src/modules/Telemetry/Sensor/BME680Sensor.cpp
index e1222bba4..f2c3804f4 100644
--- a/src/modules/Telemetry/Sensor/BME680Sensor.cpp
+++ b/src/modules/Telemetry/Sensor/BME680Sensor.cpp
@@ -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
\ No newline at end of file
diff --git a/src/modules/Telemetry/Sensor/BME680Sensor.h b/src/modules/Telemetry/Sensor/BME680Sensor.h
index 4b7f84cf0..351db50ab 100644
--- a/src/modules/Telemetry/Sensor/BME680Sensor.h
+++ b/src/modules/Telemetry/Sensor/BME680Sensor.h
@@ -1,3 +1,7 @@
+#include "configuration.h"
+
+#if !MESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR
+
#include "../mesh/generated/meshtastic/telemetry.pb.h"
#include "TelemetrySensor.h"
#include
@@ -35,4 +39,6 @@ class BME680Sensor : public TelemetrySensor
int32_t runTrigger();
virtual int32_t runOnce() override;
virtual bool getMetrics(meshtastic_Telemetry *measurement) override;
-};
\ No newline at end of file
+};
+
+#endif
\ No newline at end of file
diff --git a/src/modules/Telemetry/Sensor/BMP085Sensor.cpp b/src/modules/Telemetry/Sensor/BMP085Sensor.cpp
index b0991749b..0c4d0b5ca 100644
--- a/src/modules/Telemetry/Sensor/BMP085Sensor.cpp
+++ b/src/modules/Telemetry/Sensor/BMP085Sensor.cpp
@@ -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
#include
@@ -29,3 +32,5 @@ bool BMP085Sensor::getMetrics(meshtastic_Telemetry *measurement)
return true;
}
+
+#endif
\ No newline at end of file
diff --git a/src/modules/Telemetry/Sensor/BMP085Sensor.h b/src/modules/Telemetry/Sensor/BMP085Sensor.h
index c4a9479b9..4ba8c5af1 100644
--- a/src/modules/Telemetry/Sensor/BMP085Sensor.h
+++ b/src/modules/Telemetry/Sensor/BMP085Sensor.h
@@ -1,3 +1,7 @@
+#include "configuration.h"
+
+#if !MESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR
+
#include "../mesh/generated/meshtastic/telemetry.pb.h"
#include "TelemetrySensor.h"
#include
@@ -14,4 +18,6 @@ class BMP085Sensor : public TelemetrySensor
BMP085Sensor();
virtual int32_t runOnce() override;
virtual bool getMetrics(meshtastic_Telemetry *measurement) override;
-};
\ No newline at end of file
+};
+
+#endif
\ No newline at end of file
diff --git a/src/modules/Telemetry/Sensor/BMP280Sensor.cpp b/src/modules/Telemetry/Sensor/BMP280Sensor.cpp
index 408532388..8d0e4c180 100644
--- a/src/modules/Telemetry/Sensor/BMP280Sensor.cpp
+++ b/src/modules/Telemetry/Sensor/BMP280Sensor.cpp
@@ -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
#include
@@ -35,3 +38,5 @@ bool BMP280Sensor::getMetrics(meshtastic_Telemetry *measurement)
return true;
}
+
+#endif
\ No newline at end of file
diff --git a/src/modules/Telemetry/Sensor/BMP280Sensor.h b/src/modules/Telemetry/Sensor/BMP280Sensor.h
index 48581df8f..da85fdc1d 100644
--- a/src/modules/Telemetry/Sensor/BMP280Sensor.h
+++ b/src/modules/Telemetry/Sensor/BMP280Sensor.h
@@ -1,3 +1,7 @@
+#include "configuration.h"
+
+#if !MESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR
+
#include "../mesh/generated/meshtastic/telemetry.pb.h"
#include "TelemetrySensor.h"
#include
@@ -14,4 +18,6 @@ class BMP280Sensor : public TelemetrySensor
BMP280Sensor();
virtual int32_t runOnce() override;
virtual bool getMetrics(meshtastic_Telemetry *measurement) override;
-};
\ No newline at end of file
+};
+
+#endif
\ No newline at end of file
diff --git a/src/modules/Telemetry/Sensor/INA219Sensor.cpp b/src/modules/Telemetry/Sensor/INA219Sensor.cpp
index ecb564368..040e59575 100644
--- a/src/modules/Telemetry/Sensor/INA219Sensor.cpp
+++ b/src/modules/Telemetry/Sensor/INA219Sensor.cpp
@@ -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
#ifndef INA219_MULTIPLIER
@@ -37,4 +40,6 @@ bool INA219Sensor::getMetrics(meshtastic_Telemetry *measurement)
uint16_t INA219Sensor::getBusVoltageMv()
{
return lround(ina219.getBusVoltage_V() * 1000);
-}
\ No newline at end of file
+}
+
+#endif
\ No newline at end of file
diff --git a/src/modules/Telemetry/Sensor/INA219Sensor.h b/src/modules/Telemetry/Sensor/INA219Sensor.h
index 76f4613db..9dded067b 100644
--- a/src/modules/Telemetry/Sensor/INA219Sensor.h
+++ b/src/modules/Telemetry/Sensor/INA219Sensor.h
@@ -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;
-};
\ No newline at end of file
+};
+
+#endif
\ No newline at end of file
diff --git a/src/modules/Telemetry/Sensor/INA260Sensor.cpp b/src/modules/Telemetry/Sensor/INA260Sensor.cpp
index 89b7580d2..f156a9aba 100644
--- a/src/modules/Telemetry/Sensor/INA260Sensor.cpp
+++ b/src/modules/Telemetry/Sensor/INA260Sensor.cpp
@@ -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
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());
-}
\ No newline at end of file
+}
+
+#endif
\ No newline at end of file
diff --git a/src/modules/Telemetry/Sensor/INA260Sensor.h b/src/modules/Telemetry/Sensor/INA260Sensor.h
index 28e8944bf..f436b8f38 100644
--- a/src/modules/Telemetry/Sensor/INA260Sensor.h
+++ b/src/modules/Telemetry/Sensor/INA260Sensor.h
@@ -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;
-};
\ No newline at end of file
+};
+
+#endif
\ No newline at end of file
diff --git a/src/modules/Telemetry/Sensor/INA3221Sensor.cpp b/src/modules/Telemetry/Sensor/INA3221Sensor.cpp
index 3269ba47a..ea2cb4ea8 100644
--- a/src/modules/Telemetry/Sensor/INA3221Sensor.cpp
+++ b/src/modules/Telemetry/Sensor/INA3221Sensor.cpp
@@ -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
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);
-}
\ No newline at end of file
+}
+
+#endif
\ No newline at end of file
diff --git a/src/modules/Telemetry/Sensor/INA3221Sensor.h b/src/modules/Telemetry/Sensor/INA3221Sensor.h
index 4c82fc34d..3b8e382ee 100644
--- a/src/modules/Telemetry/Sensor/INA3221Sensor.h
+++ b/src/modules/Telemetry/Sensor/INA3221Sensor.h
@@ -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;
-};
\ No newline at end of file
+};
+
+#endif
\ No newline at end of file
diff --git a/src/modules/Telemetry/Sensor/LPS22HBSensor.cpp b/src/modules/Telemetry/Sensor/LPS22HBSensor.cpp
index 6e30113cd..c3c994cfa 100644
--- a/src/modules/Telemetry/Sensor/LPS22HBSensor.cpp
+++ b/src/modules/Telemetry/Sensor/LPS22HBSensor.cpp
@@ -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
#include
@@ -32,4 +35,6 @@ bool LPS22HBSensor::getMetrics(meshtastic_Telemetry *measurement)
measurement->variant.environment_metrics.barometric_pressure = pressure.pressure;
return true;
-}
\ No newline at end of file
+}
+
+#endif
\ No newline at end of file
diff --git a/src/modules/Telemetry/Sensor/LPS22HBSensor.h b/src/modules/Telemetry/Sensor/LPS22HBSensor.h
index 5b86539b1..955f2a1e5 100644
--- a/src/modules/Telemetry/Sensor/LPS22HBSensor.h
+++ b/src/modules/Telemetry/Sensor/LPS22HBSensor.h
@@ -1,3 +1,7 @@
+#include "configuration.h"
+
+#if !MESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR
+
#include "../mesh/generated/meshtastic/telemetry.pb.h"
#include "TelemetrySensor.h"
#include
@@ -15,4 +19,6 @@ class LPS22HBSensor : public TelemetrySensor
LPS22HBSensor();
virtual int32_t runOnce() override;
virtual bool getMetrics(meshtastic_Telemetry *measurement) override;
-};
\ No newline at end of file
+};
+
+#endif
\ No newline at end of file
diff --git a/src/modules/Telemetry/Sensor/MCP9808Sensor.cpp b/src/modules/Telemetry/Sensor/MCP9808Sensor.cpp
index c1d9bfa71..b01a19291 100644
--- a/src/modules/Telemetry/Sensor/MCP9808Sensor.cpp
+++ b/src/modules/Telemetry/Sensor/MCP9808Sensor.cpp
@@ -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
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;
-}
\ No newline at end of file
+}
+
+#endif
\ No newline at end of file
diff --git a/src/modules/Telemetry/Sensor/MCP9808Sensor.h b/src/modules/Telemetry/Sensor/MCP9808Sensor.h
index c1029f8a7..05bdabf3f 100644
--- a/src/modules/Telemetry/Sensor/MCP9808Sensor.h
+++ b/src/modules/Telemetry/Sensor/MCP9808Sensor.h
@@ -1,3 +1,7 @@
+#include "configuration.h"
+
+#if !MESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR
+
#include "../mesh/generated/meshtastic/telemetry.pb.h"
#include "TelemetrySensor.h"
#include
@@ -14,4 +18,6 @@ class MCP9808Sensor : public TelemetrySensor
MCP9808Sensor();
virtual int32_t runOnce() override;
virtual bool getMetrics(meshtastic_Telemetry *measurement) override;
-};
\ No newline at end of file
+};
+
+#endif
\ No newline at end of file
diff --git a/src/modules/Telemetry/Sensor/RCWL9620Sensor.cpp b/src/modules/Telemetry/Sensor/RCWL9620Sensor.cpp
new file mode 100644
index 000000000..49a509d38
--- /dev/null
+++ b/src/modules/Telemetry/Sensor/RCWL9620Sensor.cpp
@@ -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
\ No newline at end of file
diff --git a/src/modules/Telemetry/Sensor/RCWL9620Sensor.h b/src/modules/Telemetry/Sensor/RCWL9620Sensor.h
new file mode 100644
index 000000000..7f9486d25
--- /dev/null
+++ b/src/modules/Telemetry/Sensor/RCWL9620Sensor.h
@@ -0,0 +1,29 @@
+#include "configuration.h"
+
+#if !MESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR
+
+#include "../mesh/generated/meshtastic/telemetry.pb.h"
+#include "TelemetrySensor.h"
+#include
+
+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
\ No newline at end of file
diff --git a/src/modules/Telemetry/Sensor/SHT31Sensor.cpp b/src/modules/Telemetry/Sensor/SHT31Sensor.cpp
index 35978d970..aa2b5dcfc 100644
--- a/src/modules/Telemetry/Sensor/SHT31Sensor.cpp
+++ b/src/modules/Telemetry/Sensor/SHT31Sensor.cpp
@@ -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
SHT31Sensor::SHT31Sensor() : TelemetrySensor(meshtastic_TelemetrySensorType_SHT31, "SHT31") {}
@@ -29,3 +32,5 @@ bool SHT31Sensor::getMetrics(meshtastic_Telemetry *measurement)
return true;
}
+
+#endif
\ No newline at end of file
diff --git a/src/modules/Telemetry/Sensor/SHT31Sensor.h b/src/modules/Telemetry/Sensor/SHT31Sensor.h
index c6f8f1596..560b22436 100644
--- a/src/modules/Telemetry/Sensor/SHT31Sensor.h
+++ b/src/modules/Telemetry/Sensor/SHT31Sensor.h
@@ -1,3 +1,7 @@
+#include "configuration.h"
+
+#if !MESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR
+
#include "../mesh/generated/meshtastic/telemetry.pb.h"
#include "TelemetrySensor.h"
#include
@@ -15,3 +19,5 @@ class SHT31Sensor : public TelemetrySensor
virtual int32_t runOnce() override;
virtual bool getMetrics(meshtastic_Telemetry *measurement) override;
};
+
+#endif
\ No newline at end of file
diff --git a/src/modules/Telemetry/Sensor/SHT4XSensor.cpp b/src/modules/Telemetry/Sensor/SHT4XSensor.cpp
new file mode 100644
index 000000000..d324b7fd6
--- /dev/null
+++ b/src/modules/Telemetry/Sensor/SHT4XSensor.cpp
@@ -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
+
+// 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
\ No newline at end of file
diff --git a/src/modules/Telemetry/Sensor/SHT4XSensor.h b/src/modules/Telemetry/Sensor/SHT4XSensor.h
new file mode 100644
index 000000000..67045eb2a
--- /dev/null
+++ b/src/modules/Telemetry/Sensor/SHT4XSensor.h
@@ -0,0 +1,23 @@
+#include "configuration.h"
+
+#if !MESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR
+
+#include "../mesh/generated/meshtastic/telemetry.pb.h"
+#include "TelemetrySensor.h"
+#include
+
+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
\ No newline at end of file
diff --git a/src/modules/Telemetry/Sensor/SHTC3Sensor.cpp b/src/modules/Telemetry/Sensor/SHTC3Sensor.cpp
index b0b5d37dc..37685fed7 100644
--- a/src/modules/Telemetry/Sensor/SHTC3Sensor.cpp
+++ b/src/modules/Telemetry/Sensor/SHTC3Sensor.cpp
@@ -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
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;
-}
\ No newline at end of file
+}
+
+#endif
\ No newline at end of file
diff --git a/src/modules/Telemetry/Sensor/SHTC3Sensor.h b/src/modules/Telemetry/Sensor/SHTC3Sensor.h
index e5db417f5..7a760292f 100644
--- a/src/modules/Telemetry/Sensor/SHTC3Sensor.h
+++ b/src/modules/Telemetry/Sensor/SHTC3Sensor.h
@@ -1,3 +1,7 @@
+#include "configuration.h"
+
+#if !MESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR
+
#include "../mesh/generated/meshtastic/telemetry.pb.h"
#include "TelemetrySensor.h"
#include
@@ -14,4 +18,6 @@ class SHTC3Sensor : public TelemetrySensor
SHTC3Sensor();
virtual int32_t runOnce() override;
virtual bool getMetrics(meshtastic_Telemetry *measurement) override;
-};
\ No newline at end of file
+};
+
+#endif
\ No newline at end of file
diff --git a/src/modules/Telemetry/Sensor/TelemetrySensor.cpp b/src/modules/Telemetry/Sensor/TelemetrySensor.cpp
index cd8fe2566..d6e7d1fac 100644
--- a/src/modules/Telemetry/Sensor/TelemetrySensor.cpp
+++ b/src/modules/Telemetry/Sensor/TelemetrySensor.cpp
@@ -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
\ No newline at end of file
diff --git a/src/modules/Telemetry/Sensor/TelemetrySensor.h b/src/modules/Telemetry/Sensor/TelemetrySensor.h
index 7282e6dfa..35cb7965d 100644
--- a/src/modules/Telemetry/Sensor/TelemetrySensor.h
+++ b/src/modules/Telemetry/Sensor/TelemetrySensor.h
@@ -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;
-};
\ No newline at end of file
+};
+
+#endif
\ No newline at end of file
diff --git a/src/modules/Telemetry/Sensor/VoltageSensor.h b/src/modules/Telemetry/Sensor/VoltageSensor.h
index f2f28fb06..767ffd246 100644
--- a/src/modules/Telemetry/Sensor/VoltageSensor.h
+++ b/src/modules/Telemetry/Sensor/VoltageSensor.h
@@ -1,7 +1,13 @@
+#include "configuration.h"
+
+#if !MESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR
+
#pragma once
class VoltageSensor
{
public:
virtual uint16_t getBusVoltageMv() = 0;
-};
\ No newline at end of file
+};
+
+#endif
\ No newline at end of file
diff --git a/src/modules/Telemetry/Sensor/bme680_iaq_33v_3s_4d/bsec_iaq.c b/src/modules/Telemetry/Sensor/bme680_iaq_33v_3s_4d/bsec_iaq.c
index 1f27e6c69..0b5328306 100644
--- a/src/modules/Telemetry/Sensor/bme680_iaq_33v_3s_4d/bsec_iaq.c
+++ b/src/modules/Telemetry/Sensor/bme680_iaq_33v_3s_4d/bsec_iaq.c
@@ -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
\ No newline at end of file
diff --git a/src/modules/Telemetry/Sensor/bme680_iaq_33v_3s_4d/bsec_iaq.h b/src/modules/Telemetry/Sensor/bme680_iaq_33v_3s_4d/bsec_iaq.h
index cdd209ae5..d693f1e6a 100644
--- a/src/modules/Telemetry/Sensor/bme680_iaq_33v_3s_4d/bsec_iaq.h
+++ b/src/modules/Telemetry/Sensor/bme680_iaq_33v_3s_4d/bsec_iaq.h
@@ -1,3 +1,7 @@
+#if !MESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR
+
#include
extern const uint8_t bsec_config_iaq[1974];
+
+#endif
\ No newline at end of file
diff --git a/src/mqtt/JSONValue.cpp b/src/mqtt/JSONValue.cpp
index a229666a9..51e0c1a3b 100644
--- a/src/mqtt/JSONValue.cpp
+++ b/src/mqtt/JSONValue.cpp
@@ -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;
diff --git a/src/mqtt/JSONValue.h b/src/mqtt/JSONValue.h
index 3a50a831a..0380d324b 100644
--- a/src/mqtt/JSONValue.h
+++ b/src/mqtt/JSONValue.h
@@ -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);
diff --git a/src/mqtt/MQTT.cpp b/src/mqtt/MQTT.cpp
index da1c204b8..95b2daa99 100644
--- a/src/mqtt/MQTT.cpp
+++ b/src/mqtt/MQTT.cpp
@@ -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
diff --git a/src/platform/esp32/architecture.h b/src/platform/esp32/architecture.h
index 27088f86f..45d533a76 100644
--- a/src/platform/esp32/architecture.h
+++ b/src/platform/esp32/architecture.h
@@ -143,6 +143,8 @@
#define HW_VENDOR meshtastic_HardwareModel_STATION_G2
#elif defined(UNPHONE)
#define HW_VENDOR meshtastic_HardwareModel_UNPHONE
+#elif defined(WIPHONE)
+#define HW_VENDOR meshtastic_HardwareModel_WIPHONE
#endif
// -----------------------------------------------------------------------------
diff --git a/src/platform/nrf52/NRF52Bluetooth.cpp b/src/platform/nrf52/NRF52Bluetooth.cpp
index 759cbb404..39898ab25 100644
--- a/src/platform/nrf52/NRF52Bluetooth.cpp
+++ b/src/platform/nrf52/NRF52Bluetooth.cpp
@@ -287,7 +287,7 @@ void NRF52Bluetooth::setup()
LOG_INFO("Advertising\n");
}
-void NRF52Bluetooth::resumeAdverising()
+void NRF52Bluetooth::resumeAdvertising()
{
Bluefruit.Advertising.restartOnDisconnect(true);
Bluefruit.Advertising.setInterval(32, 244); // in unit of 0.625 ms
diff --git a/src/platform/nrf52/NRF52Bluetooth.h b/src/platform/nrf52/NRF52Bluetooth.h
index fd27bbf04..11e18c127 100644
--- a/src/platform/nrf52/NRF52Bluetooth.h
+++ b/src/platform/nrf52/NRF52Bluetooth.h
@@ -8,7 +8,7 @@ class NRF52Bluetooth : BluetoothApi
public:
void setup();
void shutdown();
- void resumeAdverising();
+ void resumeAdvertising();
void clearBonds();
bool isConnected();
int getRssi();
diff --git a/src/platform/nrf52/architecture.h b/src/platform/nrf52/architecture.h
index 35cd4fd84..68bd87801 100644
--- a/src/platform/nrf52/architecture.h
+++ b/src/platform/nrf52/architecture.h
@@ -52,6 +52,10 @@
#define HW_VENDOR meshtastic_HardwareModel_CANARYONE
#elif defined(NORDIC_PCA10059)
#define HW_VENDOR meshtastic_HardwareModel_NRF52840_PCA10059
+#elif defined(TWC_MESH_V4)
+#define HW_VENDOR meshtastic_HardwareModel_TWC_MESH_V4
+#elif defined(NRF52_PROMICRO_DIY)
+#define HW_VENDOR meshtastic_HardwareModel_NRF52_PROMICRO_DIY
#elif defined(PRIVATE_HW) || defined(FEATHER_DIY)
#define HW_VENDOR meshtastic_HardwareModel_PRIVATE_HW
#else
@@ -110,4 +114,4 @@
#if !defined(PIN_SERIAL_RX) && !defined(NRF52840_XXAA)
// No serial ports on this board - ONLY use segger in memory console
#define USE_SEGGER
-#endif
+#endif
\ No newline at end of file
diff --git a/src/platform/nrf52/main-nrf52.cpp b/src/platform/nrf52/main-nrf52.cpp
index ecffb745d..9cc52a7de 100644
--- a/src/platform/nrf52/main-nrf52.cpp
+++ b/src/platform/nrf52/main-nrf52.cpp
@@ -80,7 +80,7 @@ void setBluetoothEnable(bool enable)
// We delay brownout init until after BLE because BLE starts soft device
initBrownout();
} else {
- nrf52Bluetooth->resumeAdverising();
+ nrf52Bluetooth->resumeAdvertising();
}
}
} else {
diff --git a/src/platform/portduino/PortduinoGlue.cpp b/src/platform/portduino/PortduinoGlue.cpp
index a04c9c12c..4077a27bc 100644
--- a/src/platform/portduino/PortduinoGlue.cpp
+++ b/src/platform/portduino/PortduinoGlue.cpp
@@ -15,8 +15,6 @@
#include