Software apps and online services
Hand tools and fabrication machines
Sudden infant death syndrome (SIDS) happened a lot among less than 1 year old babies. Respond time to help these babies is critical. (usually less than few minutes). Alert must be sent as quickly as possible to care givers. Purposed system will monitor vitals including Body Temperature, Breath, Hearth Rate, send emergency alert to care givers in real time.
Here I use nRF5340 as the core for collecting data and transmitting data out, use phone as a gateway to store data and push the data to the cloud for further analytics and aggregation. I chose MAX30102 sensor for collecting health since it's capability to acquire both heart rate and oxygen data.
MAX30102 is able to record raw IR data, detailed analysis/algorithm has to be done in the host MCU. There are several parameters need to be fine tuned such as pulse width of the light, intensity to optimize the performance for our application. After several weeks of fine tuning, I decide to move on to MAX32664 bio-sensor hub. The bio-sensor hub embedded the complicated heart-rate/SPO2 calculation algorithm and is able to generate stable, reliable data in 10 seconds after finger contact. MAX30205 is chosen for human body temperature detection for it's high accuracy in human temperature range, ± 0.1 °C. APA102 (DotStar) is used to indicate status and it's small to fit into a baby wearable comparing to NeoPixel.
Data visualization includes phone visualization and web visualization. When the data is acquired by the phone, it's displayed in the phone app with charts and key metrics. Phone also acts as a gate to push the data to the cloud when it comes. Through MQTT protocol and Grafana dashboard, I was able to build up a ready-to-use dashboard in short period.System Overview
nrf5340 module is in charge of acquiring data and expose GATT service.
- Heart Rate & SpO2 Sensor - MAX30102
I use MAX30102 breakout board for prototyping.
Here is the wiring diagram for simple prototyping.
I tried both SparkFun MAX3010x Pulse and Proximity Sensor Library and DFRobot_MAX30102 Library.
Pulse oximetry is the non-invasive measurement of the oxygen saturation (SpO2 ). Oxygen saturation is defined as the measurement of the amount of oxygen dissolved in blood, based on the detection of Hemoglobin and Deoxyhemoglobin. Two different light wavelengths are used to measure the actual difference in the absorption spectra of HbO2 and Hb. The bloodstream is affected by the concentration of HbO2 and Hb, and their absorption coefficients are measured using two wavelengths 660 nm (red light spectra) and 940 nm (infrared light spectra). Pulse is measured by calculating the time interval between each peak, usually fast flourier transform will be used to achieve stable heart rate result.
If you are interested in the principles, feel free to check references below:
- Bio-Sensor Hub - MAX32664
Sparkfun Pulse Oximeter sensor integrate MAX32664 bio-sensor hub and MAX30101 sensor. The MAX32664 sensor hub is a Cortex M4 processor that handles all the algorithmic calculations, digital filtering, pressure/position compensation, advanced R-wave detection and automatic gain control. It makes measuring heart rate and SPO2 far easier than dealing the bare MAX30101 sensor.
I decided to use MAX32664 along with MAX30102 sensor for stable and easy programming. See below comparison.
- Body Temperature - MAX30205
MAX30205 is a easy to use human body temperature sensor which has high accuracy in the human body temperature range +/- 0.1 around 35 C.
It uses 3.3V input and I2C interface. Get temperature is only one I2C command.
- APA102 / LED
APA102 is a fast SPI RGB led and can also be driven by bit bang. I use this led for indicating heart beat and status of the system.
In my opinion, Zephyr is definitely not friendly to beginners, but once you get the overall structures, it can be extremely powerful, especially for large scale project. And best thing I like Zephyr is that you can use the exactly the same codebase on different boards. i.e. If I wrote code for nRF5340 using BLE and I2C, I can use the exact same code for nRF52832 or even STM32WB55, only minor pin mapping is required for peripherals. Majority of the code remain the same, make less effort for porting legacy code to newer hardware/platform.
For this project, I created custom driver for MAX30101, MAX32664, MAX30205, APA102 code is already there using SPI or bit bang.
For MAX30101, I port the code from Sparkfun Arduino Library with heart rate algorithm. I have to create a nrf5340dk_nrf5340_cpuapp.overlay file in the boards directory to add additional definitions for sensors. See code section for highlighted code.
MAX32664 & MAX30205 follow the same process, port driver, write overlay, test on the real sensor. APA102's driver is also written, it can be found in the driver/samples folder.
Also check source code on my github.
This step takes half of my time since it's a completely new framework for me, I have to understand it in and out. But I'm glad I have this chance to get to know this great framework for complex MCU projects. And the documents are well written. Many boards & sensors are supported.
Overall layout of the Zephyr:
Flutter is used in this project to create a bridge between nRF5340 and cloud. The app constantly received notifications from nRF5340 with Heart Rate data, body temperature and then transmits the data to cloud through MQTT protocol.
Flutter is pretty good for fast prototyping comparing to vanilla Android with lots ready to use widgets. For this project I mainly use flutter_blue widget, fl_chart widget and mqtt_client. Flutter_blue is used to communicate with the nRF5340 sensor and get the lastest reading from the bio-hub sensors. fl_chart is used to display the result in the line chart format and mqtt_client is used to push the data to the AWS IoT core.
I first use fl_chart with some dummy data to generate a line chart with a timer spits out random data every second.
Second, I use flutter_blue to acquire the sensor data from nRF5340. Data is stored in a 8 bytes array and transmitted through BLE notification. The first 4 bytes of data is heart rate, second 4 bytes of data is body temperature.
For example, the data in below notification is 3F 62 03 63 00 90 D6 41
0x3F = 63 bpm, heart rate
0x62 = 98 %, SPO2 level
0x03 = Status Code, 03 means contact
0x63 = 99, Confidence level from MAX32664
0x00 0x90 0xD6 0x41 is in IEEE 754 format, convert it to float is 26.82 °C.
Third, mqtt_client is used to push all relevent data to the cloud for further monitor and analytics.
In Zephyr, power management can be done through built-in api such as pm_power_state_force, pm_power_state_set. There are different levels of Power states such as PM_STATE_ACTIVE, PM_STATE_STANDBY.
I tried to measure and optimize the power consumption of the device. Idle current is around 1mA, BLE advertising only. When BLE is connected, sensor data acquisiton also started, the current draw increased to 2mA. When sleep mode is enabled, the current draw can be lowered to 200uA.
See below current measurement.
Cloud integration is done with AWS IoT core. Data is pushed to AWS IoT Core through encrypted MQTT. Data can be visualized in the AWS IoT hub test section. I then use AWS IoT Sitewise to store the data and visualize it in Grafana with it's built-in IoT sitewise plugin.
There are lots of IoT platform ready to use for makers such as adafruit.io, ubidots.com, thingspeak.com, thingsboard.io, kaaproject.org. I chose AWS MQTT as the backend and Grafana frontend for it's simplicity and flexibility.
I made two versions of the PCB, first one is not very successful due to the difficulty of hand soldering nRF5340 chip.
Here is the schematic, basically I use nRF5340 DK and Sparkfun Bio-Sensor Hub as reference with slight modifications.
PCB is then send to JLCPCB for fabrication.
I hand solder all versions of the PCB.
First rev only use MAX30102 sensor alone, it doesn't have MAX32664 bio-hub sensor. So it's difficult to get stable heart rate result.
Then I move on to Rev 1
Enclosure 3D Printing
3D model is designed in Fusion 360.
The enclosure is made turtle-like shape to make it more friendly to babies.
Below is the finished product, basic functions work as expected. However, the firmware still need lots of polishing and optimization before it puts to use.
I used nRF53-DK and Power profiler Kit to create a baby vital monitoring system, it can monitor baby's vital biometric data in real time. Parents can remotely monitor their babies' health condition and set up alerts in case of emergences such as abnormal heart rate, high temperature due to fever and respiratory issues related to SPO2 level.
nRF53 is suitable for professional / complicated wearable projects with RTOS support and easy to port libraries.