Programming is my new hobby and I thought I do something extra for this amazing project. I got myself BMM150 3-axis magentometer and I incorporated it into ESP32Flight project.
Adds support for an optional BMM150 magnetometer wired to the same I2C bus
the display already uses. When present and calibrated, the "spotter line"
on the flight detail screen (the one that currently says e.g. Look NW, 20° above horizon) shows a device-relative hint instead — Look right, 20° above horizon — telling you which way to physically turn the
board rather than a fixed compass point. Without the sensor (or before
it's calibrated), behavior is unchanged: the original geographic 8-sector
label is used, so this is a strict opt-in with no regression for boards
that don't have the chip.
Built and tested on a Waveshare ESP32-S3-Touch-LCD-7, ESP-IDF 5.5.5.
Not tested on the other 9 supported board variants — the code is written
to fail safe (reports "not detected") if the chip doesn't answer, so it
shouldn't affect boards without the sensor, but I only have the one board
to verify against.
Hardware
- Sensor: Bosch BMM150, I2C address
0x13, chip ID 0x32.
- Wiring:
SDA -> GPIO8, SCL -> GPIO9 (the same bus the board already
brings up for the GT911 touch controller at 0x5D and the CH422G I/O
expander at 0x24/0x38 — no address conflicts, no extra pins needed),
VCC -> 3.3V, GND -> GND. INT is left unconnected (polling is used,
not interrupts).
- No wiring changes needed on a board that already has the chip present;
boards without it simply never detect anything and the feature is a
no-op.
What's new
New files (main/compass.c, main/compass.h): a small module
following the existing _poll()/_get() module convention used
elsewhere in the codebase (see ships.h). On compass_init() it detects
the chip and, if found, starts a background FreeRTOS task that polls it
every 200ms, computes a heading, and (during calibration) tracks a
per-axis min/max envelope. compass_get() returns a snapshot safe to call
from any task. compass_dir_word() is the one call site UI code needs —
it returns a localized direction word for a given true bearing, using the
device heading when calibrated and transparently falling back to the
existing lang_compass() 8-sector label otherwise.
Calibration (a 30-second "rotate the board" sweep) is stored in NVS under
its own namespace (compass / key cal) rather than on an SD card, since
most boards here don't have one — this is a difference from how a similar
feature was implemented in an unrelated personal project this was ported
from.
The whole module is guarded #ifndef APKFLIGHT: in the Android build it
compiles to trivial stubs (compass_get() always reports
detected = false), since there's no I2C bus to talk to there and several
of the files it touches (ui.c, ui_settings.c, lang.c) are shared
between the ESP-IDF and Android targets.
New dependency (main/idf_component.yml): lewisxhe/sensorlib "0.4.1", which vendors Bosch's official BMM150 sensor API
(bmm150_init, bmm150_read_mag_data, etc.) — pulled automatically by
the IDF component manager on the next build, no manual step needed.
(Above is an extract from readme file I prepared).
If you would like to get a .zip file with all the modified files and readme - ping me. If it fits your roadmap or just expanding features - feel free to use it within this project!
Programming is my new hobby and I thought I do something extra for this amazing project. I got myself BMM150 3-axis magentometer and I incorporated it into ESP32Flight project.
Adds support for an optional BMM150 magnetometer wired to the same I2C bus
the display already uses. When present and calibrated, the "spotter line"
on the flight detail screen (the one that currently says e.g.
Look NW, 20° above horizon) shows a device-relative hint instead —Look right, 20° above horizon— telling you which way to physically turn theboard rather than a fixed compass point. Without the sensor (or before
it's calibrated), behavior is unchanged: the original geographic 8-sector
label is used, so this is a strict opt-in with no regression for boards
that don't have the chip.
Built and tested on a Waveshare ESP32-S3-Touch-LCD-7, ESP-IDF 5.5.5.
Not tested on the other 9 supported board variants — the code is written
to fail safe (reports "not detected") if the chip doesn't answer, so it
shouldn't affect boards without the sensor, but I only have the one board
to verify against.
Hardware
0x13, chip ID0x32.SDA -> GPIO8,SCL -> GPIO9(the same bus the board alreadybrings up for the GT911 touch controller at
0x5Dand the CH422G I/Oexpander at
0x24/0x38— no address conflicts, no extra pins needed),VCC -> 3.3V,GND -> GND.INTis left unconnected (polling is used,not interrupts).
boards without it simply never detect anything and the feature is a
no-op.
What's new
New files (
main/compass.c,main/compass.h): a small modulefollowing the existing
_poll()/_get()module convention usedelsewhere in the codebase (see
ships.h). Oncompass_init()it detectsthe chip and, if found, starts a background FreeRTOS task that polls it
every 200ms, computes a heading, and (during calibration) tracks a
per-axis min/max envelope.
compass_get()returns a snapshot safe to callfrom any task.
compass_dir_word()is the one call site UI code needs —it returns a localized direction word for a given true bearing, using the
device heading when calibrated and transparently falling back to the
existing
lang_compass()8-sector label otherwise.Calibration (a 30-second "rotate the board" sweep) is stored in NVS under
its own namespace (
compass/ keycal) rather than on an SD card, sincemost boards here don't have one — this is a difference from how a similar
feature was implemented in an unrelated personal project this was ported
from.
The whole module is guarded
#ifndef APKFLIGHT: in the Android build itcompiles to trivial stubs (
compass_get()always reportsdetected = false), since there's no I2C bus to talk to there and severalof the files it touches (
ui.c,ui_settings.c,lang.c) are sharedbetween the ESP-IDF and Android targets.
New dependency (
main/idf_component.yml):lewisxhe/sensorlib "0.4.1", which vendors Bosch's official BMM150 sensor API(
bmm150_init,bmm150_read_mag_data, etc.) — pulled automatically bythe IDF component manager on the next build, no manual step needed.
(Above is an extract from readme file I prepared).
If you would like to get a .zip file with all the modified files and readme - ping me. If it fits your roadmap or just expanding features - feel free to use it within this project!