diff --git a/arch/esp32/esp32.ini b/arch/esp32/esp32.ini index 1f17bc691..d6a756bec 100644 --- a/arch/esp32/esp32.ini +++ b/arch/esp32/esp32.ini @@ -46,7 +46,7 @@ lib_deps = ${radiolib_base.lib_deps} https://github.com/meshtastic/esp32_https_server.git#23665b3adc080a311dcbb586ed5941b5f94d6ea2 h2zero/NimBLE-Arduino@^1.4.2 - https://github.com/dbSuS/libpax.git#7bcd3fcab75037505be9b122ab2b24cc5176b587 + https://github.com/dbinfrago/libpax.git#3cdc0371c375676a97967547f4065607d4c53fd1 lewisxhe/XPowersLib@^0.2.6 https://github.com/meshtastic/ESP32_Codec2.git#633326c78ac251c059ab3a8c430fcdf25b41672f rweather/Crypto@^0.4.0 diff --git a/arch/rp2xx0/rp2040.ini b/arch/rp2xx0/rp2040.ini index 031a4848f..85efa583c 100644 --- a/arch/rp2xx0/rp2040.ini +++ b/arch/rp2xx0/rp2040.ini @@ -1,6 +1,6 @@ ; Common settings for rp2040 Processor based targets [rp2040_base] -platform = https://github.com/maxgerhardt/platform-raspberrypi.git#a606be683748c73e9a0d46baf70163478d298f0f ; For arduino-pico 4.2.0 +platform = https://github.com/maxgerhardt/platform-raspberrypi.git#19e30129fb1428b823be585c787dcb4ac0d9014c ; For arduino-pico 4.2.1 extends = arduino_base platform_packages = framework-arduinopico@https://github.com/earlephilhower/arduino-pico.git#996c3bfab9758f12c07aa20cc6d352e630c16987 ; 4.2.1 with fix for sporadic hangs diff --git a/arch/rp2xx0/rp2350.ini b/arch/rp2xx0/rp2350.ini index 0ae184d00..6daf59bdf 100644 --- a/arch/rp2xx0/rp2350.ini +++ b/arch/rp2xx0/rp2350.ini @@ -1,6 +1,6 @@ ; Common settings for rp2040 Processor based targets [rp2350_base] -platform = https://github.com/maxgerhardt/platform-raspberrypi.git#a606be683748c73e9a0d46baf70163478d298f0f ; For arduino-pico 4.2.0 +platform = https://github.com/maxgerhardt/platform-raspberrypi.git#19e30129fb1428b823be585c787dcb4ac0d9014c ; For arduino-pico 4.2.1 extends = arduino_base platform_packages = framework-arduinopico@https://github.com/earlephilhower/arduino-pico.git#96c3bfab9758f12c07aa20cc6d352e630c16987 ; 4.2.1 with fix for sporadic hangs diff --git a/bin/build-native.sh b/bin/build-native.sh index e8ed61bcf..cda77b064 100755 --- a/bin/build-native.sh +++ b/bin/build-native.sh @@ -27,5 +27,4 @@ rm -r $OUTDIR/* || true platformio pkg update --environment native || platformioFailed pio run --environment native || platformioFailed cp .pio/build/native/program "$OUTDIR/meshtasticd_linux_$(uname -m)" -cp bin/device-install.* $OUTDIR -cp bin/device-update.* $OUTDIR +cp bin/native-install.* $OUTDIR diff --git a/bin/device-install.bat b/bin/device-install.bat index f8ca9e408..c18be89a8 100755 --- a/bin/device-install.bat +++ b/bin/device-install.bat @@ -1,6 +1,7 @@ @ECHO OFF set PYTHON=python +set WEB_APP=0 :: Determine the correct esptool command to use where esptool >nul 2>&1 @@ -12,13 +13,14 @@ if %ERRORLEVEL% EQU 0 ( goto GETOPTS :HELP -echo Usage: %~nx0 [-h] [-p ESPTOOL_PORT] [-P PYTHON] [-f FILENAME^|FILENAME] +echo Usage: %~nx0 [-h] [-p ESPTOOL_PORT] [-P PYTHON] [-f FILENAME^|FILENAME] [--web] echo Flash image file to device, but first erasing and writing system information echo. echo -h Display this help and exit echo -p ESPTOOL_PORT Set the environment variable for ESPTOOL_PORT. If not set, ESPTOOL iterates all ports (Dangerrous). echo -P PYTHON Specify alternate python interpreter to use to invoke esptool. (Default: %PYTHON%) echo -f FILENAME The .bin file to flash. Custom to your device type and region. +echo --web Flash WEB APP. goto EOF :GETOPTS @@ -27,6 +29,7 @@ if /I "%1"=="--help" goto HELP if /I "%1"=="-F" set "FILENAME=%2" & SHIFT if /I "%1"=="-p" set ESPTOOL_PORT=%2 & SHIFT if /I "%1"=="-P" set PYTHON=%2 & SHIFT +if /I "%1"=="--web" set WEB_APP=1 & SHIFT SHIFT IF NOT "__%1__"=="____" goto GETOPTS @@ -49,8 +52,14 @@ IF EXIST %FILENAME% IF x%FILENAME:update=%==x%FILENAME% ( ) else ( %ESPTOOL_CMD% --baud 115200 write_flash 0x260000 bleota-s3.bin ) - for %%f in (littlefs-*.bin) do ( - %ESPTOOL_CMD% --baud 115200 write_flash 0x300000 %%f + IF %WEB_APP%==1 ( + for %%f in (littlefswebui-*.bin) do ( + %ESPTOOL_CMD% --baud 115200 write_flash 0x300000 %%f + ) + ) else ( + for %%f in (littlefs-*.bin) do ( + %ESPTOOL_CMD% --baud 115200 write_flash 0x300000 %%f + ) ) ) else ( echo "Invalid file: %FILENAME%" diff --git a/bin/device-install.sh b/bin/device-install.sh index b2a5684ee..e09c61ba6 100755 --- a/bin/device-install.sh +++ b/bin/device-install.sh @@ -1,6 +1,7 @@ #!/bin/sh PYTHON=${PYTHON:-$(which python3 python | head -n 1)} +WEB_APP=false # Determine the correct esptool command to use if "$PYTHON" -m esptool version >/dev/null 2>&1; then @@ -19,16 +20,26 @@ set -e # Usage info show_help() { cat <SetPinout(DAC_I2S_BCK, DAC_I2S_WS, DAC_I2S_DOUT); + audioOut->SetPinout(DAC_I2S_BCK, DAC_I2S_WS, DAC_I2S_DOUT, DAC_I2S_MCLK); audioOut->SetGain(0.2); }; diff --git a/src/configuration.h b/src/configuration.h index 15912be3f..2e81557b1 100644 --- a/src/configuration.h +++ b/src/configuration.h @@ -148,6 +148,7 @@ along with this program. If not, see . #define NAU7802_ADDR 0x2A #define MAX30102_ADDR 0x57 #define MLX90614_ADDR_DEF 0x5A +#define CGRADSENS_ADDR 0x66 // ----------------------------------------------------------------------------- // ACCELEROMETER diff --git a/src/detect/ScanI2C.h b/src/detect/ScanI2C.h index 8591b8433..f4516458b 100644 --- a/src/detect/ScanI2C.h +++ b/src/detect/ScanI2C.h @@ -63,7 +63,8 @@ class ScanI2C ICM20948, MAX30102, TPS65233, - MPR121KB + MPR121KB, + CGRADSENS } DeviceType; // typedef uint8_t DeviceAddress; diff --git a/src/detect/ScanI2CTwoWire.cpp b/src/detect/ScanI2CTwoWire.cpp index ef5e5ee00..55f13c5a0 100644 --- a/src/detect/ScanI2CTwoWire.cpp +++ b/src/detect/ScanI2CTwoWire.cpp @@ -314,19 +314,34 @@ void ScanI2CTwoWire::scanPort(I2CPort port, uint8_t *address, uint8_t asize) break; case INA3221_ADDR: registerValue = getRegisterValue(ScanI2CTwoWire::RegisterLocation(addr, 0xFE), 2); - LOG_DEBUG("Register MFG_UID: 0x%x", registerValue); + LOG_DEBUG("Register MFG_UID FE: 0x%x", registerValue); if (registerValue == 0x5449) { LOG_INFO("INA3221 sensor found at address 0x%x", (uint8_t)addr.address); type = INA3221; } else { - LOG_INFO("DFRobot Lark weather station found at address 0x%x", (uint8_t)addr.address); - type = DFROBOT_LARK; + /* check the first 2 bytes of the 6 byte response register + LARK FW 1.0 should return: + RESPONSE_STATUS STATUS_SUCCESS (0x53) + RESPONSE_CMD CMD_GET_VERSION (0x05) + RESPONSE_LEN_L 0x02 + RESPONSE_LEN_H 0x00 + RESPONSE_PAYLOAD 0x01 + RESPONSE_PAYLOAD+1 0x00 + */ + registerValue = getRegisterValue(ScanI2CTwoWire::RegisterLocation(addr, 0x05), 2); + LOG_DEBUG("Register MFG_UID 05: 0x%x", registerValue); + if (registerValue == 0x5305) { + LOG_INFO("DFRobot Lark weather station found at address 0x%x", (uint8_t)addr.address); + type = DFROBOT_LARK; + } + // else: probably a RAK12500/UBLOX GPS on I2C } break; case MCP9808_ADDR: // We need to check for STK8BAXX first, since register 0x07 is new data flag for the z-axis and can produce some // weird result. and register 0x00 doesn't seems to be colliding with MCP9808 and LIS3DH chips. { +#ifdef HAS_STK8XXX // Check register 0x00 for 0x8700 response to ID STK8BA53 chip. registerValue = getRegisterValue(ScanI2CTwoWire::RegisterLocation(addr, 0x00), 2); if (registerValue == 0x8700) { @@ -334,6 +349,7 @@ void ScanI2CTwoWire::scanPort(I2CPort port, uint8_t *address, uint8_t asize) LOG_INFO("STK8BAXX accelerometer found"); break; } +#endif // Check register 0x07 for 0x0400 response to ID MCP9808 chip. registerValue = getRegisterValue(ScanI2CTwoWire::RegisterLocation(addr, 0x07), 2); @@ -463,6 +479,16 @@ void ScanI2CTwoWire::scanPort(I2CPort port, uint8_t *address, uint8_t asize) } break; + case CGRADSENS_ADDR: + // Register 0x00 of the RadSens sensor contains is product identifier 0x7D + registerValue = getRegisterValue(ScanI2CTwoWire::RegisterLocation(addr, 0x00), 1); + if (registerValue == 0x7D) { + type = CGRADSENS; + LOG_INFO("ClimateGuard RadSens Geiger-Muller Sensor found"); + break; + } + break; + default: LOG_INFO("Device found at address 0x%x was not able to be enumerated", addr.address); } diff --git a/src/gps/GPS.h b/src/gps/GPS.h index cd61c5444..cb970f7db 100644 --- a/src/gps/GPS.h +++ b/src/gps/GPS.h @@ -64,6 +64,95 @@ const char *getDOPString(uint32_t dop); */ class GPS : private concurrency::OSThread { + public: + meshtastic_Position p = meshtastic_Position_init_default; + + /** This is normally bound to config.position.gps_en_gpio but some rare boards (like heltec tracker) need more advanced + * implementations. Those boards will set this public variable to a custom implementation. + * + * Normally set by GPS::createGPS() + */ + GpioVirtPin *enablePin = NULL; + + virtual ~GPS(); + + /** We will notify this observable anytime GPS state has changed meaningfully */ + Observable newStatus; + + /** + * Returns true if we succeeded + */ + virtual bool setup(); + + // re-enable the thread + void enable(); + + // Disable the thread + int32_t disable() override; + + // toggle between enabled/disabled + void toggleGpsMode(); + + // Change the power state of the GPS - for power saving / shutdown + void setPowerState(GPSPowerState newState, uint32_t sleepMs = 0); + + /// Returns true if we have acquired GPS lock. + virtual bool hasLock(); + + /// Returns true if there's valid data flow with the chip. + virtual bool hasFlow(); + + /// Return true if we are connected to a GPS + bool isConnected() const { return hasGPS; } + + bool isPowerSaving() const { return config.position.gps_mode != meshtastic_Config_PositionConfig_GpsMode_ENABLED; } + + // Empty the input buffer as quickly as possible + void clearBuffer(); + + virtual bool factoryReset(); + + // Creates an instance of the GPS class. + // Returns the new instance or null if the GPS is not present. + static GPS *createGps(); + + // Wake the GPS hardware - ready for an update + void up(); + + // Let the GPS hardware save power between updates + void down(); + + protected: + /// Record that we have a GPS + void setConnected(); + + /** Subclasses should look for serial rx characters here and feed it to their GPS parser + * + * Return true if we received a valid message from the GPS + */ + virtual bool whileActive(); + + /** + * Perform any processing that should be done only while the GPS is awake and looking for a fix. + * Override this method to check for new locations + * + * @return true if we've acquired a time + */ + virtual bool lookForTime(); + + /** + * Perform any processing that should be done only while the GPS is awake and looking for a fix. + * Override this method to check for new locations + * + * @return true if we've acquired a new location + */ + virtual bool lookForLocation(); + + GnssModel_t gnssModel = GNSS_MODEL_UNKNOWN; + + private: + GPS() : concurrency::OSThread("GPS") {} + TinyGPSPlus reader; uint8_t fixQual = 0; // fix quality from GPGGA uint32_t lastChecksumFailCount = 0; @@ -75,7 +164,6 @@ class GPS : private concurrency::OSThread TinyGPSCustom gsapdop; // custom extract PDOP from GPGSA uint8_t fixType = 0; // fix type from GPGSA #endif - private: #if GPS_BAUDRATE_FIXED // if GPS_BAUDRATE is specified in variant, only try that. const int serialSpeeds[1] = {GPS_BAUDRATE}; @@ -113,7 +201,6 @@ class GPS : private concurrency::OSThread CallbackObserver notifyDeepSleepObserver = CallbackObserver(this, &GPS::prepareDeepSleep); - public: /** If !NULL we will use this serial port to construct our GPS */ #if defined(ARCH_RP2040) static SerialUART *_serial_gps; @@ -167,53 +254,6 @@ class GPS : private concurrency::OSThread const char *ACK_SUCCESS_MESSAGE = "Get ack success!"; - meshtastic_Position p = meshtastic_Position_init_default; - - /** This is normally bound to config.position.gps_en_gpio but some rare boards (like heltec tracker) need more advanced - * implementations. Those boards will set this public variable to a custom implementation. - * - * Normally set by GPS::createGPS() - */ - GpioVirtPin *enablePin = NULL; - - GPS() : concurrency::OSThread("GPS") {} - - virtual ~GPS(); - - /** We will notify this observable anytime GPS state has changed meaningfully */ - Observable newStatus; - - /** - * Returns true if we succeeded - */ - virtual bool setup(); - - // re-enable the thread - void enable(); - - // Disable the thread - int32_t disable() override; - - // toggle between enabled/disabled - void toggleGpsMode(); - - // Change the power state of the GPS - for power saving / shutdown - void setPowerState(GPSPowerState newState, uint32_t sleepMs = 0); - - /// Returns true if we have acquired GPS lock. - virtual bool hasLock(); - - /// Returns true if there's valid data flow with the chip. - virtual bool hasFlow(); - - /// Return true if we are connected to a GPS - bool isConnected() const { return hasGPS; } - - bool isPowerSaving() const { return config.position.gps_mode != meshtastic_Config_PositionConfig_GpsMode_ENABLED; } - - // Empty the input buffer as quickly as possible - void clearBuffer(); - // Create a ublox packet for editing in memory uint8_t makeUBXPacket(uint8_t class_id, uint8_t msg_id, uint8_t payload_size, const uint8_t *msg); uint8_t makeCASPacket(uint8_t class_id, uint8_t msg_id, uint8_t payload_size, const uint8_t *msg); @@ -229,59 +269,6 @@ class GPS : private concurrency::OSThread GPS_RESPONSE getACKCas(uint8_t class_id, uint8_t msg_id, uint32_t waitMillis); - virtual bool factoryReset(); - - // Creates an instance of the GPS class. - // Returns the new instance or null if the GPS is not present. - static GPS *createGps(); - - // Wake the GPS hardware - ready for an update - void up(); - - // Let the GPS hardware save power between updates - void down(); - - protected: - /** - * Perform any processing that should be done only while the GPS is awake and looking for a fix. - * Override this method to check for new locations - * - * @return true if we've acquired a time - */ - - /** - * Perform any processing that should be done only while the GPS is awake and looking for a fix. - * Override this method to check for new locations - * - * @return true if we've acquired a new location - */ - - /// Record that we have a GPS - void setConnected(); - - /** Subclasses should look for serial rx characters here and feed it to their GPS parser - * - * Return true if we received a valid message from the GPS - */ - virtual bool whileActive(); - - /** - * Perform any processing that should be done only while the GPS is awake and looking for a fix. - * Override this method to check for new locations - * - * @return true if we've acquired a time - */ - virtual bool lookForTime(); - - /** - * Perform any processing that should be done only while the GPS is awake and looking for a fix. - * Override this method to check for new locations - * - * @return true if we've acquired a new location - */ - virtual bool lookForLocation(); - - private: /// Prepare the GPS for the cpu entering deep sleep, expect to be gone for at least 100s of msecs /// always returns 0 to indicate okay to sleep int prepareDeepSleep(void *unused); @@ -320,10 +307,7 @@ class GPS : private concurrency::OSThread uint8_t fixeddelayCtr = 0; const char *powerStateToString(); - - protected: - GnssModel_t gnssModel = GNSS_MODEL_UNKNOWN; }; extern GPS *gps; -#endif // Exclude GPS \ No newline at end of file +#endif // Exclude GPS diff --git a/src/gps/NMEAWPL.cpp b/src/gps/NMEAWPL.cpp index f528c4607..f4249ca62 100644 --- a/src/gps/NMEAWPL.cpp +++ b/src/gps/NMEAWPL.cpp @@ -23,7 +23,7 @@ uint32_t printWPL(char *buf, size_t bufsz, const meshtastic_PositionLite &pos, c { GeoCoord geoCoord(pos.latitude_i, pos.longitude_i, pos.altitude); char type = isCaltopoMode ? 'P' : 'N'; - uint32_t len = snprintf(buf, bufsz, "$G%cWPL,%02d%07.4f,%c,%03d%07.4f,%c,%s", type, geoCoord.getDMSLatDeg(), + uint32_t len = snprintf(buf, bufsz, "\r\n$G%cWPL,%02d%07.4f,%c,%03d%07.4f,%c,%s", type, geoCoord.getDMSLatDeg(), (abs(geoCoord.getLatitude()) - geoCoord.getDMSLatDeg() * 1e+7) * 6e-6, geoCoord.getDMSLatCP(), geoCoord.getDMSLonDeg(), (abs(geoCoord.getLongitude()) - geoCoord.getDMSLonDeg() * 1e+7) * 6e-6, geoCoord.getDMSLonCP(), name); diff --git a/src/graphics/Screen.cpp b/src/graphics/Screen.cpp index f18baf276..a875c11d6 100644 --- a/src/graphics/Screen.cpp +++ b/src/graphics/Screen.cpp @@ -396,7 +396,7 @@ static void drawBattery(OLEDDisplay *display, int16_t x, int16_t y, uint8_t *img display->drawFastImage(x, y, 16, 8, imgBuffer); } -#ifdef T_WATCH_S3 +#if defined(DISPLAY_CLOCK_FRAME) void Screen::drawWatchFaceToggleButton(OLEDDisplay *display, int16_t x, int16_t y, bool digitalMode, float scale) { @@ -2068,7 +2068,7 @@ void Screen::setFrames(FrameFocus focus) focus = FOCUS_FAULT; // Change our "focus" parameter, to ensure we show the fault frame } -#ifdef T_WATCH_S3 +#if defined(DISPLAY_CLOCK_FRAME) normalFrames[numframes++] = screen->digitalWatchFace ? &Screen::drawDigitalClockFrame : &Screen::drawAnalogClockFrame; #endif @@ -2699,7 +2699,7 @@ int Screen::handleUIFrameEvent(const UIFrameEvent *event) int Screen::handleInputEvent(const InputEvent *event) { -#ifdef T_WATCH_S3 +#if defined(DISPLAY_CLOCK_FRAME) // For the T-Watch, intercept touches to the 'toggle digital/analog watch face' button uint8_t watchFaceFrame = error_code ? 1 : 0; diff --git a/src/graphics/Screen.h b/src/graphics/Screen.h index ee8de69f0..2a77ca575 100644 --- a/src/graphics/Screen.h +++ b/src/graphics/Screen.h @@ -554,7 +554,7 @@ class Screen : public concurrency::OSThread static void drawDebugInfoWiFiTrampoline(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y); -#ifdef T_WATCH_S3 +#if defined(DISPLAY_CLOCK_FRAME) static void drawAnalogClockFrame(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y); static void drawDigitalClockFrame(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y); diff --git a/src/graphics/images.h b/src/graphics/images.h index fb6b176fc..b757dcf30 100644 --- a/src/graphics/images.h +++ b/src/graphics/images.h @@ -14,7 +14,7 @@ const uint8_t imgUser[] PROGMEM = {0x3C, 0x42, 0x99, 0xA5, 0xA5, 0x99, 0x42, 0x3 const uint8_t imgPositionEmpty[] PROGMEM = {0x20, 0x30, 0x28, 0x24, 0x42, 0xFF}; const uint8_t imgPositionSolid[] PROGMEM = {0x20, 0x30, 0x38, 0x3C, 0x7E, 0xFF}; -#ifdef T_WATCH_S3 +#if defined(DISPLAY_CLOCK_FRAME) const uint8_t bluetoothConnectedIcon[36] PROGMEM = {0xfe, 0x01, 0xff, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x00, 0xe3, 0x1f, 0xf3, 0x3f, 0x33, 0x30, 0x33, 0x33, 0x33, 0x33, 0x03, 0x33, 0xff, 0x33, 0xfe, 0x31, 0x00, 0x30, 0x30, 0x30, 0x30, 0x30, 0xf0, 0x3f, 0xe0, 0x1f}; diff --git a/src/main.cpp b/src/main.cpp index a64055e6d..84b070da2 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -616,6 +616,7 @@ void setup() SCANNER_TO_SENSORS_MAP(ScanI2C::DeviceType::DFROBOT_LARK, meshtastic_TelemetrySensorType_DFROBOT_LARK) SCANNER_TO_SENSORS_MAP(ScanI2C::DeviceType::ICM20948, meshtastic_TelemetrySensorType_ICM20948) SCANNER_TO_SENSORS_MAP(ScanI2C::DeviceType::MAX30102, meshtastic_TelemetrySensorType_MAX30102) + SCANNER_TO_SENSORS_MAP(ScanI2C::DeviceType::CGRADSENS, meshtastic_TelemetrySensorType_RADSENS) i2cScanner.reset(); #endif diff --git a/src/mesh/NodeDB.cpp b/src/mesh/NodeDB.cpp index 841a50d65..44a28eea2 100644 --- a/src/mesh/NodeDB.cpp +++ b/src/mesh/NodeDB.cpp @@ -61,6 +61,16 @@ meshtastic_LocalConfig config; meshtastic_LocalModuleConfig moduleConfig; meshtastic_ChannelFile channelFile; +#ifdef USERPREFS_USE_ADMIN_KEY_0 +static unsigned char userprefs_admin_key_0[] = USERPREFS_USE_ADMIN_KEY_0; +#endif +#ifdef USERPREFS_USE_ADMIN_KEY_1 +static unsigned char userprefs_admin_key_1[] = USERPREFS_USE_ADMIN_KEY_1; +#endif +#ifdef USERPREFS_USE_ADMIN_KEY_2 +static unsigned char userprefs_admin_key_2[] = USERPREFS_USE_ADMIN_KEY_2; +#endif + bool meshtastic_DeviceState_callback(pb_istream_t *istream, pb_ostream_t *ostream, const pb_field_iter_t *field) { if (ostream) { @@ -406,32 +416,37 @@ void NodeDB::installDefaultConfig(bool preserveKey = false) #else config.lora.ignore_mqtt = false; #endif -#ifdef USERPREFS_USE_ADMIN_KEY // Initialize admin_key_count to zero byte numAdminKeys = 0; +#ifdef USERPREFS_USE_ADMIN_KEY_0 // Check if USERPREFS_ADMIN_KEY_0 is non-empty - if (sizeof(USERPREFS_ADMIN_KEY_0) > 0) { - memcpy(config.security.admin_key[numAdminKeys].bytes, USERPREFS_ADMIN_KEY_0, 32); - config.security.admin_key[numAdminKeys].size = 32; + if (sizeof(userprefs_admin_key_0) > 0) { + memcpy(config.security.admin_key[0].bytes, userprefs_admin_key_0, 32); + config.security.admin_key[0].size = 32; numAdminKeys++; } - - // Check if USERPREFS_ADMIN_KEY_1 is non-empty - if (sizeof(USERPREFS_ADMIN_KEY_1) > 0) { - memcpy(config.security.admin_key[numAdminKeys].bytes, USERPREFS_ADMIN_KEY_1, 32); - config.security.admin_key[numAdminKeys].size = 32; - numAdminKeys++; - } - - // Check if USERPREFS_ADMIN_KEY_2 is non-empty - if (sizeof(USERPREFS_ADMIN_KEY_2) > 0) { - memcpy(config.security.admin_key[config.security.admin_key_count].bytes, USERPREFS_ADMIN_KEY_2, 32); - config.security.admin_key[config.security.admin_key_count].size = 32; - numAdminKeys++; - } - config.security.admin_key_count = numAdminKeys; #endif + +#ifdef USERPREFS_USE_ADMIN_KEY_1 + // Check if USERPREFS_ADMIN_KEY_1 is non-empty + if (sizeof(userprefs_admin_key_1) > 0) { + memcpy(config.security.admin_key[1].bytes, userprefs_admin_key_1, 32); + config.security.admin_key[1].size = 32; + numAdminKeys++; + } +#endif + +#ifdef USERPREFS_USE_ADMIN_KEY_2 + // Check if USERPREFS_ADMIN_KEY_2 is non-empty + if (sizeof(userprefs_admin_key_2) > 0) { + memcpy(config.security.admin_key[2].bytes, userprefs_admin_key_2, 32); + config.security.admin_key[2].size = 32; + numAdminKeys++; + } +#endif + config.security.admin_key_count = numAdminKeys; + if (shouldPreserveKey) { config.security.private_key.size = 32; memcpy(config.security.private_key.bytes, private_key_temp, config.security.private_key.size); @@ -503,7 +518,7 @@ void NodeDB::installDefaultConfig(bool preserveKey = false) #ifdef RAK4630 config.display.wake_on_tap_or_motion = true; #endif -#ifdef T_WATCH_S3 +#if defined(T_WATCH_S3) || defined(SENSECAP_INDICATOR) config.display.screen_on_secs = 30; config.display.wake_on_tap_or_motion = true; #endif @@ -527,7 +542,7 @@ void NodeDB::initConfigIntervals() config.display.screen_on_secs = default_screen_on_secs; -#if defined(T_WATCH_S3) || defined(T_DECK) || defined(RAK14014) +#if defined(T_WATCH_S3) || defined(T_DECK) || defined(RAK14014) || defined(SENSECAP_INDICATOR) config.power.is_power_saving = true; config.display.screen_on_secs = 30; config.power.wait_bluetooth_secs = 30; @@ -888,6 +903,54 @@ void NodeDB::loadFromDisk() } } + // Make sure we load hard coded admin keys even when the configuration file has none. + // Initialize admin_key_count to zero + byte numAdminKeys = 0; + uint16_t sum = 0; +#ifdef USERPREFS_USE_ADMIN_KEY_0 + for (uint8_t b = 0; b < 32; b++) { + sum += config.security.admin_key[0].bytes[b]; + } + if (sum == 0) { + numAdminKeys += 1; + LOG_INFO("Admin 0 key zero. Loading hard coded key from user preferences."); + memcpy(config.security.admin_key[0].bytes, userprefs_admin_key_0, 32); + config.security.admin_key[0].size = 32; + config.security.admin_key_count = numAdminKeys; + saveToDisk(SEGMENT_CONFIG); + } +#endif + +#ifdef USERPREFS_USE_ADMIN_KEY_1 + sum = 0; + for (uint8_t b = 0; b < 32; b++) { + sum += config.security.admin_key[1].bytes[b]; + } + if (sum == 0) { + numAdminKeys += 1; + LOG_INFO("Admin 1 key zero. Loading hard coded key from user preferences."); + memcpy(config.security.admin_key[1].bytes, userprefs_admin_key_1, 32); + config.security.admin_key[1].size = 32; + config.security.admin_key_count = numAdminKeys; + saveToDisk(SEGMENT_CONFIG); + } +#endif + +#ifdef USERPREFS_USE_ADMIN_KEY_2 + sum = 0; + for (uint8_t b = 0; b < 32; b++) { + sum += config.security.admin_key[2].bytes[b]; + } + if (sum == 0) { + numAdminKeys += 1; + LOG_INFO("Admin 2 key zero. Loading hard coded key from user preferences."); + memcpy(config.security.admin_key[2].bytes, userprefs_admin_key_2, 32); + config.security.admin_key[2].size = 32; + config.security.admin_key_count = numAdminKeys; + saveToDisk(SEGMENT_CONFIG); + } +#endif + state = loadProto(moduleConfigFileName, meshtastic_LocalModuleConfig_size, sizeof(meshtastic_LocalModuleConfig), &meshtastic_LocalModuleConfig_msg, &moduleConfig); if (state != LoadFileResult::LOAD_SUCCESS) { @@ -1346,4 +1409,4 @@ void recordCriticalError(meshtastic_CriticalErrorCode code, uint32_t address, co LOG_ERROR("A critical failure occurred, portduino is exiting"); exit(2); #endif -} +} \ No newline at end of file diff --git a/src/mesh/generated/meshtastic/telemetry.pb.h b/src/mesh/generated/meshtastic/telemetry.pb.h index 309c01dc7..874eef60f 100644 --- a/src/mesh/generated/meshtastic/telemetry.pb.h +++ b/src/mesh/generated/meshtastic/telemetry.pb.h @@ -77,7 +77,9 @@ typedef enum _meshtastic_TelemetrySensorType { /* MLX90614 non-contact IR temperature sensor */ meshtastic_TelemetrySensorType_MLX90614 = 31, /* SCD40/SCD41 CO2, humidity, temperature sensor */ - meshtastic_TelemetrySensorType_SCD4X = 32 + meshtastic_TelemetrySensorType_SCD4X = 32, + /* ClimateGuard RadSens, radiation, Geiger-Muller Tube */ + meshtastic_TelemetrySensorType_RADSENS = 33 } meshtastic_TelemetrySensorType; /* Struct definitions */ @@ -155,6 +157,9 @@ typedef struct _meshtastic_EnvironmentMetrics { /* Wind lull in m/s */ bool has_wind_lull; float wind_lull; + /* Radiation in µR/h */ + bool has_radiation; + float radiation; } meshtastic_EnvironmentMetrics; /* Power Metrics (voltage / current / etc) */ @@ -299,8 +304,8 @@ extern "C" { /* Helper constants for enums */ #define _meshtastic_TelemetrySensorType_MIN meshtastic_TelemetrySensorType_SENSOR_UNSET -#define _meshtastic_TelemetrySensorType_MAX meshtastic_TelemetrySensorType_SCD4X -#define _meshtastic_TelemetrySensorType_ARRAYSIZE ((meshtastic_TelemetrySensorType)(meshtastic_TelemetrySensorType_SCD4X+1)) +#define _meshtastic_TelemetrySensorType_MAX meshtastic_TelemetrySensorType_RADSENS +#define _meshtastic_TelemetrySensorType_ARRAYSIZE ((meshtastic_TelemetrySensorType)(meshtastic_TelemetrySensorType_RADSENS+1)) @@ -313,7 +318,7 @@ extern "C" { /* Initializer values for message structs */ #define meshtastic_DeviceMetrics_init_default {false, 0, false, 0, false, 0, false, 0, false, 0} -#define meshtastic_EnvironmentMetrics_init_default {false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0} +#define meshtastic_EnvironmentMetrics_init_default {false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0} #define meshtastic_PowerMetrics_init_default {false, 0, false, 0, false, 0, false, 0, false, 0, false, 0} #define meshtastic_AirQualityMetrics_init_default {false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0} #define meshtastic_LocalStats_init_default {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} @@ -321,7 +326,7 @@ extern "C" { #define meshtastic_Telemetry_init_default {0, 0, {meshtastic_DeviceMetrics_init_default}} #define meshtastic_Nau7802Config_init_default {0, 0} #define meshtastic_DeviceMetrics_init_zero {false, 0, false, 0, false, 0, false, 0, false, 0} -#define meshtastic_EnvironmentMetrics_init_zero {false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0} +#define meshtastic_EnvironmentMetrics_init_zero {false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0} #define meshtastic_PowerMetrics_init_zero {false, 0, false, 0, false, 0, false, 0, false, 0, false, 0} #define meshtastic_AirQualityMetrics_init_zero {false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0} #define meshtastic_LocalStats_init_zero {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} @@ -352,6 +357,7 @@ extern "C" { #define meshtastic_EnvironmentMetrics_weight_tag 15 #define meshtastic_EnvironmentMetrics_wind_gust_tag 16 #define meshtastic_EnvironmentMetrics_wind_lull_tag 17 +#define meshtastic_EnvironmentMetrics_radiation_tag 18 #define meshtastic_PowerMetrics_ch1_voltage_tag 1 #define meshtastic_PowerMetrics_ch1_current_tag 2 #define meshtastic_PowerMetrics_ch2_voltage_tag 3 @@ -422,7 +428,8 @@ X(a, STATIC, OPTIONAL, UINT32, wind_direction, 13) \ X(a, STATIC, OPTIONAL, FLOAT, wind_speed, 14) \ X(a, STATIC, OPTIONAL, FLOAT, weight, 15) \ X(a, STATIC, OPTIONAL, FLOAT, wind_gust, 16) \ -X(a, STATIC, OPTIONAL, FLOAT, wind_lull, 17) +X(a, STATIC, OPTIONAL, FLOAT, wind_lull, 17) \ +X(a, STATIC, OPTIONAL, FLOAT, radiation, 18) #define meshtastic_EnvironmentMetrics_CALLBACK NULL #define meshtastic_EnvironmentMetrics_DEFAULT NULL @@ -521,12 +528,12 @@ extern const pb_msgdesc_t meshtastic_Nau7802Config_msg; #define MESHTASTIC_MESHTASTIC_TELEMETRY_PB_H_MAX_SIZE meshtastic_Telemetry_size #define meshtastic_AirQualityMetrics_size 78 #define meshtastic_DeviceMetrics_size 27 -#define meshtastic_EnvironmentMetrics_size 85 +#define meshtastic_EnvironmentMetrics_size 91 #define meshtastic_HealthMetrics_size 11 #define meshtastic_LocalStats_size 60 #define meshtastic_Nau7802Config_size 16 #define meshtastic_PowerMetrics_size 30 -#define meshtastic_Telemetry_size 92 +#define meshtastic_Telemetry_size 98 #ifdef __cplusplus } /* extern "C" */ diff --git a/src/mesh/wifi/WiFiAPClient.cpp b/src/mesh/wifi/WiFiAPClient.cpp index 911a47093..779576d64 100644 --- a/src/mesh/wifi/WiFiAPClient.cpp +++ b/src/mesh/wifi/WiFiAPClient.cpp @@ -62,7 +62,11 @@ static void onNetworkConnected() LOG_INFO("Start WiFi network services"); // start mdns - if (!MDNS.begin("Meshtastic")) { + if ( +#ifdef ARCH_RP2040 + !moduleConfig.mqtt.enabled && // MDNS is not supported when MQTT is enabled on ARCH_RP2040 +#endif + !MDNS.begin("Meshtastic")) { LOG_ERROR("Error setting up MDNS responder!"); } else { LOG_INFO("mDNS Host: Meshtastic.local"); diff --git a/src/modules/CannedMessageModule.cpp b/src/modules/CannedMessageModule.cpp index 6d1bfdc5c..a96fcc080 100644 --- a/src/modules/CannedMessageModule.cpp +++ b/src/modules/CannedMessageModule.cpp @@ -55,7 +55,7 @@ CannedMessageModule::CannedMessageModule() LOG_INFO("CannedMessageModule is enabled"); // T-Watch interface currently has no way to select destination type, so default to 'node' -#if defined(T_WATCH_S3) || defined(RAK14014) +#if defined(USE_VIRTUAL_KEYBOARD) this->destSelect = CANNED_MESSAGE_DESTINATION_TYPE_NODE; #endif @@ -81,7 +81,7 @@ int CannedMessageModule::splitConfiguredMessages() String canned_messages = cannedMessageModuleConfig.messages; -#if defined(T_WATCH_S3) || defined(RAK14014) +#if defined(USE_VIRTUAL_KEYBOARD) String separator = canned_messages.length() ? "|" : ""; canned_messages = "[---- Free Text ----]" + separator + canned_messages; @@ -150,7 +150,7 @@ int CannedMessageModule::handleInputEvent(const InputEvent *event) } if (event->inputEvent == static_cast(meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_SELECT)) { -#if defined(T_WATCH_S3) || defined(RAK14014) +#if defined(USE_VIRTUAL_KEYBOARD) if (this->currentMessageIndex == 0) { this->runState = CANNED_MESSAGE_RUN_STATE_FREETEXT; @@ -177,7 +177,7 @@ int CannedMessageModule::handleInputEvent(const InputEvent *event) e.action = UIFrameEvent::Action::REGENERATE_FRAMESET; // We want to change the list of frames shown on-screen this->currentMessageIndex = -1; -#if !defined(T_WATCH_S3) && !defined(RAK14014) +#if !defined(T_WATCH_S3) && !defined(RAK14014) && !defined(USE_VIRTUAL_KEYBOARD) this->freetext = ""; // clear freetext this->cursor = 0; this->destSelect = CANNED_MESSAGE_DESTINATION_TYPE_NONE; @@ -190,7 +190,7 @@ int CannedMessageModule::handleInputEvent(const InputEvent *event) (event->inputEvent == static_cast(meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_LEFT)) || (event->inputEvent == static_cast(meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_RIGHT))) { -#if defined(T_WATCH_S3) || defined(RAK14014) +#if defined(USE_VIRTUAL_KEYBOARD) if (event->inputEvent == static_cast(meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_LEFT)) { this->payload = INPUT_BROKER_MSG_LEFT; } else if (event->inputEvent == static_cast(meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_RIGHT)) { @@ -312,7 +312,7 @@ int CannedMessageModule::handleInputEvent(const InputEvent *event) } } -#if defined(T_WATCH_S3) || defined(RAK14014) +#if defined(USE_VIRTUAL_KEYBOARD) if (this->runState == CANNED_MESSAGE_RUN_STATE_FREETEXT) { String keyTapped = keyForCoordinates(event->touchX, event->touchY); @@ -446,7 +446,7 @@ int32_t CannedMessageModule::runOnce() this->freetext = ""; // clear freetext this->cursor = 0; -#if !defined(T_WATCH_S3) && !defined(RAK14014) +#if !defined(T_WATCH_S3) && !defined(RAK14014) && !defined(SENSECAP_INDICATOR) this->destSelect = CANNED_MESSAGE_DESTINATION_TYPE_NONE; #endif @@ -459,7 +459,7 @@ int32_t CannedMessageModule::runOnce() this->freetext = ""; // clear freetext this->cursor = 0; -#if !defined(T_WATCH_S3) && !defined(RAK14014) +#if !defined(T_WATCH_S3) && !defined(RAK14014) && !defined(USE_VIRTUAL_KEYBOARD) this->destSelect = CANNED_MESSAGE_DESTINATION_TYPE_NONE; #endif @@ -479,7 +479,7 @@ int32_t CannedMessageModule::runOnce() powerFSM.trigger(EVENT_PRESS); return INT32_MAX; } else { -#if defined(T_WATCH_S3) || defined(RAK14014) +#if defined(USE_VIRTUAL_KEYBOARD) sendText(this->dest, indexChannels[this->channel], this->messages[this->currentMessageIndex], true); #else sendText(NODENUM_BROADCAST, channels.getPrimaryIndex(), this->messages[this->currentMessageIndex], true); @@ -496,7 +496,7 @@ int32_t CannedMessageModule::runOnce() this->freetext = ""; // clear freetext this->cursor = 0; -#if !defined(T_WATCH_S3) && !defined(RAK14014) +#if !defined(T_WATCH_S3) && !defined(RAK14014) && !defined(USE_VIRTUAL_KEYBOARD) this->destSelect = CANNED_MESSAGE_DESTINATION_TYPE_NONE; #endif @@ -513,7 +513,7 @@ int32_t CannedMessageModule::runOnce() this->freetext = ""; // clear freetext this->cursor = 0; -#if !defined(T_WATCH_S3) && !defined(RAK14014) +#if !defined(T_WATCH_S3) && !defined(RAK14014) && !defined(USE_VIRTUAL_KEYBOARD) this->destSelect = CANNED_MESSAGE_DESTINATION_TYPE_NONE; #endif @@ -526,7 +526,7 @@ int32_t CannedMessageModule::runOnce() this->freetext = ""; // clear freetext this->cursor = 0; -#if !defined(T_WATCH_S3) && !defined(RAK14014) +#if !defined(T_WATCH_S3) && !defined(RAK14014) && !defined(USE_VIRTUAL_KEYBOARD) this->destSelect = CANNED_MESSAGE_DESTINATION_TYPE_NONE; #endif @@ -769,7 +769,7 @@ void CannedMessageModule::showTemporaryMessage(const String &message) setIntervalFromNow(2000); } -#if defined(T_WATCH_S3) || defined(RAK14014) +#if defined(USE_VIRTUAL_KEYBOARD) String CannedMessageModule::keyForCoordinates(uint x, uint y) { @@ -1055,7 +1055,7 @@ void CannedMessageModule::drawFrame(OLEDDisplay *display, OLEDDisplayUiState *st display->drawString(10 + x, 0 + y + FONT_HEIGHT_SMALL, "Canned Message\nModule disabled."); } else if (cannedMessageModule->runState == CANNED_MESSAGE_RUN_STATE_FREETEXT) { requestFocus(); // Tell Screen::setFrames to move to our module's frame -#if defined(T_WATCH_S3) || defined(RAK14014) +#if defined(USE_VIRTUAL_KEYBOARD) drawKeyboard(display, state, 0, 0); #else diff --git a/src/modules/CannedMessageModule.h b/src/modules/CannedMessageModule.h index 4427be144..fd9ffc9b6 100644 --- a/src/modules/CannedMessageModule.h +++ b/src/modules/CannedMessageModule.h @@ -102,7 +102,7 @@ class CannedMessageModule : public SinglePortModule, public ObservablereadNextMeshNode(readIndex); - while (tempNodeInfo != NULL && tempNodeInfo->has_user && hasValidPosition(tempNodeInfo)) { - printWPL(outbuf, sizeof(outbuf), tempNodeInfo->position, tempNodeInfo->user.long_name, true); - serialPrint->printf("%s", outbuf); + while (tempNodeInfo != NULL) { + if (tempNodeInfo->has_user && hasValidPosition(tempNodeInfo)) { + printWPL(outbuf, sizeof(outbuf), tempNodeInfo->position, tempNodeInfo->user.long_name, true); + serialPrint->printf("%s", outbuf); + } tempNodeInfo = nodeDB->readNextMeshNode(readIndex); } } diff --git a/src/modules/Telemetry/DeviceTelemetry.cpp b/src/modules/Telemetry/DeviceTelemetry.cpp index 1f479d6f1..4989b88e2 100644 --- a/src/modules/Telemetry/DeviceTelemetry.cpp +++ b/src/modules/Telemetry/DeviceTelemetry.cpp @@ -77,9 +77,10 @@ meshtastic_MeshPacket *DeviceTelemetryModule::allocReply() // Check for a request for device metrics if (decoded->which_variant == meshtastic_Telemetry_device_metrics_tag) { LOG_INFO("Device telemetry reply to request"); - - meshtastic_Telemetry telemetry = getDeviceTelemetry(); - return allocDataProtobuf(telemetry); + return allocDataProtobuf(getDeviceTelemetry()); + } else if (decoded->which_variant == meshtastic_Telemetry_local_stats_tag) { + LOG_INFO("Device telemetry reply w/ LocalStats to request"); + return allocDataProtobuf(getLocalStatsTelemetry()); } } return NULL; @@ -112,7 +113,7 @@ meshtastic_Telemetry DeviceTelemetryModule::getDeviceTelemetry() return t; } -void DeviceTelemetryModule::sendLocalStatsToPhone() +meshtastic_Telemetry DeviceTelemetryModule::getLocalStatsTelemetry() { meshtastic_Telemetry telemetry = meshtastic_Telemetry_init_zero; telemetry.which_variant = meshtastic_Telemetry_local_stats_tag; @@ -142,7 +143,12 @@ void DeviceTelemetryModule::sendLocalStatsToPhone() LOG_INFO("num_packets_tx=%i, num_packets_rx=%i, num_packets_rx_bad=%i", telemetry.variant.local_stats.num_packets_tx, telemetry.variant.local_stats.num_packets_rx, telemetry.variant.local_stats.num_packets_rx_bad); - meshtastic_MeshPacket *p = allocDataProtobuf(telemetry); + return telemetry; +} + +void DeviceTelemetryModule::sendLocalStatsToPhone() +{ + meshtastic_MeshPacket *p = allocDataProtobuf(getLocalStatsTelemetry()); p->to = NODENUM_BROADCAST; p->decoded.want_response = false; p->priority = meshtastic_MeshPacket_Priority_BACKGROUND; diff --git a/src/modules/Telemetry/DeviceTelemetry.h b/src/modules/Telemetry/DeviceTelemetry.h index 29818d4eb..19b7d5b01 100644 --- a/src/modules/Telemetry/DeviceTelemetry.h +++ b/src/modules/Telemetry/DeviceTelemetry.h @@ -42,6 +42,8 @@ class DeviceTelemetryModule : private concurrency::OSThread, public ProtobufModu private: meshtastic_Telemetry getDeviceTelemetry(); + meshtastic_Telemetry getLocalStatsTelemetry(); + void sendLocalStatsToPhone(); uint32_t sendToPhoneIntervalMs = SECONDS_IN_MINUTE * 1000; // Send to phone every minute uint32_t sendStatsToPhoneIntervalMs = 15 * SECONDS_IN_MINUTE * 1000; // Send stats to phone every 15 minutes diff --git a/src/modules/Telemetry/EnvironmentTelemetry.cpp b/src/modules/Telemetry/EnvironmentTelemetry.cpp index 4ef68d4b7..92d964f7d 100644 --- a/src/modules/Telemetry/EnvironmentTelemetry.cpp +++ b/src/modules/Telemetry/EnvironmentTelemetry.cpp @@ -25,6 +25,7 @@ #include "Sensor/BMP085Sensor.h" #include "Sensor/BMP280Sensor.h" #include "Sensor/BMP3XXSensor.h" +#include "Sensor/CGRadSensSensor.h" #include "Sensor/DFRobotLarkSensor.h" #include "Sensor/LPS22HBSensor.h" #include "Sensor/MCP9808Sensor.h" @@ -60,6 +61,7 @@ BMP3XXSensor bmp3xxSensor; #ifdef T1000X_SENSOR_EN T1000xSensor t1000xSensor; #endif +CGRadSensSensor cgRadSens; #define FAILED_STATE_SENSOR_READ_MULTIPLIER 10 #define DISPLAY_RECEIVEID_MEASUREMENTS_ON_SCREEN true @@ -147,6 +149,8 @@ int32_t EnvironmentTelemetryModule::runOnce() result = nau7802Sensor.runOnce(); if (max17048Sensor.hasSensor()) result = max17048Sensor.runOnce(); + if (cgRadSens.hasSensor()) + result = cgRadSens.runOnce(); #endif } return result; @@ -210,16 +214,19 @@ void EnvironmentTelemetryModule::drawFrame(OLEDDisplay *display, OLEDDisplayUiSt // 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(UnitConversions::CelsiusToFahrenheit(lastMeasurement.variant.environment_metrics.temperature), 0) + "°F"; - } + if (lastMeasurement.variant.environment_metrics.has_temperature || + lastMeasurement.variant.environment_metrics.has_relative_humidity) { + String last_temp = String(lastMeasurement.variant.environment_metrics.temperature, 0) + "°C"; + if (moduleConfig.telemetry.environment_display_fahrenheit) { + last_temp = + String(UnitConversions::CelsiusToFahrenheit(lastMeasurement.variant.environment_metrics.temperature), 0) + "°F"; + } - // Continue with the remaining details - display->drawString(x, y += _fontHeight(FONT_SMALL), - "Temp/Hum: " + last_temp + " / " + - String(lastMeasurement.variant.environment_metrics.relative_humidity, 0) + "%"); + // 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) { display->drawString(x, y += _fontHeight(FONT_SMALL), @@ -243,6 +250,10 @@ void EnvironmentTelemetryModule::drawFrame(OLEDDisplay *display, OLEDDisplayUiSt if (lastMeasurement.variant.environment_metrics.weight != 0) display->drawString(x, y += _fontHeight(FONT_SMALL), "Weight: " + String(lastMeasurement.variant.environment_metrics.weight, 0) + "kg"); + + if (lastMeasurement.variant.environment_metrics.radiation != 0) + display->drawString(x, y += _fontHeight(FONT_SMALL), + "Rad: " + String(lastMeasurement.variant.environment_metrics.radiation, 2) + "µR/h"); } bool EnvironmentTelemetryModule::handleReceivedProtobuf(const meshtastic_MeshPacket &mp, meshtastic_Telemetry *t) @@ -263,6 +274,8 @@ bool EnvironmentTelemetryModule::handleReceivedProtobuf(const meshtastic_MeshPac t->variant.environment_metrics.wind_speed, t->variant.environment_metrics.wind_direction, t->variant.environment_metrics.weight); + LOG_INFO("(Received from %s): radiation=%fµR/h", sender, t->variant.environment_metrics.radiation); + #endif // release previous packet before occupying a new spot if (lastMeasurementPacket != nullptr) @@ -390,6 +403,10 @@ bool EnvironmentTelemetryModule::getEnvironmentTelemetry(meshtastic_Telemetry *m valid = valid && max17048Sensor.getMetrics(m); hasSensor = true; } + if (cgRadSens.hasSensor()) { + valid = valid && cgRadSens.getMetrics(m); + hasSensor = true; + } #endif return valid && hasSensor; @@ -443,6 +460,8 @@ bool EnvironmentTelemetryModule::sendTelemetry(NodeNum dest, bool phoneOnly) LOG_INFO("Send: wind speed=%fm/s, direction=%d degrees, weight=%fkg", m.variant.environment_metrics.wind_speed, m.variant.environment_metrics.wind_direction, m.variant.environment_metrics.weight); + LOG_INFO("Send: radiation=%fµR/h", m.variant.environment_metrics.radiation); + sensor_read_error_count = 0; meshtastic_MeshPacket *p = allocDataProtobuf(m); @@ -585,6 +604,11 @@ AdminMessageHandleResult EnvironmentTelemetryModule::handleAdminMessageForModule if (result != AdminMessageHandleResult::NOT_HANDLED) return result; } + if (cgRadSens.hasSensor()) { + result = cgRadSens.handleAdminMessage(mp, request, response); + if (result != AdminMessageHandleResult::NOT_HANDLED) + return result; + } return result; } diff --git a/src/modules/Telemetry/Sensor/CGRadSensSensor.cpp b/src/modules/Telemetry/Sensor/CGRadSensSensor.cpp new file mode 100644 index 000000000..5e69cc22f --- /dev/null +++ b/src/modules/Telemetry/Sensor/CGRadSensSensor.cpp @@ -0,0 +1,75 @@ +/* + * Support for the ClimateGuard RadSens Dosimeter + * A fun and educational sensor for Meshtastic; not for safety critical applications. + */ +#include "configuration.h" + +#if !MESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR + +#include "../mesh/generated/meshtastic/telemetry.pb.h" +#include "CGRadSensSensor.h" +#include "TelemetrySensor.h" +#include +#include + +CGRadSensSensor::CGRadSensSensor() : TelemetrySensor(meshtastic_TelemetrySensorType_RADSENS, "RadSens") {} + +int32_t CGRadSensSensor::runOnce() +{ + // Initialize the sensor following the same pattern as RCWL9620Sensor + LOG_INFO("Init sensor: %s", sensorName); + if (!hasSensor()) { + return DEFAULT_SENSOR_MINIMUM_WAIT_TIME_BETWEEN_READS; + } + + status = true; + begin(nodeTelemetrySensorsMap[sensorType].second, nodeTelemetrySensorsMap[sensorType].first); + + return initI2CSensor(); +} + +void CGRadSensSensor::setup() {} + +void CGRadSensSensor::begin(TwoWire *wire, uint8_t addr) +{ + // Store the Wire and address to the sensor following the same pattern as RCWL9620Sensor + _wire = wire; + _addr = addr; + _wire->begin(); +} + +float CGRadSensSensor::getStaticRadiation() +{ + // Read a register, following the same pattern as the RCWL9620Sensor + uint32_t data; + _wire->beginTransmission(_addr); // Transfer data to addr. + _wire->write(0x06); // Radiation intensity (static period T = 500 sec) + if (_wire->endTransmission() == 0) { + if (_wire->requestFrom(_addr, (uint8_t)3)) { + ; // Request 3 bytes + data = _wire->read(); + data <<= 8; + data |= _wire->read(); + data <<= 8; + data |= _wire->read(); + + // As per the data sheet for the RadSens + // Register 0x06 contains the reading in 0.1 * μR / h + float microRadPerHr = float(data) / 10.0; + return microRadPerHr; + } + } + return -1.0; +} + +bool CGRadSensSensor::getMetrics(meshtastic_Telemetry *measurement) +{ + // Store the meansurement in the the appropriate fields of the protobuf + measurement->variant.environment_metrics.has_radiation = true; + + LOG_DEBUG("CGRADSENS getMetrics"); + measurement->variant.environment_metrics.radiation = getStaticRadiation(); + + return true; +} +#endif \ No newline at end of file diff --git a/src/modules/Telemetry/Sensor/CGRadSensSensor.h b/src/modules/Telemetry/Sensor/CGRadSensSensor.h new file mode 100644 index 000000000..3b15a19a2 --- /dev/null +++ b/src/modules/Telemetry/Sensor/CGRadSensSensor.h @@ -0,0 +1,30 @@ +/* + * Support for the ClimateGuard RadSens Dosimeter + * A fun and educational sensor for Meshtastic; not for safety critical applications. + */ +#include "configuration.h" + +#if !MESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR + +#include "../mesh/generated/meshtastic/telemetry.pb.h" +#include "TelemetrySensor.h" +#include + +class CGRadSensSensor : public TelemetrySensor +{ + private: + uint8_t _addr = 0x66; + TwoWire *_wire = &Wire; + + protected: + virtual void setup() override; + void begin(TwoWire *wire = &Wire, uint8_t addr = 0x66); + float getStaticRadiation(); + + public: + CGRadSensSensor(); + virtual int32_t runOnce() override; + virtual bool getMetrics(meshtastic_Telemetry *measurement) override; +}; + +#endif \ No newline at end of file diff --git a/src/modules/esp32/PaxcounterModule.cpp b/src/modules/esp32/PaxcounterModule.cpp index 89e486f82..b27586771 100644 --- a/src/modules/esp32/PaxcounterModule.cpp +++ b/src/modules/esp32/PaxcounterModule.cpp @@ -95,7 +95,9 @@ int32_t PaxcounterModule::runOnce() // internal processing initialization libpax_counter_init(handlePaxCounterReportRequest, &count_from_libpax, - moduleConfig.paxcounter.paxcounter_update_interval, 0); + Default::getConfiguredOrDefault(moduleConfig.paxcounter.paxcounter_update_interval, + default_telemetry_broadcast_interval_secs), + 0); libpax_counter_start(); } else { sendInfo(NODENUM_BROADCAST); diff --git a/src/motion/AccelerometerThread.h b/src/motion/AccelerometerThread.h index 8d1260195..95f09910f 100755 --- a/src/motion/AccelerometerThread.h +++ b/src/motion/AccelerometerThread.h @@ -7,7 +7,9 @@ #if !defined(ARCH_PORTDUINO) && !defined(ARCH_STM32WL) && !MESHTASTIC_EXCLUDE_I2C #include "../concurrency/OSThread.h" +#ifdef HAS_BMA423 #include "BMA423Sensor.h" +#endif #include "BMX160Sensor.h" #include "ICM20948Sensor.h" #include "LIS3DHSensor.h" @@ -17,7 +19,9 @@ #ifdef HAS_QMA6100P #include "QMA6100PSensor.h" #endif +#ifdef HAS_STK8XXX #include "STK8XXXSensor.h" +#endif extern ScanI2C::DeviceAddress accelerometer_found; @@ -79,9 +83,11 @@ class AccelerometerThread : public concurrency::OSThread #endif switch (device.type) { +#ifdef HAS_BMA423 case ScanI2C::DeviceType::BMA423: sensor = new BMA423Sensor(device); break; +#endif case ScanI2C::DeviceType::MPU6050: sensor = new MPU6050Sensor(device); break; @@ -94,9 +100,11 @@ class AccelerometerThread : public concurrency::OSThread case ScanI2C::DeviceType::LSM6DS3: sensor = new LSM6DS3Sensor(device); break; +#ifdef HAS_STK8XXX case ScanI2C::DeviceType::STK8BAXX: sensor = new STK8XXXSensor(device); break; +#endif case ScanI2C::DeviceType::ICM20948: sensor = new ICM20948Sensor(device); break; diff --git a/src/motion/BMA423Sensor.cpp b/src/motion/BMA423Sensor.cpp index 382b595e1..d7058bab0 100755 --- a/src/motion/BMA423Sensor.cpp +++ b/src/motion/BMA423Sensor.cpp @@ -1,6 +1,6 @@ #include "BMA423Sensor.h" -#if !defined(ARCH_PORTDUINO) && !defined(ARCH_STM32WL) && !MESHTASTIC_EXCLUDE_I2C +#if !defined(ARCH_PORTDUINO) && !defined(ARCH_STM32WL) && !MESHTASTIC_EXCLUDE_I2C && defined(HAS_BMA423) using namespace MotionSensorI2C; diff --git a/src/motion/BMA423Sensor.h b/src/motion/BMA423Sensor.h index 0bc0ddf8c..455315aa9 100755 --- a/src/motion/BMA423Sensor.h +++ b/src/motion/BMA423Sensor.h @@ -4,7 +4,7 @@ #include "MotionSensor.h" -#if !defined(ARCH_PORTDUINO) && !defined(ARCH_STM32WL) && !MESHTASTIC_EXCLUDE_I2C +#if !defined(ARCH_PORTDUINO) && !defined(ARCH_STM32WL) && !MESHTASTIC_EXCLUDE_I2C && defined(HAS_BMA423) #include #include diff --git a/src/motion/STK8XXXSensor.cpp b/src/motion/STK8XXXSensor.cpp index 8e9b1a63e..377ee3c37 100755 --- a/src/motion/STK8XXXSensor.cpp +++ b/src/motion/STK8XXXSensor.cpp @@ -1,6 +1,6 @@ #include "STK8XXXSensor.h" -#if !defined(ARCH_PORTDUINO) && !defined(ARCH_STM32WL) && !MESHTASTIC_EXCLUDE_I2C +#if !defined(ARCH_PORTDUINO) && !defined(ARCH_STM32WL) && !MESHTASTIC_EXCLUDE_I2C && defined(HAS_STK8XXX) STK8XXXSensor::STK8XXXSensor(ScanI2C::FoundDevice foundDevice) : MotionSensor::MotionSensor(foundDevice) {} diff --git a/src/motion/STK8XXXSensor.h b/src/motion/STK8XXXSensor.h index 190b916b4..cff98d87d 100755 --- a/src/motion/STK8XXXSensor.h +++ b/src/motion/STK8XXXSensor.h @@ -4,7 +4,7 @@ #include "MotionSensor.h" -#if !defined(ARCH_PORTDUINO) && !defined(ARCH_STM32WL) && !MESHTASTIC_EXCLUDE_I2C +#if !defined(ARCH_PORTDUINO) && !defined(ARCH_STM32WL) && !MESHTASTIC_EXCLUDE_I2C && defined(HAS_STK8XXX) #ifdef STK8XXX_INT diff --git a/src/mqtt/MQTT.cpp b/src/mqtt/MQTT.cpp index 0e2710940..3d5948976 100644 --- a/src/mqtt/MQTT.cpp +++ b/src/mqtt/MQTT.cpp @@ -545,9 +545,11 @@ void MQTT::onSend(const meshtastic_MeshPacket &mp_encrypted, const meshtastic_Me // mp_decoded will not be decoded when it's PKI encrypted and not directed to us if (mp_decoded.which_payload_variant == meshtastic_MeshPacket_decoded_tag) { + // For uplinking other's packets, check if it's not OK to MQTT or if it's an older packet without the bitfield + bool dontUplink = !mp_decoded.decoded.has_bitfield || + (mp_decoded.decoded.has_bitfield && !(mp_decoded.decoded.bitfield & BITFIELD_OK_TO_MQTT_MASK)); // check for the lowest bit of the data bitfield set false, and the use of one of the default keys. - if (!isFromUs(&mp_decoded) && !isMqttServerAddressPrivate && mp_decoded.decoded.has_bitfield && - !(mp_decoded.decoded.bitfield & BITFIELD_OK_TO_MQTT_MASK) && + if (!isFromUs(&mp_decoded) && !isMqttServerAddressPrivate && dontUplink && (ch.settings.psk.size < 2 || (ch.settings.psk.size == 16 && memcmp(ch.settings.psk.bytes, defaultpsk, 16)) || (ch.settings.psk.size == 32 && memcmp(ch.settings.psk.bytes, eventpsk, 32)))) { LOG_INFO("MQTT onSend - Not forwarding packet due to DontMqttMeBro flag"); diff --git a/src/serialization/MeshPacketSerializer.cpp b/src/serialization/MeshPacketSerializer.cpp index 05a98f7a6..b4603186b 100644 --- a/src/serialization/MeshPacketSerializer.cpp +++ b/src/serialization/MeshPacketSerializer.cpp @@ -78,6 +78,7 @@ std::string MeshPacketSerializer::JsonSerialize(const meshtastic_MeshPacket *mp, msgPayload["wind_direction"] = new JSONValue((uint)decoded->variant.environment_metrics.wind_direction); msgPayload["wind_gust"] = new JSONValue(decoded->variant.environment_metrics.wind_gust); msgPayload["wind_lull"] = new JSONValue(decoded->variant.environment_metrics.wind_lull); + msgPayload["radiation"] = new JSONValue(decoded->variant.environment_metrics.radiation); } else if (decoded->which_variant == meshtastic_Telemetry_air_quality_metrics_tag) { msgPayload["pm10"] = new JSONValue((unsigned int)decoded->variant.air_quality_metrics.pm10_standard); msgPayload["pm25"] = new JSONValue((unsigned int)decoded->variant.air_quality_metrics.pm25_standard); diff --git a/src/serialization/MeshPacketSerializer_nRF52.cpp b/src/serialization/MeshPacketSerializer_nRF52.cpp index 15b8b1a34..89ecddfad 100644 --- a/src/serialization/MeshPacketSerializer_nRF52.cpp +++ b/src/serialization/MeshPacketSerializer_nRF52.cpp @@ -77,6 +77,7 @@ std::string MeshPacketSerializer::JsonSerialize(const meshtastic_MeshPacket *mp, jsonObj["payload"]["wind_direction"] = (uint)decoded->variant.environment_metrics.wind_direction; jsonObj["payload"]["wind_gust"] = decoded->variant.environment_metrics.wind_gust; jsonObj["payload"]["wind_lull"] = decoded->variant.environment_metrics.wind_lull; + jsonObj["payload"]["radiation"] = decoded->variant.environment_metrics.radiation; } else if (decoded->which_variant == meshtastic_Telemetry_air_quality_metrics_tag) { jsonObj["payload"]["pm10"] = (unsigned int)decoded->variant.air_quality_metrics.pm10_standard; jsonObj["payload"]["pm25"] = (unsigned int)decoded->variant.air_quality_metrics.pm25_standard; diff --git a/userPrefs.h b/userPrefs.h index 622a491c3..00f04149a 100644 --- a/userPrefs.h +++ b/userPrefs.h @@ -72,16 +72,17 @@ static unsigned char icon_bits[] = { /* * PKI Admin keys. * If a Admin key is set with '{};' - * then it will be ignored, a PKI key must have a size of 32. + * then it will be ignored, a PKI key must have a size of 32 byte. */ /* -#define USERPREFS_USE_ADMIN_KEY 1 -static unsigned char USERPREFS_ADMIN_KEY_0[] = {0xcd, 0xc0, 0xb4, 0x3c, 0x53, 0x24, 0xdf, 0x13, 0xca, 0x5a, 0xa6, - 0x0c, 0x0d, 0xec, 0x85, 0x5a, 0x4c, 0xf6, 0x1a, 0x96, 0x04, 0x1a, - 0x3e, 0xfc, 0xbb, 0x8e, 0x33, 0x71, 0xe5, 0xfc, 0xff, 0x3c}; -static unsigned char USERPREFS_ADMIN_KEY_1[] = {}; -static unsigned char USERPREFS_ADMIN_KEY_2[] = {}; +#define USERPREFS_USE_ADMIN_KEY_0 \ + { \ + 0xcd, 0xc0, 0xb4, 0x3c, 0x53, 0x24, 0xdf, 0x13, 0xca, 0x5a, 0xa6, 0x0c, 0x0d, 0xec, 0x85, 0x5a, 0x4c, 0xf6, 0x1a, 0x96, \ + 0x04, 0x1a, 0x3e, 0xfc, 0xbb, 0x8e, 0x33, 0x71, 0xe5, 0xfc, 0xff, 0x3c \ + }; */ +// #define USERPREFS_USE_ADMIN_KEY_1 {}; +// #define USERPREFS_USE_ADMIN_KEY_2 {}; /* * USERPREF_FIXED_GPS_LAT and USERPREF_FIXED_GPS_LON must be set, USERPREF_FIXED_GPS_ALT is optional diff --git a/variants/diy/platformio.ini b/variants/diy/platformio.ini index 00ff88da2..83e2175c8 100644 --- a/variants/diy/platformio.ini +++ b/variants/diy/platformio.ini @@ -2,6 +2,7 @@ [env:meshtastic-diy-v1] extends = esp32_base board = esp32doit-devkit-v1 +board_level = extra board_check = true build_flags = ${esp32_base.build_flags} diff --git a/variants/dreamcatcher/platformio.ini b/variants/dreamcatcher/platformio.ini index 46f9b9871..c57849d96 100644 --- a/variants/dreamcatcher/platformio.ini +++ b/variants/dreamcatcher/platformio.ini @@ -11,7 +11,7 @@ build_flags = -DARDUINO_USB_CDC_ON_BOOT=1 lib_deps = ${esp32s3_base.lib_deps} - earlephilhower/ESP8266Audio@^1.9.7 + earlephilhower/ESP8266Audio@^1.9.9 earlephilhower/ESP8266SAM@^1.0.1 [env:dreamcatcher-2206] diff --git a/variants/dreamcatcher/variant.h b/variants/dreamcatcher/variant.h index eb95a95dd..7835979e1 100644 --- a/variants/dreamcatcher/variant.h +++ b/variants/dreamcatcher/variant.h @@ -60,6 +60,7 @@ #define DAC_I2S_BCK 21 #define DAC_I2S_WS 9 #define DAC_I2S_DOUT 48 +#define DAC_I2S_MCLK 44 #define BIAS_T_ENABLE 7 // needs to be low #define BIAS_T_VALUE 0 diff --git a/variants/radiomaster_900_bandit/platformio.ini b/variants/radiomaster_900_bandit/platformio.ini index 4ff8a6ea2..010791d8a 100644 --- a/variants/radiomaster_900_bandit/platformio.ini +++ b/variants/radiomaster_900_bandit/platformio.ini @@ -6,9 +6,11 @@ build_flags = -DRADIOMASTER_900_BANDIT -DVTABLES_IN_FLASH=1 -DCONFIG_DISABLE_HAL_LOCKS=1 + -DHAS_STK8XXX=1 -O2 -Ivariants/radiomaster_900_bandit board_build.f_cpu = 240000000L upload_protocol = esptool lib_deps = - ${esp32_base.lib_deps} \ No newline at end of file + ${esp32_base.lib_deps} + https://github.com/gjelsoe/STK8xxx-Accelerometer.git#v0.1.1 diff --git a/variants/rak_wismeshtap/variant.h b/variants/rak_wismeshtap/variant.h index 134a20227..c21a11ac1 100644 --- a/variants/rak_wismeshtap/variant.h +++ b/variants/rak_wismeshtap/variant.h @@ -306,7 +306,7 @@ SO GPIO 39/TXEN MAY NOT BE DEFINED FOR SUCCESSFUL OPERATION OF THE SX1262 - TG #define SCREEN_TOUCH_INT WB_IO6 #define CANNED_MESSAGE_MODULE_ENABLE 1 - +#define USE_VIRTUAL_KEYBOARD 1 /*---------------------------------------------------------------------------- * Arduino objects - C++ only *----------------------------------------------------------------------------*/ diff --git a/variants/seeed-sensecap-indicator/variant.h b/variants/seeed-sensecap-indicator/variant.h index d7ed329eb..55895f353 100644 --- a/variants/seeed-sensecap-indicator/variant.h +++ b/variants/seeed-sensecap-indicator/variant.h @@ -36,12 +36,13 @@ #define TOUCH_I2C_PORT 0 #define TOUCH_SLAVE_ADDRESS 0x48 -// Buzzer -#define PIN_BUZZER 19 +// in future, we may want to add a buzzer and add all sensors to the indicator via a data protocol for now only GPS is supported +// // Buzzer +// #define PIN_BUZZER 19 -#define HAS_GPS 0 -#undef GPS_RX_PIN -#undef GPS_TX_PIN +#define GPS_RX_PIN 20 +#define GPS_TX_PIN 19 +#define HAS_GPS 1 #define USE_SX1262 #define USE_SX1268 @@ -62,3 +63,6 @@ #define SX126X_BUSY LORA_DIO2 #define SX126X_RESET LORA_RESET #define SX126X_DIO2_AS_RF_SWITCH + +#define USE_VIRTUAL_KEYBOARD 1 +#define DISPLAY_CLOCK_FRAME 1 diff --git a/variants/t-deck/platformio.ini b/variants/t-deck/platformio.ini index a63ff57a7..16769e2f2 100644 --- a/variants/t-deck/platformio.ini +++ b/variants/t-deck/platformio.ini @@ -15,5 +15,5 @@ build_flags = ${esp32_base.build_flags} lib_deps = ${esp32s3_base.lib_deps} lovyan03/LovyanGFX@^1.1.9 - earlephilhower/ESP8266Audio@^1.9.7 + earlephilhower/ESP8266Audio@^1.9.9 earlephilhower/ESP8266SAM@^1.0.1 \ No newline at end of file diff --git a/variants/t-deck/variant.h b/variants/t-deck/variant.h index 9860d608f..6d398391e 100644 --- a/variants/t-deck/variant.h +++ b/variants/t-deck/variant.h @@ -73,6 +73,7 @@ #define DAC_I2S_BCK 7 #define DAC_I2S_WS 5 #define DAC_I2S_DOUT 6 +#define DAC_I2S_MCLK 21 // GPIO lrck mic // LoRa #define USE_SX1262 diff --git a/variants/t-watch-s3/platformio.ini b/variants/t-watch-s3/platformio.ini index 1f5fc278b..005c4d021 100644 --- a/variants/t-watch-s3/platformio.ini +++ b/variants/t-watch-s3/platformio.ini @@ -9,10 +9,12 @@ build_flags = ${esp32_base.build_flags} -DT_WATCH_S3 -Ivariants/t-watch-s3 -DPCF8563_RTC=0x51 + -DHAS_BMA423=1 lib_deps = ${esp32s3_base.lib_deps} lovyan03/LovyanGFX@^1.1.9 lewisxhe/PCF8563_Library@1.0.1 adafruit/Adafruit DRV2605 Library@^1.2.2 - earlephilhower/ESP8266Audio@^1.9.7 - earlephilhower/ESP8266SAM@^1.0.1 \ No newline at end of file + earlephilhower/ESP8266Audio@^1.9.9 + earlephilhower/ESP8266SAM@^1.0.1 + lewisxhe/SensorLib@0.2.0 diff --git a/variants/t-watch-s3/variant.h b/variants/t-watch-s3/variant.h index 9f939d859..5a6aebfa2 100644 --- a/variants/t-watch-s3/variant.h +++ b/variants/t-watch-s3/variant.h @@ -34,6 +34,7 @@ #define DAC_I2S_BCK 48 #define DAC_I2S_WS 15 #define DAC_I2S_DOUT 46 +#define DAC_I2S_MCLK 0 #define HAS_AXP2101 @@ -71,3 +72,6 @@ #define SX126X_DIO3_TCXO_VOLTAGE 1.8 // Internally the TTGO module hooks the SX1262-DIO2 in to control the TX/RX switch (which is the default for // the sx1262interface code) + +#define USE_VIRTUAL_KEYBOARD 1 +#define DISPLAY_CLOCK_FRAME 1