Files
firmware/src/motion/BMM150Sensor.cpp
T
HarukiToredaandCopilot aab4cd086f Compass improvements/refactoring (#10166)
* Infinite calibration loop fix

* Save calibration

* Screen refresh

* reduce repeated code

* reduce repeated code to reduce flash

* fix Waypoint compass size and no fix no heading labels

* Don't show compass unless we have a heading and location

* If no calculated heading from moving, we should have no heading

* Slow walking calculated heading and auto stale heading when not moving

* Triming flash space

* cleanup

* show "?" when no location or heading for distance and heading screen

* cleanup

* Stale heading logic

* final trim

* Compass Calibration screen redesign

* Trunk Fix

* Compile fix

* patch

* Update src/motion/MotionSensor.cpp

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* Update WaypointModule.cpp

---------

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2026-04-18 06:53:22 -05:00

74 lines
2.2 KiB
C++

#include "BMM150Sensor.h"
#if !defined(ARCH_STM32WL) && !MESHTASTIC_EXCLUDE_I2C && __has_include(<DFRobot_BMM150.h>)
#if !defined(MESHTASTIC_EXCLUDE_SCREEN)
// screen is defined in main.cpp
extern graphics::Screen *screen;
#endif
BMM150Sensor::BMM150Sensor(ScanI2C::FoundDevice foundDevice) : MotionSensor::MotionSensor(foundDevice) {}
bool BMM150Sensor::init()
{
// Initialise the sensor
sensor = BMM150Singleton::GetInstance(device);
return sensor->init(device);
}
int32_t BMM150Sensor::runOnce()
{
#if !defined(MESHTASTIC_EXCLUDE_SCREEN) && HAS_SCREEN
float heading = sensor->getCompassDegree();
heading = applyCompassOrientation(heading);
if (screen)
screen->setHeading(heading);
#endif
return MOTION_SENSOR_CHECK_INTERVAL_MS;
}
// ----------------------------------------------------------------------
// BMM150Singleton
// ----------------------------------------------------------------------
// Get a singleton wrapper for an Sparkfun BMM_150_I2C
BMM150Singleton *BMM150Singleton::GetInstance(ScanI2C::FoundDevice device)
{
#if defined(WIRE_INTERFACES_COUNT) && (WIRE_INTERFACES_COUNT > 1)
TwoWire &bus = (device.address.port == ScanI2C::I2CPort::WIRE1 ? Wire1 : Wire);
#else
TwoWire &bus = Wire; // fallback if only one I2C interface
#endif
if (pinstance == nullptr) {
pinstance = new BMM150Singleton(&bus, device.address.address);
}
return pinstance;
}
BMM150Singleton::~BMM150Singleton() {}
BMM150Singleton *BMM150Singleton::pinstance{nullptr};
// Initialise the BMM150 Sensor
// https://github.com/DFRobot/DFRobot_BMM150/blob/master/examples/getGeomagneticData/getGeomagneticData.ino
bool BMM150Singleton::init(ScanI2C::FoundDevice device)
{
// startup
LOG_DEBUG("BMM150 begin on addr 0x%02X (port=%d)", device.address.address, device.address.port);
uint8_t status = begin();
if (status != 0) {
LOG_DEBUG("BMM150 init error %u", status);
return false;
}
// SW reset to make sure the device starts in a known state
setOperationMode(BMM150_POWERMODE_NORMAL);
setPresetMode(BMM150_PRESETMODE_LOWPOWER);
setRate(BMM150_DATA_RATE_02HZ);
setMeasurementXYZ();
return true;
}
#endif