I wanted to share a medical IoT proof-of-concept I recently built for a hackathon using the ESP32. It’s called BEAM (Bilirubin Evaluation and Analysis Meter).Clinical-grade Transcutaneous Bilirubin (TcB) meters cost thousands of dollars, making non-invasive jaundice screening inaccessible in low-resource settings. BEAM is an attempt to replicate the core optical physics of those commercial devices at a fraction of the cost, while leveraging the ESP32 to push real-time data to a Next.js web dashboard.
MCU: ESP32 Development Board (NodeMCU-32S)
Sensor: SparkFun AS7343 14-Channel Spectral Sensor (I2C)
Display: 1.8" ST7735 SPI TFT LCD
Excitation Source: 5mm Cold White LED (GPIO 26)
Input: Tactile Push Button with software debounce (GPIO 27)
Bilirubin is a yellow-orange pigment that heavily absorbs blue light (~450nm) but reflects red light. Instead of using a standard blue LED, the project uses a Cold White LED (which is fundamentally a blue diode coated in yellow phosphor). This gives us a massive emission spike in the blue range to excite the bilirubin, while providing a broad red/green baseline.The ESP32 reads the raw values from the AS7343's Blue (F3/F4) and Red (F7/F8) channels.
We then calculate the Optical Density (Absorbance) using a modified Beer-Lambert approximation for a 16-bit sensor:
$$A = \log_{10}\left(\frac{65535}{RawLight + 1}\right)$$
To account for varying skin melanin (which absorbs across the spectrum), we use a dual-wavelength subtraction model. The Red channel acts as our baseline, and the Blue channel acts as our target:
$$TcB = (A_{blue} \times M_1) - (A_{red} \times M_2)$$
As bilirubin concentration increases, blue light reflection drops, $A_{blue}$ spikes, and the final TcB score rises.
The ESP32 firmware (written via Arduino Core) is juggling a few things to make this a seamless standalone device:
Display & UI: Uses Adafruit_GFX and Adafruit_ST7735 over SPI to render a custom boot screen, real-time raw data, a scan history array, and a visual "heartbeat" to ensure the main loop isn't blocking.Wireless Flashing: Integrated ArduinoOTA so I can update the math models and UI while the unit is completely sealed in its 3D-printed enclosure.
Cloud Sync: Upon a successful scan, the ESP32 packages the $A_{blue}$, $A_{red}$, and $TcB$ values into a JSON payload and fires a POST request via HTTPClient to a locally hosted Next.js API route.State Machine: Implemented strict hardware polling and software debouncing (50ms delay) so the sensor read cycle, LED firing, and HTTP requests only execute on an intentional state change.