diff --git a/.trunk/trunk.yaml b/.trunk/trunk.yaml
index 7de96bd21..9c1dcf707 100644
--- a/.trunk/trunk.yaml
+++ b/.trunk/trunk.yaml
@@ -1,6 +1,6 @@
version: 0.1
cli:
- version: 1.16.2
+ version: 1.17.0
plugins:
sources:
- id: trunk
diff --git a/boards/tbeam-s3-core.json b/boards/tbeam-s3-core.json
index 767791d35..7bda2e5a0 100644
--- a/boards/tbeam-s3-core.json
+++ b/boards/tbeam-s3-core.json
@@ -15,7 +15,7 @@
"f_cpu": "240000000L",
"f_flash": "80000000L",
"flash_mode": "dio",
- "hwids": [["0X303A", "0x1001"]],
+ "hwids": [["0x303A", "0x1001"]],
"mcu": "esp32s3",
"variant": "tbeam-s3-core"
},
diff --git a/protobufs b/protobufs
index 175a5c97f..6290ee0f6 160000
--- a/protobufs
+++ b/protobufs
@@ -1 +1 @@
-Subproject commit 175a5c97fb608b28f100551d302603efd0c22185
+Subproject commit 6290ee0f6aa15939ee582c3c59bc7a048cc0478f
diff --git a/src/DisplayFormatters.cpp b/src/DisplayFormatters.cpp
new file mode 100644
index 000000000..f15052de6
--- /dev/null
+++ b/src/DisplayFormatters.cpp
@@ -0,0 +1,34 @@
+#include "DisplayFormatters.h"
+
+const char *DisplayFormatters::getModemPresetDisplayName(meshtastic_Config_LoRaConfig_ModemPreset preset, bool useShortName)
+{
+ switch (preset) {
+ case meshtastic_Config_LoRaConfig_ModemPreset_SHORT_SLOW:
+ return useShortName ? "ShortS" : "ShortSlow";
+ break;
+ case meshtastic_Config_LoRaConfig_ModemPreset_SHORT_FAST:
+ return useShortName ? "ShortF" : "ShortFast";
+ break;
+ case meshtastic_Config_LoRaConfig_ModemPreset_MEDIUM_SLOW:
+ return useShortName ? "MedS" : "MediumSlow";
+ break;
+ case meshtastic_Config_LoRaConfig_ModemPreset_MEDIUM_FAST:
+ return useShortName ? "MedF" : "MediumFast";
+ break;
+ case meshtastic_Config_LoRaConfig_ModemPreset_LONG_SLOW:
+ return useShortName ? "LongS" : "LongSlow";
+ break;
+ case meshtastic_Config_LoRaConfig_ModemPreset_LONG_FAST:
+ return useShortName ? "LongF" : "LongFast";
+ break;
+ case meshtastic_Config_LoRaConfig_ModemPreset_LONG_MODERATE:
+ return useShortName ? "LongM" : "LongMod";
+ break;
+ case meshtastic_Config_LoRaConfig_ModemPreset_VERY_LONG_SLOW:
+ return useShortName ? "VeryL" : "VLongSlow";
+ break;
+ default:
+ return useShortName ? "Custom" : "Invalid";
+ break;
+ }
+}
\ No newline at end of file
diff --git a/src/DisplayFormatters.h b/src/DisplayFormatters.h
new file mode 100644
index 000000000..f8ccfcbb6
--- /dev/null
+++ b/src/DisplayFormatters.h
@@ -0,0 +1,8 @@
+#pragma once
+#include "NodeDB.h"
+
+class DisplayFormatters
+{
+ public:
+ static const char *getModemPresetDisplayName(meshtastic_Config_LoRaConfig_ModemPreset preset, bool useShortName);
+};
diff --git a/src/Power.cpp b/src/Power.cpp
index da2c9da93..72bb38181 100644
--- a/src/Power.cpp
+++ b/src/Power.cpp
@@ -281,9 +281,10 @@ class AnalogBatteryLevel : public HasBatteryLevel
#if defined(HAS_TELEMETRY) && !defined(ARCH_PORTDUINO)
uint16_t getINAVoltage()
{
- if (nodeTelemetrySensorsMap[meshtastic_TelemetrySensorType_INA219] == config.power.device_battery_ina_address) {
+ if (nodeTelemetrySensorsMap[meshtastic_TelemetrySensorType_INA219].first == config.power.device_battery_ina_address) {
return ina219Sensor.getBusVoltageMv();
- } else if (nodeTelemetrySensorsMap[meshtastic_TelemetrySensorType_INA260] == config.power.device_battery_ina_address) {
+ } else if (nodeTelemetrySensorsMap[meshtastic_TelemetrySensorType_INA260].first ==
+ config.power.device_battery_ina_address) {
return ina260Sensor.getBusVoltageMv();
}
return 0;
@@ -294,11 +295,12 @@ class AnalogBatteryLevel : public HasBatteryLevel
if (!config.power.device_battery_ina_address) {
return false;
}
- if (nodeTelemetrySensorsMap[meshtastic_TelemetrySensorType_INA219] == config.power.device_battery_ina_address) {
+ if (nodeTelemetrySensorsMap[meshtastic_TelemetrySensorType_INA219].first == config.power.device_battery_ina_address) {
if (!ina219Sensor.isInitialized())
return ina219Sensor.runOnce() > 0;
return ina219Sensor.isRunning();
- } else if (nodeTelemetrySensorsMap[meshtastic_TelemetrySensorType_INA260] == config.power.device_battery_ina_address) {
+ } else if (nodeTelemetrySensorsMap[meshtastic_TelemetrySensorType_INA260].first ==
+ config.power.device_battery_ina_address) {
if (!ina260Sensor.isInitialized())
return ina260Sensor.runOnce() > 0;
return ina260Sensor.isRunning();
diff --git a/src/detect/ScanI2CTwoWire.h b/src/detect/ScanI2CTwoWire.h
index 52c3cb085..9acd736d2 100644
--- a/src/detect/ScanI2CTwoWire.h
+++ b/src/detect/ScanI2CTwoWire.h
@@ -18,6 +18,8 @@ class ScanI2CTwoWire : public ScanI2C
ScanI2C::FoundDevice find(ScanI2C::DeviceType) const override;
+ TwoWire *fetchI2CBus(ScanI2C::DeviceAddress) const;
+
bool exists(ScanI2C::DeviceType) const override;
size_t countDevices() const override;
@@ -51,6 +53,4 @@ class ScanI2CTwoWire : public ScanI2C
uint16_t getRegisterValue(const RegisterLocation &, ResponseWidth) const;
DeviceType probeOLED(ScanI2C::DeviceAddress) const;
-
- TwoWire *fetchI2CBus(ScanI2C::DeviceAddress) const;
};
diff --git a/src/graphics/Screen.cpp b/src/graphics/Screen.cpp
index 547d7f59e..b626e393a 100644
--- a/src/graphics/Screen.cpp
+++ b/src/graphics/Screen.cpp
@@ -24,6 +24,7 @@ along with this program. If not, see .
#if HAS_SCREEN
#include
+#include "DisplayFormatters.h"
#include "GPS.h"
#include "MeshService.h"
#include "NodeDB.h"
@@ -160,34 +161,9 @@ static void drawIconScreen(const char *upperMsg, OLEDDisplay *display, OLEDDispl
xstr(APP_VERSION_SHORT)); // Note: we don't bother printing region or now, it makes the string too long
display->drawString(x + SCREEN_WIDTH - display->getStringWidth(buf), y + 0, buf);
screen->forceDisplay();
-
// FIXME - draw serial # somewhere?
}
-#ifdef ARCH_ESP32
-static void drawFrameResume(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y)
-{
- uint16_t x_offset = display->width() / 2;
- display->setTextAlignment(TEXT_ALIGN_CENTER);
- display->setFont(FONT_MEDIUM);
- display->drawString(x_offset + x, 26 + y, "Resuming...");
-}
-#endif
-
-static void drawBootScreen(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y)
-{
-#ifdef ARCH_ESP32
- if (wakeCause == ESP_SLEEP_WAKEUP_TIMER || wakeCause == ESP_SLEEP_WAKEUP_EXT1) {
- drawFrameResume(display, state, x, y);
- } else
-#endif
- {
- // Draw region in upper left
- const char *region = myRegion ? myRegion->name : NULL;
- drawIconScreen(region, display, state, x, y);
- }
-}
-
static void drawOEMIconScreen(const char *upperMsg, OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y)
{
// draw an xbm image.
@@ -237,6 +213,28 @@ static void drawOEMBootScreen(OLEDDisplay *display, OLEDDisplayUiState *state, i
drawOEMIconScreen(region, display, state, x, y);
}
+static void drawFrameText(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y, const char *message)
+{
+ uint16_t x_offset = display->width() / 2;
+ display->setTextAlignment(TEXT_ALIGN_CENTER);
+ display->setFont(FONT_MEDIUM);
+ display->drawString(x_offset + x, 26 + y, message);
+}
+
+static void drawBootScreen(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y)
+{
+#ifdef ARCH_ESP32
+ if (wakeCause == ESP_SLEEP_WAKEUP_TIMER || wakeCause == ESP_SLEEP_WAKEUP_EXT1) {
+ drawFrameText(display, state, x, y, "Resuming...");
+ } else
+#endif
+ {
+ // Draw region in upper left
+ const char *region = myRegion ? myRegion->name : NULL;
+ drawIconScreen(region, display, state, x, y);
+ }
+}
+
// Used on boot when a certificate is being created
static void drawSSLScreen(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y)
{
@@ -337,22 +335,6 @@ static void drawFrameBluetooth(OLEDDisplay *display, OLEDDisplayUiState *state,
display->drawString(x_offset + x, y_offset + y, deviceName);
}
-static void drawFrameShutdown(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y)
-{
- uint16_t x_offset = display->width() / 2;
- display->setTextAlignment(TEXT_ALIGN_CENTER);
- display->setFont(FONT_MEDIUM);
- display->drawString(x_offset + x, 26 + y, "Shutting down...");
-}
-
-static void drawFrameReboot(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y)
-{
- uint16_t x_offset = display->width() / 2;
- display->setTextAlignment(TEXT_ALIGN_CENTER);
- display->setFont(FONT_MEDIUM);
- display->drawString(x_offset + x, 26 + y, "Rebooting...");
-}
-
static void drawFrameFirmware(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y)
{
display->setTextAlignment(TEXT_ALIGN_CENTER);
@@ -923,20 +905,6 @@ static void drawNodeInfo(OLEDDisplay *display, OLEDDisplayUiState *state, int16_
drawColumns(display, x, y, fields);
}
-// #ifdef RAK4630
-// Screen::Screen(uint8_t address, int sda, int scl) : OSThread("Screen"), cmdQueue(32), dispdev(address, sda, scl),
-// dispdev_oled(address, sda, scl), ui(&dispdev)
-// {
-// address_found = address;
-// cmdQueue.setReader(this);
-// if (screen_found) {
-// (void)dispdev;
-// AutoOLEDWire dispdev = dispdev_oled;
-// (void)ui;
-// OLEDDisplayUi ui(&dispdev);
-// }
-// }
-// #else
Screen::Screen(ScanI2C::DeviceAddress address, meshtastic_Config_DisplayConfig_OledType screenType, OLEDDISPLAY_GEOMETRY geometry)
: concurrency::OSThread("Screen"), address_found(address), model(screenType), geometry(geometry), cmdQueue(32),
dispdev(address.address, -1, -1, geometry, (address.port == ScanI2C::I2CPort::WIRE1) ? HW_I2C::I2C_TWO : HW_I2C::I2C_ONE),
@@ -944,7 +912,7 @@ Screen::Screen(ScanI2C::DeviceAddress address, meshtastic_Config_DisplayConfig_O
{
cmdQueue.setReader(this);
}
-// #endif
+
/**
* Prepare the display for the unit going to the lowest power mode possible. Most screens will just
* poweroff, but eink screens will show a "I'm sleeping" graphic, possibly with a QR code
@@ -1261,11 +1229,8 @@ void Screen::setWelcomeFrames()
{
if (address_found.address) {
// LOG_DEBUG("showing Welcome frames\n");
- ui.disableAllIndicators();
-
- static FrameCallback welcomeFrames[] = {drawWelcomeScreen};
- ui.setFrames(welcomeFrames, 1);
- ui.update();
+ static FrameCallback frames[] = {drawWelcomeScreen};
+ setFrameImmediateDraw(frames);
}
}
@@ -1352,12 +1317,15 @@ void Screen::handleStartBluetoothPinScreen(uint32_t pin)
LOG_DEBUG("showing bluetooth screen\n");
showingNormalScreen = false;
- static FrameCallback btFrames[] = {drawFrameBluetooth};
-
+ static FrameCallback frames[] = {drawFrameBluetooth};
snprintf(btPIN, sizeof(btPIN), "%06u", pin);
+ setFrameImmediateDraw(frames);
+}
+void Screen::setFrameImmediateDraw(FrameCallback *drawFrames)
+{
ui.disableAllIndicators();
- ui.setFrames(btFrames, 1);
+ ui.setFrames(drawFrames, 1);
setFastFramerate();
}
@@ -1366,11 +1334,12 @@ void Screen::handleShutdownScreen()
LOG_DEBUG("showing shutdown screen\n");
showingNormalScreen = false;
- static FrameCallback shutdownFrames[] = {drawFrameShutdown};
+ auto frame = [](OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y) -> void {
+ drawFrameText(display, state, x, y, "Shutting down...");
+ };
+ static FrameCallback frames[] = {frame};
- ui.disableAllIndicators();
- ui.setFrames(shutdownFrames, 1);
- setFastFramerate();
+ setFrameImmediateDraw(frames);
}
void Screen::handleRebootScreen()
@@ -1378,11 +1347,11 @@ void Screen::handleRebootScreen()
LOG_DEBUG("showing reboot screen\n");
showingNormalScreen = false;
- static FrameCallback rebootFrames[] = {drawFrameReboot};
-
- ui.disableAllIndicators();
- ui.setFrames(rebootFrames, 1);
- setFastFramerate();
+ auto frame = [](OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y) -> void {
+ drawFrameText(display, state, x, y, "Rebooting...");
+ };
+ static FrameCallback frames[] = {frame};
+ setFrameImmediateDraw(frames);
}
void Screen::handleStartFirmwareUpdateScreen()
@@ -1390,11 +1359,8 @@ void Screen::handleStartFirmwareUpdateScreen()
LOG_DEBUG("showing firmware screen\n");
showingNormalScreen = false;
- static FrameCallback btFrames[] = {drawFrameFirmware};
-
- ui.disableAllIndicators();
- ui.setFrames(btFrames, 1);
- setFastFramerate();
+ static FrameCallback frames[] = {drawFrameFirmware};
+ setFrameImmediateDraw(frames);
}
void Screen::blink()
@@ -1655,65 +1621,8 @@ void DebugInfo::drawFrameWiFi(OLEDDisplay *display, OLEDDisplayUiState *state, i
} else {
// Codes:
// https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-guides/wifi.html#wi-fi-reason-code
- if (getWifiDisconnectReason() == 2) {
- display->drawString(x, y + FONT_HEIGHT_SMALL * 1, "Authentication Invalid");
- } else if (getWifiDisconnectReason() == 3) {
- display->drawString(x, y + FONT_HEIGHT_SMALL * 1, "De-authenticated");
- } else if (getWifiDisconnectReason() == 4) {
- display->drawString(x, y + FONT_HEIGHT_SMALL * 1, "Disassociated Expired");
- } else if (getWifiDisconnectReason() == 5) {
- display->drawString(x, y + FONT_HEIGHT_SMALL * 1, "AP - Too Many Clients");
- } else if (getWifiDisconnectReason() == 6) {
- display->drawString(x, y + FONT_HEIGHT_SMALL * 1, "NOT_AUTHED");
- } else if (getWifiDisconnectReason() == 7) {
- display->drawString(x, y + FONT_HEIGHT_SMALL * 1, "NOT_ASSOCED");
- } else if (getWifiDisconnectReason() == 8) {
- display->drawString(x, y + FONT_HEIGHT_SMALL * 1, "Disassociated");
- } else if (getWifiDisconnectReason() == 9) {
- display->drawString(x, y + FONT_HEIGHT_SMALL * 1, "ASSOC_NOT_AUTHED");
- } else if (getWifiDisconnectReason() == 10) {
- display->drawString(x, y + FONT_HEIGHT_SMALL * 1, "DISASSOC_PWRCAP_BAD");
- } else if (getWifiDisconnectReason() == 11) {
- display->drawString(x, y + FONT_HEIGHT_SMALL * 1, "DISASSOC_SUPCHAN_BAD");
- } else if (getWifiDisconnectReason() == 13) {
- display->drawString(x, y + FONT_HEIGHT_SMALL * 1, "IE_INVALID");
- } else if (getWifiDisconnectReason() == 14) {
- display->drawString(x, y + FONT_HEIGHT_SMALL * 1, "MIC_FAILURE");
- } else if (getWifiDisconnectReason() == 15) {
- display->drawString(x, y + FONT_HEIGHT_SMALL * 1, "AP Handshake Timeout");
- } else if (getWifiDisconnectReason() == 16) {
- display->drawString(x, y + FONT_HEIGHT_SMALL * 1, "GROUP_KEY_UPDATE_TIMEOUT");
- } else if (getWifiDisconnectReason() == 17) {
- display->drawString(x, y + FONT_HEIGHT_SMALL * 1, "IE_IN_4WAY_DIFFERS");
- } else if (getWifiDisconnectReason() == 18) {
- display->drawString(x, y + FONT_HEIGHT_SMALL * 1, "Invalid Group Cipher");
- } else if (getWifiDisconnectReason() == 19) {
- display->drawString(x, y + FONT_HEIGHT_SMALL * 1, "Invalid Pairwise Cipher");
- } else if (getWifiDisconnectReason() == 20) {
- display->drawString(x, y + FONT_HEIGHT_SMALL * 1, "AKMP_INVALID");
- } else if (getWifiDisconnectReason() == 21) {
- display->drawString(x, y + FONT_HEIGHT_SMALL * 1, "UNSUPP_RSN_IE_VERSION");
- } else if (getWifiDisconnectReason() == 22) {
- display->drawString(x, y + FONT_HEIGHT_SMALL * 1, "INVALID_RSN_IE_CAP");
- } else if (getWifiDisconnectReason() == 23) {
- display->drawString(x, y + FONT_HEIGHT_SMALL * 1, "802_1X_AUTH_FAILED");
- } else if (getWifiDisconnectReason() == 24) {
- display->drawString(x, y + FONT_HEIGHT_SMALL * 1, "CIPHER_SUITE_REJECTED");
- } else if (getWifiDisconnectReason() == 200) {
- display->drawString(x, y + FONT_HEIGHT_SMALL * 1, "BEACON_TIMEOUT");
- } else if (getWifiDisconnectReason() == 201) {
- display->drawString(x, y + FONT_HEIGHT_SMALL * 1, "AP Not Found");
- } else if (getWifiDisconnectReason() == 202) {
- display->drawString(x, y + FONT_HEIGHT_SMALL * 1, "AUTH_FAIL");
- } else if (getWifiDisconnectReason() == 203) {
- display->drawString(x, y + FONT_HEIGHT_SMALL * 1, "ASSOC_FAIL");
- } else if (getWifiDisconnectReason() == 204) {
- display->drawString(x, y + FONT_HEIGHT_SMALL * 1, "HANDSHAKE_TIMEOUT");
- } else if (getWifiDisconnectReason() == 205) {
- display->drawString(x, y + FONT_HEIGHT_SMALL * 1, "Connection Failed");
- } else {
- display->drawString(x, y + FONT_HEIGHT_SMALL * 1, "Unknown Status");
- }
+ display->drawString(x, y + FONT_HEIGHT_SMALL * 1,
+ WiFi.disconnectReasonName(static_cast(getWifiDisconnectReason())));
}
display->drawString(x, y + FONT_HEIGHT_SMALL * 2, "SSID: " + String(wifiName));
@@ -1760,37 +1669,7 @@ void DebugInfo::drawFrameSettings(OLEDDisplay *display, OLEDDisplayUiState *stat
display->drawString(x + 1, y, String("USB"));
}
- auto mode = "";
-
- switch (config.lora.modem_preset) {
- case meshtastic_Config_LoRaConfig_ModemPreset_SHORT_SLOW:
- mode = "ShortS";
- break;
- case meshtastic_Config_LoRaConfig_ModemPreset_SHORT_FAST:
- mode = "ShortF";
- break;
- case meshtastic_Config_LoRaConfig_ModemPreset_MEDIUM_SLOW:
- mode = "MedS";
- break;
- case meshtastic_Config_LoRaConfig_ModemPreset_MEDIUM_FAST:
- mode = "MedF";
- break;
- case meshtastic_Config_LoRaConfig_ModemPreset_LONG_SLOW:
- mode = "LongS";
- break;
- case meshtastic_Config_LoRaConfig_ModemPreset_LONG_FAST:
- mode = "LongF";
- break;
- case meshtastic_Config_LoRaConfig_ModemPreset_LONG_MODERATE:
- mode = "LongM";
- break;
- case meshtastic_Config_LoRaConfig_ModemPreset_VERY_LONG_SLOW:
- mode = "VeryL";
- break;
- default:
- mode = "Custom";
- break;
- }
+ auto mode = DisplayFormatters::getModemPresetDisplayName(config.lora.modem_preset, true);
display->drawString(x + SCREEN_WIDTH - display->getStringWidth(mode), y, mode);
if (config.display.heading_bold)
@@ -1857,23 +1736,6 @@ void DebugInfo::drawFrameSettings(OLEDDisplay *display, OLEDDisplayUiState *stat
heartbeat = !heartbeat;
#endif
}
-// adjust Brightness cycle through 1 to 254 as long as attachDuringLongPress is true
-void Screen::adjustBrightness()
-{
- if (!useDisplay)
- return;
-
- if (brightness == 254) {
- brightness = 0;
- } else {
- brightness++;
- }
- int width = brightness / (254.00 / SCREEN_WIDTH);
- dispdev.drawRect(0, 30, SCREEN_WIDTH, 4);
- dispdev.fillRect(0, 31, width, 2);
- dispdev.display();
- dispdev.setBrightness(brightness);
-}
int Screen::handleStatusUpdate(const meshtastic::Status *arg)
{
diff --git a/src/graphics/Screen.h b/src/graphics/Screen.h
index 8812b7c70..d6fb7b5d3 100644
--- a/src/graphics/Screen.h
+++ b/src/graphics/Screen.h
@@ -19,7 +19,6 @@ class Screen
void setup() {}
void setOn(bool) {}
void print(const char *) {}
- void adjustBrightness() {}
void doDeepSleep() {}
void forceDisplay() {}
void startBluetoothPinScreen(uint32_t pin) {}
@@ -161,7 +160,6 @@ class Screen : public concurrency::OSThread
void showNextFrame() { enqueueCmd(ScreenCmd{.cmd = Cmd::SHOW_NEXT_FRAME}); }
// Implementation to Adjust Brightness
- void adjustBrightness();
uint8_t brightness = BRIGHTNESS_DEFAULT;
/// Starts showing the Bluetooth PIN screen.
@@ -363,6 +361,9 @@ class Screen : public concurrency::OSThread
/// Try to start drawing ASAP
void setFastFramerate();
+ // Sets frame up for immediate drawing
+ void setFrameImmediateDraw(FrameCallback *drawFrames);
+
/// Called when debug screen is to be drawn, calls through to debugInfo.drawFrame.
static void drawDebugInfoTrampoline(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y);
diff --git a/src/main.cpp b/src/main.cpp
index c9ba4c795..9b7d811c4 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -29,6 +29,7 @@
#include "target_specific.h"
#include
#include
+#include
// #include
#include "mesh/eth/ethClient.h"
@@ -122,9 +123,8 @@ uint32_t serialSinceMsec;
bool pmu_found;
-// Array map of sensor types (as array index) and i2c address as value we'll find in the i2c scan
-uint8_t nodeTelemetrySensorsMap[_meshtastic_TelemetrySensorType_MAX + 1] = {
- 0}; // one is enough, missing elements will be initialized to 0 anyway.
+// Array map of sensor types with i2c address and wire as we'll find in the i2c scan
+std::pair nodeTelemetrySensorsMap[_meshtastic_TelemetrySensorType_MAX + 1] = {};
Router *router = NULL; // Users of router don't care what sort of subclass implements that API
@@ -491,7 +491,8 @@ void setup()
{ \
auto found = i2cScanner->find(SCANNER_T); \
if (found.type != ScanI2C::DeviceType::NONE) { \
- nodeTelemetrySensorsMap[PB_T] = found.address.address; \
+ nodeTelemetrySensorsMap[PB_T].first = found.address.address; \
+ nodeTelemetrySensorsMap[PB_T].second = i2cScanner->fetchI2CBus(found.address); \
LOG_DEBUG("found i2c sensor %s\n", STRING(PB_T)); \
} \
}
diff --git a/src/mesh/Channels.cpp b/src/mesh/Channels.cpp
index 2a0b5ee39..9974297fa 100644
--- a/src/mesh/Channels.cpp
+++ b/src/mesh/Channels.cpp
@@ -1,5 +1,6 @@
#include "Channels.h"
#include "CryptoEngine.h"
+#include "DisplayFormatters.h"
#include "NodeDB.h"
#include "configuration.h"
@@ -239,38 +240,9 @@ const char *Channels::getName(size_t chIndex)
const char *channelName = channelSettings.name;
if (!*channelName) { // emptystring
// Per mesh.proto spec, if bandwidth is specified we must ignore modemPreset enum, we assume that in that case
- // the app fucked up and forgot to set channelSettings.name
-
+ // the app effed up and forgot to set channelSettings.name
if (config.lora.use_preset) {
- switch (config.lora.modem_preset) {
- case meshtastic_Config_LoRaConfig_ModemPreset_SHORT_SLOW:
- channelName = "ShortSlow";
- break;
- case meshtastic_Config_LoRaConfig_ModemPreset_SHORT_FAST:
- channelName = "ShortFast";
- break;
- case meshtastic_Config_LoRaConfig_ModemPreset_MEDIUM_SLOW:
- channelName = "MediumSlow";
- break;
- case meshtastic_Config_LoRaConfig_ModemPreset_MEDIUM_FAST:
- channelName = "MediumFast";
- break;
- case meshtastic_Config_LoRaConfig_ModemPreset_LONG_SLOW:
- channelName = "LongSlow";
- break;
- case meshtastic_Config_LoRaConfig_ModemPreset_LONG_FAST:
- channelName = "LongFast";
- break;
- case meshtastic_Config_LoRaConfig_ModemPreset_LONG_MODERATE:
- channelName = "LongMod";
- break;
- case meshtastic_Config_LoRaConfig_ModemPreset_VERY_LONG_SLOW:
- channelName = "VLongSlow";
- break;
- default:
- channelName = "Invalid";
- break;
- }
+ channelName = DisplayFormatters::getModemPresetDisplayName(config.lora.modem_preset, false);
} else {
channelName = "Custom";
}
diff --git a/src/mesh/MeshService.cpp b/src/mesh/MeshService.cpp
index 9d2ecdcee..44094f1bb 100644
--- a/src/mesh/MeshService.cpp
+++ b/src/mesh/MeshService.cpp
@@ -267,14 +267,22 @@ void MeshService::sendNetworkPing(NodeNum dest, bool wantReplies)
void MeshService::sendToPhone(meshtastic_MeshPacket *p)
{
+ perhapsDecode(p);
+
if (toPhoneQueue.numFree() == 0) {
- LOG_WARN("ToPhone queue is full, discarding oldest\n");
- meshtastic_MeshPacket *d = toPhoneQueue.dequeuePtr(0);
- if (d)
- releaseToPool(d);
+ if (p->decoded.portnum == meshtastic_PortNum_TEXT_MESSAGE_APP ||
+ p->decoded.portnum == meshtastic_PortNum_RANGE_TEST_APP) {
+ LOG_WARN("ToPhone queue is full, discarding oldest\n");
+ meshtastic_MeshPacket *d = toPhoneQueue.dequeuePtr(0);
+ if (d)
+ releaseToPool(d);
+ } else {
+ LOG_WARN("ToPhone queue is full, dropping packet.\n");
+ releaseToPool(p);
+ return;
+ }
}
- perhapsDecode(p);
assert(toPhoneQueue.enqueue(p, 0));
fromNum++;
}
@@ -335,7 +343,7 @@ int MeshService::onGPSChanged(const meshtastic::GPSStatus *newStatus)
// Used fixed position if configured regalrdless of GPS lock
if (config.position.fixed_position) {
LOG_WARN("Using fixed position\n");
- pos = ConvertToPosition(node->position);
+ pos = TypeConversions::ConvertToPosition(node->position);
}
// Add a fresh timestamp
diff --git a/src/mesh/NodeDB.cpp b/src/mesh/NodeDB.cpp
index 3b6168f27..2046c2cea 100644
--- a/src/mesh/NodeDB.cpp
+++ b/src/mesh/NodeDB.cpp
@@ -254,6 +254,8 @@ void NodeDB::installDefaultModuleConfig()
strncpy(moduleConfig.mqtt.address, default_mqtt_address, sizeof(moduleConfig.mqtt.address));
strncpy(moduleConfig.mqtt.username, default_mqtt_username, sizeof(moduleConfig.mqtt.username));
strncpy(moduleConfig.mqtt.password, default_mqtt_password, sizeof(moduleConfig.mqtt.password));
+ strncpy(moduleConfig.mqtt.root, default_mqtt_root, sizeof(moduleConfig.mqtt.root));
+ moduleConfig.mqtt.encryption_enabled = true;
moduleConfig.has_neighbor_info = true;
moduleConfig.neighbor_info.enabled = false;
@@ -285,6 +287,15 @@ void NodeDB::installRoleDefaults(meshtastic_Config_DeviceConfig_Role role)
} else if (role == meshtastic_Config_DeviceConfig_Role_SENSOR) {
moduleConfig.telemetry.environment_measurement_enabled = true;
moduleConfig.telemetry.environment_update_interval = 300;
+ } else if (role == meshtastic_Config_DeviceConfig_Role_TAK) {
+ config.device.node_info_broadcast_secs = ONE_DAY;
+ config.position.position_broadcast_smart_enabled = false;
+ config.position.position_broadcast_secs = ONE_DAY;
+ // Remove Altitude MSL from flags since CoTs use HAE (height above ellipsoid)
+ config.position.position_flags =
+ (meshtastic_Config_PositionConfig_PositionFlags_ALTITUDE | meshtastic_Config_PositionConfig_PositionFlags_SPEED |
+ meshtastic_Config_PositionConfig_PositionFlags_HEADING | meshtastic_Config_PositionConfig_PositionFlags_DOP);
+ moduleConfig.telemetry.device_update_interval = ONE_DAY;
}
}
@@ -688,7 +699,7 @@ void NodeDB::updatePosition(uint32_t nodeId, const meshtastic_Position &p, RxSou
p.longitude_i, p.altitude);
setLocalPosition(p);
- info->position = ConvertToPositionLite(p);
+ info->position = TypeConversions::ConvertToPositionLite(p);
} else if ((p.time > 0) && !p.latitude_i && !p.longitude_i && !p.timestamp && !p.location_source) {
// FIXME SPECIAL TIME SETTING PACKET FROM EUD TO RADIO
// (stop-gap fix for issue #900)
@@ -706,7 +717,7 @@ void NodeDB::updatePosition(uint32_t nodeId, const meshtastic_Position &p, RxSou
uint32_t tmp_time = info->position.time;
// Next, update atomically
- info->position = ConvertToPositionLite(p);
+ info->position = TypeConversions::ConvertToPositionLite(p);
// Last, restore any fields that may have been overwritten
if (!info->position.time)
diff --git a/src/mesh/NodeDB.h b/src/mesh/NodeDB.h
index 22d5a7780..5fca0e440 100644
--- a/src/mesh/NodeDB.h
+++ b/src/mesh/NodeDB.h
@@ -204,6 +204,7 @@ extern NodeDB nodeDB;
#define default_mqtt_address "mqtt.meshtastic.org"
#define default_mqtt_username "meshdev"
#define default_mqtt_password "large4cats"
+#define default_mqtt_root "msh"
inline uint32_t getConfiguredOrDefaultMs(uint32_t configuredInterval)
{
diff --git a/src/mesh/PhoneAPI.cpp b/src/mesh/PhoneAPI.cpp
index 672c6871e..5abcc8a31 100644
--- a/src/mesh/PhoneAPI.cpp
+++ b/src/mesh/PhoneAPI.cpp
@@ -405,7 +405,7 @@ bool PhoneAPI::available()
if (nodeInfoForPhone.num == 0) {
auto nextNode = nodeDB.readNextMeshNode(readIndex);
if (nextNode) {
- nodeInfoForPhone = ConvertToNodeInfo(nextNode);
+ nodeInfoForPhone = TypeConversions::ConvertToNodeInfo(nextNode);
}
}
return true; // Always say we have something, because we might need to advance our state machine
diff --git a/src/mesh/Router.cpp b/src/mesh/Router.cpp
index 03aa57351..b2d8d585d 100644
--- a/src/mesh/Router.cpp
+++ b/src/mesh/Router.cpp
@@ -249,29 +249,12 @@ ErrorCode Router::send(meshtastic_MeshPacket *p)
if (p->which_payload_variant == meshtastic_MeshPacket_decoded_tag) {
ChannelIndex chIndex = p->channel; // keep as a local because we are about to change it
- bool shouldActuallyEncrypt = true;
-
if (moduleConfig.mqtt.enabled) {
- // check if we should send decrypted packets to mqtt
- // truth table:
- /* mqtt_server mqtt_encryption_enabled should_encrypt
- * not set 0 1
- * not set 1 1
- * set 0 0
- * set 1 1
- *
- * => so we only decrypt mqtt if they have a custom mqtt server AND mqtt_encryption_enabled is FALSE
- */
-
- if (*moduleConfig.mqtt.address && !moduleConfig.mqtt.encryption_enabled) {
- shouldActuallyEncrypt = false;
- }
-
- LOG_INFO("Should encrypt MQTT?: %d\n", shouldActuallyEncrypt);
+ LOG_INFO("Should encrypt MQTT?: %d\n", moduleConfig.mqtt.encryption_enabled);
// the packet is currently in a decrypted state. send it now if they want decrypted packets
- if (mqtt && !shouldActuallyEncrypt)
+ if (mqtt && !moduleConfig.mqtt.encryption_enabled)
mqtt->onSend(*p, chIndex);
}
@@ -284,7 +267,7 @@ ErrorCode Router::send(meshtastic_MeshPacket *p)
if (moduleConfig.mqtt.enabled) {
// the packet is now encrypted.
// check if we should send encrypted packets to mqtt
- if (mqtt && shouldActuallyEncrypt)
+ if (mqtt && moduleConfig.mqtt.encryption_enabled)
mqtt->onSend(*p, chIndex);
}
}
diff --git a/src/mesh/TypeConversions.cpp b/src/mesh/TypeConversions.cpp
new file mode 100644
index 000000000..4e0fdd385
--- /dev/null
+++ b/src/mesh/TypeConversions.cpp
@@ -0,0 +1,55 @@
+#include "TypeConversions.h"
+#include "mesh/generated/meshtastic/deviceonly.pb.h"
+#include "mesh/generated/meshtastic/mesh.pb.h"
+
+meshtastic_NodeInfo TypeConversions::ConvertToNodeInfo(const meshtastic_NodeInfoLite *lite)
+{
+ meshtastic_NodeInfo info = meshtastic_NodeInfo_init_default;
+
+ info.num = lite->num;
+ info.snr = lite->snr;
+ info.last_heard = lite->last_heard;
+ info.channel = lite->channel;
+
+ if (lite->has_position) {
+ info.has_position = true;
+ info.position.latitude_i = lite->position.latitude_i;
+ info.position.longitude_i = lite->position.longitude_i;
+ info.position.altitude = lite->position.altitude;
+ info.position.location_source = lite->position.location_source;
+ info.position.time = lite->position.time;
+ }
+ if (lite->has_user) {
+ info.has_user = true;
+ info.user = lite->user;
+ }
+ if (lite->has_device_metrics) {
+ info.has_device_metrics = true;
+ info.device_metrics = lite->device_metrics;
+ }
+ return info;
+}
+
+meshtastic_PositionLite TypeConversions::ConvertToPositionLite(meshtastic_Position position)
+{
+ meshtastic_PositionLite lite = meshtastic_PositionLite_init_default;
+ lite.latitude_i = position.latitude_i;
+ lite.longitude_i = position.longitude_i;
+ lite.altitude = position.altitude;
+ lite.location_source = position.location_source;
+ lite.time = position.time;
+
+ return lite;
+}
+
+meshtastic_Position TypeConversions::ConvertToPosition(meshtastic_PositionLite lite)
+{
+ meshtastic_Position position = meshtastic_Position_init_default;
+ position.latitude_i = lite.latitude_i;
+ position.longitude_i = lite.longitude_i;
+ position.altitude = lite.altitude;
+ position.location_source = lite.location_source;
+ position.time = lite.time;
+
+ return position;
+}
\ No newline at end of file
diff --git a/src/mesh/TypeConversions.h b/src/mesh/TypeConversions.h
index bfc87102b..ffc3c12a7 100644
--- a/src/mesh/TypeConversions.h
+++ b/src/mesh/TypeConversions.h
@@ -1,54 +1,13 @@
#include "mesh/generated/meshtastic/deviceonly.pb.h"
#include "mesh/generated/meshtastic/mesh.pb.h"
-inline static meshtastic_NodeInfo ConvertToNodeInfo(const meshtastic_NodeInfoLite *lite)
+#pragma once
+#include "NodeDB.h"
+
+class TypeConversions
{
- meshtastic_NodeInfo info = meshtastic_NodeInfo_init_default;
-
- info.num = lite->num;
- info.snr = lite->snr;
- info.last_heard = lite->last_heard;
- info.channel = lite->channel;
-
- if (lite->has_position) {
- info.has_position = true;
- info.position.latitude_i = lite->position.latitude_i;
- info.position.longitude_i = lite->position.longitude_i;
- info.position.altitude = lite->position.altitude;
- info.position.location_source = lite->position.location_source;
- info.position.time = lite->position.time;
- }
- if (lite->has_user) {
- info.has_user = true;
- info.user = lite->user;
- }
- if (lite->has_device_metrics) {
- info.has_device_metrics = true;
- info.device_metrics = lite->device_metrics;
- }
- return info;
-}
-
-inline static meshtastic_PositionLite ConvertToPositionLite(meshtastic_Position position)
-{
- meshtastic_PositionLite lite = meshtastic_PositionLite_init_default;
- lite.latitude_i = position.latitude_i;
- lite.longitude_i = position.longitude_i;
- lite.altitude = position.altitude;
- lite.location_source = position.location_source;
- lite.time = position.time;
-
- return lite;
-}
-
-inline static meshtastic_Position ConvertToPosition(meshtastic_PositionLite lite)
-{
- meshtastic_Position position = meshtastic_Position_init_default;
- position.latitude_i = lite.latitude_i;
- position.longitude_i = lite.longitude_i;
- position.altitude = lite.altitude;
- position.location_source = lite.location_source;
- position.time = lite.time;
-
- return position;
-}
\ No newline at end of file
+ public:
+ static meshtastic_NodeInfo ConvertToNodeInfo(const meshtastic_NodeInfoLite *lite);
+ static meshtastic_PositionLite ConvertToPositionLite(meshtastic_Position position);
+ static meshtastic_Position ConvertToPosition(meshtastic_PositionLite lite);
+};
diff --git a/src/mesh/generated/meshtastic/config.pb.h b/src/mesh/generated/meshtastic/config.pb.h
index 2a811140f..9dcc14940 100644
--- a/src/mesh/generated/meshtastic/config.pb.h
+++ b/src/mesh/generated/meshtastic/config.pb.h
@@ -38,7 +38,12 @@ typedef enum _meshtastic_Config_DeviceConfig_Role {
Telemetry Mesh packets will be prioritized higher and sent more frequently by default.
When used in conjunction with power.is_power_saving = true, nodes will wake up,
send environment telemetry, and then sleep for telemetry.environment_update_interval seconds. */
- meshtastic_Config_DeviceConfig_Role_SENSOR = 6
+ meshtastic_Config_DeviceConfig_Role_SENSOR = 6,
+ /* TAK device role
+ Used for nodes dedicated for connection to an ATAK EUD.
+ Turns off many of the routine broadcasts to favor CoT packet stream
+ from the Meshtastic ATAK plugin -> IMeshService -> Node */
+ meshtastic_Config_DeviceConfig_Role_TAK = 7
} meshtastic_Config_DeviceConfig_Role;
/* Defines the device's behavior for how messages are rebroadcast */
@@ -474,8 +479,8 @@ extern "C" {
/* Helper constants for enums */
#define _meshtastic_Config_DeviceConfig_Role_MIN meshtastic_Config_DeviceConfig_Role_CLIENT
-#define _meshtastic_Config_DeviceConfig_Role_MAX meshtastic_Config_DeviceConfig_Role_SENSOR
-#define _meshtastic_Config_DeviceConfig_Role_ARRAYSIZE ((meshtastic_Config_DeviceConfig_Role)(meshtastic_Config_DeviceConfig_Role_SENSOR+1))
+#define _meshtastic_Config_DeviceConfig_Role_MAX meshtastic_Config_DeviceConfig_Role_TAK
+#define _meshtastic_Config_DeviceConfig_Role_ARRAYSIZE ((meshtastic_Config_DeviceConfig_Role)(meshtastic_Config_DeviceConfig_Role_TAK+1))
#define _meshtastic_Config_DeviceConfig_RebroadcastMode_MIN meshtastic_Config_DeviceConfig_RebroadcastMode_ALL
#define _meshtastic_Config_DeviceConfig_RebroadcastMode_MAX meshtastic_Config_DeviceConfig_RebroadcastMode_LOCAL_ONLY
diff --git a/src/mesh/generated/meshtastic/mesh.pb.h b/src/mesh/generated/meshtastic/mesh.pb.h
index 7733e1d99..dfaf693fc 100644
--- a/src/mesh/generated/meshtastic/mesh.pb.h
+++ b/src/mesh/generated/meshtastic/mesh.pb.h
@@ -113,8 +113,8 @@ typedef enum _meshtastic_HardwareModel {
meshtastic_HardwareModel_PICOMPUTER_S3 = 52,
/* Heltec HT-CT62 with ESP32-C3 CPU and SX1262 LoRa */
meshtastic_HardwareModel_HELTEC_HT62 = 53,
- /* E22-900M series modules with ESP32-S3 */
- meshtastic_HardwareModel_E22_900M_S3 = 54,
+ /* EBYTE SPI LoRa module and ESP32-S3 */
+ meshtastic_HardwareModel_EBYTE_ESP32_S3 = 54,
/* ------------------------------------------------------------------------------------------------------------------------------------------
Reserved ID For developing private Ports. These will show up in live traffic sparsely, so we can use a high number. Keep it within 8 bits.
------------------------------------------------------------------------------------------------------------------------------------------ */
diff --git a/src/modules/AdminModule.cpp b/src/modules/AdminModule.cpp
index 27b539f38..f25e8db33 100644
--- a/src/modules/AdminModule.cpp
+++ b/src/modules/AdminModule.cpp
@@ -676,7 +676,7 @@ void AdminModule::handleSetHamMode(const meshtastic_HamParameters &p)
channels.onConfigChanged();
service.reloadOwner(false);
- service.reloadConfig(SEGMENT_CONFIG | SEGMENT_DEVICESTATE | SEGMENT_CHANNELS);
+ saveChanges(SEGMENT_CONFIG | SEGMENT_DEVICESTATE | SEGMENT_CHANNELS);
}
AdminModule::AdminModule() : ProtobufModule("Admin", meshtastic_PortNum_ADMIN_APP, &meshtastic_AdminMessage_msg)
diff --git a/src/modules/Modules.cpp b/src/modules/Modules.cpp
index 1780a8528..4c3d7eb61 100644
--- a/src/modules/Modules.cpp
+++ b/src/modules/Modules.cpp
@@ -88,7 +88,7 @@ void setupModules()
#endif
#if HAS_SENSOR
new EnvironmentTelemetryModule();
- if (nodeTelemetrySensorsMap[meshtastic_TelemetrySensorType_PMSA003I] > 0) {
+ if (nodeTelemetrySensorsMap[meshtastic_TelemetrySensorType_PMSA003I].first > 0) {
new AirQualityTelemetryModule();
}
#endif
diff --git a/src/modules/PositionModule.cpp b/src/modules/PositionModule.cpp
index 445bde42b..69cd4848e 100644
--- a/src/modules/PositionModule.cpp
+++ b/src/modules/PositionModule.cpp
@@ -33,6 +33,9 @@ void PositionModule::clearPosition()
meshtastic_NodeInfoLite *node = nodeDB.getMeshNode(nodeDB.getNodeNum());
node->position.latitude_i = 0;
node->position.longitude_i = 0;
+ node->position.altitude = 0;
+ node->position.time = 0;
+ nodeDB.setLocalPosition(meshtastic_Position_init_default);
}
bool PositionModule::handleReceivedProtobuf(const meshtastic_MeshPacket &mp, meshtastic_Position *pptr)
@@ -98,7 +101,7 @@ meshtastic_MeshPacket *PositionModule::allocReply()
meshtastic_Position p = meshtastic_Position_init_default; // Start with an empty structure
// if localPosition is totally empty, put our last saved position (lite) in there
if (localPosition.latitude_i == 0 && localPosition.longitude_i == 0) {
- nodeDB.setLocalPosition(ConvertToPosition(node->position));
+ nodeDB.setLocalPosition(TypeConversions::ConvertToPosition(node->position));
}
localPosition.seq_number++;
diff --git a/src/modules/Telemetry/Sensor/BME280Sensor.cpp b/src/modules/Telemetry/Sensor/BME280Sensor.cpp
index 7bc65a418..a30614123 100644
--- a/src/modules/Telemetry/Sensor/BME280Sensor.cpp
+++ b/src/modules/Telemetry/Sensor/BME280Sensor.cpp
@@ -13,7 +13,7 @@ int32_t BME280Sensor::runOnce()
if (!hasSensor()) {
return DEFAULT_SENSOR_MINIMUM_WAIT_TIME_BETWEEN_READS;
}
- status = bme280.begin(nodeTelemetrySensorsMap[sensorType]);
+ status = bme280.begin(nodeTelemetrySensorsMap[sensorType].first, nodeTelemetrySensorsMap[sensorType].second);
bme280.setSampling(Adafruit_BME280::MODE_FORCED,
Adafruit_BME280::SAMPLING_X1, // Temp. oversampling
diff --git a/src/modules/Telemetry/Sensor/BME280Sensor.h b/src/modules/Telemetry/Sensor/BME280Sensor.h
index 780dcdb61..2034c0a82 100644
--- a/src/modules/Telemetry/Sensor/BME280Sensor.h
+++ b/src/modules/Telemetry/Sensor/BME280Sensor.h
@@ -2,7 +2,7 @@
#include "TelemetrySensor.h"
#include
-class BME280Sensor : virtual public TelemetrySensor
+class BME280Sensor : public TelemetrySensor
{
private:
Adafruit_BME280 bme280;
diff --git a/src/modules/Telemetry/Sensor/BME680Sensor.cpp b/src/modules/Telemetry/Sensor/BME680Sensor.cpp
index 5b32645e6..323dce31f 100644
--- a/src/modules/Telemetry/Sensor/BME680Sensor.cpp
+++ b/src/modules/Telemetry/Sensor/BME680Sensor.cpp
@@ -20,7 +20,7 @@ int32_t BME680Sensor::runOnce()
if (!hasSensor()) {
return DEFAULT_SENSOR_MINIMUM_WAIT_TIME_BETWEEN_READS;
}
- if (!bme680.begin(nodeTelemetrySensorsMap[sensorType], Wire))
+ if (!bme680.begin(nodeTelemetrySensorsMap[sensorType].first, *nodeTelemetrySensorsMap[sensorType].second))
checkStatus("begin");
if (bme680.status == BSEC_OK) {
diff --git a/src/modules/Telemetry/Sensor/BME680Sensor.h b/src/modules/Telemetry/Sensor/BME680Sensor.h
index 06e24b1a9..4b7f84cf0 100644
--- a/src/modules/Telemetry/Sensor/BME680Sensor.h
+++ b/src/modules/Telemetry/Sensor/BME680Sensor.h
@@ -6,7 +6,7 @@
#include "bme680_iaq_33v_3s_4d/bsec_iaq.h"
-class BME680Sensor : virtual public TelemetrySensor
+class BME680Sensor : public TelemetrySensor
{
private:
Bsec2 bme680;
diff --git a/src/modules/Telemetry/Sensor/BMP280Sensor.cpp b/src/modules/Telemetry/Sensor/BMP280Sensor.cpp
index c0b5625de..408532388 100644
--- a/src/modules/Telemetry/Sensor/BMP280Sensor.cpp
+++ b/src/modules/Telemetry/Sensor/BMP280Sensor.cpp
@@ -13,7 +13,8 @@ int32_t BMP280Sensor::runOnce()
if (!hasSensor()) {
return DEFAULT_SENSOR_MINIMUM_WAIT_TIME_BETWEEN_READS;
}
- status = bmp280.begin(nodeTelemetrySensorsMap[sensorType]);
+ bmp280 = Adafruit_BMP280(nodeTelemetrySensorsMap[sensorType].second);
+ status = bmp280.begin(nodeTelemetrySensorsMap[sensorType].first);
bmp280.setSampling(Adafruit_BMP280::MODE_FORCED,
Adafruit_BMP280::SAMPLING_X1, // Temp. oversampling
diff --git a/src/modules/Telemetry/Sensor/BMP280Sensor.h b/src/modules/Telemetry/Sensor/BMP280Sensor.h
index cc8c0b9da..48581df8f 100644
--- a/src/modules/Telemetry/Sensor/BMP280Sensor.h
+++ b/src/modules/Telemetry/Sensor/BMP280Sensor.h
@@ -2,7 +2,7 @@
#include "TelemetrySensor.h"
#include
-class BMP280Sensor : virtual public TelemetrySensor
+class BMP280Sensor : public TelemetrySensor
{
private:
Adafruit_BMP280 bmp280;
diff --git a/src/modules/Telemetry/Sensor/INA219Sensor.cpp b/src/modules/Telemetry/Sensor/INA219Sensor.cpp
index 1dd7f7f2c..5a1faa99f 100644
--- a/src/modules/Telemetry/Sensor/INA219Sensor.cpp
+++ b/src/modules/Telemetry/Sensor/INA219Sensor.cpp
@@ -13,8 +13,8 @@ int32_t INA219Sensor::runOnce()
return DEFAULT_SENSOR_MINIMUM_WAIT_TIME_BETWEEN_READS;
}
if (!ina219.success()) {
- ina219 = Adafruit_INA219(nodeTelemetrySensorsMap[sensorType]);
- status = ina219.begin();
+ ina219 = Adafruit_INA219(nodeTelemetrySensorsMap[sensorType].first);
+ status = ina219.begin(nodeTelemetrySensorsMap[sensorType].second);
} else {
status = ina219.success();
}
diff --git a/src/modules/Telemetry/Sensor/INA219Sensor.h b/src/modules/Telemetry/Sensor/INA219Sensor.h
index f11a571cc..76f4613db 100644
--- a/src/modules/Telemetry/Sensor/INA219Sensor.h
+++ b/src/modules/Telemetry/Sensor/INA219Sensor.h
@@ -3,7 +3,7 @@
#include "VoltageSensor.h"
#include
-class INA219Sensor : virtual public TelemetrySensor, VoltageSensor
+class INA219Sensor : public TelemetrySensor, VoltageSensor
{
private:
Adafruit_INA219 ina219;
diff --git a/src/modules/Telemetry/Sensor/INA260Sensor.cpp b/src/modules/Telemetry/Sensor/INA260Sensor.cpp
index 034fecca0..89b7580d2 100644
--- a/src/modules/Telemetry/Sensor/INA260Sensor.cpp
+++ b/src/modules/Telemetry/Sensor/INA260Sensor.cpp
@@ -14,7 +14,7 @@ int32_t INA260Sensor::runOnce()
}
if (!status) {
- status = ina260.begin(nodeTelemetrySensorsMap[sensorType]);
+ status = ina260.begin(nodeTelemetrySensorsMap[sensorType].first, nodeTelemetrySensorsMap[sensorType].second);
}
return initI2CSensor();
}
diff --git a/src/modules/Telemetry/Sensor/INA260Sensor.h b/src/modules/Telemetry/Sensor/INA260Sensor.h
index 8ea532697..28e8944bf 100644
--- a/src/modules/Telemetry/Sensor/INA260Sensor.h
+++ b/src/modules/Telemetry/Sensor/INA260Sensor.h
@@ -3,7 +3,7 @@
#include "VoltageSensor.h"
#include
-class INA260Sensor : virtual public TelemetrySensor, VoltageSensor
+class INA260Sensor : public TelemetrySensor, VoltageSensor
{
private:
Adafruit_INA260 ina260 = Adafruit_INA260();
diff --git a/src/modules/Telemetry/Sensor/LPS22HBSensor.cpp b/src/modules/Telemetry/Sensor/LPS22HBSensor.cpp
index 05f940656..6e30113cd 100644
--- a/src/modules/Telemetry/Sensor/LPS22HBSensor.cpp
+++ b/src/modules/Telemetry/Sensor/LPS22HBSensor.cpp
@@ -13,7 +13,7 @@ int32_t LPS22HBSensor::runOnce()
if (!hasSensor()) {
return DEFAULT_SENSOR_MINIMUM_WAIT_TIME_BETWEEN_READS;
}
- status = lps22hb.begin_I2C(nodeTelemetrySensorsMap[sensorType]);
+ status = lps22hb.begin_I2C(nodeTelemetrySensorsMap[sensorType].first, nodeTelemetrySensorsMap[sensorType].second);
return initI2CSensor();
}
diff --git a/src/modules/Telemetry/Sensor/LPS22HBSensor.h b/src/modules/Telemetry/Sensor/LPS22HBSensor.h
index 556d161c4..5b86539b1 100644
--- a/src/modules/Telemetry/Sensor/LPS22HBSensor.h
+++ b/src/modules/Telemetry/Sensor/LPS22HBSensor.h
@@ -3,7 +3,7 @@
#include
#include
-class LPS22HBSensor : virtual public TelemetrySensor
+class LPS22HBSensor : public TelemetrySensor
{
private:
Adafruit_LPS22 lps22hb;
diff --git a/src/modules/Telemetry/Sensor/MCP9808Sensor.cpp b/src/modules/Telemetry/Sensor/MCP9808Sensor.cpp
index 28db3d8a9..c1d9bfa71 100644
--- a/src/modules/Telemetry/Sensor/MCP9808Sensor.cpp
+++ b/src/modules/Telemetry/Sensor/MCP9808Sensor.cpp
@@ -12,7 +12,7 @@ int32_t MCP9808Sensor::runOnce()
if (!hasSensor()) {
return DEFAULT_SENSOR_MINIMUM_WAIT_TIME_BETWEEN_READS;
}
- status = mcp9808.begin(nodeTelemetrySensorsMap[sensorType]);
+ status = mcp9808.begin(nodeTelemetrySensorsMap[sensorType].first, nodeTelemetrySensorsMap[sensorType].second);
return initI2CSensor();
}
diff --git a/src/modules/Telemetry/Sensor/MCP9808Sensor.h b/src/modules/Telemetry/Sensor/MCP9808Sensor.h
index b70707477..c1029f8a7 100644
--- a/src/modules/Telemetry/Sensor/MCP9808Sensor.h
+++ b/src/modules/Telemetry/Sensor/MCP9808Sensor.h
@@ -2,7 +2,7 @@
#include "TelemetrySensor.h"
#include
-class MCP9808Sensor : virtual public TelemetrySensor
+class MCP9808Sensor : public TelemetrySensor
{
private:
Adafruit_MCP9808 mcp9808;
diff --git a/src/modules/Telemetry/Sensor/SHT31Sensor.h b/src/modules/Telemetry/Sensor/SHT31Sensor.h
index 60354aaea..940361325 100644
--- a/src/modules/Telemetry/Sensor/SHT31Sensor.h
+++ b/src/modules/Telemetry/Sensor/SHT31Sensor.h
@@ -2,7 +2,7 @@
#include "TelemetrySensor.h"
#include
-class SHT31Sensor : virtual public TelemetrySensor
+class SHT31Sensor : public TelemetrySensor
{
private:
Adafruit_SHT31 sht31 = Adafruit_SHT31();
diff --git a/src/modules/Telemetry/Sensor/SHTC3Sensor.h b/src/modules/Telemetry/Sensor/SHTC3Sensor.h
index c67047396..e5db417f5 100644
--- a/src/modules/Telemetry/Sensor/SHTC3Sensor.h
+++ b/src/modules/Telemetry/Sensor/SHTC3Sensor.h
@@ -2,7 +2,7 @@
#include "TelemetrySensor.h"
#include
-class SHTC3Sensor : virtual public TelemetrySensor
+class SHTC3Sensor : public TelemetrySensor
{
private:
Adafruit_SHTC3 shtc3 = Adafruit_SHTC3();
diff --git a/src/modules/Telemetry/Sensor/TelemetrySensor.h b/src/modules/Telemetry/Sensor/TelemetrySensor.h
index dec81e061..7282e6dfa 100644
--- a/src/modules/Telemetry/Sensor/TelemetrySensor.h
+++ b/src/modules/Telemetry/Sensor/TelemetrySensor.h
@@ -1,9 +1,12 @@
#pragma once
#include "../mesh/generated/meshtastic/telemetry.pb.h"
#include "NodeDB.h"
+#include
+
+class TwoWire;
#define DEFAULT_SENSOR_MINIMUM_WAIT_TIME_BETWEEN_READS 1000
-extern uint8_t nodeTelemetrySensorsMap[_meshtastic_TelemetrySensorType_MAX + 1];
+extern std::pair nodeTelemetrySensorsMap[_meshtastic_TelemetrySensorType_MAX + 1];
class TelemetrySensor
{
@@ -16,7 +19,7 @@ class TelemetrySensor
}
const char *sensorName;
- meshtastic_TelemetrySensorType sensorType;
+ meshtastic_TelemetrySensorType sensorType = meshtastic_TelemetrySensorType_SENSOR_UNSET;
unsigned status;
bool initialized = false;
@@ -24,9 +27,9 @@ class TelemetrySensor
{
if (!status) {
LOG_WARN("Could not connect to detected %s sensor.\n Removing from nodeTelemetrySensorsMap.\n", sensorName);
- nodeTelemetrySensorsMap[sensorType] = 0;
+ nodeTelemetrySensorsMap[sensorType].first = 0;
} else {
- LOG_INFO("Opened %s sensor on default i2c bus\n", sensorName);
+ LOG_INFO("Opened %s sensor on i2c bus\n", sensorName);
setup();
}
initialized = true;
@@ -35,7 +38,7 @@ class TelemetrySensor
virtual void setup();
public:
- bool hasSensor() { return sensorType < sizeof(nodeTelemetrySensorsMap) && nodeTelemetrySensorsMap[sensorType] > 0; }
+ bool hasSensor() { return nodeTelemetrySensorsMap[sensorType].first > 0; }
virtual int32_t runOnce() = 0;
virtual bool isInitialized() { return initialized; }
diff --git a/src/mqtt/MQTT.cpp b/src/mqtt/MQTT.cpp
index f369f873f..a9e80c947 100644
--- a/src/mqtt/MQTT.cpp
+++ b/src/mqtt/MQTT.cpp
@@ -133,10 +133,16 @@ void MQTT::onReceive(char *topic, byte *payload, size_t length)
if (strcmp(e.gateway_id, owner.id) == 0)
LOG_INFO("Ignoring downlink message we originally sent.\n");
else {
- if (e.packet) {
+ // Find channel by channel_id and check downlink_enabled
+ meshtastic_Channel ch = channels.getByName(e.channel_id);
+ if (strcmp(e.channel_id, channels.getGlobalId(ch.index)) == 0 && e.packet && ch.settings.downlink_enabled) {
LOG_INFO("Received MQTT topic %s, len=%u\n", topic, length);
meshtastic_MeshPacket *p = packetPool.allocCopy(*e.packet);
+ if (p->which_payload_variant == meshtastic_MeshPacket_decoded_tag) {
+ p->channel = ch.index;
+ }
+
// ignore messages sent by us or if we don't have the channel key
if (router && p->from != nodeDB.getNodeNum() && perhapsDecode(p))
router->enqueueReceivedMessage(p);
@@ -686,6 +692,10 @@ std::string MQTT::meshPacketToJson(meshtastic_MeshPacket *mp)
jsonObj["channel"] = new JSONValue((uint)mp->channel);
jsonObj["type"] = new JSONValue(msgType.c_str());
jsonObj["sender"] = new JSONValue(owner.id);
+ if (mp->rx_rssi != 0)
+ jsonObj["rssi"] = new JSONValue((int)mp->rx_rssi);
+ if (mp->rx_snr != 0)
+ jsonObj["snr"] = new JSONValue((float)mp->rx_snr);
// serialize and write it to the stream
JSONValue *value = new JSONValue(jsonObj);
diff --git a/src/platform/nrf52/architecture.h b/src/platform/nrf52/architecture.h
index 904ab908d..e6eebc45b 100644
--- a/src/platform/nrf52/architecture.h
+++ b/src/platform/nrf52/architecture.h
@@ -46,6 +46,8 @@
#define HW_VENDOR meshtastic_HardwareModel_RAK4631
#elif defined(TTGO_T_ECHO)
#define HW_VENDOR meshtastic_HardwareModel_T_ECHO
+#elif defined(NANO_G2_ULTRA)
+#define HW_VENDOR meshtastic_HardwareModel_NANO_G2_ULTRA
#elif defined(NORDIC_PCA10059)
#define HW_VENDOR meshtastic_HardwareModel_NRF52840_PCA10059
#elif defined(PRIVATE_HW) || defined(FEATHER_DIY)
diff --git a/variants/MakePython_nRF52840_eink/platformio.ini b/variants/MakePython_nRF52840_eink/platformio.ini
index 2b08ec9a1..3ac18bcf0 100644
--- a/variants/MakePython_nRF52840_eink/platformio.ini
+++ b/variants/MakePython_nRF52840_eink/platformio.ini
@@ -11,4 +11,4 @@ lib_deps =
https://github.com/meshtastic/ESP32_Codec2.git#633326c78ac251c059ab3a8c430fcdf25b41672f
zinggjm/GxEPD2@^1.4.9
debug_tool = jlink
-upload_port = /dev/ttyACM4
+;upload_port = /dev/ttyACM4
diff --git a/variants/betafpv_2400_tx_micro/platformio.ini b/variants/betafpv_2400_tx_micro/platformio.ini
index decdb390e..82fe2a9e4 100644
--- a/variants/betafpv_2400_tx_micro/platformio.ini
+++ b/variants/betafpv_2400_tx_micro/platformio.ini
@@ -11,7 +11,7 @@ build_flags =
-I variants/betafpv_2400_tx_micro
board_build.f_cpu = 240000000L
upload_protocol = esptool
-upload_port = /dev/ttyUSB0
+;upload_port = /dev/ttyUSB0
upload_speed = 460800
lib_deps =
${esp32_base.lib_deps}
diff --git a/variants/betafpv_900_tx_nano/platformio.ini b/variants/betafpv_900_tx_nano/platformio.ini
index e4c945cab..68e1a469b 100644
--- a/variants/betafpv_900_tx_nano/platformio.ini
+++ b/variants/betafpv_900_tx_nano/platformio.ini
@@ -10,7 +10,7 @@ build_flags =
-I variants/betafpv_900_tx_nano
board_build.f_cpu = 240000000L
upload_protocol = esptool
-upload_port = /dev/ttyUSB0
+;upload_port = /dev/ttyUSB0
upload_speed = 460800
lib_deps =
${esp32_base.lib_deps}
diff --git a/variants/bpi_picow_esp32_s3/platformio.ini b/variants/bpi_picow_esp32_s3/platformio.ini
index 27c420df5..7e94cc97e 100644
--- a/variants/bpi_picow_esp32_s3/platformio.ini
+++ b/variants/bpi_picow_esp32_s3/platformio.ini
@@ -6,7 +6,7 @@ board_level = extra
;upload_protocol = esp-builtin
;Normal method
upload_protocol = esptool
-upload_port = /dev/ttyACM2
+;upload_port = /dev/ttyACM2
lib_deps =
${esp32_base.lib_deps}
caveman99/ESP32 Codec2@^1.0.1
diff --git a/variants/diy/hydra/variant.h b/variants/diy/hydra/variant.h
index 98c1c2ae1..64bdd73f7 100644
--- a/variants/diy/hydra/variant.h
+++ b/variants/diy/hydra/variant.h
@@ -2,13 +2,11 @@
#define I2C_SDA 21
#define I2C_SCL 22
-// GPS
-#undef GPS_RX_PIN
-#undef GPS_TX_PIN
-#define GPS_RX_PIN 12
+// For GPS, 'undef's not needed
#define GPS_TX_PIN 15
-#define GPS_UBLOX
+#define GPS_RX_PIN 12
#define PIN_GPS_EN 4
+#define GPS_POWER_TOGGLE // Moved definition from platformio.ini to here
#define BUTTON_PIN 39 // The middle button GPIO on the T-Beam
#define BATTERY_PIN 35 // A battery voltage measurement pin, voltage divider connected here to measure battery voltage
@@ -18,28 +16,25 @@
#define EXT_NOTIFY_OUT 12 // Overridden default pin to use for Ext Notify Module (#975).
#define LED_PIN 2 // add status LED (compatible with core-pcb and DIY targets)
-#define LORA_DIO0 26 // a No connect on the SX1262/SX1268 module
-#define LORA_RESET 23 // RST for SX1276, and for SX1262/SX1268
-#define LORA_DIO1 33 // IRQ for SX1262/SX1268
-#define LORA_DIO2 32 // BUSY for SX1262/SX1268
-#define LORA_DIO3 // Not connected on PCB, but internally on the TTGO SX1262/SX1268, if DIO3 is high the TXCO is enabled
+// Radio
+#define USE_SX1262 // E22-900M30S uses SX1262
+#define SX126X_MAX_POWER \
+ 22 // Outputting 22dBm from SX1262 results in ~30dBm E22-900M30S output (module only uses last stage of the YP2233W PA)
+#define SX126X_DIO3_TCXO_VOLTAGE 1.8 // E22 series TCXO reference voltage is 1.8V
-#define RF95_SCK 5
-#define RF95_MISO 19
-#define RF95_MOSI 27
-#define RF95_NSS 18
+#define SX126X_CS 18 // EBYTE module's NSS pin
+#define SX126X_SCK 5 // EBYTE module's SCK pin
+#define SX126X_MOSI 27 // EBYTE module's MOSI pin
+#define SX126X_MISO 19 // EBYTE module's MISO pin
+#define SX126X_RESET 23 // EBYTE module's NRST pin
+#define SX126X_BUSY 32 // EBYTE module's BUSY pin
+#define SX126X_DIO1 33 // EBYTE module's DIO1 pin
-#define USE_SX1262
+#define SX126X_TXEN 13 // Schematic connects EBYTE module's TXEN pin to MCU
+#define SX126X_RXEN 14 // Schematic connects EBYTE module's RXEN pin to MCU
-#define SX126X_CS 18 // NSS for SX126X
-#define SX126X_DIO1 LORA_DIO1
-#define SX126X_BUSY LORA_DIO2
-#define SX126X_RESET LORA_RESET
-#define SX126X_RXEN 14
-#define SX126X_TXEN RADIOLIB_NC
-#define SX126X_DIO2_AS_RF_SWITCH
-
-// Set lora.tx_power to 13 for Hydra or other E22 900M30S target due to PA
-#define SX126X_MAX_POWER 13
-
-#define SX126X_DIO3_TCXO_VOLTAGE 1.8
+#define RF95_NSS SX126X_CS // Compatibility with variant file configuration structure
+#define RF95_SCK SX126X_SCK // Compatibility with variant file configuration structure
+#define RF95_MOSI SX126X_MOSI // Compatibility with variant file configuration structure
+#define RF95_MISO SX126X_MISO // Compatibility with variant file configuration structure
+#define LORA_DIO1 SX126X_DIO1 // Compatibility with variant file configuration structure
diff --git a/variants/diy/platformio.ini b/variants/diy/platformio.ini
index cb031f266..e7d72d13f 100644
--- a/variants/diy/platformio.ini
+++ b/variants/diy/platformio.ini
@@ -43,6 +43,4 @@ board_level = extra
build_flags =
${esp32_base.build_flags}
-D DIY_V1
- -D EBYTE_E22
- -D GPS_POWER_TOGGLE
-I variants/diy/hydra
diff --git a/variants/heltec_esp32c3/platformio.ini b/variants/heltec_esp32c3/platformio.ini
index a9843ef85..c9c80213e 100644
--- a/variants/heltec_esp32c3/platformio.ini
+++ b/variants/heltec_esp32c3/platformio.ini
@@ -8,5 +8,5 @@ build_flags =
-I variants/heltec_esp32c3
monitor_speed = 115200
upload_protocol = esptool
-upload_port = /dev/ttyUSB0
-upload_speed = 921600
+;upload_port = /dev/ttyUSB0
+upload_speed = 921600
\ No newline at end of file
diff --git a/variants/m5stack-stamp-c3/platformio.ini b/variants/m5stack-stamp-c3/platformio.ini
index b7cec5552..bab65b621 100644
--- a/variants/m5stack-stamp-c3/platformio.ini
+++ b/variants/m5stack-stamp-c3/platformio.ini
@@ -8,5 +8,5 @@ build_flags =
-I variants/m5stack-stamp-c3
monitor_speed = 115200
upload_protocol = esptool
-upload_port = /dev/ttyACM2
+;upload_port = /dev/ttyACM2
upload_speed = 921600
diff --git a/variants/m5stack_coreink/platformio.ini b/variants/m5stack_coreink/platformio.ini
index 1a7926d7e..e6aef380c 100644
--- a/variants/m5stack_coreink/platformio.ini
+++ b/variants/m5stack_coreink/platformio.ini
@@ -23,4 +23,4 @@ lib_ignore =
monitor_filters = esp32_exception_decoder
board_build.f_cpu = 240000000L
upload_protocol = esptool
-upload_port = /dev/ttyACM0
+;upload_port = /dev/ttyACM0
diff --git a/variants/my_esp32s3_diy_eink/platformio.ini b/variants/my_esp32s3_diy_eink/platformio.ini
index 8405f784e..d3c55afda 100644
--- a/variants/my_esp32s3_diy_eink/platformio.ini
+++ b/variants/my_esp32s3_diy_eink/platformio.ini
@@ -6,7 +6,7 @@ board_build.arduino.memory_type = dio_opi
board_build.mcu = esp32s3
board_build.f_cpu = 240000000L
upload_protocol = esptool
-upload_port = /dev/ttyACM1
+;upload_port = /dev/ttyACM1
upload_speed = 921600
platform_packages =
tool-esptoolpy@^1.40500.0
diff --git a/variants/my_esp32s3_diy_oled/platformio.ini b/variants/my_esp32s3_diy_oled/platformio.ini
index 1430dfd96..9b8b09f7f 100644
--- a/variants/my_esp32s3_diy_oled/platformio.ini
+++ b/variants/my_esp32s3_diy_oled/platformio.ini
@@ -6,7 +6,7 @@ board_build.arduino.memory_type = dio_opi
board_build.mcu = esp32s3
board_build.f_cpu = 240000000L
upload_protocol = esptool
-upload_port = /dev/ttyACM0
+;upload_port = /dev/ttyACM0
upload_speed = 921600
platform_packages =
tool-esptoolpy@^1.40500.0
diff --git a/variants/rak4631_epaper_onrxtx/platformio.ini b/variants/rak4631_epaper_onrxtx/platformio.ini
index 08c55d129..0a4f05344 100644
--- a/variants/rak4631_epaper_onrxtx/platformio.ini
+++ b/variants/rak4631_epaper_onrxtx/platformio.ini
@@ -15,4 +15,4 @@ lib_deps =
debug_tool = jlink
; If not set we will default to uploading over serial (first it forces bootloader entry by talking 1200bps to cdcacm)
;upload_protocol = jlink
-upload_port = /dev/ttyACM3
+;upload_port = /dev/ttyACM3
diff --git a/variants/trackerd/platformio.ini b/variants/trackerd/platformio.ini
new file mode 100644
index 000000000..23868ffb4
--- /dev/null
+++ b/variants/trackerd/platformio.ini
@@ -0,0 +1,13 @@
+[env:trackerd]
+extends = esp32_base
+;platform = https://github.com/platformio/platform-espressif32.git#feature/arduino-upstream
+platform = espressif32
+board = pico32
+board_build.f_flash = 80000000L
+board_level = extra
+build_flags =
+ ${esp32_base.build_flags} -D PRIVATE_HW -I variants/trackerd -D BSFILE=\"boards/dragino_lbt2.h\"
+;board_build.partitions = no_ota.csv
+;platform_packages =
+; platformio/framework-arduinoespressif32@3
+;platformio/framework-arduinoespressif32 @ https://github.com/espressif/arduino-esp32.git#2.0.1-RC1
\ No newline at end of file
diff --git a/variants/trackerd/variant.h b/variants/trackerd/variant.h
new file mode 100644
index 000000000..b3fca367f
--- /dev/null
+++ b/variants/trackerd/variant.h
@@ -0,0 +1,46 @@
+// Initialize i2c bus on sd_dat and esp_led pins, respectively. We need a bus to not hang on boot
+#define HAS_SCREEN 0
+#define I2C_SDA 21
+#define I2C_SCL 22
+
+#undef GPS_RX_PIN
+#undef GPS_TX_PIN
+#define GPS_RX_PIN 9
+#define GPS_TX_PIN 10
+
+#define LED_PIN 13 // 13 red, 2 blue, 15 red
+
+//#define HAS_BUTTON 0
+#define BUTTON_PIN 0
+#define BUTTON_NEED_PULLUP
+
+#define USE_RF95
+#define LORA_DIO0 26 // a No connect on the SX1262 module
+#define LORA_RESET 23
+#define LORA_DIO1 33
+#define LORA_DIO2 32 // Not really used
+
+#define BATTERY_PIN 35 // A battery voltage measurement pin, voltage divider connected here to measure battery voltage
+
+// Battery
+// The battery sense is hooked to pin A0 (4)
+// it is defined in the anlaolgue pin section of this file
+// and has 12 bit resolution
+#define BATTERY_SENSE_RESOLUTION_BITS 12
+#define BATTERY_SENSE_RESOLUTION 4096.0
+// Definition of milliVolt per LSB => 3.0V ADC range and 12-bit ADC resolution = 3000mV/4096
+#define VBAT_MV_PER_LSB (0.73242188F)
+// Voltage divider value => 100K + 100K voltage divider on VBAT = (100K / (100K + 100K))
+#define VBAT_DIVIDER (0.5F)
+// Compensation factor for the VBAT divider
+#define VBAT_DIVIDER_COMP (2.0)
+// Fixed calculation of milliVolt from compensation value
+#define REAL_VBAT_MV_PER_LSB (VBAT_DIVIDER_COMP * VBAT_MV_PER_LSB)
+#undef AREF_VOLTAGE
+#define AREF_VOLTAGE 3.0
+#define VBAT_AR_INTERNAL AR_INTERNAL_3_0
+#define ADC_MULTIPLIER VBAT_DIVIDER_COMP
+#define VBAT_RAW_TO_SCALED(x) (REAL_VBAT_MV_PER_LSB * x)
+
+//#define BATTERY_SENSE_SAMPLES 15 // Set the number of samples, It has an effect of increasing sensitivity.
+//#define ADC_MULTIPLIER 3.3
\ No newline at end of file
diff --git a/version.properties b/version.properties
index 43b9f255e..006a90013 100644
--- a/version.properties
+++ b/version.properties
@@ -1,4 +1,4 @@
[VERSION]
major = 2
minor = 2
-build = 11
+build = 13