Running SlimeVR firmware on the Adafruit ESP32-S3 Feather
By Robert Russell
- 5 minutes read - 1009 wordsOver the summer I built some Slime VR trackers for myself. It’s now December and I still haven’t used them very much personally. I wrote about the part selection at the time but I never explained how to put firmware on the trackers.
SlimeVR is written with the ESP32 family of microcontrollers in mind. I chose a board with the very capable ESP32-S3 for my build. There are always slight variations across different microcontrollers, even with similar names, and even from the same vendor. It can be difficult to tell which features are important to the firmware. I’ll give just the steps on how to program the boards I uses without too much extra chit-chat.
In order to follow along you’ll need:
- DIY SlimeVR tracker parts
- USB-C data cable (not that special but it has to handle data, not just charging)
- A computer, probably running Windows
- Changes like mine for the SlimeVR tracker firmware
- A bunch of FOSS: PlatformIO, the SlimeVR server, and maybe the Arduino IDE as an alternate serial console.
The basic steps are:
- Get the tracker firmware
- Plug in the tracker, boot into the bootloader
- Program the firmware using PlatformIO
- (Maybe) manually set the wifi info using the Arduino serial monitor
Tracker firmware
The SlimeVR tracker firmware is available on github and the official documentation explains how to use it. I’ve added changes in my own fork to support the Adafruit ESP32-S3 Feather. Here’s a link to my fork and this link highlights just the changes.
And I have to pause here for a brief mea culpa: I can make this simpler for other people who want to build trackers like mine but that will require me to communicate with other humans. I haven’t yet talked to anyone who actively works on SlimeVR but they seem like nice people. If I asked to integrate my changes then they may well accept them and this would be easier for other people to use. If I manage to do that then I’ll update this post.
For now you need to either clone my fork (which may get a little behind the main repo) or pull the official repo and make equivalent changes in there. Sorry about that, I really should try to get my changes upstreamed.
The differences between the main branch and my fork are small:
LiPo fuel gauge
The MAX17048 is a little different from the other battery charging and monitoring options. I added BAT_MAX17048
and use that constant to trigger the correct I2C address, register address, and conversion formula for getting the battery voltage.
Pin definitions
I added constants like ADAFRUIT_FEATHER_ESP32S3
and similar values so that Platformio can recognize the board. The board type also selects the GPIO and I2C pin numbers in defines.h
.
The values in src/consts.h
set ADAFRUIT_FEATHER_ESP32S3
to 18 and BAT_MAX17048
as 5 but they just have to be unique within the list. The values in src/defines.h
do matter though, they refer to specific pin numbers on your microcontroller board.
Normal configuration changes
As the SlimeVR docs explain, all custom hardware needs some configuration in platform.ini
and defines.h
. This handles things like which board you’re using, which IMUs you’re using, etc.
Booting into the bootloader
The Adafruit ESP32-S3 Feather normally boots up and runs a CircuitPython script as soon as you plug it into a USB port on your computer. Python is great but it’s not what we want for running the SlimeVR tracker firmware. In order to load the firmware you’ll need to enter the Arduino bootloader instead. If you see the bright light on the board pulsing different colours then you’re running the default Python script and haven’t entered the bootloader. The sequence is:
- Press the boot button, keep holding it down.
- Press the reset button then release it.
- Release the boot button.
Adafruit also explains how to boot into the bootloader on a Feather. Basically you hold down one button, press and release reset, then let go of the other button. You’ll know it worked because the neopixel isn’t glowing. There might be no lights on the board. But you’ll see the board listed in the Arduino IDE or you can access it from PlatformIO.
The downside of the Adafruit Feather boards (for this application) is that they steer pretty hard toward CircuitPython. When the Arduino code crashes it seems like the device reboots into the UF2 bootloader and runs whatever CircuitPython code is there. Rebooting back into our firmware seems to need a press of the reset button. I expect there’s a way to settle this but I haven’t figured it out yet. Leaving the default CircuitPython script on there at least helps detect when it’s happened since it makes the neopixel LED cycle through the rainbow..
Once the board shows up in the bootloader it can be programmed like any other microcontroller board with PlatformIO so the regular instructions will work with the modified firmware.
Setting up WiFi
Setting up WiFi using serial commands
I do notice that sometimes the SlimeVR server doesn’t detect my board. So I just use the serial monitor in the Arduino IDE to send it the command that the server would. I found commands in src\serial\serialcommands.cpp
that do the job. I ran something like:
SET WIFI yourssid yourwifipassword
Setting up WiFi in source code
Alternatively, you could hardcode the credentials in the source. I don’t personally like doing it since I mess with my network too often. But if it suits your needs then you can fill in the WIFI_CREDS
values in platformio.ini
.
Power Switch
Just one more thing… If you have a power switch to cut off the battery then pay attention to it when you try to reset the board. Your board can be powered from either USB or battery. If you want to cut off power to the board then you need to turn off both. I ended up using the JST 2-pin Extension Cable with On/Off Switch along with the rest of my parts from Adafruit. It’s convenient to connect but it’s really huge for this particular application.