Dual-mode BLE firmware for ESP32-C3: simultaneously acts as a client (subscribing to a physical heart rate monitor strap) and server (broadcasting to Zwift). Includes intelligent sensor auto-discovery, non-blocking loop, and NeoPixel status feedback. Full technical documentation →
ESP32-C3 climate controller that reads temperature and humidity off an HDC1080 sensor, then drives an unmodified split AC by replaying logic-analyzer-captured remote IR codes. Heat-index hysteresis, DIP switch setpoint calibration, and an independent humidifier relay. Full technical documentation →
Arduino Uno/Nano firmware that turns a StarTrac treadmill into a self-driving HIIT walking-desk controller. Physically drives the treadmill's +/− buttons via relays to ramp speed, injects fake pedometer steps via vibration motor, and runs a non-blocking interval scheduler with TM1637 display feedback. Full technical documentation →
Industrial fuel flow meter
Built · industrial client
Fuel flow monitoring instrument built for an industrial client — sensor interfacing,
measurement firmware and enclosure, delivered as a working unit.
Built for an industrial environment rather than a bench: the enclosure, the readout and the wiring all had to survive the site and be usable by an operator with no instructions.
Smart climate control system
Delivered
Reads temperature and humidity, then drives an ordinary split AC through its own IR
protocol. Decoded the Midea 48-bit remote on a logic analyzer and rebuilt the codes.
Hardware
Arduino Nano · HDC1080 (I²C) · DHT sensor · IR transmitter LED · LCD · DIP switches
Firmware
Tick-based finite state machine · Midea 48-bit IR protocol · Pronto hex arrays
Pin map
HDC1080 sits on I²C, which is fixed to A4/A5 on a Nano. Confirm the rest against your build.
Notes
The IR side was reverse-engineered, not copied from a library. The remote's output was captured on a logic analyzer, decoded in PulseView, and rebuilt as Pronto arrays — which made it possible to generate temperature and mode commands the original remote never sent.
Nurse calling system
Prototype tested
ESP32 master station handling calls from multiple room nodes over ESP-NOW — no router
needed, so it keeps working when the building network is down.
ESP-NOW peer handling · per-node call state · dynamic LED status logic
Pin map
Not documented in your records — add yours here.
Notes
ESP-NOW was chosen over WiFi deliberately: no router, no DHCP, no association delay, so a press reaches the station in milliseconds and the system survives a building network outage. Worth checking on any rebuild: WS2812 data expects 5 V logic while the ESP32 drives 3.3 V, so a level shifter or a first sacrificial LED is usually needed.
Motorcycle dyno
In development
Machined roller set with a 21-hole optical encoder, streaming live RPM and wheel speed
to a phone dashboard over Bluetooth.
Hardware
Arduino Nano · HC-05 Bluetooth · 21-hole optical disc encoder · 220 mm and 170 mm rollers
Pulse input has to sit on an interrupt-capable pin — D2 or D3 on a Nano.
Notes
21 holes give 21 edges per revolution, so wheel speed resolves finely enough to tell runs apart instead of just reporting a peak. Counting is done in an ISR and the maths outside it — doing the division inside the interrupt loses counts at high RPM.
Multi-mode automation controller
Built
Arduino Nano controller switching a mains load through several modes, with a 4-digit
readout, debounced mode cycling and a Do-Not-Disturb mode.
TM1637 needs two GPIO (CLK and DIO) — any pair, not hardware I²C despite looking like it.
Notes
Modes are named states, not integers, so adding a mode doesn't mean rewriting the input handling. Debouncing is in software with state-change detection rather than a delay, which is what stops one press registering as three.
Treadmill controller
Built
State machine with named states for each pace phase, plus PIR motion sensing that shuts
the belt down when nobody is on it.
Hardware
Arduino · PIR motion sensor · motor drive interface · control panel
Named states make the transition table read as behaviour instead of magic numbers. PIR modules have a retrigger jumper and an adjustable hold time — the inactivity timeout has to be longer than that hold or the belt cuts out on a walker standing still.
ESP32 BLE heart rate client
Built
NimBLE client for a Magene chest strap that reconnects on its own when the link drops.
NimBLE was used instead of the stock BLE stack for the smaller memory footprint. Reconnection is treated as normal operation, not an error: the client re-scans and re-subscribes without a reset when the strap goes out of range.
Sensor & platform work
Load cells & strain gauges — Wheatstone-bridge sensing, amplification and calibration to real force values.
Pressure & differential pressure — DSC-6B and similar sensors, acquisition and conversion to engineering units.
Diesel particulate filter monitoring — differential pressure across a DPF as an indicator of exhaust restriction.
Capacitive soil moisture — HW-330 module, ADC acquisition and threshold detection for irrigation control.
ESP32 + PS4 controller — wireless gamepad input over Bluetooth; traced a Bluetooth stack linker fault to a library version mismatch.
ESP32-C3 — compact wireless platform evaluated for connected builds.
ATtiny85 — low-cost MCU for jobs where an Arduino board is more chip than the product needs.
STM8S003F3P6 — cheap MCU option for cost-sensitive production runs.
Programming & automation
Web scraping & PDF consolidation
Built
Python tool that walks a site's XML sitemap, downloads scattered stencil files and merges
them into single PDFs. Requests, lxml and PyPDF2.
Written because the source files were spread over hundreds of pages with no index. The sitemap is parsed with lxml, links are fetched with Requests, and PyPDF2 merges the results into single documents.
Metal price OCR extractor
Built
Fully offline script that cleans up scanned rate sheets in Pillow, then pulls the numbers
out with Tesseract. No API, no upload, no per-request cost.
Hardware
PC
Firmware
Python · Tesseract OCR · Pillow pre-processing
Pin map
Not documented in your records — add yours here.
Notes
Runs fully offline — no API, no upload, no per-request cost. The Pillow pre-processing step is what makes it work: raw scans of rate sheets OCR badly until the contrast and threshold are cleaned up first.
Android TV mirroring app
Planned
Phone-to-TV mirroring over WiFi ADB with low enough latency to game on. Licensing checked
first — the approach is viable under Apache 2.0.
Started as a practical problem — getting a phone onto a TV without lag — and went through scrcpy and hardware alternatives before landing on a TV-side app as the missing piece. Licensing was checked before any code: the approach is viable under Apache 2.0.
Also worked with
scrcpy + ADB — Android mirroring and remote control tuned to stay usable on older PCs.
WSL + Ubuntu — Linux development environment set up against a hard disk-space limit.
PowerShell — Windows automation and deployment scripting.
Electrical & power
Three-source AC power changeover
Delivered
Relay panel that transfers a load between three mains sources, with hardware interlocking
that makes phase shorting impossible. Optocoupler sensing keeps control isolated.
Hard-wired relay logic — no microcontroller in the safety path
Pin map
Not documented in your records — add yours here.
Notes
Source presence is sensed through optocouplers, so the control side stays galvanically isolated from mains. Transfer is break-before-make and the interlock is in the wiring, not in software — two sources physically cannot close at once, so a firmware bug can't short phases.
Inverter-free DC solar system
In development
BLDC fans and DC lighting straight off a 24 V bank — no inverter losses. Panels sized with
thermal derating for Lahore summers, MPPT charging via a Tracer 1210A.
Hardware
Tracer 1210A MPPT controller · 24 V AGM bank · PV array · BLDC fans · DC lighting
No inverter in the load path, so the conversion losses disappear. Panels were sized on derated output for Lahore summer ambient, not nameplate rating — a panel at 45 °C doesn't produce the number on the sticker. Tracer 1012A and lithium storage were evaluated against this configuration.
Design studies
12 V to 400 V conversion — architecture for a ~1 kW high-voltage DC bus from a battery or solar source.
Li-ion packs — cells and pack configurations compared by capacity, energy and fit for embedded power.
Mechanical & 3D
Parametric AC vent
Delivered
3D-printable vent whose blades move together through a linkage. Modelled in OpenSCAD so
every dimension is a variable; shipped with a browser 3D viewer.
Hardware
3D-printed blades, linkage and housing
Firmware
OpenSCAD parametric model · single-file HTML/JavaScript 3D viewer
Pin map
Not documented in your records — add yours here.
Notes
Every dimension is a variable, so the model regenerates for a different duct size without redrawing geometry. The linkage was solved so one control input sets all blade angles at once. Delivered with a browser viewer so the client needed nothing installed.
Machine shop work
Ongoing
Lathe, welding, sheet metal and die making — enclosures, mounts and roller assemblies for
the electronics above, cut in-house instead of waiting on a shop.
Hardware
Lathe · welder · sheet metal tooling · dies
Pin map
Not documented in your records — add yours here.
Notes
Enclosures, mounts, brackets and the dyno roller assembly are cut in-house. It removes the usual bottleneck where a finished board waits weeks on a fabrication shop.
Not my main work, but available if you need it: Windows and Linux
troubleshooting, PC deployment and configuration, hardware fault diagnosis and repair,
and VoIP router setup (PTCL / MicroSIP).