工業製造
産業用モノのインターネット | 工業材料 | 機器のメンテナンスと修理 | 産業プログラミング |
home  MfgRobots >> 工業製造 >  >> Manufacturing Technology >> 製造プロセス

ワイヤレスECG心拍モニター:Arduino NanoとnRF24で作るウェアラブル設計

部品と材料

uECGデバイス×1実際のBPM測定用。nRF24互換プロトコルでデータ送信可能
Arduino Nano R3×1
nRF24モジュール(汎用)×1uECGからBPMデータを受信するために必要。どのモジュールでも動作
Adafruit NeoPixelリング:WS2812 5050 RGB LED×1
LiPoバッテリー×1200mAh以上の容量のもの

必要な工具と機械

プロジェクト概要

これは私の心拍モニタリングプロジェクトの第2弾です。前回は胸に心拍を表示し、uECGと有線接続していました。見た目はクールでしたが実用的ではありません - 正確なLED数が見えにくい、視野外にある、uECGへの接続ワイヤーがセンサーに問題を引き起こし、走ると基本的に動作しません。

このバージョンはそれらすべてを解決:腕時計型で走行中でも視界内にあり、ワイヤレスなので測定値に歪みがなく、ランニング中でも正常に動作し、心臓負荷を追跡できます。

1. コンポーネント

前回と同様、すべてのハードワークはuECGが担当 - データ測定とBPMのオンボード計算。さらに、ダイレクトリンクモードに切り替えると、高解像度ECGデータ(ここでは未使用)とともに、汎用nRF24チップと互換性のある無線プロトコルですべての情報を送信。第2の重要コンポーネントはnRF24モジュール。Arduino Nanoは小さなLEDリングの下にぴったり収まるサイズなのでコントローラーとして使用(実際は何でも動作)。

2. 回路図

nRF24モジュールの接続はシンプルではありません。SPI全線(MISO、MOSI、SCK、CS)、チップイネーブル線、電源を接続する必要があります。コンパクトにまとめるならピンヘッダーをすべて外し、パッドに直接ワイヤーをはんだ付け。nRFだけで7本のワイヤー、14箇所のはんだ付けが必要。良いニュースは他はシンプル:LEDリングはデータ線1本と電源線2本、バッテリーコネクターに電源線2本。

接続一覧:

重要: MOSI、MISO、SCK線を他のArduinoピンに接続することはできません。SPIハードウェアはD11、D12、D13に固定されており、そこ以外では動作しません。他のピンは変更可能(プログラム側で対応する変更が必要)。

3. プログラム

ソフトウェアで複雑なのはRFチャネル設定のみ。動作させるまでにかなり時間を費やしましたが、uECGとnRF24がパイプアドレスのビット順で異なることに気づいて修正したら、即座に動作しました。基本的には着信パケットを読み取り、5番目のバイトをBPMとして使用し、フィルタリング(RFチャネルにノイズがあるため、時々正しい読み取りの代わりにランダムな値が来る。互換性のためハードウェアCRCは無効)。その後、BPMを色とアクティブピクセル数に変換するだけです。

#include 
#ifdef __AVR__
#include 
#endif
#include 
#include 
#include 
#include 

int rf_cen = 9; // nRF24チップイネーブルピン
int rf_cs = 8;  // nRF24 CSピン
RF24 rf(rf_cen, rf_cs);

// パイプアドレス - uECG側でハードコード
uint8_t pipe_rx[8] = {0x0E, 0xE6, 0x0D, 0xA7, 0, 0, 0, 0};

#define PIN 5        // NeoPixels接続ピン
#define NUMPIXELS 16 // NeoPixelsの数
Adafruit_NeoPixel pixels = Adafruit_NeoPixel(NUMPIXELS, PIN, NEO_GRB + NEO_KHZ800);

uint8_t swapbits(uint8_t a) { // uECGのパイプアドレスはビット順が反転
  uint8_t v = 0;
  if(a & 0x80) v |= 0x01; if(a & 0x40) v |= 0x02; if(a & 0x20) v |= 0x04;
  if(a & 0x10) v |= 0x08; if(a & 0x08) v |= 0x10; if(a & 0x04) v |= 0x20;
  if(a & 0x02) v |= 0x40; if(a & 0x01) v |= 0x80;
  return v;
}

void setup() {
  pixels.begin();
  for(int i=0;i 0) rf_bpm = bb;
  }
  
  long ms = millis();
  if(ms - last_pix_upd > 10) { // ピクセル更新頻度制限
    int r, g, b;
    last_pix_upd = ms;
    int bpm = rf_bpm;
    int max_bright = 160; // 最大輝度(最大255だが必ずしも最大にする必要なし)
    float dd = 25; // 色調変化のBPM間隔(青→緑→黄→ピンク→赤)
    float t1 = 90, t2, t3, t4; // t1 - 「基準」BPM、これ未満は青
    t2 = t1 + dd; t3 = t2 + dd; t4 = t3 + dd;
    
    // どのt1...t4範囲にいるかによる色変更
    if(bpm < t1) { r=0; g=0; b=max_bright; }
    else if(bpm < t2) { r=0; g=max_bright*(bpm-t1)/dd; b=max_bright-g; }
    else if(bpm < t3) { r=max_bright*(bpm-t2)/dd; g=max_bright-r; b=r/4; }
    else if(bpm < t4) { r=max_bright; g=0; b=max_bright/2 - max_bright*(bpm-t3)/(2*dd); }
    else { r=max_bright; g=0; b=0; }
    
    int on_pixels = (bpm-80)/8; // ランニング用なので80BPM未満は非表示、高負荷域で高感度に
    for(int i=0;i

4. リストバンド組み立て

すべての配線をはんだ付けし、プログラムを書き込み、uECGデータが受信できることを確認したら、すべてをまとめます。

非常にシンプルな方法でまとめました - ホットグルー。パーツ自体がほぼフィットしています(Nanoは外側リングサイズ、nRF24モジュールは内側リングサイズ、バッテリーはどのパーツにもフィットしないが、なぜか邪魔にならない - どうなってるのか不明だが、ただ貼り付けたらうまくいった)。その後、手元にあった適当なリストバンド(はんだ付けステーション付属の余り、はんだ付け時のグラウンディング用バンド)に縫い付けて完成!

5. テスト

テストでランニングに行き、完璧に動作しましたが、一つ驚きがありました。192BPMで全LED点灯になる設定にしていましたが(推奨値を超えるため)、数分のランニングで簡単に超えてしまいました。センサーエラーかと思いましたが、止めても即座に下がらず、ゆっくり緩やかに下がっていきました(動きが少ない時はセンサーは100%信頼性があります)。つまり、標準的な成人の健康的な閾値(年齢/体重ベース)をかなり超えてトレーニングしていたことになります。

面白いことに:子供の頃からアマチュアスポーツをやっていますが、10代で心臓に問題があり、時間とともに治ったと思っていました。しかし経験では、早歩き以上の負荷は常にきつかったのに、トレーニングを続けて限界が上がり、今では自分をかなりフィットだと思っています。さて質問です - 思春期の心臓問題のせいでBPMが生まれつき高いのか、気づかないうちに追い込みすぎているのか? どちらにしろ対策が必要です - モニターの最大BPMを上げるか、トレーニング強度を下げるか。:)

追記:驚いたことにuECGはEMGセンサーとしても非常に優秀 - 詳細は私のロボットハンド制御プロジェクトを参照

コード

bpm_watch.ino

#include 
#ifdef __AVR__
#include 
#endif
#include 
#include 
#include 
#include 

int rf_cen = 9; int rf_cs = 8;
RF24 rf(rf_cen, rf_cs);
uint8_t pipe_rx[8] = {0x0E, 0xE6, 0x0D, 0xA7, 0, 0, 0, 0};
#define PIN 5
#define NUMPIXELS 16
Adafruit_NeoPixel pixels = Adafruit_NeoPixel(NUMPIXELS, PIN, NEO_GRB + NEO_KHZ800);

uint8_t swapbits(uint8_t a) {
  uint8_t v = 0;
  if(a & 0x80) v |= 0x01; if(a & 0x40) v |= 0x02; if(a & 0x20) v |= 0x04;
  if(a & 0x10) v |= 0x08; if(a & 0x08) v |= 0x10; if(a & 0x04) v |= 0x20;
  if(a & 0x02) v |= 0x40; if(a & 0x01) v |= 0x80;
  return v;
}

void setup() {
  pixels.begin();
  for(int i=0;i 0) rf_bpm = bb;
  }
  long ms = millis();
  if(ms - last_pix_upd > 10) {
    int r, g, b; last_pix_upd = ms; int bpm = rf_bpm;
    int max_bright = 160; float dd = 25;
    float t1 = 90, t2 = t1+dd, t3 = t2+dd, t4 = t3+dd;
    if(bpm < t1) { r=0; g=0; b=max_bright; }
    else if(bpm < t2) { r=0; g=max_bright*(bpm-t1)/dd; b=max_bright-g; }
    else if(bpm < t3) { r=max_bright*(bpm-t2)/dd; g=max_bright-r; b=r/4; }
    else if(bpm < t4) { r=max_bright; g=0; b=max_bright/2 - max_bright*(bpm-t3)/(2*dd); }
    else { r=max_bright; g=0; b=0; }
    int on_pixels = (bpm-80)/8;
    for(int i=0;i

回路図

ドキュメントなし。nrf24_led_ring_o2Gij5oigT.fzz

製造プロセス

  1. Raspberry Piで構築する空気質・気象ステーション:InfluxDB & Grafana活用
  2. Raspberry PiとPythonでリモート温度センサーを構築 – ステップバイステップガイド
  3. Raspberry Piダッシュボードで家庭の温度を監視する
  4. リモート心拍数監視システム:AWS IoTアラート付き
  5. Arduinoで作るモニター用Ambilightシステム:没入感アップの自作ガイド
  6. Arduinoとスマホで作るスマート電圧計 – 簡単DIYプロジェクト
  7. ArduinoとMAX30100で作るリアルタイムIoT心拍数モニター
  8. フォトレジスタとArduinoで作る高精度心拍数モニター
  9. CNC加工:材料とコンポーネントの精密加工
  10. ルネサスとAltran、ソーシャルディスタンス用初の低レートパルスUWB腕時計を開発
  11. スマート衣類に統合された心拍センサーで信頼性の高いウェアラブル監視を実現