# SlimeVR Tracker firmware, a DIY Vive-style tracker on an ESP32

> SlimeVR-Tracker-ESP is firmware that turns an ESP8266 or ESP32 with an inertial measurement unit into a Vive-like VR tracker, pairing with the SlimeVR Server to resolve pose in SteamVR. The compatibility table is the most useful part of the repository, because it grades each supported sensor by how well it actually tracks.

**SlimeVR/SlimeVR-Tracker-ESP** — SlimeVR tracker firmware for ESP32/ESP8266 and different IMUs

- Repository: https://github.com/SlimeVR/SlimeVR-Tracker-ESP
- Stars: 1,093 · Forks: 397
- Language: C++
- License: Apache-2.0
- Published: 2026-10-19 · Updated: 2026-10-19 · Language: en
- Canonical page: https://hysenlabs.com/projects/slimevr-slimevr-tracker-esp

## What the firmware is and what it needs around it

The repository is firmware for ESP8266 and ESP32 microcontrollers and different IMU sensors, used to make them act as Vive-like trackers in VR.

It is not a standalone product, and the README is clear about the dependencies. It requires SlimeVR Server to work with SteamVR and resolve pose, and it should be compatible with owoTrack but is not guaranteed. That distinction matters, because the firmware produces raw sensor data and the server does the pose resolution, so the quality of your tracking depends on the server as much as on the tracker.

The configuration is in a file, and the README points to the SlimeVR documentation for the details of the Configuring the firmware project section. The firmware works with both ESP8266 and ESP32, and you need to edit the defines file and set your pinout properly according to how you connected the IMU. The repository layout backs that up: there is a src/ directory for the code, include/ for headers, a lib/ directory for vendored libraries, a boards/ directory, a platformio.ini for the build, board-defaults.json with a board-defaults.schema.json alongside it, a ci/ directory, scripts/, a test/ directory, and a flake.nix with a flake.lock for the Nix toolchain. The .clang-format and .clang-tidy files are there for the C++ side, and the licence is Apache-2.0 with both LICENSE-APACHE and LICENSE-MIT files present.

The last push was on 2026-10-13, the release tags are v0.7.3 from 2026-08-03, v0.7.2 from 2025-12-12 and v0.7.1 from 2025-11-10, and the default branch is main.

There is also a Linux-specific note that is easy to miss and very practical. For uploading on Linux, the README points at the PlatformIO documentation on udev rules, and says this should solve any permission denied errors. That is the standard Linux serial access problem, and for a tracker that flashes over USB it is the first thing that will stop you.

## The compatibility list is really a quality ranking

The supported IMUs are listed with their IMU values, and the annotations are where the real information is. This is not a list of what compiles, it is a list of what works and what does not.

The BNO085 and BNO086, with the value IMU_BNO085, use any fusion in the internal DMP, and the README says best results with ARVR Stabilized Game Rotation Vector or ARVR Stabilized Rotation Vector if in a good magnetic environment. The BNO080, IMU_BNO080, also uses any fusion in the internal DMP, and does not have the BNO085's ARVR stabilization but still gives good results.

Then there is a group of sensors marked as not recommended or experimental, and the reasoning is specific. The MPU-6500 and MPU-6050 use the internal DMP to fuse gyroscope and accelerometer, and can drift substantially. The BNO055 performs much worse than the BNO080 despite having the same hardware, and is explicitly not recommended for use, which is a striking thing to read about a part that was widely used before the BNO080 existed.

The MPU-9250 uses Mahony fusion of gyroscope, magnetometer and accelerometer, requires a good magnetic environment, and is marked experimental. The BMI160 uses fusion of gyroscope and accelerometer, with the note that the calibration file format is unstable and may not be able to load using newer firmware versions, also marked experimental. The ICM-20948 uses fusion in the internal DMP for 6DoF or 9DoF, where 9DoF requires a good magnetic environment and you comment out USE_6DOF in debug.h to get it, and it is experimental as well.

And then a long group of newer parts treated as one block: BMI270, ICM-42688, LSM6DS3TR-C, LSM6DSV, LSM6DSO, LSM6DSR and the MPU-6050 in its SF variant. They use a common SoftFusionSensor implementation for gyroscope and accelerometer, support gyro and accelerometer sample rate, gyroscope offset and six-side accelerometer calibration, and in the case of the BMI270 the gyroscope sensitivity auto-calibration, CRT, is additionally performed. Magnetometer support is not implemented for them, and the label is VERY experimental support.

So the practical ranking is clear. The BNO085 and BNO086 are the best, the BNO080 is good, the MPU-6500 drifts, the BNO055 is worse than a part with the same hardware, and everything else is experimental with a stated caveat. If you are choosing a sensor, choose from the top of that list rather than from what is in the drawer.

## Calibration is the part that decides whether it works

The general advice comes first. It is generally recommended to turn trackers on and let them lay down on a flat surface for a few seconds, and this will calibrate them better.

Then the README documents the sensors that need more, starting with the MPU-9250, which has a distinctive sequence. Turn them on with the chip facing down, then flip up and put on a surface for a couple of seconds, and the LED will light up. After a few blinks the LED will light up again. Then slowly rotate the tracker in an eight-motion facing different directions for about thirty seconds while the LED is blinking, and the LED will turn off when calibration is complete. You do not have to calibrate next time you power it on, because the calibration values will be saved.

The BMI160 has the longest procedure, and the README explains why each step matters. The first step is to power up with the chip facing down, or press the reset and reboot button. The LED will be lit continuously, and if you have the tracker connected via USB and open the serial console you will see text prompts in addition to the LEDs. You can only calibrate one IMU at a time. You flip it back up while the LED is still solid, wait a few seconds and do not touch the device. The LED will flash three times when gyroscope calibration begins, and the README warns that if this step is done incorrectly it is the most likely source of constant drift. The tracker must not move or vibrate for five seconds. Then it flashes six times when accelerometer calibration begins, which requires holding the device in six unique orientations, the sides of a cube, keeping it still and not touching for three seconds each, and it uses gravity as a reference and automatically detects when it is stabilized, so the process is not time-sensitive. There will be two very short blinks when each position is recorded. You rotate the device 90 or 180 degrees in any direction, and it should be on a different side each time, continuing until all six sides have been recorded, and the last position has a long flash indicating exit from calibration mode.

For the BMI160 there is extra advice, and it is the kind of detail you only get from having done it. For best results, calibrate when the trackers are warmed up, so put them on for a few minutes, wait for the temperature to stabilize at 30 to 40 degrees Celsius, then calibrate, and you can enable developer mode in SlimeVR settings to see tracker temperature.

There is also a legacy accelerometer calibration method that collects data during in-place rotation by holding it in hand instead, switchable in the config file defines_bmi160.h. If you are absolutely unable to use the default six-point method you can switch to it, and if you need faster recalibration you can disable accelerometer calibration entirely by setting the BMI160_ACCEL_CALIBRATION_METHOD option to ACCEL_CALIBRATION_METHOD_SKIP in the same file, which is safe if you do not have issues with pitch and roll. To check the result, enable developer mode in SlimeVR settings under General and Interface, go back to the Home tab, press the Preview button inside the tracker settings for each tracker to show the IMU visualizer, and check whether pitch and roll resemble the real orientation.

One last practical note: calibration data is written to the flash of the MCU and is unique for each BMI160, so keep that in mind if you have detachable auxiliary trackers.

## Why the sensor choice matters more than the code

Reading the compatibility list and the calibration notes together gives a fairly complete picture of what building one of these involves, and it is worth stating the underlying reason rather than just listing the sensors.

A Vive-style tracker has to know where it is in space, and it knows that by fusing a gyroscope, which tells it how it is rotating, with an accelerometer, which tells it which way is down, and, if the mode is nine degrees of freedom, a magnetometer, which gives it an absolute heading. The difficulty is that the accelerometer is only a reference while the device is roughly still, so it corrects the gyroscope's drift, and the magnetometer is only usable in a place without too much magnetic interference. Everything in the compatibility table is a variation on how well a given chip manages that trade-off.

The BNO085 and BNO086 come out best because their device motion processor does the fusion internally with hardware designed for it, and the ARVR stabilised rotation vectors are the sensor-fusion output with the least noise. The BNO080 is the same idea without the newest stabilisation. The MPU-6500 and MPU-6050 fuse in their own DMP but can drift substantially. The BNO055 does much worse than the BNO080 despite the same hardware, which is a firmware and sensor-fusion story rather than a silicon story. The MPU-9250 adds a magnetometer through Mahony fusion and needs a good magnetic environment. The BMI160 and the LSM and ICM families use a software fusion the project calls SoftFusionSensor, which is the most experimental part of the firmware.

That is also why the calibration procedures differ so much between sensors, and why the MPU-6500 and MPU-6050 have an unusual auto-calibration note. The MPU will auto calibrate when powered on, you must place it on the ground and do not move it until calibration is complete, for a few seconds, and the LED on the ESP will blink five times after calibration is over.

The take for anyone reading this is that the firmware is the smaller half of the problem. The sensor determines the tracking quality, the calibration procedure determines whether you get that quality, and the server does the pose resolution on top.

## Conclusion

SlimeVR-Tracker-ESP suits a VR enthusiast who wants head and hand tracking without buying commercial trackers, and it suits anyone who wants to try several IMUs on the same firmware and see the difference. It is the wrong choice if you want a polished product, since the compatibility table grades most of the sensors as experimental or not recommended, and it is the wrong choice if you need one-tracker-and-go, since calibration is a manual procedure that differs per sensor. Before you build, pick your IMU from the compatibility list rather than from what you have, note that the BNO080 and BNO085 are the ones described as giving the best results, and read the calibration section for your specific chip, because a miscalibrated tracker drifts regardless of the sensor.

## FAQ

### What does SlimeVR-Tracker-ESP do?

It is firmware for ESP8266 and ESP32 microcontrollers with different IMU sensors, used to make them act as Vive-like trackers in VR. It requires the SlimeVR Server to work with SteamVR and resolve pose, and should be compatible with owoTrack but is not guaranteed.

### Which IMU sensors work best with SlimeVR-Tracker-ESP?

The BNO085 and BNO086 are described as giving the best results, using any fusion in the internal DMP with the ARVR Stabilized Game Rotation Vector or ARVR Stabilized Rotation Vector in a good magnetic environment. The BNO080 is also good but lacks the BNO085's ARVR stabilization, while the BNO055 performs much worse than the BNO080 despite the same hardware and is not recommended.

### How do I configure the firmware for my board?

Firmware configuration is in the defines.h file, where you set the IMU value and your pinout according to how you connected the sensor. The README points at the Configuring the firmware project section of the SlimeVR documentation for the full details.

### What is the BMI160 calibration procedure?

Power up with the chip facing down, wait a few seconds without touching, then it flashes three times for gyroscope calibration during which it must not move or vibrate for five seconds, and six times for accelerometer calibration, which requires holding the device in six unique orientations, like the sides of a cube, still for three seconds each, with two short blinks per recorded position and a long flash at the end.

### How do I fix permission denied errors when uploading on Linux?

The README points at the PlatformIO documentation on udev rules and says this should solve any permission denied errors, which is the standard fix for serial device access on Linux.

## Sources

- [Issues](https://github.com/SlimeVR/SlimeVR-Tracker-ESP/issues)
- [License: Apache-2.0](https://github.com/SlimeVR/SlimeVR-Tracker-ESP/blob/main/LICENSE)
- [README](https://github.com/SlimeVR/SlimeVR-Tracker-ESP/blob/main/README.md)
- [Releases](https://github.com/SlimeVR/SlimeVR-Tracker-ESP/releases)
- [SlimeVR/SlimeVR-Tracker-ESP on GitHub](https://github.com/SlimeVR/SlimeVR-Tracker-ESP)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/slimevr-slimevr-tracker-esp
