modified to integrate with Motion_Cal & Magnetometer_Calibration
This commit is contained in:
parent
4397139fb9
commit
d7258feefe
4 changed files with 243 additions and 37 deletions
|
|
@ -1,59 +1,225 @@
|
||||||
# Exercise 25: MotionCal T-Beam Bridge
|
# Exercise 25: MotionCal T-Beam Bridge
|
||||||
|
|
||||||
Streams the T-Beam Supreme QMC6310 magnetometer in the ASCII format accepted by
|
This PlatformIO project turns a LilyGO T-Beam Supreme into a serial bridge for Paul Stoffregen's MotionCal desktop calibration tool.
|
||||||
Paul Stoffregen's MotionCal desktop tool.
|
|
||||||
|
|
||||||
https://github.com/PaulStoffregen/MotionCal.git (fetch)
|
The firmware reads the onboard QMC magnetometer through SensorLib and streams MotionCal-compatible ASCII `Raw:` lines over USB serial. MotionCal can then estimate both hard-iron offsets and the soft-iron correction matrix for the board.
|
||||||
|
|
||||||
See https://github.com/PaulStoffregen/MotionCal/issues/25 for Gentoo build tricks.
|

|
||||||
|
## Hardware
|
||||||
|
|
||||||
MotionCal expects:
|
Target board:
|
||||||
|
|
||||||
|
```text
|
||||||
|
LilyGO T-Beam Supreme / ESP32-S3
|
||||||
|
QMC6310/QMC5883-family magnetometer
|
||||||
|
SH1106 OLED display
|
||||||
|
```
|
||||||
|
|
||||||
|
The firmware probes these magnetometer I2C addresses:
|
||||||
|
|
||||||
|
```text
|
||||||
|
0x1C QMC6310U
|
||||||
|
0x3C QMC6310N
|
||||||
|
0x2C QMC5883P
|
||||||
|
```
|
||||||
|
|
||||||
|
The default PlatformIO environment is `cy`, with additional board labels available in `platformio.ini`:
|
||||||
|
|
||||||
|
```text
|
||||||
|
amy bob cy dan ed flo guy
|
||||||
|
```
|
||||||
|
|
||||||
|
## Serial Format
|
||||||
|
|
||||||
|
MotionCal expects lines in this format:
|
||||||
|
|
||||||
```text
|
```text
|
||||||
Raw:accel_x,accel_y,accel_z,gyro_x,gyro_y,gyro_z,mag_x,mag_y,mag_z
|
Raw:accel_x,accel_y,accel_z,gyro_x,gyro_y,gyro_z,mag_x,mag_y,mag_z
|
||||||
```
|
```
|
||||||
|
|
||||||
This exercise only has a magnetometer, so it sends a stationary accelerometer
|
This bridge only has a magnetometer, so it sends fixed placeholder accel/gyro values:
|
||||||
placeholder and zero gyro:
|
|
||||||
|
|
||||||
```text
|
```text
|
||||||
Raw:0,0,8192,0,0,0,mag_x,mag_y,mag_z
|
Raw:0,0,8192,0,0,0,mag_x,mag_y,mag_z
|
||||||
```
|
```
|
||||||
|
|
||||||
The magnetic values are converted from SensorLib Gauss readings into MotionCal's
|
The placeholder values mean:
|
||||||
integer units where 1 count is 0.1 microtesla.
|
|
||||||
|
```text
|
||||||
|
accel = 0,0,8192 approximately stationary upright in MotionCal's count convention
|
||||||
|
gyro = 0,0,0 no gyro data supplied
|
||||||
|
mag = live QMC magnetometer data
|
||||||
|
```
|
||||||
|
|
||||||
|
## Magnetometer Units
|
||||||
|
|
||||||
|
SensorLib returns QMC magnetometer readings in Gauss. The firmware converts them like this:
|
||||||
|
|
||||||
|
```text
|
||||||
|
1 gauss = 100 microtesla
|
||||||
|
MotionCal count = microtesla * 10
|
||||||
|
1 MotionCal count = 0.1 microtesla
|
||||||
|
```
|
||||||
|
|
||||||
|
So a streamed value like this:
|
||||||
|
|
||||||
|
```text
|
||||||
|
Raw:0,0,8192,0,0,0,-1735,428,793
|
||||||
|
```
|
||||||
|
|
||||||
|
means:
|
||||||
|
|
||||||
|
```text
|
||||||
|
X = -1735 counts = -173.5 uT = -1.735 gauss
|
||||||
|
Y = 428 counts = 42.8 uT = 0.428 gauss
|
||||||
|
Z = 793 counts = 79.3 uT = 0.793 gauss
|
||||||
|
```
|
||||||
|
|
||||||
|
These are MotionCal-compatible integer counts, not raw QMC register values.
|
||||||
|
|
||||||
## Build
|
## Build
|
||||||
|
|
||||||
|
Activate the Python environment that contains PlatformIO:
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
cd /usr/local/src/microreticulum/microReticulumTbeam/exercises/25_motioncal_tbeam
|
source /home/jlpoole/pioenv/bin/activate
|
||||||
source /home/jlpoole/rnsenv/bin/activate
|
```
|
||||||
|
|
||||||
|
Build the default environment:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
cd /usr/local/src/microReticulumTbeam/exercises/25_motioncal_tbeam
|
||||||
pio run
|
pio run
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Build a specific board label:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
pio run -e dan
|
||||||
|
```
|
||||||
|
|
||||||
## Upload
|
## Upload
|
||||||
|
|
||||||
|
Upload the default environment:
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
source /home/jlpoole/rnsenv/bin/activate
|
source /home/jlpoole/pioenv/bin/activate
|
||||||
|
cd /usr/local/src/microReticulumTbeam/exercises/25_motioncal_tbeam
|
||||||
pio run -t upload
|
pio run -t upload
|
||||||
```
|
```
|
||||||
|
|
||||||
Use a specific board environment if needed:
|
Upload a specific board label:
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
pio run -e guy -t upload
|
pio run -e dan -t upload
|
||||||
```
|
```
|
||||||
|
|
||||||
## MotionCal
|
## Serial Monitor
|
||||||
|
|
||||||
Build and run MotionCal as before:
|
After flashing, monitor the USB serial stream at 115200 baud:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
pio device monitor -b 115200 --port /dev/ttytDAN
|
||||||
|
```
|
||||||
|
|
||||||
|
Expected boot/status output includes lines like:
|
||||||
|
|
||||||
|
```text
|
||||||
|
exercise=Exercise 25 MotionCal T-Beam bridge
|
||||||
|
serial_format=Raw:accel_x,accel_y,accel_z,gyro_x,gyro_y,gyro_z,mag_x,mag_y,mag_z
|
||||||
|
mag_units=MotionCal integer counts, 1 count = 0.1 uT
|
||||||
|
magnetometer_init=ok label=QMC6310U addr=0x1C chip=0x..
|
||||||
|
```
|
||||||
|
|
||||||
|
Expected streaming output looks like:
|
||||||
|
|
||||||
|
```text
|
||||||
|
Raw:0,0,8192,0,0,0,-1578,447,1266
|
||||||
|
Raw:0,0,8192,0,0,0,-1583,438,1258
|
||||||
|
Raw:0,0,8192,0,0,0,-1585,442,1250
|
||||||
|
```
|
||||||
|
|
||||||
|
If the firmware prints `read_fail` or `overflow` status lines, check I2C wiring/power and the configured magnetometer full-scale range.
|
||||||
|
|
||||||
|
## Running MotionCal
|
||||||
|
|
||||||
|
Build MotionCal if needed:
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
cd /usr/local/src/MotionCal
|
cd /usr/local/src/MotionCal
|
||||||
make WXCONFIG=wx-config LDFLAGS="-lglut -lGLU -lGL -lm"
|
make WXCONFIG=wx-config LDFLAGS="-lglut -lGLU -lGL -lm"
|
||||||
|
```
|
||||||
|
|
||||||
|
Run it:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
cd /usr/local/src/MotionCal
|
||||||
GDK_BACKEND=x11 ./MotionCal
|
GDK_BACKEND=x11 ./MotionCal
|
||||||
```
|
```
|
||||||
|
|
||||||
Select the T-Beam USB serial port in MotionCal. The firmware also accepts
|
Then select the T-Beam USB serial port in MotionCal.
|
||||||
MotionCal's 68-byte calibration packet and echoes `Cal1:` and `Cal2:` lines so
|
|
||||||
MotionCal can confirm the send.
|
Move and rotate the T-Beam through as many orientations as possible. The goal is to cover the sphere well, not just wave it flat on the table. Better 3D coverage improves both hard-iron and soft-iron calibration.
|
||||||
|
|
||||||
|
## Saving Calibration
|
||||||
|
|
||||||
|
MotionCal computes:
|
||||||
|
|
||||||
|
```text
|
||||||
|
magnetic_offset_uT hard-iron offset, in microtesla
|
||||||
|
magnetic_mapping_matrix inverse soft-iron correction matrix
|
||||||
|
magnetic_field_uT fitted local field magnitude
|
||||||
|
```
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
```text
|
||||||
|
magnetic_offset_uT=-172.96843,43.0260162,78.8941956
|
||||||
|
magnetic_field_uT=52.4668198
|
||||||
|
magnetic_mapping_matrix=
|
||||||
|
0.943139076 0.0439298451 0.0595370531
|
||||||
|
0.0439298451 1.04979992 -0.0347476006
|
||||||
|
0.0595370531 -0.0347476006 1.01706612
|
||||||
|
```
|
||||||
|
|
||||||
|
The firmware also accepts MotionCal's 68-byte calibration packet and echoes `Cal1:` and `Cal2:` lines so MotionCal can confirm the send.
|
||||||
|
|
||||||
|
## Applying Calibration
|
||||||
|
|
||||||
|
MotionCal's calibration model is:
|
||||||
|
|
||||||
|
```text
|
||||||
|
mag_uT = raw_motioncal_counts * 0.1
|
||||||
|
centered = mag_uT - magnetic_offset_uT
|
||||||
|
corrected = magnetic_mapping_matrix * centered
|
||||||
|
```
|
||||||
|
|
||||||
|
Hard iron moves the center of the magnetometer cloud back to zero. Soft iron transforms the ellipsoid-shaped cloud back toward a sphere.
|
||||||
|
|
||||||
|
## Troubleshooting
|
||||||
|
|
||||||
|
If MotionCal does not show points:
|
||||||
|
|
||||||
|
```text
|
||||||
|
Confirm the serial port is correct.
|
||||||
|
Confirm baud is 115200.
|
||||||
|
Confirm monitor output contains Raw: lines.
|
||||||
|
Close any serial monitor before opening the port in MotionCal.
|
||||||
|
```
|
||||||
|
|
||||||
|
If the values look 10x different from a notebook or script:
|
||||||
|
|
||||||
|
```text
|
||||||
|
The notebook/script may be using MotionCal counts.
|
||||||
|
MotionCal's saved magnetic_offset_uT is already in microtesla.
|
||||||
|
Convert counts to uT with: uT = counts * 0.1
|
||||||
|
```
|
||||||
|
|
||||||
|
If the fit is poor:
|
||||||
|
|
||||||
|
```text
|
||||||
|
Collect more orientations.
|
||||||
|
Rotate around all axes.
|
||||||
|
Keep the board away from steel, speakers, motors, magnets, and high-current wiring.
|
||||||
|
Try a different location and repeat the calibration.
|
||||||
|
```
|
||||||
|
|
|
||||||
1
exercises/25_motioncal_tbeam/lib/SensorLib
Symbolic link
1
exercises/25_motioncal_tbeam/lib/SensorLib
Symbolic link
|
|
@ -0,0 +1 @@
|
||||||
|
/usr/local/src/LilyGo-LoRa-Series/lib/SensorLib
|
||||||
|
|
@ -16,14 +16,17 @@ lib_deps =
|
||||||
olikraus/U8g2@^2.36.4
|
olikraus/U8g2@^2.36.4
|
||||||
lewisxhe/XPowersLib@0.3.3
|
lewisxhe/XPowersLib@0.3.3
|
||||||
|
|
||||||
|
|
||||||
|
; MOTIONCAL_MAG_RANGE_G must be either 2 or 8 (less precision)
|
||||||
build_flags =
|
build_flags =
|
||||||
-I ../../shared/boards
|
-I ../../shared/boards
|
||||||
-I ../../external/microReticulum_Firmware
|
-I ../../external/microReticulum_Firmware
|
||||||
-I ../../../../LilyGo-LoRa-Series/lib/SensorLib/src
|
-I ../../../LilyGo-LoRa-Series/lib/SensorLib/src
|
||||||
-D BOARD_MODEL=BOARD_TBEAM_S_V1
|
-D BOARD_MODEL=BOARD_TBEAM_S_V1
|
||||||
-D OLED_SDA=17
|
-D OLED_SDA=17
|
||||||
-D OLED_SCL=18
|
-D OLED_SCL=18
|
||||||
-D OLED_ADDR=0x3C
|
-D OLED_ADDR=0x3C
|
||||||
|
-D MOTIONCAL_MAG_RANGE_G=2
|
||||||
-D ARDUINO_USB_MODE=1
|
-D ARDUINO_USB_MODE=1
|
||||||
-D ARDUINO_USB_CDC_ON_BOOT=1
|
-D ARDUINO_USB_CDC_ON_BOOT=1
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -35,15 +35,30 @@ namespace {
|
||||||
#define OLED_ADDR 0x3C
|
#define OLED_ADDR 0x3C
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef MOTIONCAL_MAG_RANGE_G
|
||||||
|
#define MOTIONCAL_MAG_RANGE_G 8
|
||||||
|
#endif
|
||||||
|
|
||||||
#define STR_INNER(x) #x
|
#define STR_INNER(x) #x
|
||||||
#define STR(x) STR_INNER(x)
|
#define STR(x) STR_INNER(x)
|
||||||
|
|
||||||
|
#if MOTIONCAL_MAG_RANGE_G == 2
|
||||||
|
static constexpr MagFullScaleRange kMagFullScaleRange = MagFullScaleRange::FS_2G;
|
||||||
|
static constexpr const char* kMagRangeLabel = "FS2G";
|
||||||
|
#elif MOTIONCAL_MAG_RANGE_G == 8
|
||||||
|
static constexpr MagFullScaleRange kMagFullScaleRange = MagFullScaleRange::FS_8G;
|
||||||
|
static constexpr const char* kMagRangeLabel = "FS8G";
|
||||||
|
#else
|
||||||
|
#error "MOTIONCAL_MAG_RANGE_G must be 2 or 8"
|
||||||
|
#endif
|
||||||
|
|
||||||
static constexpr const char* kExerciseName = "Exercise 25";
|
static constexpr const char* kExerciseName = "Exercise 25";
|
||||||
static constexpr const char* kBoardId = BOARD_ID;
|
static constexpr const char* kBoardId = BOARD_ID;
|
||||||
static constexpr const char* kNodeLabel = NODE_LABEL;
|
static constexpr const char* kNodeLabel = NODE_LABEL;
|
||||||
static constexpr const char* kBuildUtc = STR(FW_BUILD_UTC);
|
static constexpr const char* kFirmwareVersion = STR(FW_BUILD_UTC);
|
||||||
static constexpr uint32_t kSampleIntervalMs = 40;
|
static constexpr uint32_t kSampleIntervalMs = 40;
|
||||||
static constexpr uint32_t kDisplayIntervalMs = 250;
|
static constexpr uint32_t kDisplayIntervalMs = 250;
|
||||||
|
static constexpr uint32_t kStatusIntervalMs = 1000;
|
||||||
static constexpr uint8_t kMagCandidateCount = 3;
|
static constexpr uint8_t kMagCandidateCount = 3;
|
||||||
static constexpr uint8_t kMagCandidates[kMagCandidateCount] = {0x1C, 0x3C, 0x2C};
|
static constexpr uint8_t kMagCandidates[kMagCandidateCount] = {0x1C, 0x3C, 0x2C};
|
||||||
static constexpr uint16_t kCalibrationPacketSize = 68;
|
static constexpr uint16_t kCalibrationPacketSize = 68;
|
||||||
|
|
@ -61,7 +76,10 @@ uint8_t g_magChipId = 0;
|
||||||
char g_magLabel[16] = "UNKNOWN";
|
char g_magLabel[16] = "UNKNOWN";
|
||||||
uint32_t g_lastSampleMs = 0;
|
uint32_t g_lastSampleMs = 0;
|
||||||
uint32_t g_lastDisplayMs = 0;
|
uint32_t g_lastDisplayMs = 0;
|
||||||
|
uint32_t g_lastStatusMs = 0;
|
||||||
uint32_t g_sampleCount = 0;
|
uint32_t g_sampleCount = 0;
|
||||||
|
uint32_t g_readFailCount = 0;
|
||||||
|
uint32_t g_overflowCount = 0;
|
||||||
int16_t g_lastMagCounts[3] = {0, 0, 0};
|
int16_t g_lastMagCounts[3] = {0, 0, 0};
|
||||||
float g_lastMagUt[3] = {0.0f, 0.0f, 0.0f};
|
float g_lastMagUt[3] = {0.0f, 0.0f, 0.0f};
|
||||||
|
|
||||||
|
|
@ -106,18 +124,20 @@ void drawLines(const char* l1,
|
||||||
const char* l2 = nullptr,
|
const char* l2 = nullptr,
|
||||||
const char* l3 = nullptr,
|
const char* l3 = nullptr,
|
||||||
const char* l4 = nullptr,
|
const char* l4 = nullptr,
|
||||||
const char* l5 = nullptr) {
|
const char* l5 = nullptr,
|
||||||
|
const char* l6 = nullptr) {
|
||||||
if (!g_displayReady) {
|
if (!g_displayReady) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
g_oled.clearBuffer();
|
g_oled.clearBuffer();
|
||||||
g_oled.setFont(u8g2_font_6x12_tf);
|
g_oled.setFont(u8g2_font_5x8_tf);
|
||||||
if (l1) g_oled.drawUTF8(0, 12, l1);
|
if (l1) g_oled.drawUTF8(0, 10, l1);
|
||||||
if (l2) g_oled.drawUTF8(0, 24, l2);
|
if (l2) g_oled.drawUTF8(0, 20, l2);
|
||||||
if (l3) g_oled.drawUTF8(0, 36, l3);
|
if (l3) g_oled.drawUTF8(0, 30, l3);
|
||||||
if (l4) g_oled.drawUTF8(0, 48, l4);
|
if (l4) g_oled.drawUTF8(0, 40, l4);
|
||||||
if (l5) g_oled.drawUTF8(0, 60, l5);
|
if (l5) g_oled.drawUTF8(0, 50, l5);
|
||||||
|
if (l6) g_oled.drawUTF8(0, 60, l6);
|
||||||
g_oled.sendBuffer();
|
g_oled.sendBuffer();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -129,7 +149,7 @@ void initDisplay() {
|
||||||
g_oled.begin();
|
g_oled.begin();
|
||||||
g_oled.setPowerSave(0);
|
g_oled.setPowerSave(0);
|
||||||
g_displayReady = true;
|
g_displayReady = true;
|
||||||
drawLines(kExerciseName, "MotionCal Bridge", kBoardId, "starting...");
|
drawLines(kExerciseName, kFirmwareVersion, kBoardId, "MotionCal Bridge", "starting...");
|
||||||
}
|
}
|
||||||
|
|
||||||
bool probeI2cAddr(TwoWire& wire, uint8_t addr) {
|
bool probeI2cAddr(TwoWire& wire, uint8_t addr) {
|
||||||
|
|
@ -171,7 +191,7 @@ bool initMagnetometer() {
|
||||||
g_magChipId = g_qmc.getChipID();
|
g_magChipId = g_qmc.getChipID();
|
||||||
return g_qmc.configMagnetometer(
|
return g_qmc.configMagnetometer(
|
||||||
OperationMode::CONTINUOUS_MEASUREMENT,
|
OperationMode::CONTINUOUS_MEASUREMENT,
|
||||||
MagFullScaleRange::FS_2G,
|
kMagFullScaleRange,
|
||||||
100.0f,
|
100.0f,
|
||||||
MagOverSampleRatio::OSR_4,
|
MagOverSampleRatio::OSR_4,
|
||||||
MagDownSampleRatio::DSR_1);
|
MagDownSampleRatio::DSR_1);
|
||||||
|
|
@ -179,9 +199,10 @@ bool initMagnetometer() {
|
||||||
|
|
||||||
void printBootSummary() {
|
void printBootSummary() {
|
||||||
Serial.printf("exercise=%s MotionCal T-Beam bridge\r\n", kExerciseName);
|
Serial.printf("exercise=%s MotionCal T-Beam bridge\r\n", kExerciseName);
|
||||||
Serial.printf("board_id=%s node_label=%s build=%s\r\n", kBoardId, kNodeLabel, kBuildUtc);
|
Serial.printf("board_id=%s node_label=%s build=%s\r\n", kBoardId, kNodeLabel, kFirmwareVersion);
|
||||||
Serial.printf("serial_format=Raw:accel_x,accel_y,accel_z,gyro_x,gyro_y,gyro_z,mag_x,mag_y,mag_z\r\n");
|
Serial.printf("serial_format=Raw:accel_x,accel_y,accel_z,gyro_x,gyro_y,gyro_z,mag_x,mag_y,mag_z\r\n");
|
||||||
Serial.printf("mag_units=MotionCal integer counts, 1 count = 0.1 uT\r\n");
|
Serial.printf("mag_units=MotionCal integer counts, 1 count = 0.1 uT\r\n");
|
||||||
|
Serial.printf("mag_range=%s\r\n", kMagRangeLabel);
|
||||||
}
|
}
|
||||||
|
|
||||||
void streamMotionCalRaw(const MagnetometerData& data) {
|
void streamMotionCalRaw(const MagnetometerData& data) {
|
||||||
|
|
@ -208,10 +229,10 @@ void updateDisplay() {
|
||||||
char line4[28];
|
char line4[28];
|
||||||
char line5[28];
|
char line5[28];
|
||||||
|
|
||||||
snprintf(line3, sizeof(line3), "%s 0x%02X id 0x%02X", g_magLabel, g_magAddress, g_magChipId);
|
|
||||||
snprintf(line4, sizeof(line4), "%6.1f %6.1f", g_lastMagUt[0], g_lastMagUt[1]);
|
snprintf(line4, sizeof(line4), "%6.1f %6.1f", g_lastMagUt[0], g_lastMagUt[1]);
|
||||||
snprintf(line5, sizeof(line5), "Z:%6.1f N:%lu", g_lastMagUt[2], (unsigned long)g_sampleCount);
|
snprintf(line5, sizeof(line5), "Z:%6.1f N:%lu", g_lastMagUt[2], (unsigned long)g_sampleCount);
|
||||||
drawLines(kExerciseName, "MotionCal Raw stream", line3, line4, line5);
|
snprintf(line3, sizeof(line3), "%s %s 0x%02X", kMagRangeLabel, g_magLabel, g_magAddress);
|
||||||
|
drawLines(kExerciseName, kFirmwareVersion, line3, line4, line5, "Raw stream");
|
||||||
}
|
}
|
||||||
|
|
||||||
void printCalibrationEcho(const float* values) {
|
void printCalibrationEcho(const float* values) {
|
||||||
|
|
@ -293,7 +314,7 @@ void appSetup() {
|
||||||
|
|
||||||
if (!tbeam_supreme::initPmuForPeripherals(g_pmu, &Serial)) {
|
if (!tbeam_supreme::initPmuForPeripherals(g_pmu, &Serial)) {
|
||||||
Serial.println("pmu_init=failed");
|
Serial.println("pmu_init=failed");
|
||||||
drawLines(kExerciseName, "PMU init failed", kBoardId, "see serial");
|
drawLines(kExerciseName, kFirmwareVersion, "PMU init failed", kBoardId, "see serial");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Serial.println("pmu_init=ok");
|
Serial.println("pmu_init=ok");
|
||||||
|
|
@ -301,15 +322,16 @@ void appSetup() {
|
||||||
g_magReady = initMagnetometer();
|
g_magReady = initMagnetometer();
|
||||||
if (!g_magReady) {
|
if (!g_magReady) {
|
||||||
Serial.println("magnetometer_init=failed");
|
Serial.println("magnetometer_init=failed");
|
||||||
drawLines(kExerciseName, "MAG init failed", kBoardId, "see serial");
|
drawLines(kExerciseName, kFirmwareVersion, "MAG init failed", kBoardId, "see serial");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Serial.printf("magnetometer_init=ok label=%s addr=0x%02X chip=0x%02X\r\n",
|
Serial.printf("magnetometer_init=ok label=%s addr=0x%02X chip=0x%02X\r\n",
|
||||||
g_magLabel, g_magAddress, g_magChipId);
|
g_magLabel, g_magAddress, g_magChipId);
|
||||||
drawLines(kExerciseName, "MotionCal Bridge", g_magLabel, "streaming Raw...");
|
drawLines(kExerciseName, kFirmwareVersion, "MotionCal Bridge", g_magLabel, "streaming Raw...");
|
||||||
g_lastSampleMs = millis();
|
g_lastSampleMs = millis();
|
||||||
g_lastDisplayMs = millis();
|
g_lastDisplayMs = millis();
|
||||||
|
g_lastStatusMs = millis();
|
||||||
}
|
}
|
||||||
|
|
||||||
void appLoop() {
|
void appLoop() {
|
||||||
|
|
@ -324,7 +346,11 @@ void appLoop() {
|
||||||
if ((uint32_t)(now - g_lastSampleMs) >= kSampleIntervalMs) {
|
if ((uint32_t)(now - g_lastSampleMs) >= kSampleIntervalMs) {
|
||||||
g_lastSampleMs = now;
|
g_lastSampleMs = now;
|
||||||
MagnetometerData data;
|
MagnetometerData data;
|
||||||
if (g_qmc.readData(data) && !data.overflow) {
|
if (!g_qmc.readData(data)) {
|
||||||
|
++g_readFailCount;
|
||||||
|
} else if (data.overflow) {
|
||||||
|
++g_overflowCount;
|
||||||
|
} else {
|
||||||
streamMotionCalRaw(data);
|
streamMotionCalRaw(data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -334,6 +360,16 @@ void appLoop() {
|
||||||
updateDisplay();
|
updateDisplay();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ((uint32_t)(now - g_lastStatusMs) >= kStatusIntervalMs) {
|
||||||
|
g_lastStatusMs = now;
|
||||||
|
if (g_readFailCount > 0 || g_overflowCount > 0) {
|
||||||
|
Serial.printf("motioncal_status=samples:%lu read_fail:%lu overflow:%lu\r\n",
|
||||||
|
(unsigned long)g_sampleCount,
|
||||||
|
(unsigned long)g_readFailCount,
|
||||||
|
(unsigned long)g_overflowCount);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
delay(1);
|
delay(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue