This document provides comprehensive instructions for building, flashing, and managing the OMI Glass firmware.
The UF2 (USB Flashing Format) method is the simplest way to flash your ESP32-S3 device by dragging and dropping a file.
From the firmware directory, run the build script:
# Build optimized release version (recommended)
./scripts/build_uf2.sh -e uf2_release
# Or build standard version
./scripts/build_uf2.sh-
Enter Bootloader Mode:
- Hold down the BOOT button on your ESP32-S3.
- While holding BOOT, press and release the RESET button.
- Release the BOOT button.
- Your device should appear as a USB drive named "ESP32S3".
-
Flash the Firmware:
- Copy the generated
omi_glass_firmware.uf2file to the "ESP32S3" drive. - The device will automatically flash and reboot.
- Copy the generated
-
Monitor (Optional):
pio device monitor --baud 115200
| Environment | Description | Use Case |
|---|---|---|
seeed_xiao_esp32s3 |
Standard build | Development |
seeed_xiao_esp32s3_slow |
Slower upload | For connection issues |
uf2_release |
Optimized release | Production/Best battery |
After building, you'll get:
omi_glass_firmware.uf2- Main firmware file (ready to flash)..pio/build/*/firmware.bin- Original binary (for advanced use).
- Device Not Appearing as USB Drive: Ensure you are correctly entering bootloader mode. Try a different USB cable or port.
- Build Fails: Make sure PlatformIO is installed (
pip install platformio). Try cleaning the build first (pio run --target clean). - Upload Issues: Use the slower environment (
./scripts/build_uf2.sh -e seeed_xiao_esp32s3_slow).
PlatformIO provides more control over the build and upload process.
- PlatformIO installed.
- ESP32 S3 XIAO board connected via USB.
- Connect your ESP32 S3 XIAO board.
- Enter Bootloader Mode (see UF2 section for instructions).
- Run the upload command from the
firmwaredirectory:# Try standard environment first platformio run -e seeed_xiao_esp32s3 --target upload # If the above fails, try the slower environment platformio run -e seeed_xiao_esp32s3_slow --target upload
- Monitor the serial output:
platformio device monitor --baud 115200
- "No serial data received" Error: Ensure the board is in bootloader mode. Try the
seeed_xiao_esp32s3_slowenvironment. - Cannot Find Device: Check USB connection and drivers. On macOS, ensure you allow the device in System Settings.
- Upload Fails: Try holding the BOOT button during the entire upload process.
This method is for users who prefer using arduino-cli.
arduino-cli config add board_manager.additional_urls https://raw.githubusercontent.com/espressif/arduino-esp32/gh-pages/package_esp32_index.json
arduino-cli core install esp32:[email protected]On Windows 11 board should be showing as esp32:esp32:XIAO_ESP32S3
but instead might show as esp32:esp32:nora_w10, esp32:esp32:wifiduino32c3, or something else.
arduino-cli board list
arduino-cli board details -b esp32:esp32:XIAO_ESP32S3Change COM5 to the port name from the board list output.
arduino-cli compile --build-path build --output-dir dist -e -u -p COM5 -b esp32:esp32:XIAO_ESP32S3:PSRAM=opiGo to your Arduino libraries folder. You can find the location with arduino-cli config get directories.user (add /libraries to the path).
Then clone the two libraries needed for Opus support:
git clone https://github.com/pschatzmann/arduino-libopus.git
git clone https://github.com/pschatzmann/arduino-audio-tools.gitThis section covers battery setup, charging, and monitoring.
The firmware includes a battery service that reports the battery level to the companion app.
- ADC Pin:
A0 - Voltage Divider: A voltage divider is required to safely measure the 4.2V battery voltage with the 3.3V ADC.
- ADC Pin:
A0 - Battery: 3.7V LiPo (3.7V - 4.2V range)
- Voltage divider: R1=169kΩ, R2=110kΩ (2.536:1 ratio)
- ADC Reference: 3.3V
Your current setup:
Battery + ----[R1: 169kΩ]----+----[R2: 110kΩ]---- Battery -
|
ADC Pin A0
The firmware is configured for these values. If you use different resistors, you must update the voltage multiplier in the code.
- Batteries: Dual 250mAh Li-ion batteries (500mAh total, 3.7V-4.3V range)
- Charging Method: Connect USB-C cable to ESP32-S3 board
- Charging LED: On-board LED indicates charging status
- Connect USB-C cable to the ESP32-S3 board (or Mac/PC)
- Red LED = Charging in progress
- Green LED = Fully charged
- Charging time: ~1-1.5 hours for full charge (from Mac USB)
- USB 2.0 port: ~500mA (1-1.5 hours full charge)
- USB 3.0 port: ~900mA (45-60 minutes full charge)
- USB-C port: ~1.5A (30-45 minutes full charge)
- Actual rate: Limited by ESP32 charging circuit (~500mA typical)
Connect to the device via serial monitor (115200 baud) and use these commands:
status
Shows current battery level, connection status, and device state.
charging
Takes 10 readings over 20 seconds and shows charging status:
- 🔋 CHARGING (>4.1V) - Actively charging
- ⚡ CHARGED (3.9-4.1V) - Good charge level
- 🔴 LOW (3.7-3.9V) - Needs charging
- ❌ CRITICAL (<3.7V) - Check connections
runtime
Shows how long your glasses will last with current charge level for different usage scenarios.
chargetime
Calculates estimated time to reach 80%, 90%, and 100% charge based on current level.
monitor
Continuous 5-second interval monitoring. Type any command to stop.
The OMI app automatically shows battery percentage when connected to the glasses.
| Voltage Range | Battery % | Status | Time to Full (Mac USB) |
|---|---|---|---|
| 4.2V - 4.3V | 100% | Fully charged | 0 minutes |
| 4.0V - 4.2V | 80-100% | Good charge | 15-20 minutes |
| 3.8V - 4.0V | 20-80% | Moderate | 30-60 minutes |
| 3.7V - 3.8V | 0-20% | Low battery | 60-90 minutes |
| 3.5V - 3.7V | Critical | Very low | 90+ minutes |
| <3.5V | Critical | Unsafe | Check hardware |
Note: Times are for 500mAh total capacity (2 x 250mAh) at typical Mac USB rates.
| Usage Pattern | Runtime | Description |
|---|---|---|
| 🔥 Heavy Use | 6-7 hours | Continuous photo capture, always active |
| ⚡ Normal Use | 8-10 hours | Mixed usage: 60% active, 30% standby, 10% sleep |
| 💤 Light Use | 12-15 hours | Mostly connected but idle, occasional photos |
- Active Mode: ~80mA (Camera + BLE + processing)
- Standby Mode: ~40mA (BLE connected, camera off)
- Sleep Mode: ~2mA (Deep sleep, button wake-up)
- 30-second photo intervals
- Continuous BLE connection
- Expected result: 8-10 hours runtime ✅
- Photos every few minutes
- Connected but mostly idle
- Expected result: 12-15 hours runtime ✅
- Continuous photo capture
- High processing load
- Expected result: 6-7 hours runtime
⚠️
status
Note the starting voltage (should be <4.1V if not charged).
- Plug in USB-C charger
- Check for charging LED (red light)
- Wait 5 minutes for voltage to stabilize
charging
You should see:
- Voltage increasing over time
- Status showing "CHARGING" when >4.1V
- Steady upward trend in readings
After 2-3 hours:
status
Should show:
- Voltage: 4.2V-4.3V
- Battery: 100%
- Green charging LED
Solution: Check voltage divider connections.
status
Look for unrealistic voltages (<2V or >5V).
Solution:
- Verify charger is connected.
- Check charging LED on ESP32-S3.
- Try different USB cable/charger.
- Check battery connections.
Solution:
- Check voltage divider wiring.
- Ensure
A0is connected correctly. - Verify resistor values (169kΩ and 110kΩ).
- Charge when battery drops below 20% (3.8V)
- Don't let battery go below 3.5V (damages Li-ion cells)
- Charge in moderate temperatures (10°C-40°C)
- Use quality USB-C charger (5V, 1A minimum)
- Avoid complete discharge (stop using at 3.7V)
- Charge regularly (don't leave dead for days)
- Store at 50% charge if not using for weeks
- Optimize usage patterns for longer runtime:
- Use light sleep mode when possible
- Reduce photo frequency for all-day use
- Disconnect when not needed to save power
- Before use: Quick
statuscheck - During long sessions: Periodic
statuschecks - While charging: Use
chargingcommand to verify progress - For troubleshooting: Use
monitorfor continuous tracking
| Issue | Command | Expected Result | Fix |
|---|---|---|---|
| Won't charge | charging |
Voltage increases | Check charger/cable |
| Shows 0% always | status |
Voltage <2V | Check hardware connections |
| Won't turn on | monitor |
No response | Charge for 30+ minutes |
| Inconsistent readings | charging |
Fluctuating values | Check loose connections |
| App shows wrong % | status |
Compare readings | Reconnect BLE |
For hardware issues: Check the voltage divider circuit and ensure the ADC pin A0 is properly connected to the battery voltage divider midpoint.