← Back to blog
hackathon hardware Arduino HackaBull VII

Revive: Why I Built a CPR Trainer from $50 of Arduino Hardware

Most CPR training tools are expensive, clinic-only, or don't feel real enough to stick. We thought we could fix that with a force-sensing pad, some agents, and voice.

Sudden cardiac arrest kills around 350,000 people a year in the US. Bystander CPR — someone nearby starting compressions before paramedics arrive — doubles or triples survival odds. The problem isn't that people don't know CPR exists. It's that most people either never learned it, or learned it once in a certification class years ago and haven't thought about it since.

The reason training doesn't stick is straightforward: you learn CPR in a classroom, on a manikin, with an instructor. Then you go home and don't touch it again until the one moment in your life when you actually need it — at which point you're panicked, it's been years, and you're trying to remember something you practiced for forty-five minutes. That's not a good setup.

Revive was an attempt to make CPR training something you could actually do repeatedly, at home, without a $3,000 manikin or a class schedule.


The hardware

The physical part is a force-sensitive resistor (FSR) mounted on a foam pad. You press down on it to simulate chest compressions. An Arduino reads the sensor at 200Hz and streams the data to the browser over the Web Serial API. Total hardware cost: under $50.

The tricky part is that force sensors are noisy. A single compression produces multiple threshold crossings — the sensor bounces around at peak force and again as you release. If you count every threshold crossing as a compression, you get numbers that are completely wrong. The fix is dual-threshold hysteresis in the Arduino firmware: the sensor has to cross a high threshold to register the start of a compression and a separate low threshold to register the end. Everything in between is treated as noise. This alone cut false compression counts by about 30%.

The 200Hz sampling rate matters because you're measuring two things simultaneously: compression depth (derived from how hard you press) and compression rate (compressions per minute). AHA guidelines care about both. At 200Hz you have enough resolution to distinguish a shallow tap from a proper compression, and to count rate accurately at the 100–120 compressions/minute target. At lower sampling rates you'd start missing peaks.


The multi-agent design

The AI side has three Gemini agents, each with a distinct responsibility:

The physiology agent tracks the virtual patient's vitals. Based on the quality of your compressions over the last few seconds, it updates heart rate, blood pressure, and SpO2. This is what makes the training feel real — you're not just pressing a pad and getting a score, you're watching someone respond to what you're doing.

The evaluation agent compares your compressions against AHA guidelines and generates coaching in real time. Is your depth adequate? Is your rate on target? Are you letting the chest fully recoil between compressions? This agent knows the standards and keeps you honest.

The scenario agent controls the narrative. Is the patient stabilizing or deteriorating? Does a passerby appear and ask if they can help? Should the 911 dispatcher give updated instructions? This is what turns it from a feedback tool into a simulation.

These three agents share data through an event bus. Every 500ms, the compression buffer is batched and sent to whichever agents need it. The 500ms batching interval is intentional — you genuinely don't want feedback arriving every half-second while you're doing compressions. It's overwhelming and pulls your attention away from the patient. At 500ms the feedback arrives at a pace you can actually absorb and act on.


The voice layer

Audio output uses ElevenLabs TTS with three distinct voices: a calm instructor, a 911 dispatcher, and a panicked bystander. Each agent owns one voice. This distinction matters for a reason that sounds small but isn't: when you're focused on doing compressions and your eyes are on the patient, you need to know who's talking without looking at a screen. A different voice tells you immediately whether it's coaching (instructor), procedural guidance (dispatcher), or scene context (bystander). That's the kind of UX decision that only makes sense in the context of simulating an emergency.


Why hardware at all

A fair question is: why not just simulate this entirely in software? You could have a user click a button to simulate compressions, or measure something through the camera.

The honest answer is partly that we thought it was more interesting. But there's a more principled reason: muscle memory is real. If you want to train someone to do something under physical and emotional pressure, having them do the physical motion — even a simplified version of it — is meaningfully different from clicking a button. The cognitive and motor rehearsal happens together.

There's also an accessibility angle. Professional CPR training manikins cost hundreds to thousands of dollars. A foam pad and an Arduino is under $50. If the software is the expensive part of good training, maybe the hardware doesn't have to be.


What I'd change

The Web Serial API works on Chromium-based browsers and nowhere else — no Firefox, no Safari, no iOS. For a real product you'd need either a native wrapper or a Bluetooth LE path from the Arduino. We knew this going in; for the hackathon it was an acceptable constraint. For a real deployment it's a blocking issue.

The scenario library is also thin — there's one scenario (adult cardiac arrest). A meaningful training tool needs a library: drowning, choking, infant CPR, two-rescuer scenarios. That's the next layer of work, and it's mostly content and prompt engineering rather than new infrastructure.