mirror of
https://github.com/meshtastic/firmware.git
synced 2025-10-06 23:09:56 +00:00
Use 20948 for compass direction
This commit is contained in:
parent
36be446027
commit
8d464bb07e
@ -24,7 +24,6 @@ lib_deps =
|
||||
${networking_base.lib_deps}
|
||||
${radiolib_base.lib_deps}
|
||||
${environmental_base.lib_deps}
|
||||
${environmental_base.lib_deps}
|
||||
# renovate: datasource=custom.pio depName=rweather/Crypto packageName=rweather/library/Crypto
|
||||
rweather/Crypto@^0.4.0
|
||||
# renovate: datasource=custom.pio depName=LovyanGFX packageName=lovyan03/library/LovyanGFX
|
||||
@ -49,4 +48,4 @@ build_flags =
|
||||
-std=gnu17
|
||||
-std=c++17
|
||||
|
||||
lib_ignore = Adafruit NeoPixel
|
||||
lib_ignore = Adafruit NeoPixel
|
||||
|
@ -1,6 +1,11 @@
|
||||
#include "ICM20948Sensor.h"
|
||||
|
||||
#if !defined(ARCH_STM32WL) && !MESHTASTIC_EXCLUDE_I2C && __has_include(<ICM_20948.h>)
|
||||
#if !defined(MESHTASTIC_EXCLUDE_SCREEN)
|
||||
|
||||
// screen is defined in main.cpp
|
||||
extern graphics::Screen *screen;
|
||||
#endif
|
||||
|
||||
// Flag when an interrupt has been detected
|
||||
volatile static bool ICM20948_IRQ = false;
|
||||
@ -41,6 +46,90 @@ int32_t ICM20948Sensor::runOnce()
|
||||
|
||||
int32_t ICM20948Sensor::runOnce()
|
||||
{
|
||||
#if !defined(MESHTASTIC_EXCLUDE_SCREEN)
|
||||
float magX = 0, magY = 0, magZ = 0;
|
||||
if (sensor->dataReady()) {
|
||||
sensor->getAGMT();
|
||||
magX = sensor->agmt.mag.axes.x;
|
||||
magY = sensor->agmt.mag.axes.y;
|
||||
magZ = sensor->agmt.mag.axes.z;
|
||||
}
|
||||
|
||||
if (doCalibration) {
|
||||
|
||||
if (!showingScreen) {
|
||||
powerFSM.trigger(EVENT_PRESS); // keep screen alive during calibration
|
||||
showingScreen = true;
|
||||
screen->startAlert((FrameCallback)drawFrameCalibration);
|
||||
}
|
||||
|
||||
if (magX > highestX)
|
||||
highestX = magX;
|
||||
if (magX < lowestX)
|
||||
lowestX = magX;
|
||||
if (magY > highestY)
|
||||
highestY = magY;
|
||||
if (magY < lowestY)
|
||||
lowestY = magY;
|
||||
if (magZ > highestZ)
|
||||
highestZ = magZ;
|
||||
if (magZ < lowestZ)
|
||||
lowestZ = magZ;
|
||||
|
||||
uint32_t now = millis();
|
||||
if (now > endCalibrationAt) {
|
||||
doCalibration = false;
|
||||
endCalibrationAt = 0;
|
||||
showingScreen = false;
|
||||
screen->endAlert();
|
||||
}
|
||||
|
||||
// LOG_DEBUG("ICM20948 min_x: %.4f, max_X: %.4f, min_Y: %.4f, max_Y: %.4f, min_Z: %.4f, max_Z: %.4f", lowestX, highestX,
|
||||
// lowestY, highestY, lowestZ, highestZ);
|
||||
}
|
||||
|
||||
int highestRealX = highestX - (highestX + lowestX) / 2;
|
||||
|
||||
magX -= (highestX + lowestX) / 2;
|
||||
magY -= (highestY + lowestY) / 2;
|
||||
magZ -= (highestZ + lowestZ) / 2;
|
||||
FusionVector ga, ma;
|
||||
ga.axis.x = -(sensor->agmt.acc.axes.x); // default location for the BMX160 is on the rear of the board
|
||||
ga.axis.y = -(sensor->agmt.acc.axes.y);
|
||||
ga.axis.z = (sensor->agmt.acc.axes.z);
|
||||
ma.axis.x = -magX;
|
||||
ma.axis.y = -magY;
|
||||
ma.axis.z = magZ * 3;
|
||||
|
||||
// If we're set to one of the inverted positions
|
||||
if (config.display.compass_orientation > meshtastic_Config_DisplayConfig_CompassOrientation_DEGREES_270) {
|
||||
ma = FusionAxesSwap(ma, FusionAxesAlignmentNXNYPZ);
|
||||
ga = FusionAxesSwap(ga, FusionAxesAlignmentNXNYPZ);
|
||||
}
|
||||
|
||||
float heading = FusionCompassCalculateHeading(FusionConventionNed, ga, ma);
|
||||
|
||||
switch (config.display.compass_orientation) {
|
||||
case meshtastic_Config_DisplayConfig_CompassOrientation_DEGREES_0_INVERTED:
|
||||
case meshtastic_Config_DisplayConfig_CompassOrientation_DEGREES_0:
|
||||
break;
|
||||
case meshtastic_Config_DisplayConfig_CompassOrientation_DEGREES_90:
|
||||
case meshtastic_Config_DisplayConfig_CompassOrientation_DEGREES_90_INVERTED:
|
||||
heading += 90;
|
||||
break;
|
||||
case meshtastic_Config_DisplayConfig_CompassOrientation_DEGREES_180:
|
||||
case meshtastic_Config_DisplayConfig_CompassOrientation_DEGREES_180_INVERTED:
|
||||
heading += 180;
|
||||
break;
|
||||
case meshtastic_Config_DisplayConfig_CompassOrientation_DEGREES_270:
|
||||
case meshtastic_Config_DisplayConfig_CompassOrientation_DEGREES_270_INVERTED:
|
||||
heading += 270;
|
||||
break;
|
||||
}
|
||||
|
||||
screen->setHeading(heading);
|
||||
#endif
|
||||
|
||||
// Wake on motion using polling - this is not as efficient as using hardware interrupt pin (see above)
|
||||
auto status = sensor->setBank(0);
|
||||
if (sensor->status != ICM_20948_Stat_Ok) {
|
||||
@ -64,6 +153,17 @@ int32_t ICM20948Sensor::runOnce()
|
||||
|
||||
#endif
|
||||
|
||||
void ICM20948Sensor::calibrate(uint16_t forSeconds)
|
||||
{
|
||||
#if !defined(MESHTASTIC_EXCLUDE_SCREEN)
|
||||
LOG_DEBUG("BMX160 calibration started for %is", forSeconds);
|
||||
|
||||
doCalibration = true;
|
||||
uint16_t calibrateFor = forSeconds * 1000; // calibrate for seconds provided
|
||||
endCalibrationAt = millis() + calibrateFor;
|
||||
screen->setEndCalibration(endCalibrationAt);
|
||||
#endif
|
||||
}
|
||||
// ----------------------------------------------------------------------
|
||||
// ICM20948Singleton
|
||||
// ----------------------------------------------------------------------
|
||||
@ -121,6 +221,11 @@ bool ICM20948Singleton::init(ScanI2C::FoundDevice device)
|
||||
return false;
|
||||
}
|
||||
|
||||
if (startupMagnetometer(false) != ICM_20948_Stat_Ok) {
|
||||
LOG_DEBUG("ICM20948 init magnetometer - %s", statusString());
|
||||
return false;
|
||||
}
|
||||
|
||||
#ifdef ICM_20948_INT_PIN
|
||||
|
||||
// Active low
|
||||
|
@ -6,6 +6,7 @@
|
||||
|
||||
#if !defined(ARCH_STM32WL) && !MESHTASTIC_EXCLUDE_I2C && __has_include(<ICM_20948.h>)
|
||||
|
||||
#include "Fusion/Fusion.h"
|
||||
#include <ICM_20948.h>
|
||||
|
||||
// Set the default gyro scale - dps250, dps500, dps1000, dps2000
|
||||
@ -80,6 +81,8 @@ class ICM20948Sensor : public MotionSensor
|
||||
{
|
||||
private:
|
||||
ICM20948Singleton *sensor = nullptr;
|
||||
bool showingScreen = false;
|
||||
float highestX = 0, lowestX = 0, highestY = 0, lowestY = 0, highestZ = 0, lowestZ = 0;
|
||||
|
||||
public:
|
||||
explicit ICM20948Sensor(ScanI2C::FoundDevice foundDevice);
|
||||
@ -89,6 +92,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;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue
Block a user