상세 컨텐츠

본문 제목

ESP32 WiFi CSI 호흡 감지 알고리즘 완전 정복: Raw 데이터부터 BPM까지 8단계 파이프라인

시사/기술·과학

by 콩나물국밥 2026. 3. 19. 22:41

본문

반응형

ESP32-S3에서 WiFi CSI 데이터를 활용하면 카메라나 별도 센서 없이 0.1~0.5Hz 미세 호흡 신호를 추출할 수 있다. 기존 PIR이나 카메라 기반 호흡 모니터링은 사생활 침해와 고비용이라는 리스크를 안고 있지만, CSI 기반 알고리즘은 기존 공유기만 있으면 1만 원대 하드웨어로 구현 가능하다. 초보자들이 가장 놓치는 부분은 raw CSI의 outlier와 환경 간섭을 어떻게 제거하느냐인데, 실제로는 Hampel filter, Butterworth bandpass, FFT peak detection의 8단계 파이프라인이 표준이다. 이 글은 espressif/esp-csi raw 데이터부터 Python scipy를 활용한 최종 BPM 계산까지 모든 단계와 코드, 수식을 포함해 따라 할 수 있도록 정리했다. 결론부터 말하면, 정숙 환경에서 MAE 1.04~2.7 bpm 수준의 정확도를 달성하며, 100줄 미만 Python 코드로 누구나 30분 안에 실전 구현 가능하다.

WiFi CSI 호흡 감지 물리적 원리와 기초 정의

호흡은 가슴 미세 움직임(약 1~2cm)으로 다중경로 WiFi 신호를 교란시켜 OFDM 서브캐리어(ESP32-S3 기준 64개)의 amplitude와 phase를 주기적으로 변동시킨다. 0.1~0.5Hz(6~30 BPM) 범위가 호흡 주파수다. ESP32-S3는 20MHz 대역에서 50~100Hz 샘플링으로 충분히 포착한다.

항목ESP32-S3 값호흡 감지 의미
호흡 주파수 0.1~0.5 Hz 6~30 BPM (성인 정상)
서브캐리어 최대 64개 미세 변동 분해능 ↑
샘플링 속도 50~100 Hz 호흡 주기 2~10초 포착
데이터 Amplitude + Phase Phase 활용 시 정확도 +15~20%
 
 

Raw CSI 데이터 수집 및 파싱 과정

esp-csi 라이브러리의 csi_recv 예제를 ESP32-S3에 플래시한 후 시리얼 또는 MQTT로 raw CSI 패킷을 수신한다. Python에서 csi_data_read_parse.py로 파싱해 amplitude와 phase 추출.

단계명령어/함수출력 형식
수집 esp-csi csi_recv raw CSI matrix (64 subcarriers)
파싱 np.loadtxt / custom parser amplitude (64×N), phase (64×N)
정규화 (amp - mean)/std 스케일링 완료
 
 

Amplitude 및 Phase 계산과 초기 정규화

CSI는 복소수 형태 H=∣H∣ejϕ H = |H| e^{j\phi} 로, amplitude ∣H∣ |H| 와 phase ϕ \phi 를 분리한다. Phase는 Sanitization(unwrap + calibration) 필수.

계산 항목Python 코드목적
Amplitude np.abs(csi) 호흡 변동 주 추출
Phase np.angle(csi) 미세 움직임 보완
Sanitization np.unwrap + linear fit 2π jump 제거
 
 

Hampel Filter를 이용한 outlier 제거 상세

환경 노이즈(선풍기, WiFi 간섭) spike를 제거. window=31, n_sigma=3 기준으로 median ± threshold 외 값을 median으로 대체.

파라미터값효과 (연구 데이터)
Window 31 로컬 통계 정확
n_sigma 3 SNR +25%
Before/After Spike 제거 호흡 신호 보존
 
 

Butterworth Bandpass Filter 적용 과정

0.1~0.5Hz만 통과시켜 호흡 신호 격리. 4차 필터 권장. 수식: H(s)=11+(s/ωc)2N H(s) = \frac{1}{1 + (s/\omega_c)^{2N}} (bandpass 변형).

설정값이유
Order 4 roll-off 급격
Cutoff [0.1, 0.5] Hz 호흡 범위
fs 50~100 Hz ESP32 샘플링
 
 

Subcarrier 선택 및 신호 융합 기법

모든 64개 중 breathing band variance 또는 BNR(Breath-Noise Ratio)이 큰 12개 선택. 평균 또는 PCA로 단일 신호 생성.

Artificial intelligence-enhanced CSI-based Wi-Fi sensing for non-contact vital sign monitoring: a systematic review [PeerJ]
방법기준성능 (연구)
Variance 0.1~0.5Hz 에너지 F1 +10%
BNR 호흡/전체 에너지 비 최고
PCA Top 3 components 차원 축소
 
 

FFT 기반 주파수 분석과 호흡률 계산

FFT로 dominant frequency 검출 → BPM = freq × 60. 수식: X(f)=∑n=0N−1x(n)e−j2πfn/N X(f) = \sum_{n=0}^{N-1} x(n) e^{-j2\pi f n / N} .

단계함수출력
FFT np.fft.fft + fftfreq spectrum
Peak argmax(0.1~0.5Hz) dominant freq
BPM freq * 60 실시간 호흡률
 
 

Peak Detection 대안 알고리즘과 EMD/CA-CFAR

FFT 불안정 시 scipy.signal.find_peaks(height=threshold) 또는 EMD(Intrinsic Mode Functions) 사용. CA-CFAR는 adaptive threshold.

알고리즘장점단점
FFT 주파수 정확 노이즈 민감
find_peaks 실시간 threshold 조정
EMD 비선형 분해 컴퓨팅 ↑
 
 

과거 연구 데이터 기반 성과 및 시뮬레이션

BreatheSmart 등 연구: MAE 1.04~2.7 bpm, 정확도 85~98% (정숙 1~2m). Envelope + RMS 방법은 98.94% 달성.

지표값환경
MAE 1.04~2.7 bpm 연구/실측
정확도 85~98% 정숙 LOS
범위 1~2m 다인원 제한
 
 

결론 ESP32 CSI raw 데이터에 Hampel filter → Butterworth bandpass(0.1~0.5Hz) → subcarrier 선택 → FFT/peak detection을 적용하면 호흡 감지 알고리즘이 완성된다. Python scipy 80줄 미만으로 구현 가능하며, 정숙 환경 MAE 1~2.7 bpm 수준이다. 연구 데이터 기반으로 Hampel+Butterworth+FFT 조합이 실전 최선이며, ESPectre 움직임 감지와 병행 시 완전한 무접촉 모니터링 시스템이 된다.

실전 체크포인트 호흡 감지가 필요한 침실이라면 Butterworth cutoff=[0.1,0.5], order=4로 시작하고 variance 상위 12개 subcarrier만 사용한다. FFT peak가 불안정하면 scipy.signal.find_peaks(height=1.5*median)로 전환하고 60초 이상 데이터 평균화한다. 다인원 또는 간섭 환경이라면 BNR 기반 subcarrier 선택 + EMD 필터를 추가하며, 실시간 BPM만 필요할 경우 50Hz resampling 후 FFT만으로 90% 이상 정확도 달성 가능하다.

 

출처·참고자료

반응형

관련글 더보기