calls recorded
Project · Hospital IoT
Nurse call system
A button next to every bed. When the patient presses it, a light turns on in the corridor, an alert appears at the nurses station and the time of the call and the time of the response are recorded. That is what makes it different from a buzzer: response time can be measured.

Pilot results
9 rooms in a surgical ward at Hospital Sabogal (EsSalud, Peru), from 20 Feb to 24 Jul 2026. Figures come from a full database export.
median response · 74% under 1 minute
patients covered · 2,239 patient-days
of calls came from the bathroom · median 7.5 s
The problem
Several wards in the hospital network had been asking for call buttons for years. Without one, patients shout or wait for someone to walk by. And with a conventional buzzer, nobody knows how long it took to respond.
The decision that defines the system
An emergency button that depends on the hospital WiFi is not an emergency button. The link between the button and the room ESP32 uses no WiFi and no router: it uses ESP-NOW, Espressif's direct radio protocol. The call gets through even if the network is down.
WiFi only appears in the next hop, from the ESP32 to the server over MQTT. That is no longer the critical path: if it fails, the corridor light is already on.
My role
I designed the whole system: electronics and PCB, firmware, backend, database, dashboard and integration with the hospital information system. I also did the on-site deployment and trained the nursing staff.
Stack
| Device | ESP32 · C++ / Arduino · ESP-NOW · MQTT · LittleFS · custom PCB |
|---|---|
| Server | Node.js · Express · MQTT · cron |
| Data | PostgreSQL, with business logic in stored functions |
| Dashboard | Angular 17 · Material |
| Deployment | Docker Compose · OTA firmware updates |
Design decisions
- Logic lives in PostgreSQL. The hospital already has DBAs, and the rules stay next to the data.
- Devices report their own health. Each ESP32 sends a heartbeat with serial number, MAC, IP, relay state and signal strength, so a dead device is detected before anyone complains.
- The system does not own patient data. It reads it from the hospital system every 30 minutes and keeps working with the last known snapshot if that API is down.
- Over-the-air updates. Going bed by bed with a cable is not an option.
What the data showed
40% of calls came from the bathroom (102 of 256). That is where falls happen, and exactly where a bedside button does not reach.
Daytime responses were 20 to 40 times faster than at night. Nobody asked for that insight; it appears on its own once every call is recorded.
One caveat: the overall figure is influenced by February and March, the installation months. The most representative month of normal operation is April: 47 calls, 22.7 s median, 64% answered within a minute. That is the number I would defend.
Known limitations
- The dashboard polls instead of receiving push notifications. Moving to WebSocket or SSE is the clearest next step.
- The 30-minute patient sync is real: a patient admitted ten minutes ago does not show up by name yet.
- The average shown on the dashboard is misleading because it includes alerts nobody cancelled. The median is the right metric.
The public repository contains no patient data. Every photo was reviewed and those showing names, IDs or identifiable staff were discarded.