-
-
VaxCheck Hardware
-
Vaccine Vials (One is Healthy and One is Damaged) , Damaged one was frozen and thawed — on purpose, to create ground truth.
-
Baseline Report
-
Admin Dashboard
-
Worker Dashboard
-
Vaccine Test Records
-
-
-
Vials tested ( 50 Healthy Vials and 50 Damaged Vials)
-
VaxCheck SVM - Training , Validation and Testing Accuracy
-
Acoustic Features
Inspiration :
In India's immunization programme, a vaccine vial passes through 4–5 storage levels before it reaches a child. It must stay between +2 °C and +8 °C the whole way. Everyone guards the top of that range — heat has stickers, alarms, and training. Almost nobody guards the bottom. And the bottom is where the silent killer lives: the very equipment meant to protect vaccines from heat (over-cold refrigerators, frozen ice packs packed directly against vials) is what freezes them.
Freezing destroys an aluminum-adjuvanted vaccine — DTP, Hepatitis B, pentavalent — permanently. These vaccines are suspensions: microscopic adjuvant particles carrying the antigen, evenly spread in water. Ice crystals crush those particles into dense clumps, and when the vial thaws, they never spread out again. The dose loses its potency. And here is the part that kept us awake: a frozen-thawed vial looks completely normal. Same liquid, same label, same seal.
This is not a rare event. A systematic review in the journal Vaccine (2007) found 14–35% of refrigerators and shipments exposed vaccines to freezing — and in shipments tracked end-to-end, 75–100% hit freezing at least once. An India-specific 10-state study found the freezing concentrated in the last miles — peripheral health centres and transport — the legs closest to the child.
The only field test that reads the vial itself is the WHO Shake Test: shake the suspect vial next to a deliberately-frozen control vial, wait 15–30 minutes, and compare how fast sediment settles — by eye. It is validated, but it is slow, subjective, and destroys its control vial every single time. So in practice, it is rarely done. The one piece of information that decides whether a child gets a real dose or a dead one is simply not available where the injection happens.
So we asked one question: the damage changes the physics of the suspension — can we hear it?
What it does :
VaxCheck turns the WHO's 30-minute Shake Test into a one-second tap.
A solenoid gives the vial a gentle, calibrated 50 ms strike — like flicking a wine glass. A digital MEMS microphone records 800 ms of the vial's ring. From that sound we extract physics-based features — chiefly τ_env, the time the ring takes to fade (envelope decay), and a Prony-pole estimate of the resonance (a classical signal-processing method that measures the ring's frequency and how fast it dies). A tuned SVM — a support-vector machine — then classifies the vial:
✅ Healthy — the ring fades slowly (fine suspension; pilot τ ≈ 40 ms) ❌ Damaged — the ring dies fast (clumped adjuvant; pilot τ ≈ 12 ms) ⚠️ Retest Needed — the recording was too noisy, weak, or the model was unsure That third verdict is the design decision we're proudest of. A vaccine-safety device is allowed to say "measure again" — it is not allowed to guess. Five independent quality gates (dead microphone, signal-to-noise below 10 dB, strike amplitude outside 15–95% of the sensor's range, failed decay fit, model confidence under 0.6) route any bad capture to Retest instead of a verdict.
The physics is the same phenomenon the Shake Test reads by eye after 30 minutes of settling: clumped particles both settle faster and damp sound faster. We read it in one second of sound, on hardware that costs ₹3,000 (~$36) — and the vial survives the test.
A web dashboard ties it together: a health worker presses STRIKE in a browser, watches the verdict card appear (green/red/amber, with the reason), and every test is saved as batch history with per-strike detail — turning each vial check into cold-chain quality data.
How we built it :
Hardware (₹3,000 class). An ESP32 microcontroller; a solenoid striker driven through a logic-level MOSFET (a transistor switch) with flyback protection; and an ICS-43434 digital I²S MEMS microphone. We chose a digital mic deliberately: its 24-bit ADC sits inside the chip, so the signal leaves as numbers — an analog mic would have carried the solenoid's 2-amp switching noise straight into the measurement. The firmware (Arduino C++) fires the striker and streams raw audio over USB at 921,600 baud. No inference on the microcontroller, by design — so the intelligence lives in software, and deployed hardware never needs touching when the model improves.
Signal integrity — the hard 20%. A 2-amp solenoid centimeters from a microphone is electromagnetically hostile, and our first data was dominated by a ~1.2 kHz electrical artifact. We debugged it like an experiment, not a guess: silent captures with the striker off, noise-floor reports that split the spectrum by band, and step-by-step bisection of the USB, power, and ground paths. The fixes: star grounding (every component gets its own wire to one single ground point, so the solenoid's current never flows through the microphone's ground), a filtered mic power supply (ferrite bead + RC filter), and a 2.4 kHz high-pass guard in the analysis — clinic and electrical noise live below 2.4 kHz, the vial's ring lives at 3–7 kHz, so the measurement is structurally deaf to background noise.
Feature extraction (Python). Onset detection; envelope decay τ_env via Hilbert transform with a noise-referenced fit window; Prony (Levinson–Durbin) dominant-pole analysis for ring frequency and decay; signal-to-noise ratio against the pre-strike floor; ring energy; spectral band fractions; clipping diagnostics. Every analysis run prints a CAPTURE QUALITY report — the system audits its own data before trusting it.
Machine learning. A scikit-learn pipeline: median imputation (fills missing features) → standardization (puts all features on one scale) → SelectKBest (picks the most discriminative features) → SVC, an RBF-kernel support-vector machine with probability outputs. It was tuned with GridSearchCV under stratified 5-fold cross-validation — the data is split five ways, the model trains on four parts and is tested on the fifth, five times over — and evaluated on a held-out test set it had never seen, with a confusion matrix and per-class report. Damaged = 0, healthy = 1; verdicts come from predict_proba with confidence banding.
The ring's loudness fades as e^(−t/τ) — healthy vials: τ ≈ 40 ms · damaged vials: τ ≈ 12 ms. That one number, τ, is what the AI reads.
We deliberately chose a small, interpretable model over end-to-end deep learning: with a small, structured dataset, physics features plus a regularized classifier is more accurate, explainable to a clinician, and honest about uncertainty.
Trained on 100 labeled strikes (50 healthy / 50 damaged): best stratified 5-fold CV accuracy 77.5%. On the pilot physics dataset, the decay-time separation between classes is enormous — Cohen's d ≈ 16, where 0.8 is already considered a large effect. We treat classifier accuracy as data-volume-limited, not physics-limited: the class separation in τ is already decisive, and the model retrains automatically as strike data grows.
Web dashboard. A STRIKE button creates a request; a laptop agent polls for it, fires the solenoid, classifies the capture, and POSTs the verdict back. The page shows result cards, confidence, per-strike detail (τ, frequency, fit R²), and full history.
Challenges we ran into :
The 1.2 kHz ghost. Our first datasets were garbage wearing a costume: an electrical artifact locked to the capture command, with peaks near full scale in a quiet room. We hunted it with silent captures, spectrum-split noise reports, and step-by-step bisection of the ground/power/USB paths — star grounding, the filtered mic supply, and the spectral guard killed it. The rig now proves its noise floor on every capture.
Clipping masquerading as signal. Near-saturated recordings produced confident, wrong features. The fix became a feature: the quality-gate layer that now refuses bad captures with "Retest Needed" and a reason.
Evaluating honestly. Random train/test splits at strike level leak vial identity and inflate accuracy — strikes from the same vial end up in both sets — and we know because our earliest evaluations used them. Our reported SVM numbers use stratified 5-fold cross-validation plus a held-out test set; our baseline pipeline additionally scores leave-one-vial-out, and per-vial-held-out validation is the standard we are moving to as the dataset grows.
Accomplishments we're proud of :
A complete working vertical slice — firmware → capture → physics features → tuned SVM → quality gates → live web dashboard — demonstrated on real strikes of real vials. The class separation in our pilot data is enormous: healthy and freeze-damaged vials differ by roughly 3× in decay time (Cohen's d ≈ 16, where 0.8 is "large"). A refuse-to-guess architecture: quality gates, confidence banding, multi-strike aggregation. The failure mode is "ask again," never a silent wrong answer. Every number we quote, we can reproduce from logs on the spot. What we learned Physics first, AI second. The discriminative information lives in one decay constant; the ML layer should be small, interpretable, and uncertain on purpose. This is the opposite of "throw a big model at it." A measurement device must know when it's blind. Our worst data taught us more than our best — the gates exist because we watched confident garbage happen. Electromagnetic hygiene is a design discipline, not a debugging chore. Grounding topology, supply filtering, and spectral separation did more for data quality than any algorithm.
What's next for VaxCheck :
Blinded validation against the WHO Shake Test at a real cold-chain site (labels randomized, decoded only after). Per-vial-format calibration sets (the ring signature depends on glass geometry and fill volume). Noise-robust training — mixing real recorded clinic noise into training data at controlled SNRs (the DNS-challenge methodology, adapted to a resonance signal). Enclosure + phone app; CDSCO engagement as a screening/triage device.
Built With
- accessibility
- accuracy
- ai
- apis
- arduino
- c++
- electronics
- embedded-systems
- esp32
- healthcare
- html/css
- iot
- javascript
- jupyter
- machine-learning
- node.js
- numpy
- python
- react
- scikit-learn
- sensors
- social-good
- svm
- who
Log in or sign up for Devpost to join the conversation.