Selected work
Neurocalm
An EEG system that reads a live signal from OpenBCI hardware and scores focus, load and anomaly against a baseline calibrated to the person wearing it. Built by a team of five.
The problem
Relaxation advice is generic. Everyone is told to breathe slowly. For some people that works, for others it does nothing, and there is normally no way to tell which group you are in except by how you feel afterwards. If you can measure what a technique actually does to someone's brain activity, the recommendation stops being a guess.
The engineering difficulty is that EEG is a continuous, noisy stream. It is not a value you fetch, it is a signal you follow, and everything downstream has to be built for that.
What I built
A local Python service reads from OpenBCI hardware through BrainFlow, computes band powers from the raw signal, and streams them over a WebSocket. A React dashboard turns those into three running figures, focus, load and anomaly, plotted live against each other as the signal arrives.
A session starts with calibration: thirty seconds of rest recorded as a personal baseline, so every score afterwards is relative to that person rather than to a population average. Readings are then grouped by what the wearer is actually doing, across meetings, studying, lectures and a health journal, because the same load figure means something different in a lecture than it does in a meeting.
Events are written to SQLite with a timestamp, mode, scores and context, and that history is what the reinforcement learning component trains against. A synthetic board mode stands in for the hardware, so the system runs end to end without an OpenBCI headset attached.
This was a five person project. My work was on the Python service and the data path between the hardware and the dashboard.
Decisions
Stream it, do not poll it.
Band powers are computed continuously from a live signal. Polling an endpoint would have imposed a second, arbitrary sampling rate on data that already has one, and would have left the visualisation lagging the person wearing the headset. A WebSocket keeps the dashboard at the rate of the signal instead of the rate of a timer.
Keep signal processing out of the browser.
Band power computation happens in Python next to the hardware, through BrainFlow, and the browser receives derived values. That keeps a numerical pipeline in the language that has the libraries for it, and it turns the dashboard into a rendering problem rather than a signal processing one.
Make the hardware optional.
The synthetic board path went in early. Five people cannot share one headset, and a system that only runs with specific hardware attached is a system exactly one person can work on at a time.