Hi,
I implemented a ‘Sleep Monitoring’ device based on the great Seeed nRF52840 Sense board and the code is developed in the Arduino environment / IDE. It measures breathing rate, sleep positions, movements, suspected sleep apnea events by measuring low‑frequency micro‑movements of the human body.
It also measures audio noises to detect snoring.
Alerts can be triggered in case of position on the back that favors apneas and snoring.
Snoring volume can also trigger vibration alerts.
The project is designed mostly for experimentation, and my wife is the real life and happy tester, as she suffers apneas, only when she sleeps on the back. Some vibrations when she is ont eh back and… she moves to the side
The software is Arduino based, in C. The user interface generating graphics is written in Python.
Its available on Github, with some level of documentation: GitHub - midibody/Sleep_monitor: Sleep-monitoring wearable for breathing, apnea, and snoring detection with vibration alerts
It works quite well, but I would be happy to get some advices regarding the power consumption: I use the IMU and even when switching to system off (NRF_POWER->SYSTEMOFF = 1), it still burns aound 570uA. If I remove the calls to UMI functions, it falls to mostly 0uA. So, the LSM6DS3.h library included in the Arduino nRF52 package seems to force something up (I dont use the BLE firmware as I dont use Blutooth).
Any idea , code in this environment is welcome
So , You will want to check out @msfujino Posts he has some very excellent examples and code for BLE and Sleep Apnea. The Radar sensors are also very effective and getting better with each new revision.
The Tiny Size of Xiao and the Sensors makes it very suitable for these kinds of products.
I’ve also built a similar device for experimentation. It uses the MAX30102 to measure heart rate and oxygen saturation. Later, I modified it to directly measure respiration using a BME280 pressure sensor, but it hasn’t been fully debugged yet.
I’ll look into your link as well.
EDIT: I wired a push button to D0 and an LED to D1 instead of a motor, then uploaded the sketch.
I wish there was a “quick start guide” that lets I try things out without reading all the documentation.
I tried SleepMonitor.exe. Commands c and p don’t work and produce errors. Using SerialMonitor works fine.
The graph occasionally stops. Is this normal? (Especially when moving XIAO a bit faster, or when the motor LED flashes four times.)
Is it recording summary data every minute, or is it recording raw data aggregated every minute?
EDIT:
The average current during battery operation was 3mA. Peak currents occur at 100mS and 15mS intervals. ”NRF_POWER->DCDCEN = 1;” When set to DCDC mode, 3mA becomes 2.3mA.
I tried placing xiao on my chest, and it detects breathing status quite well.
It seems easier to use than the method with the BMP280 pressure sensor and nose tube.
May I use it in my project?
Modern sleep-monitoring systems can track your breathing, detect apneas, record body movements, and identify snoring during the night. By using sensitive sensors, the device continuously measures breathing patterns and notices pauses in airflow that may indicate sleep apnea. It also monitors how often you change position or move, which helps to understand sleep quality and restlessness. Snoring detection is useful for identifying possible airway problems or poor sleeping posture.
One of the most helpful features is vibration-based alerts. When the system detects abnormal breathing, long apnea events, or loud snoring, it can gently vibrate to prompt the user to change position without fully waking up. This improves comfort and safety during sleep.
Overall, this type of monitoring provides real-time feedback and valuable data for long-term sleep analysis. It helps users better understand their sleep habits, identify potential health issues early, and take steps toward healthier and more restful sleep.
Let me try to answer your questions:
1- Errors with the UI (SleepMonitor.exe). Could you copy/past the error displayed? Do other commands work?
2-The graph can stop indeed in 2 cases: (a) If the gyro detects movements: I consider that if the person is moving beyond threshold defined in variables , there is certainly no apneas, and it becomes also super hard to isolate the accelero deviations due to breath from the body general movements. (b) when the motor is activated as it is synchronous function… To avoid the interrupts when the motor activates, you can disable it with the flag ‘fEnableVibrations’ (command: ‘f50’ to set it to 0).
You can change the gyroVeto by changing values in ÍmuLib.h => gyroVeto = 100.0f.
3- Current consumption: thanks for the tip with ”NRF_POWER->DCDCEN = 1.
you can reduce further consumption if you compile without the ‘serial’ or / and the PDM microphone libraries. You can do it by commenting the line in config.h: #define USE_USB, #define DETECT_SNORE. But… its more painful to flash the board after a build as the board is not seem by the IDE and you need to double click the board reset SW to make it enter boot loader mode.
When the board is de-activated (long press on the SW / D0 to ground), it goes “NRF_POWER->SYSTEMOFF = 1;” and should burn around 700 mA.
I struggle to go lower and cannot go to a few uA only, as long as the IMU Lib is linked with the code.
4- Yes, of course you can use/ fork the code as you wish You will need to embarq ImuLib.h, and certainly a large part of config.h and utilities.h
c
Index;AccelMax;Position;BreathPerMinute;BreathMax;cSnores;cSmallMoves
Traceback (most recent call last):
File “sleepMonitor.py”, line 200, in
with open(“../dataImport.csv”, “w”, encoding=“utf-8”) as f:
FileNotFoundError: [Errno 2] No such file or directory: ‘../dataImport.csv’
[PYI-15696:ERROR] Failed to execute script ‘sleepMonitor’ due to unhandled exception!
p
Index;AccelMax;Position;BreathPerMinute;BreathMax;cSnores;cSmallMoves
Traceback (most recent call last):
File “sleepMonitor.py”, line 200, in
with open(“../dataImport.csv”, “w”, encoding=“utf-8”) as f:
FileNotFoundError: [Errno 2] No such file or directory: ‘../dataImport.csv’
[PYI-6100:ERROR] Failed to execute script ‘sleepMonitor’ due to unhandled exception!
I’d like to incorporate the algorithm for separating breathing from acceleration into my own project after reading your code. While I’ll use your code as a reference, I’d like to write it myself for practice.
EDIT:Is it recording summary data every minute, or is it recording raw data aggregated every minute?
OK, I see the bug in the SleepMonitor.exe: it seems it cannot access the parent directory of the exe to store the retrieved data into “../dataImport.csv”. I changed the path to store into the current directory. Available on github.
On the principal of the recording in Flash every minute: basically, it stores a summary of the the 600 measures within 1 minut (count of breath, max breath duration, count of moves, etc), and not raw data.
You can increase the storing frequency in Flash by modifying this param in config.h: #define TIMER_ADD_RECORD (60000UL) // 1 mn - 60000.
But… it could use a lot of flash, as I didnt structure the records to optimize their size for such case.
I spent a lot of time debugging my code to minimize the write into Flash and increase its life time (around 10k writes max apparently for the Flash), by building a ring storage to not always re-write at the same Flash positions.
But as the size of the user flash is small, I can only store 5 to 7 nights before the ring restarts at the begining of the memory. It’s mostly usefull during the long debugging/ testing period as I store heavilly small amount of data in this case.
1. An error occurs. Are there any restrictions on where it can be run?
Does it require Python? Are there any issues with how the c and p commands are used?
c
Index;AccelMax;Position;BreathPerMinute;BreathMax;cSnores;cSmallMoves
010;23;02;00;00;06;00
011;44;02;00;00;15;04
012;42;02;00;00;06;01
Traceback (most recent call last):
File “sleepMonitor.py”, line 205, in
with open(“dataImport.csv”, “w”, encoding=“utf-8”) as f:
FileNotFoundError: [Errno 2] No such file or directory: ‘dataImport.csv’
[PYI-18524:ERROR] Failed to execute script ‘sleepMonitor’ due to unhandled exception!
p
Index;AccelMax;Position;BreathPerMinute;BreathMax;cSnores;cSmallMoves
Traceback (most recent call last):
File “sleepMonitor.py”, line 205, in
with open(“dataImport.csv”, “w”, encoding=“utf-8”) as f:
FileNotFoundError: [Errno 2] No such file or directory: ‘dataImport.csv’
[PYI-8092:ERROR] Failed to execute script ‘sleepMonitor’ due to unhandled exception!
2.Are you using the onboard 2MB flash memory P25Q16H? According to the datasheet, it has 100k cycles and 20-year retention.
3.In my project, all raw data is sent via BLE to the central unit for recording to an SD card and processing. If your algorithm can separate respiration from acceleration, then the pressure sensor may not be necessary. I’ll let you know once I get results.
Sorry for your trouble with the Python UI part. There is clearly an issue to write the data file, that I dont have on my environment. May be a restriction to write in the directory where you launch the exe. You could remove the part of the code that handle it in the Python code directly as its not a key feature by the way.
Regarding the flash, I didn’t have the info on the huge writes that the integrated Flash supports, thanks! I thought also that the size was 1 Mb, not 2. I could have done a simpler storage lib
Now, it’s done and it works as an ultra basic file system.