Skip to content

Releases: fobiat/openBPM

openBPM v1.2.0 - tested, and a real bug fixed

Choose a tag to compare

@fobiat fobiat released this 19 Jul 16:03

This release adds a desktop unit-test suite, and the suite immediately earned its keep by finding a genuine bug in the tap-tempo engine.

The bug it found

An off-beat tap cleared the averaging window and was then stored as its only sample. So one fumbled tap while tapping a steady 120 BPM slammed the readout to ~43 BPM — precisely the behaviour the docs claimed was handled.

The outlier is now discarded as well as resetting the window, and the previous reading stands while the window refills. Two clean taps re-establish the tempo, which is also what you want when you've genuinely moved to a record at a different speed.

Configurable pitch range

±8 % was hardcoded — correct for a Technics 1210, wrong for the many decks that do ±16 or wider, which were being told perfectly reachable matches were OUT OF RANGE.

Set it from the WiFi page; it's persisted to flash, and the pitch bar scales with it so full deflection always means the end of your fader.

Other fixes

  • Clearing a slot on the device zeroed the BPM but left the record's name behind
  • The OLED's jitter readout built its ± from a raw 0xB1 byte, which a font without U+00B1 would silently drop — now ASCII +/-
  • A failed TFT sprite allocation left a silently black screen, indistinguishable from a wiring fault; it now says so
  • The CSV download was still named openbpmcount.csv after the rename

Testing

pio test -e native      # 34 tests, no board required

app.cpp has no Arduino dependency — Deck takes the current time as a parameter rather than calling millis() — so a whole tapping session can be simulated deterministically. Coverage spans tempo averaging, outlier rejection, idle reset, jitter, beat prediction, octave matching, pitch range and the drift timer. CI now runs these before building any firmware, so binaries can't ship from a tree whose maths is broken.

Flashing

pio run -e tft -t upload

Or flash a prebuilt binary at offset 0x10000:

esptool.py --chip esp32 write_flash 0x10000 openBPM-tft.bin

Full changelog: v1.1.0...v1.2.0

openBPM v1.1.0 - works with no wiring

Choose a tag to compare

@fobiat fobiat released this 19 Jul 15:06

openBPM now runs with nothing wired to the board.

A pin scan of the ideaspark ESP32-WROOM-32 showed that GPIO0 (BOOT) is the only onboard button software can read — the board's other buttons are EN/RST, which reset the chip in hardware and never reach a GPIO. GPIO34GPIO39 idle low and cross-talk because they're input-only with no internal pull-up, so their apparent presses were floating noise rather than buttons.

So the BOOT button now drives all three actions by press length:

Gesture Action
Short press (< 0.6 s) TAP
Long press (0.6 – 1.6 s) SWAP
Hold (≥ 1.6 s) MODE

Flash it and it works immediately — no soldering required.

Also in this release

  • Wired buttons keep single-press behaviour and work alongside the onboard one; each action accepts several pins. Set GESTURE_PIN = 255 in src/main.cpp to turn gestures off once you have three real buttons.
  • pinscan no longer reports per-edge noise on input-only pins. It prints a twice-a-second level snapshot instead, so a held button is distinguishable from a floating pin.

Flashing

pio run -e tft -t upload

Or flash a prebuilt binary at offset 0x10000:

esptool.py --chip esp32 write_flash 0x10000 openBPM-tft.bin

Full changelog: v1.0.0...v1.1.0

openBPM v1.0.0

Choose a tag to compare

@fobiat fobiat released this 19 Jul 14:54

First tagged release of openBPM — a tap-tempo BPM counter and beatmatch assistant for vinyl DJing on an ideaspark ESP32-WROOM-32.

Features

  • Tap tempo with a rolling 8-interval average, outlier rejection and 3s idle auto-reset
  • Two decks (A/B) with a pitch % readout — exactly how far to move the pitch fader
  • Octave-aware matching — half/double-time records still line up, tagged x2 / 1/2
  • Drift timer — how long until the decks slip a full beat apart (60 / ΔBPM)
  • Pitch bar with a centre detent, colour-coded green/amber/red on the TFT
  • Pitch-range warning when a match needs more than ±8 %
  • Beat pulse indicator as a visual metronome
  • Tap-jitter readout so you know whether to trust the reading
  • 8 named BPM slots persisted to flash, survive power-off
  • WiFi library — the ESP32 hosts its own AP so you can name records and export CSV from a phone
  • Screen sleep after 2 minutes idle

Supported boards

Firmware Board
openBPM-tft.bin ideaspark ESP32-WROOM-32 + 1.14" ST7789 240×135 colour
openBPM-oled.bin ideaspark ESP32-WROOM-32 + 0.96" SSD1306 128×64 mono
openBPM-pinscan.bin Diagnostic — reports which GPIO each onboard button uses

Buttons

Every action accepts several pins, so the board's onboard buttons and external wired buttons both work. Defaults: TAP = GPIO0 (onboard BOOT) + GPIO27, SWAP = GPIO26, MODE = GPIO25. Use the pin scanner to identify your board's onboard buttons and edit the lists in src/main.cpp.

Flashing

Build from source with PlatformIO:

pio run -e tft -t upload

Or flash a prebuilt binary at offset 0x10000:

esptool.py --chip esp32 write_flash 0x10000 openBPM-tft.bin

MIT licensed.