I have read a decent amount of papers that used wrist smartwatches to measure respiratory rate, or papers that used sensors attached to a persons chest. I can link them if it is necessary.

I am working on a project in my spare time to help my mother and myself understand our respiratory rate/breathing rate while sleeping.

My idea uses an ADXL362 Datasheet here. The sampling rate is about 12 hz, and measures 12 movement changes in a second. I can make this larger, I just need to verify it is the correct way to do it :)

Currently the data I recover seem decent. I am measuring on myself, and I have realized that measuring sleep is really difficult with an accelerometer, as I for instance move a lot while I sleep. It's interesting to see, but also really difficult to "filter" and understand. Ideally I would use the z axis data, as this should measure the movement I want to address while breathing, so an upwards movement from the chest, while laying down on my back. The problem comes when I twist and turn in my bed.

Here is an example of my data. This is only an 1 hour segment, as the 24 hour data is too large. Sharecsv link, not sure if it is allowed here. I can also add the big file I am working on, but it is 50mbs large

I read that the typical approach was to use a butterworth filter alongside a lowpass filter, which I tried implementing after reading a similar question asked on this forum(thanks for being cool guys!).

import numpy as np
from scipy.signal import butter, lfilter, freqz
import matplotlib.pyplot as plt

def butter_lowpass(cutoff, fs, order=5):
    nyq = 0.5 * fs
    normal_cutoff = cutoff / nyq
    b, a = butter(order, normal_cutoff, btype='Low', analog=False)
    return b, a

def butter_lowpass_filter(data, cutoff, fs, order=5):
    b, a = butter_lowpass(cutoff, fs, order=order)
    y = lfilter(b, a, data)
    return y

# Filter requirements.
order = 6
fs = 12.0       # sample rate, Hz
cutoff = 2 # desired cutoff frequency of the filter, Hz

# Get the filter coefficients so we can check its frequency response.
b, a = butter_lowpass(cutoff, fs, order)

# Plot the frequency response.
w, h = freqz(b, a, worN=8000)
plt.subplot(2, 1, 1)
plt.plot(0.5*fs*w/np.pi, np.abs(h), 'b')
plt.plot(cutoff, 0.5*np.sqrt(2), 'ko')
plt.axvline(cutoff, color='k')
plt.xlim(0, 0.5*fs)
plt.title("Lowpass Filter Frequency Response")
plt.xlabel('Frequency [Hz]')

# Demonstrate the use of the filter.
# First make some data to be filtered.
T = 76160.5       # seconds
n = int(T * fs) # total number of samples
t = np.linspace(0, T, n, endpoint=False)
# "Noisy" data.
data = df['z']

# Filter the data, and plot both the original and filtered signals.
y = butter_lowpass_filter(data, cutoff, fs, order)

plt.subplot(2, 1, 2)
# plt.ylim(1.8,2.3)
plt.plot(t, data, 'r-', linewidth=1,label='data')
plt.plot(t,y, 'g-', linewidth=2, label='filtered data')
plt.xlabel('Time [sec]')


I know this is a stupid way of doing it. I am just trying to understand the world of signal processing.

I have tried reading various papers and interesting articles on this subject, and It seems as it is possible.

What I have done so far, is that I have measured myself at the abdomen level(close to the right lung, as I read a paper that stated the right lung was slightly larger then the left, I can link this if anyone is interested). I have measured 24 hour data for a couple of days, and I can clearly see when I wake up and when I go to sleep, just by viewing the data with my eyes. Here is an example of how I slept. 24 hour data, green is filtered data, red is unfiltered

Ideally as the placement of my sensor suggests that I use the z-axis to measure respiratory changes, I have only used that axis. This is wrong, as I would love to incorporate the other axes to normalize my data, I just don't know how or what the notion is exactly. This is an image of all the 3 axes plotted: Wake up at around the 30000 second mark, slow morning, and minimal movement.

So what I am really asking is, what should I do? I was thinking to add max thresholds to delimit the large fluctuations, or somehow normalize my data by using all the axis. Currently I am only looking at the z-axis, and I know it is wrong, I am just not sure what to do more. I am not that savvy in signal processing, so any links and papers that teach me methods and knowledge would be great! :)

And another thing. I ultimately want to figure out respiratory rate, and I am unsure if their exists a formula to attain this? My logic would be to count the peaks in minute segments and thus having an idea of a "breathing rate". Is this the typical way of doing it?

And I apologize for my fluctuating English, it is not my native language and I have a tendency to overexplain what I am thinking :)


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.