OXRecorder SDK

Download the OXRecorder SDK as a PlatformIO library and reuse it in your own project

Download

The OXRecorder SDK bundles the firmware's ten core classes as a self-contained, redistributable PlatformIO library. Grab an archive and drop it into any PlatformIO project (see Install below).

Both archives contain an identical OXRecorder/ SDK tree — pick the one for your OS (the .zip unpacks natively on Windows, the .tar.gz on macOS/Linux). They are otherwise interchangeable.

The SDK's custom partition table is shipped separately so you can drop it into your project (see partition table below):

partitions.csv

What's inside

The SDK classes keep every hardware peripheral behind an injected interface (storage, radios, LED, I2S, cipher, GPIO), so the library is board-agnostic. It also ships production ESP32/Arduino backends for every seam and registers them as the managers' defaults at static-init time — so on a real board a manager's begin() just works with no wiring, while you can still inject your own backend (a different board, or a fake for host tests). It builds against the Arduino framework (OXLog and OXSecurity use Arduino's String/Print/Serial) and ships a host shim so it also compiles in a bare native build for unit tests.

ClassResponsibilityBundled backend
OXLogLeveled, printf-style logging to an injectable sink— (Arduino Serial)
OXFileManagerInternal-flash + SD file I/O over an IStorageBackendLittleFsBackend, SdFatBackend
OXWirelessManagerWi-Fi + BLE transport over IWifiDevice / IBluetoothDeviceEspWifiDevice, EspBluetoothDevice
OXAPIManagerREST routing + BLE command dispatch + outbound HTTP clientEspHttpClient
OXConfigManagerKey/value config and reset-button handling(uses OXSwitchManager)
OXLEDManagerStatus-LED color + animation over an ILedDeviceWs2812Device
OXAudioManagerAudio capture over an injected I2S deviceEsp32I2SDevice
OXBatteryManagerADC battery-voltage sampling with divider/curve mappingEspAdcInput
OXSecurityAES-CBC over an injected cipherMbedAesCbc
OXSwitchManagerGPIO debounce + long-press over an IGpioInputEspGpioInput
OXRecorder/ # the downloaded library
├── library.json # PlatformIO manifest (libArchive:false)
├── LICENSE # MIT
├── README.md # usage + install
├── MANIFEST.md # exact list of exported files
├── examples/BlinkStatusLed/ # runnable sample sketch
├── extras/host-mock/Arduino.h # shim for native (host) test builds
└── src/ # managers (flat) + hardware backends (subfolders)
├── OXRecorder.{h,cpp} # SDK facade — optional init()
├── OXLog.{h,cpp} OXLEDManager.{h,cpp} … # 10 managers + shared headers, flat
└── led/ wifi/ bluetooth/ audio/ http/ gpio/ crypto/ backends/ # backends

Install in a PlatformIO project

  1. 1

    Install the PlatformIO IDE extension

    In VS Code: Extensions panel → search “PlatformIO IDE” → Install → reload. A new alien-head icon appears in the sidebar.

  2. 2

    New project

    PlatformIO icon → PIO Home → Open+ New Project. Set Board to Espressif ESP32-S3-DevKitC-1-N8 and Framework to Arduino, then Finish. This is the compatible PlatformIO profile with a 4 MB flash-size override for the no-PSRAM ESP32-S3 Super Mini used by OXRecorder.

  3. 3

    Unpack the download & reference it

    Extract OXRecorder-1.0.0.zip somewhere, then point lib_deps at the folder (next section). PlatformIO copies it into .pio/libdeps/ on the next build — no manual file juggling.

  4. 4

    Build · Upload · Monitor

    Use the bottom PlatformIO toolbar: ✓ build, → upload, plug icon for the serial monitor (115200 baud to see OXLog output).

platformio.ini

Reference the SDK with one of the three lib_deps forms below. Two bundled backends link third-party libraries, so add those to lib_deps as well:

You only need these if you use the SD-card or Bluetooth backends; drop the matching line (and SD flags) if you don't.

[env:esp32-s3-super-mini]
platform = espressif32
board = esp32-s3-devkitc-1
framework = arduino
monitor_speed = 115200
board_build.partitions = partitions.csv   ; enlarge the app partition (see below)
build_flags =
    -std=gnu++17
    -D ARDUINO_USB_MODE=1
    -D ARDUINO_USB_CDC_ON_BOOT=1
    ; SdFat (for SdFatBackend): FAT16/FAT32 + exFAT API (SdFs/FsFile).
    -D SDFAT_FILE_TYPE=3
    -D DISABLE_FS_H_WARNING
    -D USE_SD_CRC=1

lib_deps =
    ; --- third-party backends (add only the ones you use) ---
    greiman/SdFat@^2.2.2            ; for SdFatBackend.cpp (SD card)
    h2zero/NimBLE-Arduino@^1.4.2    ; for EspBluetoothDevice.cpp (BLE)
    ; --- the OXRecorder SDK itself — one of: ---
    ; (a) the unpacked download — simplest:
    file:///path/to/OXRecorder
    ; (b) OR the archive directly (PlatformIO unpacks it):
    ; https://your-host.com/OXRecorder-1.0.0.zip
    ; (c) OR a git repo:
    ; https://gitlab.com/your/oxrecorder-lib.git

Partition table

The SDK is large enough that the default Arduino partition table can run the app partition out of room. The standard 8 MB S3 table splits flash into two ~3.2 MB app slots (for OTA). The bundled partitions.csv drops the second OTA slot and folds that space into a single 6 MB app partition, keeping an internal LittleFS partition for config and a coredump region.

Download partitions.csv (button at the top), drop it in your project root next to platformio.ini, and point to it with:

board_build.partitions = partitions.csv

The table targets the 4 MB ESP32-S3 Super Mini with no OTA. Its layout:

nvs 20 KB # Wi-Fi calibration + Preferences key-value store
otadata 8 KB # boot-slot selector (kept for Arduino-core compatibility)
app0 3 MB # firmware (was 1.28 MB in the default table)
spiffs 896 KB # internal LittleFS (config.json / device.cfg / health.json)
coredump 64 KB # crash dump region
If your Super Mini has a different flash capacity, or you need OTA, adjust the offsets/sizes accordingly — this table is sized to end exactly at 0x400000 (4 MB). Recorded audio is meant for the SD card (Storage::External), not internal flash, so the 896 KB LittleFS partition is sized only for small config files.

Use it in src/main.cpp

Headers are included with angle brackets (<OXLog.h>) — the library is on the include path. Everything lives in the OXRecorder namespace. Because each manager's bundled backend registers itself as the default, you just call begin() — no device argument, no extra wiring.

#include <Arduino.h>
#include <time.h>
#include <OXRecorder.h>
#include <OXLog.h>
#include <OXLEDManager.h>

using namespace OXRecorder;
OXLEDManager led;

unsigned long diff = 0;

void setup() {

  // optional; guarantees the bundled default devices
  OXRecorder::init();

  // initialize logging to the USB serial port at 115200 baud, with INFO level
  OXLog::begin(115200);

  // The bundled Ws2812Device drives the LED automatically. No device argument.
  // To override it on a different board:  led.setDevice(&myLedDevice);
  led.begin();
  led.setStatus(SystemStatus::BluetoothPairing);

}

void loop() {
  // get current timestamp
  unsigned long now = millis();

  //set the led reference time to animate the led
  led.animate(now);

  // every one second, we output the timestamp
  if (diff != now/1000) {
     diff = now/1000;
     OXLog::info("current time: %u", now/1000);
  }

  delay(5);
}
Why OXRecorder::init() is optional. Each hardware backend registers itself as its manager's default at static-init time, and this SDK ships with libArchive: false so PlatformIO links that self-registering glue directly — begin() works on its own. OXRecorder::init() is a belt-and-suspenders call for toolchains that link the SDK as a static archive with aggressive dead-stripping (which can discard glue nothing references directly): calling it once before your first begin() forces every bundled default device to link in. It is idempotent, needs no backend classes in your code, and does not call any manager's begin().

Override a bundled backend

The bundled ESP32/Arduino backends cover the OXRecorder reference board. To run on different hardware — or to inject a fake in host tests — you implement the relevant interface and register it before begin(), which overrides the default. Example for storage:

#include <OXFileManager.h>
using namespace OXRecorder;

// You provide a class implementing IStorageBackend (e.g. wrapping LittleFS).
class MyLittleFs : public IStorageBackend { /* mount(), readFile(), … */ };

OXFileManager files;
MyLittleFs flash;

void setup() {
  files.setBackend(Storage::Internal, &flash);   // override the bundled default
  files.writeFile(Storage::Internal, "/hello.txt",
                  reinterpret_cast<const uint8_t*>("hi"), 2);
}

The same seam exists on every manager: OXWirelessManager::setWifiDevice() / setBluetoothDevice(), OXLEDManager::setDevice(), OXSecurity's cipher, and OXSwitchManager's IGpioInput. Each interface is documented on its class's API reference page.

The bundled backends live under src/led/, src/wifi/, src/bluetooth/, src/backends/, etc., and double as reference implementations of these interfaces — the model to follow when writing a backend for your own board. They link ESP-IDF / NimBLE / SdFat, so exclude those folders on a bare native build (see below).

Host testing (native, no hardware)

OXLog and OXSecurity include <Arduino.h>, which does not exist in a bare native build. The download bundles a minimal Arduino shim at extras/host-mock/Arduino.h; point a native test env's include path at it (and nowhere else, so device builds still use the real header). The hardware backends link ESP32 headers, so exclude their folders — and OXRecorder.cpp, which references them — with build_src_filter, and inject your own fakes instead:

[env:native]
platform = native
build_flags =
    -std=gnu++17
    -I .pio/libdeps/native/OXRecorder/extras/host-mock   ; supplies <Arduino.h>
build_src_filter =
    +<*>
    -<OXRecorder.cpp>
    -<audio> -<backends> -<bluetooth> -<crypto> -<gpio> -<http> -<led> -<wifi>
lib_deps = file:///path/to/OXRecorder

The shim provides just enough (Print, Serial, millis()) for the managers to compile and run on the host; inject your own fakes for the hardware seams (don't call OXRecorder::init() here — it's excluded with the backends). This is the same shim the OXRecorder firmware uses for its own native unit tests.

Notes & caveats