# Motion

How a Kode Dot knows which way is down, how fast it is turning and where north is, and why that takes two chips.

## What it is

A motion sensor answers three questions about the Kode Dot: which way is
down, how fast it is turning, and where north is. Three small sensors answer
them, three axes each, which is where "9-axis" comes from.

- The **accelerometer** measures acceleration, gravity included. At rest it
  reads 1 g straight down, so tilting the Kode Dot moves that 1 g from one
  axis to another. It is how a screen knows it has been turned, and how a
  step counter counts.
- The **gyroscope** measures rotation rate, in degrees per second. It says
  nothing about where you are pointing, only how fast that is changing.
  Integrate it and you get an angle; leave it long enough and the angle
  drifts.
- The **magnetometer** measures the magnetic field around it. Away from
  magnets that field is the Earth's, and its direction is a compass heading.

The first two share one chip: they are both made of tiny moving structures
etched in silicon, and one die can hold both. A magnetometer is a different
kind of sensor, a magneto-resistive bridge, and lives in a chip of its own.
That is why the Kode Dot carries two parts for one job: a **QMI8658A** for
the accelerometer and the gyroscope, and a **QMC5883P** for the compass.

Used together they cover for each other. The accelerometer knows down but
not north; the compass knows north but tilts with the board; the gyroscope
is fast and smooth but drifts. A heading that stays right while you move the
Kode Dot is the three combined, which is what "sensor fusion" means.

## How it is connected

```mermaid
flowchart LR
  p4["ESP32-P4"] -- "I2C, 0x6A" --> imu["QMI8658A, accelerometer + gyroscope"]
  p4 -- "I2C, 0x2C" --> mag["QMC5883P, magnetometer"]
```

*Both parts sit on the P4's shared I2C bus, each at its own address*

Both chips hang off the P4's shared I2C bus, `GPIO4` for data and `GPIO5`
for clock at 400 kHz, next to the panel expander, the audio codec, the
charger, the fuel gauge and the touch controller. `kode_bsp_init` brings that
bus up and owns it; your code asks for the handle with `kode_bsp_i2c()` and
adds each sensor to it. A bus scan finds both at their own addresses.

## Apps that use it

On the marketplace, apps that put this part to work. Install one from
`start/first-app` and see it before you write a line.

- https://apps.kode.diy/app/cb2636c7-8273-4df2-9fb6-be5a007dc49d
- https://apps.kode.diy/app/04c1ec90-c7c1-48fb-ac53-c8822aef31ad
- https://apps.kode.diy/app/bb67aa95-94a5-486a-9e26-1f6b88d17470
- https://apps.kode.diy/app/53a19ce7-8fe5-4706-8dae-5fb312b732e6
- https://apps.kode.diy/app/7b60e571-9826-405f-8af5-3185899dfc74
- https://apps.kode.diy/app/db6f7781-9d9c-4240-87cb-8f4f9bf1e796
- https://apps.kode.diy/app/91c94c3c-9562-47fc-9e5f-ea5e5d064350
- https://apps.kode.diy/app/fa5d6a2b-5b29-4ba9-b380-af96b2a31bc0

## The parts

| Part | What it gives you | Page |
| --- | --- | --- |
| QMI8658A | Acceleration and rotation rate, three axes each, plus a die thermometer | `device/motion/imu` |
| QMC5883P | Magnetic field, three axes: a compass | `device/motion/magnetometer` |

## In the SDK

- [`kdrv_motion`](https://github.com/kodediy/kode-sdk/tree/main/components/kdrv/kdrv_motion): the motion drivers in `kode-sdk`. **TBD**: today it holds the prototype's parts; the QMI8658A and QMC5883P drivers are not written.
