Map the board
We map your board’s power, buttons, signals, and radios onto the rig’s channels, and agree the test cases actually worth automating. If your board doesn’t need a rig this size, that is a fine answer too.
The bugs that survive to the field are the physical ones: a board that boots nine times in ten, a long-press that trips at the wrong threshold, a setting that doesn’t survive a hard power cut, Bluetooth that goes flaky after thirty reconnects. Nobody reproduces those by hand on every build. Bench is being built to: a rig designed to power-cycle, press, and measure your device and take its Bluetooth connections, driven from your test suite. The firmware and test framework work today; the first run on a real device is next.
For hardware and firmware teams who want the regressions caught on the bench, not by the first customer.
Not just firmware. A physical fixture designed to wire to your device, the ESP32 that runs it, and the Python framework your tests speak to: one product, from the relay to the assertion. In development: firmware and framework built, fixture board routed and awaiting review.
Designed to power your device through relays and press its buttons through optocouplers, with calibrated ADC and digital sense lines reading it back. The firmware drives 4 relays, 8 button lines, 4 ADC and 2 sense channels today. The carrier PCB is routed, DRC-clean, with Gerbers exported, and awaits review before it is ordered; no fixture has been wired to a device yet.
An ESP32 runs the rig over a line-based serial protocol: relay pulses and button presses timed on the ESP32 by a hardware timer, a safe power-on state with every output inactive, and BLE plus Bluetooth Classic (SPP, A2DP sink) that accept connections from your device; the rig does not initiate them. Firmware v0.2.1 is flashed on a breadboarded ESP32-WROOM-32 and verified command by command over serial.
A Python library, a CLI, and a pytest plugin, with 5 written recipes and typed accessors (rig.relay[1].pulse(500), rig.adc[1].millivolts()), so tests read like tests, not like wire protocol.
The design: actuate, measure, and connect from a single test run, so a hardware fault surfaces as a failing test with a trace. Today the library’s 34 unit tests pass against a simulated rig, and no recipe has yet run on a real device. That first run is next.
The worst bugs are often physical, like a board that boots 9 times out of 10.
Bench is Salix's test rig, designed to put real hardware inside your test suite.
An ESP32 drives relays for power, optocouplers for buttons, and reads voltages back.
Its carrier board is designed and routed, and waiting for review before it is ordered.
The firmware is built, flashed and answering commands on a real ESP32.
Relay pulses and button presses are timed on the ESP32 by a hardware timer.
A Python library, a command line tool and a pytest plugin turn that into readable tests.
5 recipes cover boot loops, brownouts, long presses, hard power cuts and Bluetooth reconnection.
The library's 34 unit tests pass against a simulated rig.
Exit codes are built for CI, so a hardware fault can surface as a failing test.
Next up is a first run on a real device.
Salix. Bench: your hardware, tested like software.
The checks that are tedious, timing-sensitive, or statistical: the ones people skip under deadline. Each is a written recipe you point at your device by editing a few constants. None has run on real hardware yet; with no rig attached they skip cleanly.
Written to cycle power N times and assert the device prints its boot banner within a deadline every time. Aimed at the intermittent boot a single manual power cycle never surfaces.
Written to drop power for 10 to 500 ms in steps and assert a clean recovery at each. The gaps are timed on the host, good to a few milliseconds; the recipe notes that sub-10 ms gaps need the relay wired differently so the ESP32 times them.
Written to hold a button 200 ms either side of its threshold and assert the right action fires on each side. The press is timed on the ESP32 by a hardware timer, not a thumb and a stopwatch; its accuracy has not been measured yet.
Written to set a value, wait for the device to acknowledge it, cut power hard with no clean shutdown, restore, and assert the value survived. A hard cut, not a graceful reboot; the cut comes after the save is acknowledged, not during the write.
For a device that connects out as a BLE central: over 30 connect and disconnect cycles driven by the device, it asserts the rig sees each connection and resumes advertising after each drop. Aimed at the handle and pairing-table leaks that only show after tens of cycles.
A rig is only useful wired to a real board. We adapt Bench to yours (channels, connectors, and test cases) in the same shape as the rest of our embedded work.
We map your board’s power, buttons, signals, and radios onto the rig’s channels, and agree the test cases actually worth automating. If your board doesn’t need a rig this size, that is a fine answer too.
We build the fixture around your device and adapt the recipes (power-cycle, brownout, timing, persistence, reconnection) to your cases, to run on the bench and, if you wire them in, from your CI: the CLI’s exit codes are designed for that. Bench has not yet run on a real device, so yours would be among the first.
You get the rig and the tests, documented. We can maintain and extend them on a retainer as the product changes: new firmware, new failure modes, new checks.
We read every enquiry ourselves and reply within two working days. Quick chats, long briefs, half-formed ideas: all welcome.
Tell us about the device: what it does, how it’s powered, the buttons and radios, and the failures you’re chasing. Prototype or in production, we’ll scope a rig around it. If an NDA needs to come first, say so and we’ll start there.