本当に自家製の酸素計センサー
コンポーネントと消耗品
> |
| × | 1 | |||
| × | 1 | ||||
| × | 1 | ||||
| × | 1 | ||||
| × | 2 | ||||
| × | 1 | ||||
| × | 1 | ||||
| × | 1 | ||||
| × | 1 |
必要なツールとマシン
> |
|
アプリとオンラインサービス
> |
|
このプロジェクトについて
この隔離期間に、私はすでに部品を内蔵したオキシメータを構築しました。結局のところ、オキシメータは2つのLEDとフォトダイオードで作られています。
私は医学知識の専門家ではありません。プロジェクトのこの段階では、この作業に診断上の価値があるかどうかはわかりませんが、それがどのように機能するかを研究するための優れた教育プロジェクトであり、おそらくいくつかのヒントがあります。自家製の医療ツールになる可能性があります。
酸素飽和度とCOVID-19
私たちの人生のこの信じられないほどの期間で、私たちはウイルス、肺、サージカルマスク、石鹸、手洗いについて多くのことを学びました。誰もが咳、発熱、呼吸困難などの症状について読んでいます。また、呼吸困難を測定する1つの方法は、血液中の酸素量を読み取ることであることもわかっています。
この測定値は、 Oximeter と呼ばれる医療機器を使用して間接的に読み取ることができます。 。あなたはおそらくそれをすでに見たことがあるでしょう、それは仕事をするいくつかの脈動するライトで指に置かれる非侵襲的な装置です。このように:
<図>通常、問題がなければ、酸素飽和度(SpO2)のパーセンテージは95%に近いかそれ以上です。飽和度が90%を下回り、咳や発熱がある場合は、問題があります。
いずれかのメーカーがオキシメーターを作成できれば、感染を発見するのがより簡単になり、パニック発作ではなく、問題が実際に存在するときに人々が病院に行くことを決定するのに役立つ可能性があります。
まず、心拍センサーがどのように機能するかを理解します
私はこのプロジェクトを、私たちの多くが家に持っているキットセンサーで見つけたKY-039心拍センサーで遊んで始めました。下の回路でわかるように、フォトダイオードを照らすのは赤外線LEDだけです。 LEDを保護し、センサーの小信号を読み取るための2つの抵抗もあります。
したがって、KY-039センサーがない場合は、いくつかのコンポーネントで独自のセンサーを構築できます。
<図>この写真のように、センサーとフォトダイオードの間に指を置きます(元々このサイトから取得して変更しました):
<図>赤外線LEDが発する光は、爪や皮膚などの指の部分に部分的に吸収されますが、静脈を流れる血液の変化に伴って変化するため、一定ではありません。心臓が鼓動すると、血液が静脈に押し込まれ、光の吸収が変化します。フォトダイオードに到達する赤外光で照らされたフォトダイオードによって生成される電流を測定できます。
KY-039センサーには S があります (信号)その変化する値を読み取るためのピン。
信号のピークを数えることで心拍数を測定できます
センサーからの可変信号から値を読み取るのはそれほど簡単ではありません。ノイズが多く、信号が非常に低いため、プロットするのに適した値を見つけるためにいくつかの計算を行う必要があります。
Johan Haからのこの便利な投稿に感謝します。この投稿では、信号の平均を計算する方法と、ホームランプによって発生するノイズを除去する方法について説明しています(その光はノイズです!)。
秘訣は、値をプッシュおよびドロップして、センサーから読み取られた最後のX値の平均を作成する配列を作成することです。彼はまた、N個の成長する値を数えることによって信号の上昇を見つける方法を説明しています。つまり、値が前の値よりN回大きい場合、それはピークです。
Arduinoシリアルプロットツールまたは別のシリアルツールを使用してCOMポートに出力された値(SerialPlotなど)を分析し、さまざまな値を試して、正しい数値N( rise_threshold
)を定義できます。 定数nコード)。数値が大きすぎたり小さすぎたりすると、ビートを見逃したり、二分されたノッチを数えたりする可能性があります。 ビートとして。
ピークを細かくする方法を理解したら、それらを数えるか、一連の小さなビート間の時間を計算して、 BPM
を決定します。 レート( 1分あたりのビート数 。
酸素飽和度を見つけるためにオキシメータを構築する(KY-039センサーをハッキングする)
私たちの血液は、光の波長の変化に応じて異なる方法で光を吸収します。赤色光( 〜600nm
)より多くの酸素を含む血液によってよりよく吸収されるので、赤外線LED( 〜950nm
で行われた測定値を比較できます )赤いLEDで作られたもので、私たちの血液中の酸素のパーセンテージを見つけてください。その値は Sp02%
と呼ばれます (末梢毛細血管酸素飽和度 。
私はKY-039センサーを持っているので、それを変更することにしました。赤外線LEDだけなので、赤を追加しました LED、 IR を切断します Vcc から導かれました 330 ohm
で接続します 2つのLEDをArduinoの2つの異なるピンに抵抗します。
(変更するKY-039センサーがない場合は、それを構築できます。これは、2つのLED、フォトダイオード、および3つの抵抗器であり、回路図は非常に単純です!)
変更されたセンサーの概略図は次のとおりです。
<図>このようにして、 IR をオンにすることができます 主導し、KY-039 S から値を読み取ります ピンを押すと、 IR をオフにできます 主導して赤をオンにします 導かれ、KY-039 S から値を読み取ります ピン。
これが私のものです:
<図>2つの信号をプロットすると、IR値が常に赤の値よりも低いことがわかります。
<図>良い信号を見つけるには、フォトダイオードに指先を正しく置くことを忘れないでください。プロットで読みやすい快適な位置を見つけたら、LEDを爪に接触させる必要があります。
信号が低く、ノイズが非常に問題があるため、有用な測定値を取得するには、常に適切な周囲光が必要であることに気づきました。したがって、測定中に指を動かしたり、光を変えたりしないでください。センサーの影だけですべてが変わる可能性があります。
飽和SpO2%の測定方法
酸素飽和度(SpO2)は、総ヘモグロビンに対する酸素飽和ヘモグロビンの割合であり、 R と呼ばれるパラメーターの関数です。 (この情報はミラノ工科大学の学術論文で見つかりました)。これは、2つの信号の最小値と最大値を使用して計算されます。
R =((REDmax-REDmin)/ REDmin)/((IRmax-IRmin)/ IRmin)
各楽器には独自の R があります RとSpO2%を結ぶ曲線(関数)を見つけるには、キャリブレーションが必要です。
ピークの数を数えましたが、今度は最大を見つける必要があります および分 2つの曲線の値(赤 主導および IR 主導)。
この作業を実行するために、ハートビートの「周期」(つまり、ビートが何ミリ秒続くか)を評価し、それをサンプリングレートで割って、周期を構成するサンプルの数を決定します。この場合、サンプリングレートは40ミリ秒です。これは、IR LEDを20ミリ秒読み取り、次にREDLEDをさらに20ミリ秒読み取るためです。
ビートの周期は、信号の2つの立ち上がり曲線の間を通過する時間です。
だから私は最後の L を分析することができます REDmax を見つけるために、配列に保存したサンプル(L =期間/ 40) 、 REDmin 、 IRmax および IRmin 値。
最大値と最小値を使用して、 R を計算できます 。
R、L、および周期はビートごとに計算されるため、Rの計算もビートごとに行われます。
RからSpO2%へ:オキシメータを校正する方法は?
R をリンクする関数 SpO2 を使用 直線で簡略化できます:
SpO2 =K * R + M
したがって、KとMを決定するには、2つのポイント(SpO2とRの値の2つのカップル)が必要です。これらの2つのポイントを見つける唯一の方法は、別のパルスオキシメータを使用して、その表示から値を読み取ることです。
新しいパルスオキシメータが基準になります。自家製のパルスオキシメータからR値を測定しながら、SpO2値を読み取ります。
最初に普通に呼吸し、SpO2とRの値を読み取ります。書き留めます。
次に、息を止めてみてください。10〜20秒後に、新しいオキシメータのSpO2が減少していることがわかります。また、オキシメータのRパラメータが増加しているのがわかります。気絶する前に、到達したSpO2の値とRパラメータの値を書き留めます。
2次方程式を解き、オキシメータのKとMを見つけます。
これで、両方の bpm を計算できるようになりました および SpO2 R のすべてのメジャーの値 。
また、すべての数値を表示するディスプレイを追加しました。あまり変化しない期間の測定値が5つ以上見つかった場合にのみ値を表示します(± 10%
期間の長さの)。このようにして、貧弱なコンポーネントや周囲の光や指の動きの変化に応じて変化しすぎる値を削除します。
c valueは、表示されている値が c で計算されていることを示します 安定した対策。
プロジェクトの改善:周囲光の変動を取り除く
プロジェクトで数日間遊んだ後、プロジェクトを改善する方法を見つけました。
これらの低コストのコンポーネント(LEDとフォトダイオードだけを使用しています!)では、測定値が周囲光に依存しすぎていることに気付きました。実際にデータを適切に読み取りたい場合、これは良いことではありません。作業環境。晴れた日は曇った光よりも良い結果が得られることに気付いたので、または電気ランプを使用する夕方には、常にオンで指にちょうど光を当てる3番目のLEDを追加することにしました。 。
<図>この3LEDセンサーでは、常に変化する可能性のある周囲光を排除するために、黒い布の下でも対策が講じられています。
<図>これで、結果が改善され、周囲光に依存しなくなりました。
また、数秒後にビデオからわかるように、オキシメータを再校正する必要がありました。これは、 bpm を正しく検出します。 ans SpO2% :
コード
- oximeter-diy-ver-0.92.ino
oximeter-diy-ver-0.92.ino Arduino
これはOximeterDIYのソースコードであり、メーカーが家庭で持つことができるいくつかのコンポーネントで作られています。/ **オキシメーターDIY。 v.0.92(マイナーな修正)* ky-039ハートビートセンサーをハッキングするか、赤外線LEDを使用する*赤いLEDとフォトダイオード。 * https://hackaday.io/project/170752-oximeter-do-it-yourself * /#include#include #define maxperiod_siz 80 //期間内のサンプルの最大数#メジャーの定義10 //保存された期間の数#definesamp_siz4 //平均のサンプル数#definerise_threshold 3 //ピークを決定するための立ち上がりメジャーの数//液晶ディスプレイBPMLiquidCrystal_I2C lcd(0x3F、16、2); int T =20; // sensorintセンサーから値を読み取るためのスロットミリ秒SensorPin =A1; int REDLed =3; int IRLed =4; byte sym [3] [8] ={{B00000、B01010、B11111、B11111、B01110、B00100、B00000、B00000}、{B00000、B00000、B00000、B11000、B00100、B01000 、B10000、B11100}、{B00000、B00100、B01010、B00010、B00100、B00100、B00000、B00100}}; void setup(){Serial.begin(9600); Serial.flush(); pinMode(sensorPin、INPUT); pinMode(REDLed、OUTPUT); pinMode(IRLed、OUTPUT); // LCDを初期化しますlcd.init(); lcd.backlight(); // LEDをオフにしますdigitalWrite(REDLed、LOW); digitalWrite(IRLed、LOW); for(int i =0; i <8; i ++)lcd.createChar(i、sym [i]);} void loop(){bool finger_status =true; float readIR [samp_siz]、sumIR、lastIR、reader、start; float readRED [samp_siz]、sumRED、lastRED; int期間、サンプル;期間=0;サンプル=0; int samplesCounter =0; float readIRMM [maxperiod_siz]、readsREDMM [maxperiod_siz]; int ptrMM =0; for(int i =0; i =samples){samplesCounter =0; IRmax =0; IRmin =1023; REDmax =0; REDmin =1023; for(int i =0; i IRmax)IRmax =readIRMM [i]; if(readsIRMM [i]> 0 &&readIRMM [i] REDmax)REDmax =readREDMM [i]; if(readsREDMM [i]> 0 &&readREDMM [i] beforeIR){rise_count ++; //上昇しているサンプルの数をカウントしますif(!rising &&rise_count> rise_threshold){lcd.setCursor(3,0); lcd.write(0); // <3 //わかりました、心拍を意味する上昇曲線を検出しました。 //最後のビートからの時間を記録し、前の10個のピークを追跡して//平均値を取得します。 //上昇フラグは、同じ上昇を//複数回検出することを防ぎます。上昇=真;メジャーR [m] =R; measuresPeriods [m] =millis()-last_beat; last_beat =millis(); int期間=0; for(int i =0; i measuresPeriods [i-1] / 1.1)){c ++; avPeriod + =measuresPeriods [i]; avR + =メジャーR [i]; }} m ++; m%=メジャー; lcd.setCursor(12,0); lcd.print(String(c)+ ""); //表示されているbpmとRは、//少なくとも5つの良好なピークの平均として計算されますavBPM =60000 /(avPeriod / c); avR =avR / c; //最後に5つのメジャーがある場合lcd.setCursor(12,1); if(c ==0)lcd.print( ""); else lcd.print(String(avR)+ ""); //少なくとも5つの適切なメジャーがある場合... if(c> 4){// // SATURTION IS A FUNCTION OF R(キャリブレーション)// Y =k * x + m // kとmは次のように計算されます別のオキシメータintSpO2 =-19 * R + 112; lcd.setCursor(4,0); if(avBPM> 40 &&avBPM <220)lcd.print(String(avBPM)+ ""); // else lcd.print( "---"); lcd.setCursor(4,1); if(SpO2> 70 &&SpO2 <150)lcd.print( "" + String(SpO2)+ "%"); // else lcd.print( "-%"); } else {if(c <3){// 2小節未満の場合は追加しますか? lcd.setCursor(3,0); lcd.write(2); // bpm? lcd.setCursor(4,1); lcd.write(2); // SpO2? }}}} else {//わかりました、曲線は下降しています上昇=false; rise_count =0; lcd.setCursor(3,0); lcd.print( ""); } //それを新しい値と比較し、ピークを見つけるbeforeIR =lastIR; } //指は内側にあります//すべてをプロットしますSerial.print(lastIR); Serial.print( "、"); Serial.print(lastRED); / * * Serial.print( "、"); Serial.print(R); Serial.print( "、"); Serial.print(IRmax); Serial.print( "、"); Serial.print(IRmin); Serial.print( "、"); Serial.print(REDmax); Serial.print( "、"); Serial.print(REDmin); Serial.print( "、"); Serial.print(avR); Serial.print( "、"); Serial.print(avBPM); * / Serial.println(); //配列を処理しますptr ++; ptr%=samp_siz; } // while1をループする}
回路図
私のプロジェクトでは、KY-039を変更しましたが、そのセンサーはフリッツライブラリで使用できないため、いくつかのコンポーネントで構成されていますが、フリッティングライブラリで適切なフォトダイオードが見つかりませんでした。 oximeter-diy_oW9ZI5zQtJ.fzz血液中の酸素を読み取る簡単なオキシメーターは、KY-039センサーをハッキングするか、センサーを最初から作成することで作成できます。 製造プロセス