Inspiration
Diabetic foot ulcers often start without anyone noticing. Nerve damage (neuropathy) means many people with diabetes can't feel a blister or pressure point, so a wound can get serious before anyone sees it. Ulcers are one of the leading causes of lower-limb amputation.
Before a wound opens, there is often a warning sign: local inflammation makes that spot of skin warmer. Clinical studies on home foot-temperature monitoring use a simple rule. If one spot is about 2.2 °C (4 °F) warmer than the same spot on the other foot for two days in a row, it's time to offload that foot and call a clinician. The problem is that this means pointing a thermometer at your soles every day, and most people stop doing it. We wanted the shoe to do the measuring.
What it does
Sweet Feet is a smart insole plus a dashboard. It compares left and right plantar (sole) temperature at five matched sites: the great toe, the 1st, 3rd and 5th metatarsal heads, and the heel. For each site and each night:
ΔT = T(left, at rest) − T(right, at rest)
Each site gets one of three tiers:
| Tier | Condition |
|---|---|
| 🟢 Normal | ΔT between −1.5 °C and +1.5 °C |
| 🟡 Warning | ΔT ≥ +1.5 °C or ≤ −1.5 °C |
| 🔴 Alert | ΔT ≥ +2.2 °C or ≤ −2.2 °C on 2 consecutive days, same site, same side warmer |
The dashboard has two tabs:
- Daily tracker: a 14-night history with a foot heat map, a ΔT chart per site, a day-by-day grid, and a sensor-health panel.
- Live demo: readings from the real insole hardware once per second, streamed over Bluetooth.
It's a screening aid, not a diagnosis, and all of its messages are worded that way.
How we built it
Hardware. An Arduino with BLE reads NTC thermistors in voltage dividers. To save battery, the dividers are powered only during a reading. It converts resistance to temperature with the Beta equation:
\(1/T = 1/T₀ + (1/β) · ln(R/R₀)\), with β = 3950, R₀ = 10 kΩ, T₀ = 25 °C
An MPU6050 accelerometer decides when the foot is actually still, so the board takes its readings at rest instead of mid-step. Readings are stored in flash until a Mac connects over BLE. Each JSON line is sent as a BLE indication, which the Mac acknowledges, so nothing is lost or sent twice.
Pipeline (Python, pandas/NumPy).
- Fault masking. Every sample goes through three checks: a range check (18–40 °C), a Hampel-style spike filter against a rolling median, and a stuck-sensor detector. Bad samples are removed before any analysis.
- Rest-window detection. Feet are only comparable once they've reached thermal equilibrium. We fit a rolling least-squares slope to the average temperature and take the longest stretch where it changes by less than 0.3 °C per hour and that lasts at least 2 hours. That night's value for each sensor is the median inside that window.
- Tiering. A pure, I/O-free function applies the clinical rule above, so it's easy to unit-test.
Backend + dashboard. Convex stores the readings and pushes live updates. Writes go through mutations protected by a shared ingest key. The dashboard itself is read-only. The frontend is React 19 + Vite + TypeScript. Every threshold lives in a single config.json that both the Python pipeline and the dashboard read, so they can't disagree.
Synthetic data. We couldn't wait two weeks for a real ulcer to develop, so we built a physiological simulator. It models a body-temperature baseline, sleep plateaus, walking, a 30-minute thermal lag, and sensor noise. We used it to inject labelled scenarios: a healthy control, a developing hotspot ramping to +3 °C, and a faulty sensor.
Challenges we ran into
- A stuck sensor looks like a hotspot. A thermistor stuck at 25 °C produces a fake 5 °C asymmetry, which would trigger a false alarm. But a healthy foot at rest is also flat for hours. We fixed this by flagging a flat run as "stuck" only if the other sensors moved by more than 0.5 °C over the same period.
- Comparing feet at the right time. Raw daytime readings mostly track activity, not inflammation. Only rest windows chosen by slope gave stable, comparable ΔT values.
- A BLE service with nothing inside. The Mac connected every cycle but couldn't find our data characteristic. It turned out ArduinoBLE's
BLE.end()silently clears every service's characteristics, and our "add it once" guard stopped them from being re-added. We only found it by reading the library source. - Duplicate uploads. Treating a BLE timeout as a failure made the board resend readings that had already arrived. Switching to acknowledged indications and boot counters fixed it.
- Fewer sensors than sites. Our prototype has 3 thermistors for 10 possible positions. We made the channel-to-site mapping configurable, and the dashboard shows unwired sites as "no data" instead of guessing.
Accomplishments that we're proud of
- A complete working chain, from thermistor to dashboard: firmware, BLE receiver, analysis pipeline, real-time backend and UI.
- The fault guard works: the faulty-sensor scenario flags the bad sensor and does not raise a false alert.
- 59 unit tests plus scenario validation. The hotspot scenario reaches Warning and then Alert on exactly the expected days.
- The clinical rule is a small, pure, tested function, and every threshold is in one config file.
What we learned
- Most of the work in medical sensing is data hygiene: deciding what not to trust matters as much as the threshold itself.
- Physiology drives the algorithm: you can only compare left against right when both feet are at rest.
- BLE on microcontrollers is full of lifecycle surprises. Sometimes you have to read the library source.
- Writing a simulator with labelled ground truth let us test the full system end to end long before we had real data.
What's next for Sweet Feet
- A thin, flexible insole with all 10 sensors and a long-lasting battery.
- A pilot study with real patients to calibrate thresholds and measure false-alarm rates.
- Patient and clinician authentication before storing any real health data.
- A phone app with push notifications that guide the patient ("rest that foot, contact your care team"), plus a clinician view across many patients.
- Pressure sensing alongside temperature, to show why a spot is heating up.
Log in or sign up for Devpost to join the conversation.