Skip to main content

read the undocumented mems accelerometer + gyroscope on apple silicon macs via iokit hid

Project description

apple-silicon-accelerometer

reads the undocumented internal accelerometer + gyroscope on apple silicon macbook pros via iokit hid (spu / AppleSPUHIDDevice), lid angle and ambient light.

more information: read the article

it turns out modern macbook pros have an undocumented mems accelerometer + gyroscope managed by the sensor processing unit (spu). this project reads both via iokit hid, along with lid angle and ambient light sensors from the same interface

install

pip install macimu
from macimu import IMU

with IMU() as imu:
    accel = imu.latest_accel()       # Sample(x, y, z) in g
    gyro = imu.latest_gyro()         # Sample(x, y, z) in deg/s

    for s in imu.read_accel():       # all new samples since last call
        print(s.x, s.y, s.z)

requires root (sudo) because iokit hid device access needs elevated privileges. also supports imu.read_lid() and imu.read_als() -- see macimu/__init__.py for the full api

demo

what is this

apple silicon macbooks appear to expose a hard to find mems imu (accelerometer + gyroscope) managed by the sensor processing unit (spu). it's not exposed through any public api or framework. this project reads raw 3-axis acceleration (accelerometer) and 3-axis angular velocity (gyroscope) data via iokit hid callbacks.

only tested on macbook pro m3 so far

how it works

the sensor lives under AppleSPUHIDDevice in the iokit registry, on vendor usage page 0xFF00. usage 3 is the accelerometer, usage 9 is the gyroscope (same physical IMU, believed to be Bosch BMI286 based on teardowns). the driver is AppleSPUHIDDriver which is part of the sensor processing unit. we open it with IOHIDDeviceCreate and register an asynchronous callback via IOHIDDeviceRegisterInputReportCallback. data comes as 22-byte hid reports with x/y/z as int32 little-endian at byte offsets 6, 10, 14. divide by 65536 to get the value in g (accel) or deg/s (gyro). callback rate is ~100hz (decimated from ~800hz native)

orientation is computed by fusing accel + gyro with a Mahony AHRS quaternion filter and displayed as roll/pitch/yaw gauges

you can verify the device exists on your machine with:

ioreg -l -w0 | grep -A5 AppleSPUHIDDevice

demo dashboard

git clone https://github.com/olvvier/apple-silicon-accelerometer
cd apple-silicon-accelerometer
pip install -e .[demo]
sudo python3 motion_live.py

the demo includes vibration detection, orientation gauges, experimental heartbeat (bcg), lid angle, ambient light, and optional keyboard flash

keyboard flash mode (bundled KBPulse)

motion_live.py can flash the keyboard backlight from vibration intensity in near realtime. the repo now vendors KBPulse, including a prebuilt apple silicon binary at KBPulse/bin/KBPulse.

run as usual:

sudo python3 motion_live.py

optional overrides:

sudo python3 motion_live.py --no-kbpulse
sudo python3 motion_live.py --kbpulse-bin /path/to/KBPulse

with uv

If you have uv/uvx installed, you can also just

sudo uvx git+https://github.com/olvvier/apple-silicon-accelerometer.git

code structure

  • macimu/ - python package (pip install macimu): high-level IMU class + low-level iokit bindings, shared memory ring buffers
  • motion_live.py - demo app: vibration detection, heartbeat bcg, terminal ui
  • KBPulse/ - vendored keyboard backlight driver code + binary (KBPulse/bin/KBPulse)

heartbeat demo

place your wrists on the laptop near the trackpad and wait 10-20 seconds for the signal to stabilize. this uses ballistocardiography - the mechanical vibrations from your heartbeat transmitted through your arms into the chassis. experimental, not reliable, just a fun use-case to show what the sensor can pick up. the bcg bandpass is 0.8-3hz and bpm is estimated via autocorrelation on the filtered signal

notes

  • experimental / undocumented AppleSPU hid path
  • requires sudo
  • may break on future macos updates
  • use at your own risk
  • not for medical use

does not work on

  • intel macbooks (pre-m1)
  • m1 macbook air/pro (2020)

license

MIT


not affiliated with Apple or any employer

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

macimu-0.1.0.tar.gz (8.8 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

macimu-0.1.0-py3-none-any.whl (9.1 kB view details)

Uploaded Python 3

File details

Details for the file macimu-0.1.0.tar.gz.

File metadata

  • Download URL: macimu-0.1.0.tar.gz
  • Upload date:
  • Size: 8.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.3

File hashes

Hashes for macimu-0.1.0.tar.gz
Algorithm Hash digest
SHA256 6c40936c279ea6a90f1f0401508664a1ccf94b878edb13bf4cb5aa274883bb42
MD5 cf77c03463a37f29191a7befcad59780
BLAKE2b-256 4d0695b609608c310baeacd3d2bb3e0e83c095f2df6d1b800b58479e27a1fd96

See more details on using hashes here.

File details

Details for the file macimu-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: macimu-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 9.1 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.3

File hashes

Hashes for macimu-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 54758728d4e8eb3106a4c85c804133b92f84d236a0ee53546710c157a6bb9400
MD5 fe3487a3ccbb0e11100e5b796b9605cb
BLAKE2b-256 5bf4da496082838fcbde55bcde8bf4b4d7a6fd3f5a68479575055dc0e0cecb60

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page