Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 25 additions & 12 deletions src/modules/AdminModule.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -786,6 +786,27 @@ void AdminModule::handleSetOwner(const meshtastic_User &o)
}
}

#if !defined(ARCH_PORTDUINO) && !defined(ARCH_STM32WL) && !MESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR && \
!MESHTASTIC_EXCLUDE_ACCELEROMETER
// Shared by double-tap-as-button (device) and wake-on-motion (display). Start on either flag's
// off->on edge; stop on the on->off edge once neither needs it (disable() clears `enabled` so a
// later re-enable restarts). Skip the stop if the sensor also drives the compass, else the heading
// freezes until reboot. wasOn/nowOn = old/new of the changed flag; otherFeatureOn = the other flag.
static void reconcileAccelerometerThread(bool wasOn, bool nowOn, bool otherFeatureOn)
{
if (!accelerometerThread) // null unless a sensor was detected at boot
return;

if (!wasOn && nowOn && accelerometerThread->enabled == false) {
accelerometerThread->enabled = true;
accelerometerThread->start();
} else if (wasOn && !nowOn && !otherFeatureOn && accelerometerThread->enabled == true &&
!accelerometerThread->providesHeading()) {
accelerometerThread->disable();
}
}
#endif

void AdminModule::handleSetConfig(const meshtastic_Config &c, bool fromOthers)
{
auto changes = SEGMENT_CONFIG;
Expand All @@ -801,12 +822,8 @@ void AdminModule::handleSetConfig(const meshtastic_Config &c, bool fromOthers)
config.has_device = true;
#if !defined(ARCH_PORTDUINO) && !defined(ARCH_STM32WL) && !MESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR && \
!MESHTASTIC_EXCLUDE_ACCELEROMETER
if (config.device.double_tap_as_button_press == false && c.payload_variant.device.double_tap_as_button_press == true &&
accelerometerThread->enabled == false) {
config.device.double_tap_as_button_press = c.payload_variant.device.double_tap_as_button_press;
accelerometerThread->enabled = true;
accelerometerThread->start();
}
reconcileAccelerometerThread(config.device.double_tap_as_button_press,
c.payload_variant.device.double_tap_as_button_press, config.display.wake_on_tap_or_motion);
#endif
if (config.device.button_gpio == c.payload_variant.device.button_gpio &&
config.device.buzzer_gpio == c.payload_variant.device.buzzer_gpio &&
Expand Down Expand Up @@ -905,12 +922,8 @@ void AdminModule::handleSetConfig(const meshtastic_Config &c, bool fromOthers)
}
#if !defined(ARCH_PORTDUINO) && !defined(ARCH_STM32WL) && !MESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR && \
!MESHTASTIC_EXCLUDE_ACCELEROMETER
if (config.display.wake_on_tap_or_motion == false && c.payload_variant.display.wake_on_tap_or_motion == true &&
accelerometerThread->enabled == false) {
config.display.wake_on_tap_or_motion = c.payload_variant.display.wake_on_tap_or_motion;
accelerometerThread->enabled = true;
accelerometerThread->start();
}
reconcileAccelerometerThread(config.display.wake_on_tap_or_motion, c.payload_variant.display.wake_on_tap_or_motion,
config.device.double_tap_as_button_press);
#endif
config.display = c.payload_variant.display;
break;
Expand Down
4 changes: 4 additions & 0 deletions src/motion/AccelerometerThread.h
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,10 @@ class AccelerometerThread : public concurrency::OSThread
}
}

// True if the active sensor drives the compass heading in runOnce(). Callers must not
// disable() the thread in this case, or the compass would freeze until the next reboot.
bool providesHeading() const { return isInitialised && sensor && sensor->providesHeading(); }

protected:
int32_t runOnce() override
{
Expand Down
1 change: 1 addition & 0 deletions src/motion/BMM150Sensor.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ class BMM150Sensor : public MotionSensor

// Called each time our sensor gets a chance to run
virtual int32_t runOnce() override;
virtual bool providesHeading() const override { return true; }
};

#endif
Expand Down
1 change: 1 addition & 0 deletions src/motion/BMX160Sensor.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ class BMX160Sensor : public MotionSensor
virtual bool init() override;
virtual int32_t runOnce() override;
virtual void calibrate(uint16_t forSeconds) override;
virtual bool providesHeading() const override { return true; }
};

#else
Expand Down
1 change: 1 addition & 0 deletions src/motion/ICM20948Sensor.h
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,7 @@ class ICM20948Sensor : public MotionSensor
// Called each time our sensor gets a chance to run
virtual int32_t runOnce() override;
virtual void calibrate(uint16_t forSeconds) override;
virtual bool providesHeading() const override { return true; }
};

#endif
Expand Down
6 changes: 6 additions & 0 deletions src/motion/MotionSensor.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,12 @@ class MotionSensor

virtual void calibrate(uint16_t forSeconds){};

// True if this sensor produces the compass heading (screen->setHeading()) in runOnce().
// Combined accel+magnetometer parts (e.g. BMX160, ICM20948) and standalone magnetometers
// handled by the accelerometer thread (e.g. BMM150) override this. Used to avoid halting
// the thread - and freezing the compass - when motion-only features are disabled at runtime.
inline virtual bool providesHeading() const { return false; };
Comment thread
thebentern marked this conversation as resolved.

protected:
// Turn on the screen when a tap or motion is detected
virtual void wakeScreen();
Expand Down
Loading