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

OLEDスクリーンでリアルタイムECGを取得

コンポーネントと消耗品

>
Arduino UNO
× 1
uECGデバイス
× 1
nRF24モジュール(汎用)
× 1
ElectroPeak 0.96 "OLED64x128ディスプレイモジュール
× 1

このプロジェクトについて


少し前に、uECGデバイスからデータを取得する方法を示すいくつかのプロジェクトを投稿しましたが、それらにはかなり多くの厄介なコードがあり、それでも基本的なデータのみを使用していました。最後に、この方法をよりシンプルで信頼性の高いものにするArduinoライブラリを作成しました。https://github.com/ultimaterobotics/uECG_library(ライブラリマネージャーからRF24ライブラリもインストールする必要があることに注意してください。このプロジェクトのようにOLEDにデータを表示したい-AdafruitのSSD1306ライブラリも)。

1.回路図

回路図は、nRF24モジュールとOLEDを使用する他のプロジェクトと同じです。nRF24はArduinoのSPIバス(D13、D12、D11)と、モジュールCSおよびCEライン用の2つの任意のピンに接続されています。便宜上D10とD9を選択しました。唯一の重要なポイント :nRF24モジュールは 3.3V に接続する必要があります ライン、5Vではありません!また、3.3VとGNDの間に1uFまたは10uFのコンデンサを追加することも大いに役立ちます-これらのnRF24モジュールは、Arduinoが3.3Vラインで常に提供できるとは限らない安定した電圧を必要とします。コンデンサはそれを助けます。

OLEDはI2C(SDAからA4、SCLからA5)を介して接続され、5Vラインから電力が供給されます。私の場合、OLEDモジュールにはI2Cプロトコル用の抵抗が組み込まれていました。モジュールに抵抗がない場合は、SDAから3.3VおよびSCLから3.3Vに4.7kの抵抗を追加する必要がありますが、最近見たほとんどのモジュールにはすでに抵抗があります。

以下に添付されている回路図を見ることができます。これが組み立てられたプロジェクトの写真です:

<図>

2.コード

uECGライブラリは、適切に動作するためにかなりの数行のコードを必要とします。つまり、

setup()では、uECG.begin(pin_cs、pin_ce)を呼び出す必要があります。nRF24CSおよびCE回線に使用されているピン番号を指定する必要があります。これにより、モジュールがオンになり、内部で正しいモードになります。

loop()では、できるだけ頻繁にuECG.run()を呼び出す必要があります。uECGデバイスは大量のデータ(数ミリ秒ごとに1つのパケット)を送信します。次の時間までにuECG.run()を呼び出さない場合パケットが到着すると、そのデータは失われます。つまり、ループ内でdelay()関数を呼び出さず、タイミングが必要なタスクにはmillis()を使用します(ライブラリの例にその例を追加しました)。

このプロジェクトコードは、ライブラリ内の例として利用でき、以下にも添付されています(複雑すぎる場合は、コードの95%が最適化された表示描画専用であり、シリアルモニターに値を簡単に印刷できることに注意してください。ほんの数行必要です):

  #include  
#include
#include

#define SCREEN_WIDTH 128 // OLEDディスプレイ幅(ピクセル単位)
#define SCREEN_HEIGHT 64 // OLEDディスプレイ高さ(ピクセル単位)

// I2Cに接続されたSSD1306ディスプレイの宣言(SDA、SCLピン)
# define OLED_RESET -1 //ピン番号をリセット(またはArduinoリセットピンを共有している場合は-1)
Adafruit_SSD1306 display(SCREEN_WIDTH、SCREEN_HEIGHT、&Wire、OLED_RESET);

int rf_cen =9; // nRF24チップイネーブルピン
int rf_cs =10; // nRF24CSピン

void setup(){
Serial.begin(115200); //シリアル出力-デバッグに非常に役立ちます
while(!display.begin(SSD1306_SWITCHCAPVCC、0x3C)){// 128x64のアドレス0x3D
Serial.println(F( "SSD1306割り当てに失敗しました"));
}
display.display();
delay(100);
uECG.begin(rf_cs、rf_cen);
delay(100);

//バッファをクリアします
display.clearDisplay();
display.setTextSize(1); //通常の1:1ピクセルスケール
display.setTextColor(WHITE); //白いテキストを描画します
display.cp437(true); //完全な256文字を使用 'コードページ437'font
display.display();
delay(100);
Serial.println( "after display");
}

uint32_t prev_data_count =0;
uint32_t prev_displ =0;

uint8_t ecg_screen [128];
int ecg_screen_len =128;
float ecg_avg =0;
float ecg_max =1;
float ecg_min =-1;
int ecg_size =40;

int displ_phase =0;

void loop()
{
uECG.run();
uint32_t data_count =uECG.getDataCount();
int new_data =data_count --prev_data_count;
prev_data_count =data_count;
if(new_data> 0)
{
uint32_t ms =millis();
int16_t ecg_data [8];
uECG.getECG(ecg_data、 new_data);
for(int x =0; x Serial.println(ecg_data [x]);

for(int x =new_data; x ecg_screen [x-new_data] =ecg_screen [x];
for(int x =0; x {
ecg_a vg * =0.99;
ecg_avg + =0.01 * ecg_data [x];
ecg_max =ecg_max * 0.995 + ecg_avg * 0.005;
ecg_min =ecg_min * 0.995 + ecg_avg * 0.005;
if(ecg_data [x]> ecg_max)ecg_max =ecg_data [x];
if(ecg_data [x] int ecg_y =63-ecg_size *(ecg_data [x] --ecg_min)/(ecg_max --ecg_min + 1);
ecg_screen [ecg_screen_len-1-new_data + x] =ecg_y;
}

if(ms --prev_displ> 30)
{
prev_displ =ms;
if(displ_phase ==0)
{
display.clearDisplay();
display.setCursor( 0、0);
display.print( "BPM:");
display.println(uECG.getBPM());
display.print( "RR:");
display.println(uECG.getLastRR());
display.print( "steps:");
display.print(uECG.getSteps());
int batt_mv =uECG .getBattery();
int batt_perc =(batt_mv-3300)/ 8;
if(batt_p erc <0)batt_perc =0;
if(batt_perc> 100)batt_perc =100;
display.drawLine(110、0、127、0、WHITE);
display.drawLine(110 、10、127、10、WHITE);
display.drawLine(110、0、110、10、WHITE);
display.drawLine(127、0、127、10、WHITE);
int bat_len =batt_perc / 6;
for(int x =1; x <10; x ++)
display.drawLine(110、x、110 + bat_len、x、WHITE);
}
if(displ_phase ==1)
{
for( int x =1; x display.drawLine(x-1、ecg_screen [x-1]、x、ecg_screen [x]、WHITE);
}
if(displ_phase ==2)
{
for(int x =ecg_screen_len / 2; x display.drawLine(x-1、ecg_screen [x- 1]、x、ecg_screen [x]、WHITE);
}
if(displ_phase ==3)
display.display();
displ_phase ++;
if (displ_phase> 3)displ_phase =0;
}
}
}

3.データの処理

多くの処理がオンボードで実行され、デバイスによって計算されたさまざまな統計情報を取得できます:BPM、GSR、最後のRR間隔、HRVパラメーターおよび16個のHRVビン(最初のビンは変動が1%未満のビートの量を表し、2番目のビン- 1〜2%の変動など)、歩数、加速度計の測定値(ただし、リフレッシュレートが低いため、ポーズの推定にのみ適しています)。

ただし、生のECG測定値も取得できます。データストリームは完全ではなく、一部のパケットが失われることがありますが、それでも使用可能なものを取得できます。

<図>

さて、それだけです-このデバイスが隅にほこりを集めていた場合、今ではそれほど問題なく動作します:)

コード

uECGarduinoライブラリ
https://github.com/ultimaterobotics/uECG_library
内にOLEDと簡単なシリアル例があります

回路図


製造プロセス

  1. マキシム:モバイルデバイス用の統合PPGおよびECGバイオセンサーモジュール
  2. RPiを使用した環境センサーAPI
  3. TJBot入門
  4. Verilog モジュール
  5. Verilog パラメータ
  6. Java 9 - モジュールシステム
  7. ArduinoPongゲーム-OLEDディスプレイ
  8. JX Wave Generator
  9. ArduinoおよびOLEDベースのセルオートマトン
  10. Dodge The Defs!
  11. Arduinoチュートリアル01:はじめに