BMM350_Bosch_v1
Public Made by Adomby adom
9-contact breakout for the Bosch BMM350 WLCSP magnetometer. Separate 1.8 V VDD rail. Default address 0x15 (ADSEL pulled high via R5).
BMM350 Molecule — Hardware Reference
Compact 9-contact breakout for the Bosch BMM350 3-axis magnetometer (WLCSP). Brings out separate VDD and VDDIO rails (the BMM350 has a stricter VDD range than most Bosch parts).
- Source: adom-inc/bosch-molecules/Moecule_BMM350_Bosch_V1 — imported 2026-04-17 (folder name misspelled
Moeculeupstream; we preserve that on disk) - KiCad project:
Moecule_BMM350_Bosch_V1.kicad_pro - Wiki page: molecules/bmm350-bosch-v1-075000
- Board: 9 contacts — 4 corner mount-pins carry I²C + VDDIO, 3 side contacts carry VDD / INT / address strap, silk revision
V1: 2025-09-03 - IC: BMM350 (Bosch BGA-9, 1.28 × 1.28 × 0.5 mm WLCSP, U1)
Component summary
| Ref | Part | Function |
|---|---|---|
| U1 | BMM350 | 3-axis magnetometer |
| C1 | 2.2 µF 0805 X7R | CRST reset / reservoir cap (schematic note: "CRST 2.2uF Recommended, X7R") |
| C2 | 100 nF 0402 | VDDIO decoupling |
| C3 | 100 nF 0402 | VDD decoupling |
| R5 | 10 kΩ 0402 | Default pull-up from +VDDIO → /0x15 strap net (→ default address 0x15) |
External contact map
Positions in mm on the front copper. Two columns: west (X=139.8) and east (X=147.8).
West edge
| Ref | Silk | Net | Role |
|---|---|---|---|
| MP2 | VDDIO |
+VDDIO |
Logic rail — 1.72–3.6 V |
| MC6 | VDD (silk y) |
+VDD |
Analog rail — 1.72–1.98 V only (tight tolerance!) |
| MC4 | INT |
BMM_INT |
Interrupt (push-pull or open-drain, pull-up at host if OD) |
| MP1 | GND |
GND |
Ground |
East edge
| Ref | Silk | Net | Role |
|---|---|---|---|
| MP3 | SDA (silk BMM350) |
BMM_SDA |
I²C SDA |
| MC12 | BMM350 |
/0x15 |
Strap test-point (pulled to +VDDIO via R5) |
| MC3 | ADSEL |
BMM_ADSEL/0x14/0x15 |
I²C address select — routed to U1 pin B2 |
| MC10 | 0x14 |
GND |
Strap option: bridge MC3 ↔ MC10 for 0x14 |
| MP4 | SCK |
BMM_SCK |
I²C SCL |
I²C address strap
BMM350 I²C slave address is set by ADSEL at power-up:
| ADSEL tied to | I²C address |
|---|---|
GND (bridge MC3 ↔ MC10, silk 0x14) |
0x14 |
+VDDIO (default — R5 pull-up to /0x15 net) |
0x15 (demo firmware target ✓) |
Schematic text: "ADSEL (Legacy I2C, LSB): GND = 0x14, VDDIO = 0x15."
Default is 0x15 — matches the firmware. Unless you intend to run it at 0x14, leave MC3 / MC10 unbridged.
Address conflict check on the arm bus
The arm I²C bus has: BMI270 @ 0x68, BMA400 @ 0x14, BMA580 @ 0x18, BMM350 @ 0x15 (this molecule), BHI360 @ 0x28, BHI385 @ 0x29.
If you accidentally strap BMM350 to 0x14 it will collide with the BMA400 on the same bus.
Power
| Rail | Voltage | Source |
|---|---|---|
| VDD (analog) | 1.72–1.98 V | 1.8 V supply required — cannot run at 3.3 V |
| VDDIO | 1.72–3.6 V | Host via MP2 (3.3 V in demo) |
This is the one molecule in the arm bus that needs a 1.8 V rail. The HARDWARE_CONFIG.md power plan uses the 1.8 V LDO (fed from 3.3 V) for BMV080 core + BHI360 VDD + BHI385 VDD + BMM350 VDD. Do not accidentally tie MC6 (silk y = VDD) to 3.3 V — that exceeds the BMM350 absolute maximum.
Also from schematic: "VDDIO is 300 mV max when VDD = 0 V." If you shut off VDD during operation, VDDIO must drop too or the chip sustains stress. Not an issue if both rails come up together and stay up.
Typical active current: 200 µA.
Interrupt
INT (MC4) is software-configurable for data-ready, FIFO watermark, or threshold events. Output can be push-pull or open-drain; if open-drain, supply an external pull-up on the host (not present on this molecule).
Magnetic field range
Schematic annotation: "Max ±2000 µT: (Bx, By, Bz < 0.75 × 2400 µT)." The BMM350's full-scale is ±2400 µT on each axis, and for linear behavior Bosch recommends staying under 2000 µT. Keep magnets / motors / ferrous tooling away from the mounted sensor.
Wiring to the Arm RM2 I²C bus
BMM350 MP2 (VDDIO) ──── RM2 +3V3
BMM350 MC6 (VDD) ──── +1.8 V rail (NOT +3V3!)
BMM350 MP1 (GND) ──── RM2 GND
BMM350 MP3 (SDA) ──── RM2 GPIO4 (I²C0 SDA, shared bus)
BMM350 MP4 (SCK) ──── RM2 GPIO5 (I²C0 SCL, shared bus)
BMM350 MC4 (INT) ──── (optional; if open-drain, needs external pull-up)
BMM350 MC3 (ADSEL) ──── (leave floating — default 0x15 via R5 pull-up)
Gotchas for firmware bring-up
- VDD is 1.8 V only. Do not feed 3.3 V into MC6 — the BMM350 will be damaged. This is the most common wiring mistake on the arm bus.
- Default address is 0x15 (matches firmware). Only bridge MC3↔MC10 if you explicitly want 0x14.
- CRST cap (C1, 2.2 µF X7R) is on-board — no external reset circuitry needed. But if you see the sensor NACKing after a brown-out, verify C1 is charging properly and the supply is stable.
- BMM350 OTP trim + self-test must run at init before the first measurement — already handled in
firmware/sensors/bmm350.c. - No 4.7 kΩ I²C pull-ups on this board — provided by the RM2 carrier / main arm bus.
# BMM350 Molecule — Hardware Reference
Compact 9-contact breakout for the Bosch BMM350 3-axis magnetometer (WLCSP). Brings out separate VDD and VDDIO rails (the BMM350 has a stricter VDD range than most Bosch parts).
- **Source:** [adom-inc/bosch-molecules/Moecule_BMM350_Bosch_V1](https://github.com/adom-inc/bosch-molecules/tree/main/Moecule_BMM350_Bosch_V1) — imported 2026-04-17 (folder name misspelled `Moecule` upstream; we preserve that on disk)
- **KiCad project:** `Moecule_BMM350_Bosch_V1.kicad_pro`
- **Wiki page:** [molecules/bmm350-bosch-v1-075000](https://wiki-ufypy5dpx93o.adom.cloud/wiki/molecules/bmm350-bosch-v1-075000)
- **Board:** 9 contacts — 4 corner mount-pins carry I²C + VDDIO, 3 side contacts carry VDD / INT / address strap, silk revision `V1: 2025-09-03`
- **IC:** BMM350 (Bosch BGA-9, 1.28 × 1.28 × 0.5 mm WLCSP, U1)
## Component summary
| Ref | Part | Function |
|---|---|---|
| U1 | BMM350 | 3-axis magnetometer |
| C1 | 2.2 µF 0805 X7R | CRST reset / reservoir cap (schematic note: *"CRST 2.2uF Recommended, X7R"*) |
| C2 | 100 nF 0402 | VDDIO decoupling |
| C3 | 100 nF 0402 | VDD decoupling |
| R5 | 10 kΩ 0402 | **Default pull-up** from +VDDIO → `/0x15` strap net (→ default address **0x15**) |
## External contact map
Positions in mm on the front copper. **Two columns:** west (X=139.8) and east (X=147.8).
### West edge
| Ref | Silk | Net | Role |
|---|---|---|---|
| MP2 | `VDDIO` | `+VDDIO` | Logic rail — 1.72–3.6 V |
| MC6 | `VDD` *(silk `y`)* | `+VDD` | **Analog rail — 1.72–1.98 V only** (tight tolerance!) |
| MC4 | `INT` | `BMM_INT` | Interrupt (push-pull or open-drain, pull-up at host if OD) |
| MP1 | `GND` | `GND` | Ground |
### East edge
| Ref | Silk | Net | Role |
|---|---|---|---|
| MP3 | `SDA` *(silk `BMM350`)* | `BMM_SDA` | I²C SDA |
| MC12 | `BMM350` | `/0x15` | Strap test-point (pulled to +VDDIO via R5) |
| MC3 | `ADSEL` | `BMM_ADSEL/0x14/0x15` | **I²C address select** — routed to U1 pin B2 |
| MC10 | `0x14` | `GND` | Strap option: bridge MC3 ↔ MC10 for 0x14 |
| MP4 | `SCK` | `BMM_SCK` | I²C SCL |
## I²C address strap
BMM350 I²C slave address is set by ADSEL at power-up:
| ADSEL tied to | I²C address |
|---|---|
| GND (bridge MC3 ↔ MC10, silk `0x14`) | 0x14 |
| +VDDIO (default — R5 pull-up to `/0x15` net) | **0x15** (demo firmware target ✓) |
Schematic text: *"ADSEL (Legacy I2C, LSB): GND = 0x14, VDDIO = 0x15."*
**Default is 0x15** — matches the firmware. Unless you intend to run it at 0x14, leave MC3 / MC10 unbridged.
### Address conflict check on the arm bus
The arm I²C bus has: BMI270 @ 0x68, BMA400 @ 0x14, BMA580 @ 0x18, **BMM350 @ 0x15** (this molecule), BHI360 @ 0x28, BHI385 @ 0x29.
If you accidentally strap BMM350 to 0x14 it will collide with the BMA400 on the same bus.
## Power
| Rail | Voltage | Source |
|---|---|---|
| VDD (analog) | 1.72–1.98 V | **1.8 V supply required** — cannot run at 3.3 V |
| VDDIO | 1.72–3.6 V | Host via MP2 (3.3 V in demo) |
This is the one molecule in the arm bus that **needs a 1.8 V rail**. The HARDWARE_CONFIG.md power plan uses the 1.8 V LDO (fed from 3.3 V) for BMV080 core + BHI360 VDD + BHI385 VDD + **BMM350 VDD**. Do not accidentally tie MC6 (silk `y` = VDD) to 3.3 V — that exceeds the BMM350 absolute maximum.
Also from schematic: *"VDDIO is 300 mV max when VDD = 0 V."* If you shut off VDD during operation, VDDIO must drop too or the chip sustains stress. Not an issue if both rails come up together and stay up.
Typical active current: 200 µA.
## Interrupt
INT (MC4) is software-configurable for data-ready, FIFO watermark, or threshold events. Output can be push-pull or open-drain; if open-drain, supply an external pull-up on the host (not present on this molecule).
## Magnetic field range
Schematic annotation: *"Max ±2000 µT: (Bx, By, Bz < 0.75 × 2400 µT)."* The BMM350's full-scale is ±2400 µT on each axis, and for linear behavior Bosch recommends staying under 2000 µT. Keep magnets / motors / ferrous tooling away from the mounted sensor.
## Wiring to the Arm RM2 I²C bus
```
BMM350 MP2 (VDDIO) ──── RM2 +3V3
BMM350 MC6 (VDD) ──── +1.8 V rail (NOT +3V3!)
BMM350 MP1 (GND) ──── RM2 GND
BMM350 MP3 (SDA) ──── RM2 GPIO4 (I²C0 SDA, shared bus)
BMM350 MP4 (SCK) ──── RM2 GPIO5 (I²C0 SCL, shared bus)
BMM350 MC4 (INT) ──── (optional; if open-drain, needs external pull-up)
BMM350 MC3 (ADSEL) ──── (leave floating — default 0x15 via R5 pull-up)
```
## Gotchas for firmware bring-up
- **VDD is 1.8 V only.** Do not feed 3.3 V into MC6 — the BMM350 will be damaged. This is the most common wiring mistake on the arm bus.
- **Default address is 0x15** (matches firmware). Only bridge MC3↔MC10 if you explicitly want 0x14.
- **CRST cap (C1, 2.2 µF X7R)** is on-board — no external reset circuitry needed. But if you see the sensor NACKing after a brown-out, verify C1 is charging properly and the supply is stable.
- **BMM350 OTP trim + self-test** must run at init before the first measurement — already handled in `firmware/sensors/bmm350.c`.
- **No 4.7 kΩ I²C pull-ups on this board** — provided by the RM2 carrier / main arm bus.