mirror of
https://github.com/meshtastic/firmware.git
synced 2025-08-03 20:30:43 +00:00
Merge branch 'master' into nomad-gemini
This commit is contained in:
commit
30a3f39ed0
@ -46,7 +46,7 @@ lib_deps =
|
|||||||
${radiolib_base.lib_deps}
|
${radiolib_base.lib_deps}
|
||||||
https://github.com/meshtastic/esp32_https_server.git#23665b3adc080a311dcbb586ed5941b5f94d6ea2
|
https://github.com/meshtastic/esp32_https_server.git#23665b3adc080a311dcbb586ed5941b5f94d6ea2
|
||||||
h2zero/NimBLE-Arduino@^1.4.2
|
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
|
lewisxhe/XPowersLib@^0.2.6
|
||||||
https://github.com/meshtastic/ESP32_Codec2.git#633326c78ac251c059ab3a8c430fcdf25b41672f
|
https://github.com/meshtastic/ESP32_Codec2.git#633326c78ac251c059ab3a8c430fcdf25b41672f
|
||||||
rweather/Crypto@^0.4.0
|
rweather/Crypto@^0.4.0
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
; Common settings for rp2040 Processor based targets
|
; Common settings for rp2040 Processor based targets
|
||||||
[rp2040_base]
|
[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
|
extends = arduino_base
|
||||||
platform_packages = framework-arduinopico@https://github.com/earlephilhower/arduino-pico.git#996c3bfab9758f12c07aa20cc6d352e630c16987 ; 4.2.1 with fix for sporadic hangs
|
platform_packages = framework-arduinopico@https://github.com/earlephilhower/arduino-pico.git#996c3bfab9758f12c07aa20cc6d352e630c16987 ; 4.2.1 with fix for sporadic hangs
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
; Common settings for rp2040 Processor based targets
|
; Common settings for rp2040 Processor based targets
|
||||||
[rp2350_base]
|
[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
|
extends = arduino_base
|
||||||
platform_packages = framework-arduinopico@https://github.com/earlephilhower/arduino-pico.git#96c3bfab9758f12c07aa20cc6d352e630c16987 ; 4.2.1 with fix for sporadic hangs
|
platform_packages = framework-arduinopico@https://github.com/earlephilhower/arduino-pico.git#96c3bfab9758f12c07aa20cc6d352e630c16987 ; 4.2.1 with fix for sporadic hangs
|
||||||
|
|
||||||
|
@ -27,5 +27,4 @@ rm -r $OUTDIR/* || true
|
|||||||
platformio pkg update --environment native || platformioFailed
|
platformio pkg update --environment native || platformioFailed
|
||||||
pio run --environment native || platformioFailed
|
pio run --environment native || platformioFailed
|
||||||
cp .pio/build/native/program "$OUTDIR/meshtasticd_linux_$(uname -m)"
|
cp .pio/build/native/program "$OUTDIR/meshtasticd_linux_$(uname -m)"
|
||||||
cp bin/device-install.* $OUTDIR
|
cp bin/native-install.* $OUTDIR
|
||||||
cp bin/device-update.* $OUTDIR
|
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
@ECHO OFF
|
@ECHO OFF
|
||||||
|
|
||||||
set PYTHON=python
|
set PYTHON=python
|
||||||
|
set WEB_APP=0
|
||||||
|
|
||||||
:: Determine the correct esptool command to use
|
:: Determine the correct esptool command to use
|
||||||
where esptool >nul 2>&1
|
where esptool >nul 2>&1
|
||||||
@ -12,13 +13,14 @@ if %ERRORLEVEL% EQU 0 (
|
|||||||
|
|
||||||
goto GETOPTS
|
goto GETOPTS
|
||||||
:HELP
|
: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 Flash image file to device, but first erasing and writing system information
|
||||||
echo.
|
echo.
|
||||||
echo -h Display this help and exit
|
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 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 -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 -f FILENAME The .bin file to flash. Custom to your device type and region.
|
||||||
|
echo --web Flash WEB APP.
|
||||||
goto EOF
|
goto EOF
|
||||||
|
|
||||||
:GETOPTS
|
:GETOPTS
|
||||||
@ -27,6 +29,7 @@ if /I "%1"=="--help" goto HELP
|
|||||||
if /I "%1"=="-F" set "FILENAME=%2" & SHIFT
|
if /I "%1"=="-F" set "FILENAME=%2" & SHIFT
|
||||||
if /I "%1"=="-p" set ESPTOOL_PORT=%2 & SHIFT
|
if /I "%1"=="-p" set ESPTOOL_PORT=%2 & SHIFT
|
||||||
if /I "%1"=="-P" set PYTHON=%2 & SHIFT
|
if /I "%1"=="-P" set PYTHON=%2 & SHIFT
|
||||||
|
if /I "%1"=="--web" set WEB_APP=1 & SHIFT
|
||||||
SHIFT
|
SHIFT
|
||||||
IF NOT "__%1__"=="____" goto GETOPTS
|
IF NOT "__%1__"=="____" goto GETOPTS
|
||||||
|
|
||||||
@ -49,8 +52,14 @@ IF EXIST %FILENAME% IF x%FILENAME:update=%==x%FILENAME% (
|
|||||||
) else (
|
) else (
|
||||||
%ESPTOOL_CMD% --baud 115200 write_flash 0x260000 bleota-s3.bin
|
%ESPTOOL_CMD% --baud 115200 write_flash 0x260000 bleota-s3.bin
|
||||||
)
|
)
|
||||||
for %%f in (littlefs-*.bin) do (
|
IF %WEB_APP%==1 (
|
||||||
%ESPTOOL_CMD% --baud 115200 write_flash 0x300000 %%f
|
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 (
|
) else (
|
||||||
echo "Invalid file: %FILENAME%"
|
echo "Invalid file: %FILENAME%"
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
|
|
||||||
PYTHON=${PYTHON:-$(which python3 python | head -n 1)}
|
PYTHON=${PYTHON:-$(which python3 python | head -n 1)}
|
||||||
|
WEB_APP=false
|
||||||
|
|
||||||
# Determine the correct esptool command to use
|
# Determine the correct esptool command to use
|
||||||
if "$PYTHON" -m esptool version >/dev/null 2>&1; then
|
if "$PYTHON" -m esptool version >/dev/null 2>&1; then
|
||||||
@ -19,16 +20,26 @@ set -e
|
|||||||
# Usage info
|
# Usage info
|
||||||
show_help() {
|
show_help() {
|
||||||
cat <<EOF
|
cat <<EOF
|
||||||
Usage: $(basename $0) [-h] [-p ESPTOOL_PORT] [-P PYTHON] [-f FILENAME|FILENAME]
|
Usage: $(basename $0) [-h] [-p ESPTOOL_PORT] [-P PYTHON] [-f FILENAME|FILENAME] [--web]
|
||||||
Flash image file to device, but first erasing and writing system information"
|
Flash image file to device, but first erasing and writing system information"
|
||||||
|
|
||||||
-h Display this help and exit
|
-h Display this help and exit
|
||||||
-p ESPTOOL_PORT Set the environment variable for ESPTOOL_PORT. If not set, ESPTOOL iterates all ports (Dangerous).
|
-p ESPTOOL_PORT Set the environment variable for ESPTOOL_PORT. If not set, ESPTOOL iterates all ports (Dangerous).
|
||||||
-P PYTHON Specify alternate python interpreter to use to invoke esptool. (Default: "$PYTHON")
|
-P PYTHON Specify alternate python interpreter to use to invoke esptool. (Default: "$PYTHON")
|
||||||
-f FILENAME The .bin file to flash. Custom to your device type and region.
|
-f FILENAME The .bin file to flash. Custom to your device type and region.
|
||||||
|
--web Flash WEB APP.
|
||||||
|
|
||||||
EOF
|
EOF
|
||||||
}
|
}
|
||||||
|
# Preprocess long options like --web
|
||||||
|
for arg in "$@"; do
|
||||||
|
case "$arg" in
|
||||||
|
--web)
|
||||||
|
WEB_APP=true
|
||||||
|
shift # Remove this argument from the list
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
while getopts ":hp:P:f:" opt; do
|
while getopts ":hp:P:f:" opt; do
|
||||||
case "${opt}" in
|
case "${opt}" in
|
||||||
@ -73,7 +84,11 @@ if [ -f "${FILENAME}" ] && [ -n "${FILENAME##*"update"*}" ]; then
|
|||||||
else
|
else
|
||||||
$ESPTOOL_CMD write_flash 0x260000 bleota-s3.bin
|
$ESPTOOL_CMD write_flash 0x260000 bleota-s3.bin
|
||||||
fi
|
fi
|
||||||
$ESPTOOL_CMD write_flash 0x300000 littlefs-*.bin
|
if [ "$WEB_APP" = true ]; then
|
||||||
|
$ESPTOOL_CMD write_flash 0x300000 littlefswebui-*.bin
|
||||||
|
else
|
||||||
|
$ESPTOOL_CMD write_flash 0x300000 littlefs-*.bin
|
||||||
|
fi
|
||||||
|
|
||||||
else
|
else
|
||||||
show_help
|
show_help
|
||||||
|
@ -155,15 +155,11 @@ lib_deps =
|
|||||||
sparkfun/SparkFun 9DoF IMU Breakout - ICM 20948 - Arduino Library@1.2.13
|
sparkfun/SparkFun 9DoF IMU Breakout - ICM 20948 - Arduino Library@1.2.13
|
||||||
ClosedCube OPT3001@1.1.2
|
ClosedCube OPT3001@1.1.2
|
||||||
emotibit/EmotiBit MLX90632@1.0.8
|
emotibit/EmotiBit MLX90632@1.0.8
|
||||||
dfrobot/DFRobot_RTU@1.0.3
|
|
||||||
sparkfun/SparkFun MAX3010x Pulse and Proximity Sensor Library@1.1.2
|
sparkfun/SparkFun MAX3010x Pulse and Proximity Sensor Library@1.1.2
|
||||||
adafruit/Adafruit MLX90614 Library@2.1.5
|
adafruit/Adafruit MLX90614 Library@2.1.5
|
||||||
|
|
||||||
https://github.com/boschsensortec/Bosch-BSEC2-Library#v1.7.2502
|
https://github.com/boschsensortec/Bosch-BSEC2-Library#v1.7.2502
|
||||||
boschsensortec/BME68x Sensor Library@1.1.40407
|
boschsensortec/BME68x Sensor Library@1.1.40407
|
||||||
https://github.com/KodinLanewave/INA3221@1.0.1
|
https://github.com/KodinLanewave/INA3221@1.0.1
|
||||||
lewisxhe/SensorLib@0.2.0
|
|
||||||
mprograms/QMC5883LCompass@1.2.3
|
mprograms/QMC5883LCompass@1.2.3
|
||||||
|
dfrobot/DFRobot_RTU@1.0.3
|
||||||
https://github.com/meshtastic/DFRobot_LarkWeatherStation#4de3a9cadef0f6a5220a8a906cf9775b02b0040d
|
https://github.com/meshtastic/DFRobot_LarkWeatherStation#4de3a9cadef0f6a5220a8a906cf9775b02b0040d
|
||||||
https://github.com/gjelsoe/STK8xxx-Accelerometer.git#v0.1.1
|
|
||||||
|
@ -1 +1 @@
|
|||||||
Subproject commit af7521c3a77d56eb7a64efae5637a311ac33f76d
|
Subproject commit c952f8a4c1c30f724743ee322dd3ec3ec2f934c4
|
1
release/latest/.gitignore
vendored
1
release/latest/.gitignore
vendored
@ -1 +0,0 @@
|
|||||||
curfirmwareversion.xml
|
|
@ -64,7 +64,7 @@ class AudioThread : public concurrency::OSThread
|
|||||||
void initOutput()
|
void initOutput()
|
||||||
{
|
{
|
||||||
audioOut = new AudioOutputI2S(1, AudioOutputI2S::EXTERNAL_I2S);
|
audioOut = new AudioOutputI2S(1, AudioOutputI2S::EXTERNAL_I2S);
|
||||||
audioOut->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);
|
audioOut->SetGain(0.2);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -148,6 +148,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||||||
#define NAU7802_ADDR 0x2A
|
#define NAU7802_ADDR 0x2A
|
||||||
#define MAX30102_ADDR 0x57
|
#define MAX30102_ADDR 0x57
|
||||||
#define MLX90614_ADDR_DEF 0x5A
|
#define MLX90614_ADDR_DEF 0x5A
|
||||||
|
#define CGRADSENS_ADDR 0x66
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
// ACCELEROMETER
|
// ACCELEROMETER
|
||||||
|
@ -63,7 +63,8 @@ class ScanI2C
|
|||||||
ICM20948,
|
ICM20948,
|
||||||
MAX30102,
|
MAX30102,
|
||||||
TPS65233,
|
TPS65233,
|
||||||
MPR121KB
|
MPR121KB,
|
||||||
|
CGRADSENS
|
||||||
} DeviceType;
|
} DeviceType;
|
||||||
|
|
||||||
// typedef uint8_t DeviceAddress;
|
// typedef uint8_t DeviceAddress;
|
||||||
|
@ -314,19 +314,34 @@ void ScanI2CTwoWire::scanPort(I2CPort port, uint8_t *address, uint8_t asize)
|
|||||||
break;
|
break;
|
||||||
case INA3221_ADDR:
|
case INA3221_ADDR:
|
||||||
registerValue = getRegisterValue(ScanI2CTwoWire::RegisterLocation(addr, 0xFE), 2);
|
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) {
|
if (registerValue == 0x5449) {
|
||||||
LOG_INFO("INA3221 sensor found at address 0x%x", (uint8_t)addr.address);
|
LOG_INFO("INA3221 sensor found at address 0x%x", (uint8_t)addr.address);
|
||||||
type = INA3221;
|
type = INA3221;
|
||||||
} else {
|
} else {
|
||||||
LOG_INFO("DFRobot Lark weather station found at address 0x%x", (uint8_t)addr.address);
|
/* check the first 2 bytes of the 6 byte response register
|
||||||
type = DFROBOT_LARK;
|
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;
|
break;
|
||||||
case MCP9808_ADDR:
|
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
|
// 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.
|
// 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.
|
// Check register 0x00 for 0x8700 response to ID STK8BA53 chip.
|
||||||
registerValue = getRegisterValue(ScanI2CTwoWire::RegisterLocation(addr, 0x00), 2);
|
registerValue = getRegisterValue(ScanI2CTwoWire::RegisterLocation(addr, 0x00), 2);
|
||||||
if (registerValue == 0x8700) {
|
if (registerValue == 0x8700) {
|
||||||
@ -334,6 +349,7 @@ void ScanI2CTwoWire::scanPort(I2CPort port, uint8_t *address, uint8_t asize)
|
|||||||
LOG_INFO("STK8BAXX accelerometer found");
|
LOG_INFO("STK8BAXX accelerometer found");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
// Check register 0x07 for 0x0400 response to ID MCP9808 chip.
|
// Check register 0x07 for 0x0400 response to ID MCP9808 chip.
|
||||||
registerValue = getRegisterValue(ScanI2CTwoWire::RegisterLocation(addr, 0x07), 2);
|
registerValue = getRegisterValue(ScanI2CTwoWire::RegisterLocation(addr, 0x07), 2);
|
||||||
@ -463,6 +479,16 @@ void ScanI2CTwoWire::scanPort(I2CPort port, uint8_t *address, uint8_t asize)
|
|||||||
}
|
}
|
||||||
break;
|
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:
|
default:
|
||||||
LOG_INFO("Device found at address 0x%x was not able to be enumerated", addr.address);
|
LOG_INFO("Device found at address 0x%x was not able to be enumerated", addr.address);
|
||||||
}
|
}
|
||||||
|
196
src/gps/GPS.h
196
src/gps/GPS.h
@ -64,6 +64,95 @@ const char *getDOPString(uint32_t dop);
|
|||||||
*/
|
*/
|
||||||
class GPS : private concurrency::OSThread
|
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<const meshtastic::GPSStatus *> 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;
|
TinyGPSPlus reader;
|
||||||
uint8_t fixQual = 0; // fix quality from GPGGA
|
uint8_t fixQual = 0; // fix quality from GPGGA
|
||||||
uint32_t lastChecksumFailCount = 0;
|
uint32_t lastChecksumFailCount = 0;
|
||||||
@ -75,7 +164,6 @@ class GPS : private concurrency::OSThread
|
|||||||
TinyGPSCustom gsapdop; // custom extract PDOP from GPGSA
|
TinyGPSCustom gsapdop; // custom extract PDOP from GPGSA
|
||||||
uint8_t fixType = 0; // fix type from GPGSA
|
uint8_t fixType = 0; // fix type from GPGSA
|
||||||
#endif
|
#endif
|
||||||
private:
|
|
||||||
#if GPS_BAUDRATE_FIXED
|
#if GPS_BAUDRATE_FIXED
|
||||||
// if GPS_BAUDRATE is specified in variant, only try that.
|
// if GPS_BAUDRATE is specified in variant, only try that.
|
||||||
const int serialSpeeds[1] = {GPS_BAUDRATE};
|
const int serialSpeeds[1] = {GPS_BAUDRATE};
|
||||||
@ -113,7 +201,6 @@ class GPS : private concurrency::OSThread
|
|||||||
|
|
||||||
CallbackObserver<GPS, void *> notifyDeepSleepObserver = CallbackObserver<GPS, void *>(this, &GPS::prepareDeepSleep);
|
CallbackObserver<GPS, void *> notifyDeepSleepObserver = CallbackObserver<GPS, void *>(this, &GPS::prepareDeepSleep);
|
||||||
|
|
||||||
public:
|
|
||||||
/** If !NULL we will use this serial port to construct our GPS */
|
/** If !NULL we will use this serial port to construct our GPS */
|
||||||
#if defined(ARCH_RP2040)
|
#if defined(ARCH_RP2040)
|
||||||
static SerialUART *_serial_gps;
|
static SerialUART *_serial_gps;
|
||||||
@ -167,53 +254,6 @@ class GPS : private concurrency::OSThread
|
|||||||
|
|
||||||
const char *ACK_SUCCESS_MESSAGE = "Get ack success!";
|
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<const meshtastic::GPSStatus *> 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
|
// 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 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);
|
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);
|
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
|
/// 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
|
/// always returns 0 to indicate okay to sleep
|
||||||
int prepareDeepSleep(void *unused);
|
int prepareDeepSleep(void *unused);
|
||||||
@ -320,10 +307,7 @@ class GPS : private concurrency::OSThread
|
|||||||
uint8_t fixeddelayCtr = 0;
|
uint8_t fixeddelayCtr = 0;
|
||||||
|
|
||||||
const char *powerStateToString();
|
const char *powerStateToString();
|
||||||
|
|
||||||
protected:
|
|
||||||
GnssModel_t gnssModel = GNSS_MODEL_UNKNOWN;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
extern GPS *gps;
|
extern GPS *gps;
|
||||||
#endif // Exclude GPS
|
#endif // Exclude GPS
|
||||||
|
@ -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);
|
GeoCoord geoCoord(pos.latitude_i, pos.longitude_i, pos.altitude);
|
||||||
char type = isCaltopoMode ? 'P' : 'N';
|
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(),
|
(abs(geoCoord.getLatitude()) - geoCoord.getDMSLatDeg() * 1e+7) * 6e-6, geoCoord.getDMSLatCP(),
|
||||||
geoCoord.getDMSLonDeg(), (abs(geoCoord.getLongitude()) - geoCoord.getDMSLonDeg() * 1e+7) * 6e-6,
|
geoCoord.getDMSLonDeg(), (abs(geoCoord.getLongitude()) - geoCoord.getDMSLonDeg() * 1e+7) * 6e-6,
|
||||||
geoCoord.getDMSLonCP(), name);
|
geoCoord.getDMSLonCP(), name);
|
||||||
|
@ -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);
|
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)
|
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
|
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;
|
normalFrames[numframes++] = screen->digitalWatchFace ? &Screen::drawDigitalClockFrame : &Screen::drawAnalogClockFrame;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -2699,7 +2699,7 @@ int Screen::handleUIFrameEvent(const UIFrameEvent *event)
|
|||||||
int Screen::handleInputEvent(const InputEvent *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
|
// For the T-Watch, intercept touches to the 'toggle digital/analog watch face' button
|
||||||
uint8_t watchFaceFrame = error_code ? 1 : 0;
|
uint8_t watchFaceFrame = error_code ? 1 : 0;
|
||||||
|
|
||||||
|
@ -554,7 +554,7 @@ class Screen : public concurrency::OSThread
|
|||||||
|
|
||||||
static void drawDebugInfoWiFiTrampoline(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y);
|
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 drawAnalogClockFrame(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y);
|
||||||
|
|
||||||
static void drawDigitalClockFrame(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y);
|
static void drawDigitalClockFrame(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y);
|
||||||
|
@ -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 imgPositionEmpty[] PROGMEM = {0x20, 0x30, 0x28, 0x24, 0x42, 0xFF};
|
||||||
const uint8_t imgPositionSolid[] PROGMEM = {0x20, 0x30, 0x38, 0x3C, 0x7E, 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,
|
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,
|
0xf3, 0x3f, 0x33, 0x30, 0x33, 0x33, 0x33, 0x33, 0x03, 0x33, 0xff, 0x33,
|
||||||
0xfe, 0x31, 0x00, 0x30, 0x30, 0x30, 0x30, 0x30, 0xf0, 0x3f, 0xe0, 0x1f};
|
0xfe, 0x31, 0x00, 0x30, 0x30, 0x30, 0x30, 0x30, 0xf0, 0x3f, 0xe0, 0x1f};
|
||||||
|
@ -616,6 +616,7 @@ void setup()
|
|||||||
SCANNER_TO_SENSORS_MAP(ScanI2C::DeviceType::DFROBOT_LARK, meshtastic_TelemetrySensorType_DFROBOT_LARK)
|
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::ICM20948, meshtastic_TelemetrySensorType_ICM20948)
|
||||||
SCANNER_TO_SENSORS_MAP(ScanI2C::DeviceType::MAX30102, meshtastic_TelemetrySensorType_MAX30102)
|
SCANNER_TO_SENSORS_MAP(ScanI2C::DeviceType::MAX30102, meshtastic_TelemetrySensorType_MAX30102)
|
||||||
|
SCANNER_TO_SENSORS_MAP(ScanI2C::DeviceType::CGRADSENS, meshtastic_TelemetrySensorType_RADSENS)
|
||||||
|
|
||||||
i2cScanner.reset();
|
i2cScanner.reset();
|
||||||
#endif
|
#endif
|
||||||
|
@ -61,6 +61,16 @@ meshtastic_LocalConfig config;
|
|||||||
meshtastic_LocalModuleConfig moduleConfig;
|
meshtastic_LocalModuleConfig moduleConfig;
|
||||||
meshtastic_ChannelFile channelFile;
|
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)
|
bool meshtastic_DeviceState_callback(pb_istream_t *istream, pb_ostream_t *ostream, const pb_field_iter_t *field)
|
||||||
{
|
{
|
||||||
if (ostream) {
|
if (ostream) {
|
||||||
@ -406,32 +416,37 @@ void NodeDB::installDefaultConfig(bool preserveKey = false)
|
|||||||
#else
|
#else
|
||||||
config.lora.ignore_mqtt = false;
|
config.lora.ignore_mqtt = false;
|
||||||
#endif
|
#endif
|
||||||
#ifdef USERPREFS_USE_ADMIN_KEY
|
|
||||||
// Initialize admin_key_count to zero
|
// Initialize admin_key_count to zero
|
||||||
byte numAdminKeys = 0;
|
byte numAdminKeys = 0;
|
||||||
|
|
||||||
|
#ifdef USERPREFS_USE_ADMIN_KEY_0
|
||||||
// Check if USERPREFS_ADMIN_KEY_0 is non-empty
|
// Check if USERPREFS_ADMIN_KEY_0 is non-empty
|
||||||
if (sizeof(USERPREFS_ADMIN_KEY_0) > 0) {
|
if (sizeof(userprefs_admin_key_0) > 0) {
|
||||||
memcpy(config.security.admin_key[numAdminKeys].bytes, USERPREFS_ADMIN_KEY_0, 32);
|
memcpy(config.security.admin_key[0].bytes, userprefs_admin_key_0, 32);
|
||||||
config.security.admin_key[numAdminKeys].size = 32;
|
config.security.admin_key[0].size = 32;
|
||||||
numAdminKeys++;
|
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
|
#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) {
|
if (shouldPreserveKey) {
|
||||||
config.security.private_key.size = 32;
|
config.security.private_key.size = 32;
|
||||||
memcpy(config.security.private_key.bytes, private_key_temp, config.security.private_key.size);
|
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
|
#ifdef RAK4630
|
||||||
config.display.wake_on_tap_or_motion = true;
|
config.display.wake_on_tap_or_motion = true;
|
||||||
#endif
|
#endif
|
||||||
#ifdef T_WATCH_S3
|
#if defined(T_WATCH_S3) || defined(SENSECAP_INDICATOR)
|
||||||
config.display.screen_on_secs = 30;
|
config.display.screen_on_secs = 30;
|
||||||
config.display.wake_on_tap_or_motion = true;
|
config.display.wake_on_tap_or_motion = true;
|
||||||
#endif
|
#endif
|
||||||
@ -527,7 +542,7 @@ void NodeDB::initConfigIntervals()
|
|||||||
|
|
||||||
config.display.screen_on_secs = default_screen_on_secs;
|
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.power.is_power_saving = true;
|
||||||
config.display.screen_on_secs = 30;
|
config.display.screen_on_secs = 30;
|
||||||
config.power.wait_bluetooth_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),
|
state = loadProto(moduleConfigFileName, meshtastic_LocalModuleConfig_size, sizeof(meshtastic_LocalModuleConfig),
|
||||||
&meshtastic_LocalModuleConfig_msg, &moduleConfig);
|
&meshtastic_LocalModuleConfig_msg, &moduleConfig);
|
||||||
if (state != LoadFileResult::LOAD_SUCCESS) {
|
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");
|
LOG_ERROR("A critical failure occurred, portduino is exiting");
|
||||||
exit(2);
|
exit(2);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
@ -77,7 +77,9 @@ typedef enum _meshtastic_TelemetrySensorType {
|
|||||||
/* MLX90614 non-contact IR temperature sensor */
|
/* MLX90614 non-contact IR temperature sensor */
|
||||||
meshtastic_TelemetrySensorType_MLX90614 = 31,
|
meshtastic_TelemetrySensorType_MLX90614 = 31,
|
||||||
/* SCD40/SCD41 CO2, humidity, temperature sensor */
|
/* 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;
|
} meshtastic_TelemetrySensorType;
|
||||||
|
|
||||||
/* Struct definitions */
|
/* Struct definitions */
|
||||||
@ -155,6 +157,9 @@ typedef struct _meshtastic_EnvironmentMetrics {
|
|||||||
/* Wind lull in m/s */
|
/* Wind lull in m/s */
|
||||||
bool has_wind_lull;
|
bool has_wind_lull;
|
||||||
float wind_lull;
|
float wind_lull;
|
||||||
|
/* Radiation in µR/h */
|
||||||
|
bool has_radiation;
|
||||||
|
float radiation;
|
||||||
} meshtastic_EnvironmentMetrics;
|
} meshtastic_EnvironmentMetrics;
|
||||||
|
|
||||||
/* Power Metrics (voltage / current / etc) */
|
/* Power Metrics (voltage / current / etc) */
|
||||||
@ -299,8 +304,8 @@ extern "C" {
|
|||||||
|
|
||||||
/* Helper constants for enums */
|
/* Helper constants for enums */
|
||||||
#define _meshtastic_TelemetrySensorType_MIN meshtastic_TelemetrySensorType_SENSOR_UNSET
|
#define _meshtastic_TelemetrySensorType_MIN meshtastic_TelemetrySensorType_SENSOR_UNSET
|
||||||
#define _meshtastic_TelemetrySensorType_MAX meshtastic_TelemetrySensorType_SCD4X
|
#define _meshtastic_TelemetrySensorType_MAX meshtastic_TelemetrySensorType_RADSENS
|
||||||
#define _meshtastic_TelemetrySensorType_ARRAYSIZE ((meshtastic_TelemetrySensorType)(meshtastic_TelemetrySensorType_SCD4X+1))
|
#define _meshtastic_TelemetrySensorType_ARRAYSIZE ((meshtastic_TelemetrySensorType)(meshtastic_TelemetrySensorType_RADSENS+1))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -313,7 +318,7 @@ extern "C" {
|
|||||||
|
|
||||||
/* Initializer values for message structs */
|
/* Initializer values for message structs */
|
||||||
#define meshtastic_DeviceMetrics_init_default {false, 0, false, 0, false, 0, false, 0, false, 0}
|
#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_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_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}
|
#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_Telemetry_init_default {0, 0, {meshtastic_DeviceMetrics_init_default}}
|
||||||
#define meshtastic_Nau7802Config_init_default {0, 0}
|
#define meshtastic_Nau7802Config_init_default {0, 0}
|
||||||
#define meshtastic_DeviceMetrics_init_zero {false, 0, false, 0, false, 0, false, 0, false, 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_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_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}
|
#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_weight_tag 15
|
||||||
#define meshtastic_EnvironmentMetrics_wind_gust_tag 16
|
#define meshtastic_EnvironmentMetrics_wind_gust_tag 16
|
||||||
#define meshtastic_EnvironmentMetrics_wind_lull_tag 17
|
#define meshtastic_EnvironmentMetrics_wind_lull_tag 17
|
||||||
|
#define meshtastic_EnvironmentMetrics_radiation_tag 18
|
||||||
#define meshtastic_PowerMetrics_ch1_voltage_tag 1
|
#define meshtastic_PowerMetrics_ch1_voltage_tag 1
|
||||||
#define meshtastic_PowerMetrics_ch1_current_tag 2
|
#define meshtastic_PowerMetrics_ch1_current_tag 2
|
||||||
#define meshtastic_PowerMetrics_ch2_voltage_tag 3
|
#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, wind_speed, 14) \
|
||||||
X(a, STATIC, OPTIONAL, FLOAT, weight, 15) \
|
X(a, STATIC, OPTIONAL, FLOAT, weight, 15) \
|
||||||
X(a, STATIC, OPTIONAL, FLOAT, wind_gust, 16) \
|
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_CALLBACK NULL
|
||||||
#define meshtastic_EnvironmentMetrics_DEFAULT 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_MESHTASTIC_TELEMETRY_PB_H_MAX_SIZE meshtastic_Telemetry_size
|
||||||
#define meshtastic_AirQualityMetrics_size 78
|
#define meshtastic_AirQualityMetrics_size 78
|
||||||
#define meshtastic_DeviceMetrics_size 27
|
#define meshtastic_DeviceMetrics_size 27
|
||||||
#define meshtastic_EnvironmentMetrics_size 85
|
#define meshtastic_EnvironmentMetrics_size 91
|
||||||
#define meshtastic_HealthMetrics_size 11
|
#define meshtastic_HealthMetrics_size 11
|
||||||
#define meshtastic_LocalStats_size 60
|
#define meshtastic_LocalStats_size 60
|
||||||
#define meshtastic_Nau7802Config_size 16
|
#define meshtastic_Nau7802Config_size 16
|
||||||
#define meshtastic_PowerMetrics_size 30
|
#define meshtastic_PowerMetrics_size 30
|
||||||
#define meshtastic_Telemetry_size 92
|
#define meshtastic_Telemetry_size 98
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
} /* extern "C" */
|
} /* extern "C" */
|
||||||
|
@ -62,7 +62,11 @@ static void onNetworkConnected()
|
|||||||
LOG_INFO("Start WiFi network services");
|
LOG_INFO("Start WiFi network services");
|
||||||
|
|
||||||
// start mdns
|
// 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!");
|
LOG_ERROR("Error setting up MDNS responder!");
|
||||||
} else {
|
} else {
|
||||||
LOG_INFO("mDNS Host: Meshtastic.local");
|
LOG_INFO("mDNS Host: Meshtastic.local");
|
||||||
|
@ -55,7 +55,7 @@ CannedMessageModule::CannedMessageModule()
|
|||||||
LOG_INFO("CannedMessageModule is enabled");
|
LOG_INFO("CannedMessageModule is enabled");
|
||||||
|
|
||||||
// T-Watch interface currently has no way to select destination type, so default to 'node'
|
// 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;
|
this->destSelect = CANNED_MESSAGE_DESTINATION_TYPE_NODE;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -81,7 +81,7 @@ int CannedMessageModule::splitConfiguredMessages()
|
|||||||
|
|
||||||
String canned_messages = cannedMessageModuleConfig.messages;
|
String canned_messages = cannedMessageModuleConfig.messages;
|
||||||
|
|
||||||
#if defined(T_WATCH_S3) || defined(RAK14014)
|
#if defined(USE_VIRTUAL_KEYBOARD)
|
||||||
String separator = canned_messages.length() ? "|" : "";
|
String separator = canned_messages.length() ? "|" : "";
|
||||||
|
|
||||||
canned_messages = "[---- Free Text ----]" + separator + canned_messages;
|
canned_messages = "[---- Free Text ----]" + separator + canned_messages;
|
||||||
@ -150,7 +150,7 @@ int CannedMessageModule::handleInputEvent(const InputEvent *event)
|
|||||||
}
|
}
|
||||||
if (event->inputEvent == static_cast<char>(meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_SELECT)) {
|
if (event->inputEvent == static_cast<char>(meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_SELECT)) {
|
||||||
|
|
||||||
#if defined(T_WATCH_S3) || defined(RAK14014)
|
#if defined(USE_VIRTUAL_KEYBOARD)
|
||||||
if (this->currentMessageIndex == 0) {
|
if (this->currentMessageIndex == 0) {
|
||||||
this->runState = CANNED_MESSAGE_RUN_STATE_FREETEXT;
|
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
|
e.action = UIFrameEvent::Action::REGENERATE_FRAMESET; // We want to change the list of frames shown on-screen
|
||||||
this->currentMessageIndex = -1;
|
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->freetext = ""; // clear freetext
|
||||||
this->cursor = 0;
|
this->cursor = 0;
|
||||||
this->destSelect = CANNED_MESSAGE_DESTINATION_TYPE_NONE;
|
this->destSelect = CANNED_MESSAGE_DESTINATION_TYPE_NONE;
|
||||||
@ -190,7 +190,7 @@ int CannedMessageModule::handleInputEvent(const InputEvent *event)
|
|||||||
(event->inputEvent == static_cast<char>(meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_LEFT)) ||
|
(event->inputEvent == static_cast<char>(meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_LEFT)) ||
|
||||||
(event->inputEvent == static_cast<char>(meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_RIGHT))) {
|
(event->inputEvent == static_cast<char>(meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_RIGHT))) {
|
||||||
|
|
||||||
#if defined(T_WATCH_S3) || defined(RAK14014)
|
#if defined(USE_VIRTUAL_KEYBOARD)
|
||||||
if (event->inputEvent == static_cast<char>(meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_LEFT)) {
|
if (event->inputEvent == static_cast<char>(meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_LEFT)) {
|
||||||
this->payload = INPUT_BROKER_MSG_LEFT;
|
this->payload = INPUT_BROKER_MSG_LEFT;
|
||||||
} else if (event->inputEvent == static_cast<char>(meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_RIGHT)) {
|
} else if (event->inputEvent == static_cast<char>(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) {
|
if (this->runState == CANNED_MESSAGE_RUN_STATE_FREETEXT) {
|
||||||
String keyTapped = keyForCoordinates(event->touchX, event->touchY);
|
String keyTapped = keyForCoordinates(event->touchX, event->touchY);
|
||||||
|
|
||||||
@ -446,7 +446,7 @@ int32_t CannedMessageModule::runOnce()
|
|||||||
this->freetext = ""; // clear freetext
|
this->freetext = ""; // clear freetext
|
||||||
this->cursor = 0;
|
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;
|
this->destSelect = CANNED_MESSAGE_DESTINATION_TYPE_NONE;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -459,7 +459,7 @@ int32_t CannedMessageModule::runOnce()
|
|||||||
this->freetext = ""; // clear freetext
|
this->freetext = ""; // clear freetext
|
||||||
this->cursor = 0;
|
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;
|
this->destSelect = CANNED_MESSAGE_DESTINATION_TYPE_NONE;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -479,7 +479,7 @@ int32_t CannedMessageModule::runOnce()
|
|||||||
powerFSM.trigger(EVENT_PRESS);
|
powerFSM.trigger(EVENT_PRESS);
|
||||||
return INT32_MAX;
|
return INT32_MAX;
|
||||||
} else {
|
} else {
|
||||||
#if defined(T_WATCH_S3) || defined(RAK14014)
|
#if defined(USE_VIRTUAL_KEYBOARD)
|
||||||
sendText(this->dest, indexChannels[this->channel], this->messages[this->currentMessageIndex], true);
|
sendText(this->dest, indexChannels[this->channel], this->messages[this->currentMessageIndex], true);
|
||||||
#else
|
#else
|
||||||
sendText(NODENUM_BROADCAST, channels.getPrimaryIndex(), this->messages[this->currentMessageIndex], true);
|
sendText(NODENUM_BROADCAST, channels.getPrimaryIndex(), this->messages[this->currentMessageIndex], true);
|
||||||
@ -496,7 +496,7 @@ int32_t CannedMessageModule::runOnce()
|
|||||||
this->freetext = ""; // clear freetext
|
this->freetext = ""; // clear freetext
|
||||||
this->cursor = 0;
|
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;
|
this->destSelect = CANNED_MESSAGE_DESTINATION_TYPE_NONE;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -513,7 +513,7 @@ int32_t CannedMessageModule::runOnce()
|
|||||||
this->freetext = ""; // clear freetext
|
this->freetext = ""; // clear freetext
|
||||||
this->cursor = 0;
|
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;
|
this->destSelect = CANNED_MESSAGE_DESTINATION_TYPE_NONE;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -526,7 +526,7 @@ int32_t CannedMessageModule::runOnce()
|
|||||||
this->freetext = ""; // clear freetext
|
this->freetext = ""; // clear freetext
|
||||||
this->cursor = 0;
|
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;
|
this->destSelect = CANNED_MESSAGE_DESTINATION_TYPE_NONE;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -769,7 +769,7 @@ void CannedMessageModule::showTemporaryMessage(const String &message)
|
|||||||
setIntervalFromNow(2000);
|
setIntervalFromNow(2000);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(T_WATCH_S3) || defined(RAK14014)
|
#if defined(USE_VIRTUAL_KEYBOARD)
|
||||||
|
|
||||||
String CannedMessageModule::keyForCoordinates(uint x, uint y)
|
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.");
|
display->drawString(10 + x, 0 + y + FONT_HEIGHT_SMALL, "Canned Message\nModule disabled.");
|
||||||
} else if (cannedMessageModule->runState == CANNED_MESSAGE_RUN_STATE_FREETEXT) {
|
} else if (cannedMessageModule->runState == CANNED_MESSAGE_RUN_STATE_FREETEXT) {
|
||||||
requestFocus(); // Tell Screen::setFrames to move to our module's frame
|
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);
|
drawKeyboard(display, state, 0, 0);
|
||||||
#else
|
#else
|
||||||
|
|
||||||
|
@ -102,7 +102,7 @@ class CannedMessageModule : public SinglePortModule, public Observable<const UIF
|
|||||||
int getNextIndex();
|
int getNextIndex();
|
||||||
int getPrevIndex();
|
int getPrevIndex();
|
||||||
|
|
||||||
#if defined(T_WATCH_S3) || defined(RAK14014)
|
#if defined(USE_VIRTUAL_KEYBOARD)
|
||||||
void drawKeyboard(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y);
|
void drawKeyboard(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y);
|
||||||
String keyForCoordinates(uint x, uint y);
|
String keyForCoordinates(uint x, uint y);
|
||||||
bool shift = false;
|
bool shift = false;
|
||||||
@ -156,7 +156,7 @@ class CannedMessageModule : public SinglePortModule, public Observable<const UIF
|
|||||||
unsigned long lastTouchMillis = 0;
|
unsigned long lastTouchMillis = 0;
|
||||||
String temporaryMessage;
|
String temporaryMessage;
|
||||||
|
|
||||||
#if defined(T_WATCH_S3) || defined(RAK14014)
|
#if defined(USE_VIRTUAL_KEYBOARD)
|
||||||
Letter keyboard[2][4][10] = {{{{"Q", 20, 0, 0, 0, 0},
|
Letter keyboard[2][4][10] = {{{{"Q", 20, 0, 0, 0, 0},
|
||||||
{"W", 22, 0, 0, 0, 0},
|
{"W", 22, 0, 0, 0, 0},
|
||||||
{"E", 17, 0, 0, 0, 0},
|
{"E", 17, 0, 0, 0, 0},
|
||||||
|
@ -204,9 +204,11 @@ int32_t SerialModule::runOnce()
|
|||||||
lastNmeaTime = millis();
|
lastNmeaTime = millis();
|
||||||
uint32_t readIndex = 0;
|
uint32_t readIndex = 0;
|
||||||
const meshtastic_NodeInfoLite *tempNodeInfo = nodeDB->readNextMeshNode(readIndex);
|
const meshtastic_NodeInfoLite *tempNodeInfo = nodeDB->readNextMeshNode(readIndex);
|
||||||
while (tempNodeInfo != NULL && tempNodeInfo->has_user && hasValidPosition(tempNodeInfo)) {
|
while (tempNodeInfo != NULL) {
|
||||||
printWPL(outbuf, sizeof(outbuf), tempNodeInfo->position, tempNodeInfo->user.long_name, true);
|
if (tempNodeInfo->has_user && hasValidPosition(tempNodeInfo)) {
|
||||||
serialPrint->printf("%s", outbuf);
|
printWPL(outbuf, sizeof(outbuf), tempNodeInfo->position, tempNodeInfo->user.long_name, true);
|
||||||
|
serialPrint->printf("%s", outbuf);
|
||||||
|
}
|
||||||
tempNodeInfo = nodeDB->readNextMeshNode(readIndex);
|
tempNodeInfo = nodeDB->readNextMeshNode(readIndex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -77,9 +77,10 @@ meshtastic_MeshPacket *DeviceTelemetryModule::allocReply()
|
|||||||
// Check for a request for device metrics
|
// Check for a request for device metrics
|
||||||
if (decoded->which_variant == meshtastic_Telemetry_device_metrics_tag) {
|
if (decoded->which_variant == meshtastic_Telemetry_device_metrics_tag) {
|
||||||
LOG_INFO("Device telemetry reply to request");
|
LOG_INFO("Device telemetry reply to request");
|
||||||
|
return allocDataProtobuf(getDeviceTelemetry());
|
||||||
meshtastic_Telemetry telemetry = getDeviceTelemetry();
|
} else if (decoded->which_variant == meshtastic_Telemetry_local_stats_tag) {
|
||||||
return allocDataProtobuf(telemetry);
|
LOG_INFO("Device telemetry reply w/ LocalStats to request");
|
||||||
|
return allocDataProtobuf(getLocalStatsTelemetry());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
@ -112,7 +113,7 @@ meshtastic_Telemetry DeviceTelemetryModule::getDeviceTelemetry()
|
|||||||
return t;
|
return t;
|
||||||
}
|
}
|
||||||
|
|
||||||
void DeviceTelemetryModule::sendLocalStatsToPhone()
|
meshtastic_Telemetry DeviceTelemetryModule::getLocalStatsTelemetry()
|
||||||
{
|
{
|
||||||
meshtastic_Telemetry telemetry = meshtastic_Telemetry_init_zero;
|
meshtastic_Telemetry telemetry = meshtastic_Telemetry_init_zero;
|
||||||
telemetry.which_variant = meshtastic_Telemetry_local_stats_tag;
|
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,
|
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);
|
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->to = NODENUM_BROADCAST;
|
||||||
p->decoded.want_response = false;
|
p->decoded.want_response = false;
|
||||||
p->priority = meshtastic_MeshPacket_Priority_BACKGROUND;
|
p->priority = meshtastic_MeshPacket_Priority_BACKGROUND;
|
||||||
|
@ -42,6 +42,8 @@ class DeviceTelemetryModule : private concurrency::OSThread, public ProtobufModu
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
meshtastic_Telemetry getDeviceTelemetry();
|
meshtastic_Telemetry getDeviceTelemetry();
|
||||||
|
meshtastic_Telemetry getLocalStatsTelemetry();
|
||||||
|
|
||||||
void sendLocalStatsToPhone();
|
void sendLocalStatsToPhone();
|
||||||
uint32_t sendToPhoneIntervalMs = SECONDS_IN_MINUTE * 1000; // Send to phone every minute
|
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
|
uint32_t sendStatsToPhoneIntervalMs = 15 * SECONDS_IN_MINUTE * 1000; // Send stats to phone every 15 minutes
|
||||||
|
@ -25,6 +25,7 @@
|
|||||||
#include "Sensor/BMP085Sensor.h"
|
#include "Sensor/BMP085Sensor.h"
|
||||||
#include "Sensor/BMP280Sensor.h"
|
#include "Sensor/BMP280Sensor.h"
|
||||||
#include "Sensor/BMP3XXSensor.h"
|
#include "Sensor/BMP3XXSensor.h"
|
||||||
|
#include "Sensor/CGRadSensSensor.h"
|
||||||
#include "Sensor/DFRobotLarkSensor.h"
|
#include "Sensor/DFRobotLarkSensor.h"
|
||||||
#include "Sensor/LPS22HBSensor.h"
|
#include "Sensor/LPS22HBSensor.h"
|
||||||
#include "Sensor/MCP9808Sensor.h"
|
#include "Sensor/MCP9808Sensor.h"
|
||||||
@ -60,6 +61,7 @@ BMP3XXSensor bmp3xxSensor;
|
|||||||
#ifdef T1000X_SENSOR_EN
|
#ifdef T1000X_SENSOR_EN
|
||||||
T1000xSensor t1000xSensor;
|
T1000xSensor t1000xSensor;
|
||||||
#endif
|
#endif
|
||||||
|
CGRadSensSensor cgRadSens;
|
||||||
|
|
||||||
#define FAILED_STATE_SENSOR_READ_MULTIPLIER 10
|
#define FAILED_STATE_SENSOR_READ_MULTIPLIER 10
|
||||||
#define DISPLAY_RECEIVEID_MEASUREMENTS_ON_SCREEN true
|
#define DISPLAY_RECEIVEID_MEASUREMENTS_ON_SCREEN true
|
||||||
@ -147,6 +149,8 @@ int32_t EnvironmentTelemetryModule::runOnce()
|
|||||||
result = nau7802Sensor.runOnce();
|
result = nau7802Sensor.runOnce();
|
||||||
if (max17048Sensor.hasSensor())
|
if (max17048Sensor.hasSensor())
|
||||||
result = max17048Sensor.runOnce();
|
result = max17048Sensor.runOnce();
|
||||||
|
if (cgRadSens.hasSensor())
|
||||||
|
result = cgRadSens.runOnce();
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
@ -210,16 +214,19 @@ void EnvironmentTelemetryModule::drawFrame(OLEDDisplay *display, OLEDDisplayUiSt
|
|||||||
// Display "Env. From: ..." on its own
|
// Display "Env. From: ..." on its own
|
||||||
display->drawString(x, y, "Env. From: " + String(lastSender) + "(" + String(agoSecs) + "s)");
|
display->drawString(x, y, "Env. From: " + String(lastSender) + "(" + String(agoSecs) + "s)");
|
||||||
|
|
||||||
String last_temp = String(lastMeasurement.variant.environment_metrics.temperature, 0) + "°C";
|
if (lastMeasurement.variant.environment_metrics.has_temperature ||
|
||||||
if (moduleConfig.telemetry.environment_display_fahrenheit) {
|
lastMeasurement.variant.environment_metrics.has_relative_humidity) {
|
||||||
last_temp =
|
String last_temp = String(lastMeasurement.variant.environment_metrics.temperature, 0) + "°C";
|
||||||
String(UnitConversions::CelsiusToFahrenheit(lastMeasurement.variant.environment_metrics.temperature), 0) + "°F";
|
if (moduleConfig.telemetry.environment_display_fahrenheit) {
|
||||||
}
|
last_temp =
|
||||||
|
String(UnitConversions::CelsiusToFahrenheit(lastMeasurement.variant.environment_metrics.temperature), 0) + "°F";
|
||||||
|
}
|
||||||
|
|
||||||
// Continue with the remaining details
|
// Continue with the remaining details
|
||||||
display->drawString(x, y += _fontHeight(FONT_SMALL),
|
display->drawString(x, y += _fontHeight(FONT_SMALL),
|
||||||
"Temp/Hum: " + last_temp + " / " +
|
"Temp/Hum: " + last_temp + " / " +
|
||||||
String(lastMeasurement.variant.environment_metrics.relative_humidity, 0) + "%");
|
String(lastMeasurement.variant.environment_metrics.relative_humidity, 0) + "%");
|
||||||
|
}
|
||||||
|
|
||||||
if (lastMeasurement.variant.environment_metrics.barometric_pressure != 0) {
|
if (lastMeasurement.variant.environment_metrics.barometric_pressure != 0) {
|
||||||
display->drawString(x, y += _fontHeight(FONT_SMALL),
|
display->drawString(x, y += _fontHeight(FONT_SMALL),
|
||||||
@ -243,6 +250,10 @@ void EnvironmentTelemetryModule::drawFrame(OLEDDisplay *display, OLEDDisplayUiSt
|
|||||||
if (lastMeasurement.variant.environment_metrics.weight != 0)
|
if (lastMeasurement.variant.environment_metrics.weight != 0)
|
||||||
display->drawString(x, y += _fontHeight(FONT_SMALL),
|
display->drawString(x, y += _fontHeight(FONT_SMALL),
|
||||||
"Weight: " + String(lastMeasurement.variant.environment_metrics.weight, 0) + "kg");
|
"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)
|
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.wind_speed, t->variant.environment_metrics.wind_direction,
|
||||||
t->variant.environment_metrics.weight);
|
t->variant.environment_metrics.weight);
|
||||||
|
|
||||||
|
LOG_INFO("(Received from %s): radiation=%fµR/h", sender, t->variant.environment_metrics.radiation);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
// release previous packet before occupying a new spot
|
// release previous packet before occupying a new spot
|
||||||
if (lastMeasurementPacket != nullptr)
|
if (lastMeasurementPacket != nullptr)
|
||||||
@ -390,6 +403,10 @@ bool EnvironmentTelemetryModule::getEnvironmentTelemetry(meshtastic_Telemetry *m
|
|||||||
valid = valid && max17048Sensor.getMetrics(m);
|
valid = valid && max17048Sensor.getMetrics(m);
|
||||||
hasSensor = true;
|
hasSensor = true;
|
||||||
}
|
}
|
||||||
|
if (cgRadSens.hasSensor()) {
|
||||||
|
valid = valid && cgRadSens.getMetrics(m);
|
||||||
|
hasSensor = true;
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
return valid && hasSensor;
|
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,
|
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);
|
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;
|
sensor_read_error_count = 0;
|
||||||
|
|
||||||
meshtastic_MeshPacket *p = allocDataProtobuf(m);
|
meshtastic_MeshPacket *p = allocDataProtobuf(m);
|
||||||
@ -585,6 +604,11 @@ AdminMessageHandleResult EnvironmentTelemetryModule::handleAdminMessageForModule
|
|||||||
if (result != AdminMessageHandleResult::NOT_HANDLED)
|
if (result != AdminMessageHandleResult::NOT_HANDLED)
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
if (cgRadSens.hasSensor()) {
|
||||||
|
result = cgRadSens.handleAdminMessage(mp, request, response);
|
||||||
|
if (result != AdminMessageHandleResult::NOT_HANDLED)
|
||||||
|
return result;
|
||||||
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
75
src/modules/Telemetry/Sensor/CGRadSensSensor.cpp
Normal file
75
src/modules/Telemetry/Sensor/CGRadSensSensor.cpp
Normal file
@ -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 <Wire.h>
|
||||||
|
#include <typeinfo>
|
||||||
|
|
||||||
|
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
|
30
src/modules/Telemetry/Sensor/CGRadSensSensor.h
Normal file
30
src/modules/Telemetry/Sensor/CGRadSensSensor.h
Normal file
@ -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 <Wire.h>
|
||||||
|
|
||||||
|
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
|
@ -95,7 +95,9 @@ int32_t PaxcounterModule::runOnce()
|
|||||||
|
|
||||||
// internal processing initialization
|
// internal processing initialization
|
||||||
libpax_counter_init(handlePaxCounterReportRequest, &count_from_libpax,
|
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();
|
libpax_counter_start();
|
||||||
} else {
|
} else {
|
||||||
sendInfo(NODENUM_BROADCAST);
|
sendInfo(NODENUM_BROADCAST);
|
||||||
|
@ -7,7 +7,9 @@
|
|||||||
#if !defined(ARCH_PORTDUINO) && !defined(ARCH_STM32WL) && !MESHTASTIC_EXCLUDE_I2C
|
#if !defined(ARCH_PORTDUINO) && !defined(ARCH_STM32WL) && !MESHTASTIC_EXCLUDE_I2C
|
||||||
|
|
||||||
#include "../concurrency/OSThread.h"
|
#include "../concurrency/OSThread.h"
|
||||||
|
#ifdef HAS_BMA423
|
||||||
#include "BMA423Sensor.h"
|
#include "BMA423Sensor.h"
|
||||||
|
#endif
|
||||||
#include "BMX160Sensor.h"
|
#include "BMX160Sensor.h"
|
||||||
#include "ICM20948Sensor.h"
|
#include "ICM20948Sensor.h"
|
||||||
#include "LIS3DHSensor.h"
|
#include "LIS3DHSensor.h"
|
||||||
@ -17,7 +19,9 @@
|
|||||||
#ifdef HAS_QMA6100P
|
#ifdef HAS_QMA6100P
|
||||||
#include "QMA6100PSensor.h"
|
#include "QMA6100PSensor.h"
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef HAS_STK8XXX
|
||||||
#include "STK8XXXSensor.h"
|
#include "STK8XXXSensor.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
extern ScanI2C::DeviceAddress accelerometer_found;
|
extern ScanI2C::DeviceAddress accelerometer_found;
|
||||||
|
|
||||||
@ -79,9 +83,11 @@ class AccelerometerThread : public concurrency::OSThread
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
switch (device.type) {
|
switch (device.type) {
|
||||||
|
#ifdef HAS_BMA423
|
||||||
case ScanI2C::DeviceType::BMA423:
|
case ScanI2C::DeviceType::BMA423:
|
||||||
sensor = new BMA423Sensor(device);
|
sensor = new BMA423Sensor(device);
|
||||||
break;
|
break;
|
||||||
|
#endif
|
||||||
case ScanI2C::DeviceType::MPU6050:
|
case ScanI2C::DeviceType::MPU6050:
|
||||||
sensor = new MPU6050Sensor(device);
|
sensor = new MPU6050Sensor(device);
|
||||||
break;
|
break;
|
||||||
@ -94,9 +100,11 @@ class AccelerometerThread : public concurrency::OSThread
|
|||||||
case ScanI2C::DeviceType::LSM6DS3:
|
case ScanI2C::DeviceType::LSM6DS3:
|
||||||
sensor = new LSM6DS3Sensor(device);
|
sensor = new LSM6DS3Sensor(device);
|
||||||
break;
|
break;
|
||||||
|
#ifdef HAS_STK8XXX
|
||||||
case ScanI2C::DeviceType::STK8BAXX:
|
case ScanI2C::DeviceType::STK8BAXX:
|
||||||
sensor = new STK8XXXSensor(device);
|
sensor = new STK8XXXSensor(device);
|
||||||
break;
|
break;
|
||||||
|
#endif
|
||||||
case ScanI2C::DeviceType::ICM20948:
|
case ScanI2C::DeviceType::ICM20948:
|
||||||
sensor = new ICM20948Sensor(device);
|
sensor = new ICM20948Sensor(device);
|
||||||
break;
|
break;
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
#include "BMA423Sensor.h"
|
#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;
|
using namespace MotionSensorI2C;
|
||||||
|
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
#include "MotionSensor.h"
|
#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 <SensorBMA423.hpp>
|
#include <SensorBMA423.hpp>
|
||||||
#include <Wire.h>
|
#include <Wire.h>
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
#include "STK8XXXSensor.h"
|
#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) {}
|
STK8XXXSensor::STK8XXXSensor(ScanI2C::FoundDevice foundDevice) : MotionSensor::MotionSensor(foundDevice) {}
|
||||||
|
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
#include "MotionSensor.h"
|
#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
|
#ifdef STK8XXX_INT
|
||||||
|
|
||||||
|
@ -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
|
// 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) {
|
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.
|
// 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 &&
|
if (!isFromUs(&mp_decoded) && !isMqttServerAddressPrivate && dontUplink &&
|
||||||
!(mp_decoded.decoded.bitfield & BITFIELD_OK_TO_MQTT_MASK) &&
|
|
||||||
(ch.settings.psk.size < 2 || (ch.settings.psk.size == 16 && memcmp(ch.settings.psk.bytes, defaultpsk, 16)) ||
|
(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)))) {
|
(ch.settings.psk.size == 32 && memcmp(ch.settings.psk.bytes, eventpsk, 32)))) {
|
||||||
LOG_INFO("MQTT onSend - Not forwarding packet due to DontMqttMeBro flag");
|
LOG_INFO("MQTT onSend - Not forwarding packet due to DontMqttMeBro flag");
|
||||||
|
@ -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_direction"] = new JSONValue((uint)decoded->variant.environment_metrics.wind_direction);
|
||||||
msgPayload["wind_gust"] = new JSONValue(decoded->variant.environment_metrics.wind_gust);
|
msgPayload["wind_gust"] = new JSONValue(decoded->variant.environment_metrics.wind_gust);
|
||||||
msgPayload["wind_lull"] = new JSONValue(decoded->variant.environment_metrics.wind_lull);
|
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) {
|
} 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["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);
|
msgPayload["pm25"] = new JSONValue((unsigned int)decoded->variant.air_quality_metrics.pm25_standard);
|
||||||
|
@ -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_direction"] = (uint)decoded->variant.environment_metrics.wind_direction;
|
||||||
jsonObj["payload"]["wind_gust"] = decoded->variant.environment_metrics.wind_gust;
|
jsonObj["payload"]["wind_gust"] = decoded->variant.environment_metrics.wind_gust;
|
||||||
jsonObj["payload"]["wind_lull"] = decoded->variant.environment_metrics.wind_lull;
|
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) {
|
} 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"]["pm10"] = (unsigned int)decoded->variant.air_quality_metrics.pm10_standard;
|
||||||
jsonObj["payload"]["pm25"] = (unsigned int)decoded->variant.air_quality_metrics.pm25_standard;
|
jsonObj["payload"]["pm25"] = (unsigned int)decoded->variant.air_quality_metrics.pm25_standard;
|
||||||
|
15
userPrefs.h
15
userPrefs.h
@ -72,16 +72,17 @@ static unsigned char icon_bits[] = {
|
|||||||
/*
|
/*
|
||||||
* PKI Admin keys.
|
* PKI Admin keys.
|
||||||
* If a Admin key is set with '{};'
|
* 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
|
#define USERPREFS_USE_ADMIN_KEY_0 \
|
||||||
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,
|
0xcd, 0xc0, 0xb4, 0x3c, 0x53, 0x24, 0xdf, 0x13, 0xca, 0x5a, 0xa6, 0x0c, 0x0d, 0xec, 0x85, 0x5a, 0x4c, 0xf6, 0x1a, 0x96, \
|
||||||
0x3e, 0xfc, 0xbb, 0x8e, 0x33, 0x71, 0xe5, 0xfc, 0xff, 0x3c};
|
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_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
|
* USERPREF_FIXED_GPS_LAT and USERPREF_FIXED_GPS_LON must be set, USERPREF_FIXED_GPS_ALT is optional
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
[env:meshtastic-diy-v1]
|
[env:meshtastic-diy-v1]
|
||||||
extends = esp32_base
|
extends = esp32_base
|
||||||
board = esp32doit-devkit-v1
|
board = esp32doit-devkit-v1
|
||||||
|
board_level = extra
|
||||||
board_check = true
|
board_check = true
|
||||||
build_flags =
|
build_flags =
|
||||||
${esp32_base.build_flags}
|
${esp32_base.build_flags}
|
||||||
|
@ -11,7 +11,7 @@ build_flags =
|
|||||||
-DARDUINO_USB_CDC_ON_BOOT=1
|
-DARDUINO_USB_CDC_ON_BOOT=1
|
||||||
|
|
||||||
lib_deps = ${esp32s3_base.lib_deps}
|
lib_deps = ${esp32s3_base.lib_deps}
|
||||||
earlephilhower/ESP8266Audio@^1.9.7
|
earlephilhower/ESP8266Audio@^1.9.9
|
||||||
earlephilhower/ESP8266SAM@^1.0.1
|
earlephilhower/ESP8266SAM@^1.0.1
|
||||||
|
|
||||||
[env:dreamcatcher-2206]
|
[env:dreamcatcher-2206]
|
||||||
|
@ -60,6 +60,7 @@
|
|||||||
#define DAC_I2S_BCK 21
|
#define DAC_I2S_BCK 21
|
||||||
#define DAC_I2S_WS 9
|
#define DAC_I2S_WS 9
|
||||||
#define DAC_I2S_DOUT 48
|
#define DAC_I2S_DOUT 48
|
||||||
|
#define DAC_I2S_MCLK 44
|
||||||
|
|
||||||
#define BIAS_T_ENABLE 7 // needs to be low
|
#define BIAS_T_ENABLE 7 // needs to be low
|
||||||
#define BIAS_T_VALUE 0
|
#define BIAS_T_VALUE 0
|
||||||
|
@ -6,9 +6,11 @@ build_flags =
|
|||||||
-DRADIOMASTER_900_BANDIT
|
-DRADIOMASTER_900_BANDIT
|
||||||
-DVTABLES_IN_FLASH=1
|
-DVTABLES_IN_FLASH=1
|
||||||
-DCONFIG_DISABLE_HAL_LOCKS=1
|
-DCONFIG_DISABLE_HAL_LOCKS=1
|
||||||
|
-DHAS_STK8XXX=1
|
||||||
-O2
|
-O2
|
||||||
-Ivariants/radiomaster_900_bandit
|
-Ivariants/radiomaster_900_bandit
|
||||||
board_build.f_cpu = 240000000L
|
board_build.f_cpu = 240000000L
|
||||||
upload_protocol = esptool
|
upload_protocol = esptool
|
||||||
lib_deps =
|
lib_deps =
|
||||||
${esp32_base.lib_deps}
|
${esp32_base.lib_deps}
|
||||||
|
https://github.com/gjelsoe/STK8xxx-Accelerometer.git#v0.1.1
|
||||||
|
@ -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 SCREEN_TOUCH_INT WB_IO6
|
||||||
|
|
||||||
#define CANNED_MESSAGE_MODULE_ENABLE 1
|
#define CANNED_MESSAGE_MODULE_ENABLE 1
|
||||||
|
#define USE_VIRTUAL_KEYBOARD 1
|
||||||
/*----------------------------------------------------------------------------
|
/*----------------------------------------------------------------------------
|
||||||
* Arduino objects - C++ only
|
* Arduino objects - C++ only
|
||||||
*----------------------------------------------------------------------------*/
|
*----------------------------------------------------------------------------*/
|
||||||
|
@ -36,12 +36,13 @@
|
|||||||
#define TOUCH_I2C_PORT 0
|
#define TOUCH_I2C_PORT 0
|
||||||
#define TOUCH_SLAVE_ADDRESS 0x48
|
#define TOUCH_SLAVE_ADDRESS 0x48
|
||||||
|
|
||||||
// Buzzer
|
// 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
|
||||||
#define PIN_BUZZER 19
|
// // Buzzer
|
||||||
|
// #define PIN_BUZZER 19
|
||||||
|
|
||||||
#define HAS_GPS 0
|
#define GPS_RX_PIN 20
|
||||||
#undef GPS_RX_PIN
|
#define GPS_TX_PIN 19
|
||||||
#undef GPS_TX_PIN
|
#define HAS_GPS 1
|
||||||
|
|
||||||
#define USE_SX1262
|
#define USE_SX1262
|
||||||
#define USE_SX1268
|
#define USE_SX1268
|
||||||
@ -62,3 +63,6 @@
|
|||||||
#define SX126X_BUSY LORA_DIO2
|
#define SX126X_BUSY LORA_DIO2
|
||||||
#define SX126X_RESET LORA_RESET
|
#define SX126X_RESET LORA_RESET
|
||||||
#define SX126X_DIO2_AS_RF_SWITCH
|
#define SX126X_DIO2_AS_RF_SWITCH
|
||||||
|
|
||||||
|
#define USE_VIRTUAL_KEYBOARD 1
|
||||||
|
#define DISPLAY_CLOCK_FRAME 1
|
||||||
|
@ -15,5 +15,5 @@ build_flags = ${esp32_base.build_flags}
|
|||||||
|
|
||||||
lib_deps = ${esp32s3_base.lib_deps}
|
lib_deps = ${esp32s3_base.lib_deps}
|
||||||
lovyan03/LovyanGFX@^1.1.9
|
lovyan03/LovyanGFX@^1.1.9
|
||||||
earlephilhower/ESP8266Audio@^1.9.7
|
earlephilhower/ESP8266Audio@^1.9.9
|
||||||
earlephilhower/ESP8266SAM@^1.0.1
|
earlephilhower/ESP8266SAM@^1.0.1
|
@ -73,6 +73,7 @@
|
|||||||
#define DAC_I2S_BCK 7
|
#define DAC_I2S_BCK 7
|
||||||
#define DAC_I2S_WS 5
|
#define DAC_I2S_WS 5
|
||||||
#define DAC_I2S_DOUT 6
|
#define DAC_I2S_DOUT 6
|
||||||
|
#define DAC_I2S_MCLK 21 // GPIO lrck mic
|
||||||
|
|
||||||
// LoRa
|
// LoRa
|
||||||
#define USE_SX1262
|
#define USE_SX1262
|
||||||
|
@ -9,10 +9,12 @@ build_flags = ${esp32_base.build_flags}
|
|||||||
-DT_WATCH_S3
|
-DT_WATCH_S3
|
||||||
-Ivariants/t-watch-s3
|
-Ivariants/t-watch-s3
|
||||||
-DPCF8563_RTC=0x51
|
-DPCF8563_RTC=0x51
|
||||||
|
-DHAS_BMA423=1
|
||||||
|
|
||||||
lib_deps = ${esp32s3_base.lib_deps}
|
lib_deps = ${esp32s3_base.lib_deps}
|
||||||
lovyan03/LovyanGFX@^1.1.9
|
lovyan03/LovyanGFX@^1.1.9
|
||||||
lewisxhe/PCF8563_Library@1.0.1
|
lewisxhe/PCF8563_Library@1.0.1
|
||||||
adafruit/Adafruit DRV2605 Library@^1.2.2
|
adafruit/Adafruit DRV2605 Library@^1.2.2
|
||||||
earlephilhower/ESP8266Audio@^1.9.7
|
earlephilhower/ESP8266Audio@^1.9.9
|
||||||
earlephilhower/ESP8266SAM@^1.0.1
|
earlephilhower/ESP8266SAM@^1.0.1
|
||||||
|
lewisxhe/SensorLib@0.2.0
|
||||||
|
@ -34,6 +34,7 @@
|
|||||||
#define DAC_I2S_BCK 48
|
#define DAC_I2S_BCK 48
|
||||||
#define DAC_I2S_WS 15
|
#define DAC_I2S_WS 15
|
||||||
#define DAC_I2S_DOUT 46
|
#define DAC_I2S_DOUT 46
|
||||||
|
#define DAC_I2S_MCLK 0
|
||||||
|
|
||||||
#define HAS_AXP2101
|
#define HAS_AXP2101
|
||||||
|
|
||||||
@ -71,3 +72,6 @@
|
|||||||
#define SX126X_DIO3_TCXO_VOLTAGE 1.8
|
#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
|
// Internally the TTGO module hooks the SX1262-DIO2 in to control the TX/RX switch (which is the default for
|
||||||
// the sx1262interface code)
|
// the sx1262interface code)
|
||||||
|
|
||||||
|
#define USE_VIRTUAL_KEYBOARD 1
|
||||||
|
#define DISPLAY_CLOCK_FRAME 1
|
||||||
|
Loading…
Reference in New Issue
Block a user