Compare commits

..

1 Commits

Author SHA1 Message Date
Ben Meadors
c0d8602e7c WIP 2024-09-10 18:25:39 -05:00
23 changed files with 195 additions and 119 deletions

View File

@@ -151,13 +151,10 @@ lib_deps =
ClosedCube OPT3001@^1.1.2
emotibit/EmotiBit MLX90632@^1.0.8
dfrobot/DFRobot_RTU@^1.0.3
https://github.com/boschsensortec/Bosch-BSEC2-Library#v1.7.2502
boschsensortec/BME68x Sensor Library@^1.1.40407
https://github.com/KodinLanewave/INA3221@^1.0.0
lewisxhe/SensorLib@^0.2.0
mprograms/QMC5883LCompass@^1.2.0
https://github.com/meshtastic/DFRobot_LarkWeatherStation#dee914270dc7cb3e43fbf034edd85a63a16a12ee
https://github.com/meshtastic/DFRobot_LarkWeatherStation#dee914270dc7cb3e43fbf034edd85a63a16a12ee
https://github.com/meshtastic/i2c-sensor#8e97122268960593c8c279df1a84a29970136a8f

View File

@@ -52,7 +52,8 @@ class ScanI2C
AHT10,
BMX160,
DFROBOT_LARK,
NAU7802
NAU7802,
CUSTOM_SENSOR,
} DeviceType;
// typedef uint8_t DeviceAddress;

View File

@@ -7,6 +7,7 @@
#include "linux/LinuxHardwareI2C.h"
#endif
#if !defined(ARCH_PORTDUINO) && !defined(ARCH_STM32WL)
#include "I2CDefinitions.h"
#include "main.h" // atecc
#endif
@@ -377,6 +378,7 @@ void ScanI2CTwoWire::scanPort(I2CPort port, uint8_t *address, uint8_t asize)
SCAN_SIMPLE_CASE(OPT3001_ADDR, OPT3001, "OPT3001 light sensor found\n");
SCAN_SIMPLE_CASE(MLX90632_ADDR, MLX90632, "MLX90632 IR temp sensor found\n");
SCAN_SIMPLE_CASE(NAU7802_ADDR, NAU7802, "NAU7802 based scale found\n");
SCAN_SIMPLE_CASE(MT_I2C_ADDRESS, CUSTOM_SENSOR, "Meshtastic custom I2C sensor found\n");
default:
LOG_INFO("Device found at address 0x%x was not able to be enumerated\n", addr.address);

View File

@@ -505,18 +505,18 @@ bool GPS::setup()
delay(250);
_serial_gps->write("$CFGMSG,6,1,0\r\n");
delay(250);
} else if (gnssModel == GNSS_MODEL_AG3335 || gnssModel == GNSS_MODEL_AG3352) {
} else if (gnssModel == GNSS_MODEL_AG3335) {
_serial_gps->write("$PAIR066,1,0,1,0,0,1*3B\r\n"); // Enable GPS+GALILEO+NAVIC
// Configure NMEA (sentences will output once per fix)
_serial_gps->write("$PAIR062,0,1*3F\r\n"); // GGA ON
_serial_gps->write("$PAIR062,0,0*3F\r\n"); // GGA ON
_serial_gps->write("$PAIR062,1,0*3F\r\n"); // GLL OFF
_serial_gps->write("$PAIR062,2,0*3C\r\n"); // GSA OFF
_serial_gps->write("$PAIR062,2,1*3D\r\n"); // GSA ON
_serial_gps->write("$PAIR062,3,0*3D\r\n"); // GSV OFF
_serial_gps->write("$PAIR062,4,1*3B\r\n"); // RMC ON
_serial_gps->write("$PAIR062,4,0*3B\r\n"); // RMC ON
_serial_gps->write("$PAIR062,5,0*3B\r\n"); // VTG OFF
_serial_gps->write("$PAIR062,6,0*38\r\n"); // ZDA ON
_serial_gps->write("$PAIR062,6,1*39\r\n"); // ZDA ON
delay(250);
_serial_gps->write("$PAIR513*3D\r\n"); // save configuration
@@ -1204,6 +1204,9 @@ GnssModel_t GPS::probe(int serialSpeed)
_serial_gps->updateBaudRate(serialSpeed);
}
#endif
#ifdef GNSS_AIROHA
return GNSS_MODEL_AG3335;
#endif
memset(&info, 0, sizeof(struct uBloxGnssModelInfo));
uint8_t buffer[768] = {0};
@@ -1222,12 +1225,7 @@ GnssModel_t GPS::probe(int serialSpeed)
PROBE_SIMPLE("ATGM332D", "$PCAS06,1*1A", "$GPTXT,01,01,02,HW=ATGM332D", GNSS_MODEL_ATGM336H, 500);
/* Airoha (Mediatek) AG3335A/M/S, A3352Q, Quectel L89 2.0, SimCom SIM65M */
_serial_gps->write("$PAIR062,2,0*3C\r\n"); // GSA OFF to reduce volume
_serial_gps->write("$PAIR062,3,0*3D\r\n"); // GSV OFF to reduce volume
_serial_gps->write("$PAIR513*3D\r\n"); // save configuration
PROBE_SIMPLE("AG3335", "$PAIR021*39", "$PAIR021,AG3335", GNSS_MODEL_AG3335, 500);
PROBE_SIMPLE("AG3352", "$PAIR021*39", "$PAIR021,AG3352", GNSS_MODEL_AG3352, 500);
PROBE_SIMPLE("LC86", "$PQTMVERNO*58", "$PQTMVERNO,LC86", GNSS_MODEL_AG3352, 500);
PROBE_SIMPLE("AG3335", "PAIR020*38", "$PAIR020,AG3335", GNSS_MODEL_AG3335, 500);
PROBE_SIMPLE("L76K", "$PCAS06,0*1B", "$GPTXT,01,01,02,SW=", GNSS_MODEL_MTK, 500);
@@ -1804,4 +1802,4 @@ void GPS::toggleGpsMode()
enable();
}
}
#endif // Exclude GPS
#endif // Exclude GPS

View File

@@ -30,8 +30,7 @@ typedef enum {
GNSS_MODEL_UC6580,
GNSS_MODEL_UNKNOWN,
GNSS_MODEL_MTK_L76B,
GNSS_MODEL_AG3335,
GNSS_MODEL_AG3352
GNSS_MODEL_AG3335
} GnssModel_t;
typedef enum {

View File

@@ -43,10 +43,7 @@ void readFromRTC()
t.tm_sec = rtc.getSecond();
tv.tv_sec = gm_mktime(&t);
tv.tv_usec = 0;
uint32_t printableEpoch = tv.tv_sec; // Print lib only supports 32 bit but time_t can be 64 bit on some platforms
LOG_DEBUG("Read RTC time from RV3028 getTime as %02d-%02d-%02d %02d:%02d:%02d (%ld)\n", t.tm_year + 1900, t.tm_mon + 1,
t.tm_mday, t.tm_hour, t.tm_min, t.tm_sec, printableEpoch);
LOG_DEBUG("Read RTC time from RV3028 as %ld\n", tv.tv_sec);
timeStartMsec = now;
zeroOffsetSecs = tv.tv_sec;
if (currentQuality == RTCQualityNone) {
@@ -74,10 +71,7 @@ void readFromRTC()
t.tm_sec = tc.second;
tv.tv_sec = gm_mktime(&t);
tv.tv_usec = 0;
uint32_t printableEpoch = tv.tv_sec; // Print lib only supports 32 bit but time_t can be 64 bit on some platforms
LOG_DEBUG("Read RTC time from PCF8563 getDateTime as %02d-%02d-%02d %02d:%02d:%02d (%ld)\n", t.tm_year + 1900,
t.tm_mon + 1, t.tm_mday, t.tm_hour, t.tm_min, t.tm_sec, printableEpoch);
LOG_DEBUG("Read RTC time from PCF8563 as %ld\n", tv.tv_sec);
timeStartMsec = now;
zeroOffsetSecs = tv.tv_sec;
if (currentQuality == RTCQualityNone) {
@@ -87,8 +81,7 @@ void readFromRTC()
#else
if (!gettimeofday(&tv, NULL)) {
uint32_t now = millis();
uint32_t printableEpoch = tv.tv_sec; // Print lib only supports 32 bit but time_t can be 64 bit on some platforms
LOG_DEBUG("Read RTC time as %ld\n", printableEpoch);
LOG_DEBUG("Read RTC time as %ld\n", tv.tv_sec);
timeStartMsec = now;
zeroOffsetSecs = tv.tv_sec;
}
@@ -108,7 +101,6 @@ bool perhapsSetRTC(RTCQuality q, const struct timeval *tv, bool forceUpdate)
{
static uint32_t lastSetMsec = 0;
uint32_t now = millis();
uint32_t printableEpoch = tv->tv_sec; // Print lib only supports 32 bit but time_t can be 64 bit on some platforms
bool shouldSet;
if (forceUpdate) {
@@ -121,7 +113,7 @@ bool perhapsSetRTC(RTCQuality q, const struct timeval *tv, bool forceUpdate)
} else if (q >= RTCQualityNTP && (now - lastSetMsec) > (12 * 60 * 60 * 1000UL)) {
// Every 12 hrs we will slam in a new GPS or Phone GPS / NTP time, to correct for local RTC clock drift
shouldSet = true;
LOG_DEBUG("Reapplying external time to correct clock drift %ld secs\n", printableEpoch);
LOG_DEBUG("Reapplying external time to correct clock drift %ld secs\n", tv->tv_sec);
} else {
shouldSet = false;
LOG_DEBUG("Current RTC quality: %s. Ignoring time of RTC quality of %s\n", RtcName(currentQuality), RtcName(q));
@@ -148,8 +140,8 @@ bool perhapsSetRTC(RTCQuality q, const struct timeval *tv, bool forceUpdate)
#endif
tm *t = gmtime(&tv->tv_sec);
rtc.setTime(t->tm_year + 1900, t->tm_mon + 1, t->tm_wday, t->tm_mday, t->tm_hour, t->tm_min, t->tm_sec);
LOG_DEBUG("RV3028_RTC setTime %02d-%02d-%02d %02d:%02d:%02d (%ld)\n", t->tm_year + 1900, t->tm_mon + 1, t->tm_mday,
t->tm_hour, t->tm_min, t->tm_sec, printableEpoch);
LOG_DEBUG("RV3028_RTC setTime %02d-%02d-%02d %02d:%02d:%02d %ld\n", t->tm_year + 1900, t->tm_mon + 1, t->tm_mday,
t->tm_hour, t->tm_min, t->tm_sec, tv->tv_sec);
}
#elif defined(PCF8563_RTC)
if (rtc_found.address == PCF8563_RTC) {
@@ -162,8 +154,8 @@ bool perhapsSetRTC(RTCQuality q, const struct timeval *tv, bool forceUpdate)
#endif
tm *t = gmtime(&tv->tv_sec);
rtc.setDateTime(t->tm_year + 1900, t->tm_mon + 1, t->tm_mday, t->tm_hour, t->tm_min, t->tm_sec);
LOG_DEBUG("PCF8563_RTC setDateTime %02d-%02d-%02d %02d:%02d:%02d (%ld)\n", t->tm_year + 1900, t->tm_mon + 1,
t->tm_mday, t->tm_hour, t->tm_min, t->tm_sec, printableEpoch);
LOG_DEBUG("PCF8563_RTC setDateTime %02d-%02d-%02d %02d:%02d:%02d %ld\n", t->tm_year + 1900, t->tm_mon + 1, t->tm_mday,
t->tm_hour, t->tm_min, t->tm_sec, tv->tv_sec);
}
#elif defined(ARCH_ESP32)
settimeofday(tv, NULL);
@@ -280,4 +272,4 @@ time_t gm_mktime(struct tm *tm)
#else
return mktime(tm);
#endif
}
}

View File

@@ -9,7 +9,7 @@ CardKbI2cImpl::CardKbI2cImpl() : KbI2cBase("cardKB") {}
void CardKbI2cImpl::init()
{
#if !MESHTASTIC_EXCLUDE_I2C && !defined(ARCH_PORTDUINO)
#ifndef ARCH_PORTDUINO
if (cardkb_found.address == 0x00) {
LOG_DEBUG("Rescanning for I2C keyboard\n");
uint8_t i2caddr_scan[] = {CARDKB_ADDR, TDECK_KB_ADDR, BBQ10_KB_ADDR};
@@ -57,4 +57,4 @@ void CardKbI2cImpl::init()
}
#endif
inputBroker->registerSource(this);
}
}

View File

@@ -569,6 +569,7 @@ void setup()
SCANNER_TO_SENSORS_MAP(ScanI2C::DeviceType::SHT4X, meshtastic_TelemetrySensorType_SHT4X)
SCANNER_TO_SENSORS_MAP(ScanI2C::DeviceType::AHT10, meshtastic_TelemetrySensorType_AHT10)
SCANNER_TO_SENSORS_MAP(ScanI2C::DeviceType::DFROBOT_LARK, meshtastic_TelemetrySensorType_DFROBOT_LARK)
SCANNER_TO_SENSORS_MAP(ScanI2C::DeviceType::CUSTOM_SENSOR, meshtastic_TelemetrySensorType_CUSTOM_SENSOR)
i2cScanner.reset();
#endif

View File

@@ -121,8 +121,6 @@ NodeDB::NodeDB()
owner.hw_model = HW_VENDOR;
// Ensure user (nodeinfo) role is set to whatever we're configured to
owner.role = config.device.role;
// Ensure macaddr is set to our macaddr as it will be copied in our info below
memcpy(owner.macaddr, ourMacAddr, sizeof(owner.macaddr));
// Include our owner in the node db under our nodenum
meshtastic_NodeInfoLite *info = getOrCreateMeshNode(getNodeNum());
@@ -245,7 +243,7 @@ bool NodeDB::factoryReset(bool eraseBleBonds)
#endif
// second, install default state (this will deal with the duplicate mac address issue)
installDefaultDeviceState();
installDefaultConfig(!eraseBleBonds); // Also preserve the private key if we're not erasing BLE bonds
installDefaultConfig();
installDefaultModuleConfig();
installDefaultChannels();
// third, write everything to disk
@@ -268,13 +266,8 @@ bool NodeDB::factoryReset(bool eraseBleBonds)
return true;
}
void NodeDB::installDefaultConfig(bool preserveKey = false)
void NodeDB::installDefaultConfig()
{
uint8_t private_key_temp[32];
bool shouldPreserveKey = preserveKey && config.has_security && config.security.private_key.size > 0;
if (shouldPreserveKey) {
memcpy(private_key_temp, config.security.private_key.bytes, config.security.private_key.size);
}
LOG_INFO("Installing default LocalConfig\n");
memset(&config, 0, sizeof(meshtastic_LocalConfig));
config.version = DEVICESTATE_CUR_VER;
@@ -315,14 +308,8 @@ void NodeDB::installDefaultConfig(bool preserveKey = false)
#else
config.security.admin_key[0].size = 0;
#endif
if (shouldPreserveKey) {
config.security.private_key.size = 32;
memcpy(config.security.private_key.bytes, private_key_temp, config.security.private_key.size);
printBytes("Restored key", config.security.private_key.bytes, config.security.private_key.size);
} else {
config.security.private_key.size = 0;
}
config.security.public_key.size = 0;
config.security.private_key.size = 0;
#ifdef PIN_GPS_EN
config.position.gps_en_gpio = PIN_GPS_EN;
#endif
@@ -657,9 +644,7 @@ void NodeDB::pickNewNodeNum()
while ((nodeNum == NODENUM_BROADCAST || nodeNum < NUM_RESERVED) ||
((found = getMeshNode(nodeNum)) && memcmp(found->user.macaddr, ourMacAddr, sizeof(ourMacAddr)) != 0)) {
NodeNum candidate = random(NUM_RESERVED, LONG_MAX); // try a new random choice
LOG_WARN("NOTE! Our desired nodenum 0x%x is invalid or in use, by MAC ending in 0x%02x%02x vs our 0x%02x%02x, so "
"trying for 0x%x\n",
nodeNum, found->user.macaddr[4], found->user.macaddr[5], ourMacAddr[4], ourMacAddr[5], candidate);
LOG_WARN("NOTE! Our desired nodenum 0x%x is invalid or in use, so trying for 0x%x\n", nodeNum, candidate);
nodeNum = candidate;
}
LOG_DEBUG("Using nodenum 0x%x \n", nodeNum);
@@ -725,7 +710,7 @@ void NodeDB::loadFromDisk()
//} else {
if (devicestate.version < DEVICESTATE_MIN_VER) {
LOG_WARN("Devicestate %d is old, discarding\n", devicestate.version);
installDefaultDeviceState();
factoryReset();
} else {
LOG_INFO("Loaded saved devicestate version %d, with nodecount: %d\n", devicestate.version,
devicestate.node_db_lite.size());
@@ -741,7 +726,7 @@ void NodeDB::loadFromDisk()
} else {
if (config.version < DEVICESTATE_MIN_VER) {
LOG_WARN("config %d is old, discarding\n", config.version);
installDefaultConfig(true);
installDefaultConfig();
} else {
LOG_INFO("Loaded saved config version %d\n", config.version);
}
@@ -1054,7 +1039,7 @@ bool NodeDB::updateUser(uint32_t nodeId, meshtastic_User &p, uint8_t channelInde
if (p.public_key.size > 0) {
printBytes("Incoming Pubkey: ", p.public_key.bytes, 32);
if (info->user.public_key.size > 0) { // if we have a key for this user already, don't overwrite with a new one
LOG_INFO("Public Key set for node, not updating!\n");
LOG_INFO("Public Key set for node, not updateing!\n");
// we copy the key into the incoming packet, to prevent overwrite
memcpy(p.public_key.bytes, info->user.public_key.bytes, 32);
} else {
@@ -1209,4 +1194,4 @@ void recordCriticalError(meshtastic_CriticalErrorCode code, uint32_t address, co
LOG_ERROR("A critical failure occurred, portduino is exiting...");
exit(2);
#endif
}
}

View File

@@ -182,8 +182,7 @@ class NodeDB
void cleanupMeshDB();
/// Reinit device state from scratch (not loading from disk)
void installDefaultDeviceState(), installDefaultChannels(), installDefaultConfig(bool preserveKey),
installDefaultModuleConfig();
void installDefaultDeviceState(), installDefaultChannels(), installDefaultConfig(), installDefaultModuleConfig();
/// write to flash
/// @return true if the save was successful

View File

@@ -78,7 +78,7 @@ meshtastic_UserLite TypeConversions::ConvertToUserLite(meshtastic_User user)
lite.hw_model = user.hw_model;
lite.role = user.role;
lite.is_licensed = user.is_licensed;
memcpy(lite.macaddr, user.macaddr, sizeof(lite.macaddr));
memccpy(lite.macaddr, user.macaddr, sizeof(user.macaddr), sizeof(lite.macaddr));
memcpy(lite.public_key.bytes, user.public_key.bytes, sizeof(lite.public_key.bytes));
lite.public_key.size = user.public_key.size;
return lite;
@@ -94,7 +94,7 @@ meshtastic_User TypeConversions::ConvertToUser(uint32_t nodeNum, meshtastic_User
user.hw_model = lite.hw_model;
user.role = lite.role;
user.is_licensed = lite.is_licensed;
memcpy(user.macaddr, lite.macaddr, sizeof(user.macaddr));
memccpy(user.macaddr, lite.macaddr, sizeof(lite.macaddr), sizeof(user.macaddr));
memcpy(user.public_key.bytes, lite.public_key.bytes, sizeof(user.public_key.bytes));
user.public_key.size = lite.public_key.size;

View File

@@ -186,22 +186,18 @@ bool AdminModule::handleReceivedProtobuf(const meshtastic_MeshPacket &mp, meshta
break;
}
case meshtastic_AdminMessage_factory_reset_config_tag: {
disableBluetooth();
LOG_INFO("Initiating factory config reset\n");
nodeDB->factoryReset();
LOG_INFO("Factory config reset finished, rebooting soon.\n");
reboot(DEFAULT_REBOOT_SECONDS);
break;
}
case meshtastic_AdminMessage_factory_reset_device_tag: {
disableBluetooth();
LOG_INFO("Initiating full factory reset\n");
nodeDB->factoryReset(true);
reboot(DEFAULT_REBOOT_SECONDS);
break;
}
case meshtastic_AdminMessage_nodedb_reset_tag: {
disableBluetooth();
LOG_INFO("Initiating node-db reset\n");
nodeDB->resetNodes();
reboot(DEFAULT_REBOOT_SECONDS);
@@ -213,7 +209,6 @@ bool AdminModule::handleReceivedProtobuf(const meshtastic_MeshPacket &mp, meshta
break;
}
case meshtastic_AdminMessage_commit_edit_settings_tag: {
disableBluetooth();
LOG_INFO("Committing transaction for edited settings\n");
hasOpenEditTransaction = false;
saveChanges(SEGMENT_CONFIG | SEGMENT_MODULECONFIG | SEGMENT_DEVICESTATE | SEGMENT_CHANNELS);
@@ -564,16 +559,12 @@ void AdminModule::handleSetConfig(const meshtastic_Config &c)
break;
}
if (requiresReboot) {
disableBluetooth();
}
saveChanges(changes, requiresReboot);
}
void AdminModule::handleSetModuleConfig(const meshtastic_ModuleConfig &c)
{
disableBluetooth();
switch (c.which_payload_variant) {
case meshtastic_ModuleConfig_mqtt_tag:
LOG_INFO("Setting module config: MQTT\n");
@@ -645,6 +636,7 @@ void AdminModule::handleSetModuleConfig(const meshtastic_ModuleConfig &c)
moduleConfig.paxcounter = c.payload_variant.paxcounter;
break;
}
saveChanges(SEGMENT_MODULECONFIG);
}
@@ -1039,16 +1031,3 @@ bool AdminModule::messageIsRequest(meshtastic_AdminMessage *r)
else
return false;
}
void disableBluetooth()
{
#if HAS_BLUETOOTH
#ifdef ARCH_ESP32
if (nimbleBluetooth)
nimbleBluetooth->deinit();
#elif defined(ARCH_NRF52)
if (nrf52Bluetooth)
nrf52Bluetooth->shutdown();
#endif
#endif
}

View File

@@ -59,6 +59,4 @@ class AdminModule : public ProtobufModule<meshtastic_AdminMessage>, public Obser
bool messageIsRequest(meshtastic_AdminMessage *r);
};
extern AdminModule *adminModule;
void disableBluetooth();
extern AdminModule *adminModule;

View File

@@ -63,7 +63,7 @@ class PositionModule : public ProtobufModule<meshtastic_Position>, private concu
bool hasQualityTimesource();
const uint32_t minimumTimeThreshold =
Default::getConfiguredOrDefaultMs(config.position.broadcast_smart_minimum_interval_secs, 30);
Default::getConfiguredOrDefaultMsScaled(config.position.broadcast_smart_minimum_interval_secs, 30, numOnlineNodes);
};
struct SmartPosition {

View File

@@ -24,6 +24,7 @@
#include "Sensor/BMP085Sensor.h"
#include "Sensor/BMP280Sensor.h"
#include "Sensor/BMP3XXSensor.h"
#include "Sensor/CustomI2CSensor.h"
#include "Sensor/DFRobotLarkSensor.h"
#include "Sensor/LPS22HBSensor.h"
#include "Sensor/MCP9808Sensor.h"
@@ -56,6 +57,7 @@ MLX90632Sensor mlx90632Sensor;
DFRobotLarkSensor dfRobotLarkSensor;
NAU7802Sensor nau7802Sensor;
BMP3XXSensor bmp3xxSensor;
CustomI2CSensor customI2CSensor;
#ifdef T1000X_SENSOR_EN
T1000xSensor t1000xSensor;
#endif
@@ -82,7 +84,7 @@ int32_t EnvironmentTelemetryModule::runOnce()
*/
// moduleConfig.telemetry.environment_measurement_enabled = 1;
// moduleConfig.telemetry.environment_screen_enabled = 1;
// moduleConfig.telemetry.environment_screen_enabled = 1;
// moduleConfig.telemetry.environment_update_interval = 15;
if (!(moduleConfig.telemetry.environment_measurement_enabled || moduleConfig.telemetry.environment_screen_enabled)) {
@@ -143,6 +145,8 @@ int32_t EnvironmentTelemetryModule::runOnce()
result = mlx90632Sensor.runOnce();
if (nau7802Sensor.hasSensor())
result = nau7802Sensor.runOnce();
if (customI2CSensor.hasSensor())
result = customI2CSensor.runOnce();
#endif
}
return result;
@@ -397,6 +401,10 @@ bool EnvironmentTelemetryModule::getEnvironmentTelemetry(meshtastic_Telemetry *m
m->variant.environment_metrics.relative_humidity = m_ahtx.variant.environment_metrics.relative_humidity;
}
}
if (customI2CSensor.hasSensor()) {
valid = valid && customI2CSensor.getMetrics(m);
hasSensor = true;
}
#endif
return valid && hasSensor;

View File

@@ -0,0 +1,107 @@
#include "configuration.h"
#if !MESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR
#include "../mesh/generated/meshtastic/telemetry.pb.h"
#include "CustomI2CSensor.h"
#include "I2CClient.h"
#include "I2CDefinitions.h"
#include "TelemetrySensor.h"
CustomI2CSensor::CustomI2CSensor() : TelemetrySensor(meshtastic_TelemetrySensorType_CUSTOM_SENSOR, "CUSTOM") {}
int32_t CustomI2CSensor::runOnce()
{
LOG_INFO("Init sensor: %s\n", sensorName);
if (!hasSensor()) {
return DEFAULT_SENSOR_MINIMUM_WAIT_TIME_BETWEEN_READS;
} else {
status = 1;
}
return initI2CSensor();
}
void CustomI2CSensor::setup()
{
// populates lastMetricsRecieved when data is received
Wire.requestFrom(MT_I2C_ADDRESS, meshtastic_EnvironmentMetrics_size);
Wire.onReceive(onReceiveMetrics);
}
bool CustomI2CSensor::getMetrics(meshtastic_Telemetry *measurement)
{
// Wire.requestFrom(MT_I2C_ADDRESS, meshtastic_EnvironmentMetrics_size);
// auto length = Wire.available();
// LOG_DEBUG("CustomI2CSensor::getMetrics=%d\n", length);
// uint8_t buffer[meshtastic_EnvironmentMetrics_size];
// Wire.readBytes(buffer, length);
// meshtastic_EnvironmentMetrics metrics = meshtastic_EnvironmentMetrics_init_zero;
// proto_decode(buffer, meshtastic_EnvironmentMetrics_size, meshtastic_EnvironmentMetrics_fields, &metrics);
measurement->which_variant = meshtastic_Telemetry_environment_metrics_tag;
if (lastMetricsRecieved.has_temperature) {
measurement->variant.environment_metrics.has_temperature = true;
measurement->variant.environment_metrics.temperature = lastMetricsRecieved.temperature;
}
if (lastMetricsRecieved.has_relative_humidity) {
measurement->variant.environment_metrics.has_relative_humidity = true;
measurement->variant.environment_metrics.relative_humidity = lastMetricsRecieved.relative_humidity;
}
if (lastMetricsRecieved.has_barometric_pressure) {
measurement->variant.environment_metrics.has_barometric_pressure = true;
measurement->variant.environment_metrics.barometric_pressure = lastMetricsRecieved.barometric_pressure;
}
if (lastMetricsRecieved.has_gas_resistance) {
measurement->variant.environment_metrics.has_gas_resistance = true;
measurement->variant.environment_metrics.gas_resistance = lastMetricsRecieved.gas_resistance;
}
if (lastMetricsRecieved.has_iaq) {
measurement->variant.environment_metrics.has_iaq = true;
measurement->variant.environment_metrics.iaq = lastMetricsRecieved.iaq;
}
if (lastMetricsRecieved.has_voltage) {
measurement->variant.environment_metrics.has_voltage = true;
measurement->variant.environment_metrics.voltage = lastMetricsRecieved.voltage;
}
if (lastMetricsRecieved.has_current) {
measurement->variant.environment_metrics.has_current = true;
measurement->variant.environment_metrics.current = lastMetricsRecieved.current;
}
if (lastMetricsRecieved.has_distance) {
measurement->variant.environment_metrics.has_distance = true;
measurement->variant.environment_metrics.distance = lastMetricsRecieved.distance;
}
if (lastMetricsRecieved.has_lux) {
measurement->variant.environment_metrics.has_lux = true;
measurement->variant.environment_metrics.lux = lastMetricsRecieved.lux;
}
if (lastMetricsRecieved.has_white_lux) {
measurement->variant.environment_metrics.has_white_lux = true;
measurement->variant.environment_metrics.white_lux = lastMetricsRecieved.white_lux;
}
if (lastMetricsRecieved.has_ir_lux) {
measurement->variant.environment_metrics.has_ir_lux = true;
measurement->variant.environment_metrics.ir_lux = lastMetricsRecieved.ir_lux;
}
if (lastMetricsRecieved.has_uv_lux) {
measurement->variant.environment_metrics.has_uv_lux = true;
measurement->variant.environment_metrics.uv_lux = lastMetricsRecieved.uv_lux;
}
if (lastMetricsRecieved.has_wind_direction) {
measurement->variant.environment_metrics.has_wind_direction = true;
measurement->variant.environment_metrics.wind_direction = lastMetricsRecieved.wind_direction;
}
if (lastMetricsRecieved.has_wind_speed) {
measurement->variant.environment_metrics.has_wind_speed = true;
measurement->variant.environment_metrics.wind_speed = lastMetricsRecieved.wind_speed;
}
if (lastMetricsRecieved.has_wind_lull) {
measurement->variant.environment_metrics.has_wind_lull = true;
measurement->variant.environment_metrics.wind_lull = lastMetricsRecieved.wind_lull;
}
return true;
}
#endif

View File

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

View File

@@ -95,7 +95,7 @@ float T1000xSensor::getTemp()
Vout = ntc_vot;
Rt = (HEATER_NTC_RP * vcc_vot) / Vout - HEATER_NTC_RP;
for (u8i = 0; u8i < 135; u8i++) {
for (u8i = 0; u8i < 136; u8i++) {
if (Rt >= ntc_res2[u8i]) {
break;
}

View File

@@ -53,7 +53,7 @@ void TraceRouteModule::insertUnknownHops(meshtastic_MeshPacket &p, meshtastic_Ro
uint8_t hopsTaken = p.hop_start - p.hop_limit;
int8_t diff = hopsTaken - *route_count;
for (uint8_t i = 0; i < diff; i++) {
if (*route_count < ROUTE_SIZE) {
if (*route_count < sizeof(*route) / sizeof(route[0])) {
route[*route_count] = NODENUM_BROADCAST; // This will represent an unknown hop
*route_count += 1;
}
@@ -61,7 +61,7 @@ void TraceRouteModule::insertUnknownHops(meshtastic_MeshPacket &p, meshtastic_Ro
// Add unknown SNR values if necessary
diff = *route_count - *snr_count;
for (uint8_t i = 0; i < diff; i++) {
if (*snr_count < ROUTE_SIZE) {
if (*snr_count < sizeof(*snr_list) / sizeof(snr_list[0])) {
snr_list[*snr_count] = INT8_MIN; // This will represent an unknown SNR
*snr_count += 1;
}
@@ -89,7 +89,7 @@ void TraceRouteModule::appendMyIDandSNR(meshtastic_RouteDiscovery *updated, floa
snr_list = updated->snr_back;
}
if (*snr_count < ROUTE_SIZE) {
if (*snr_count < sizeof(*snr_list) / sizeof(snr_list[0])) {
snr_list[*snr_count] = (int8_t)(snr * 4); // Convert SNR to 1 byte
*snr_count += 1;
}
@@ -97,7 +97,7 @@ void TraceRouteModule::appendMyIDandSNR(meshtastic_RouteDiscovery *updated, floa
return;
// Length of route array can normally not be exceeded due to the max. hop_limit of 7
if (*route_count < ROUTE_SIZE) {
if (*route_count < sizeof(*route) / sizeof(route[0])) {
route[*route_count] = myNodeInfo.my_node_num;
*route_count += 1;
} else {

View File

@@ -1,8 +1,6 @@
#pragma once
#include "ProtobufModule.h"
#define ROUTE_SIZE sizeof(((meshtastic_RouteDiscovery *)0)->route) / sizeof(((meshtastic_RouteDiscovery *)0)->route[0])
/**
* A module that traces the route to a certain destination node
*/

View File

@@ -10,14 +10,10 @@
void lateInitVariant()
{
// LOG_DEBUG("Heltec tracker initVariant\n");
#ifndef MESHTASTIC_EXCLUDE_GPS
#ifdef VEXT_ENABLE
GpioPin *hwEnable = new GpioHwPin(VEXT_ENABLE);
GpioVirtPin *virtGpsEnable = gps ? gps->enablePin : new GpioVirtPin();
#else
GpioVirtPin *virtGpsEnable = new GpioVirtPin();
#endif
#ifndef MESHTASTIC_EXCLUDE_SCREEN
// On this board we are actually using the backlightEnable signal to already be controlling a physical enable to the
// display controller. But we'd _ALSO_ like to have that signal drive a virtual GPIO. So nest it as needed.
GpioVirtPin *virtScreenEnable = new GpioVirtPin();
@@ -29,11 +25,8 @@ void lateInitVariant()
// Assume screen is initially powered
splitter->set(true);
}
#endif
#if defined(VEXT_ENABLE) && (!defined(MESHTASTIC_EXCLUDE_GPS) || !defined(MESHTASTIC_EXCLUDE_SCREEN))
// If either the GPS or the screen is on, turn on the external power regulator
GpioPin *hwEnable = new GpioHwPin(VEXT_ENABLE);
new GpioBinaryTransformer(virtGpsEnable, virtScreenEnable, hwEnable, GpioBinaryTransformer::Or);
#endif
}

View File

@@ -40,15 +40,15 @@ class JSONValue
public:
JSONValue(/*NULL*/);
explicit JSONValue(const char *m_char_value);
explicit JSONValue(const std::string &m_string_value);
explicit JSONValue(bool m_bool_value);
explicit JSONValue(double m_number_value);
explicit JSONValue(int m_integer_value);
explicit JSONValue(unsigned int m_integer_value);
explicit JSONValue(const JSONArray &m_array_value);
explicit JSONValue(const JSONObject &m_object_value);
explicit JSONValue(const JSONValue &m_source);
JSONValue(const char *m_char_value);
JSONValue(const std::string &m_string_value);
JSONValue(bool m_bool_value);
JSONValue(double m_number_value);
JSONValue(int m_integer_value);
JSONValue(unsigned int m_integer_value);
JSONValue(const JSONArray &m_array_value);
JSONValue(const JSONObject &m_object_value);
JSONValue(const JSONValue &m_source);
~JSONValue();
bool IsNull() const;

View File

@@ -1,4 +1,4 @@
[VERSION]
major = 2
minor = 5
build = 0
build = 1