臨床工学技士の皆さんとそうでない方 こんにちは。
もしCEの為のArduino入門を一読されていない場合は先に目を通し、Arduino初心者になっておいてください。
さて、前回はライトガイドケーブルチェッカーの制作をご紹介しましたがどうだったでしょうか?
今回も少し面白い製作例をご紹介します。
今回は自然滴下で使用する輸液療法の際に輸液の滴下から点滴速度(流量)を滴下毎に計測してくれるマシーンを制作していきたいと思います。
題してArduinoで作る!!自然滴下流量計 DropFlowMeterの制作です。
作成にあたり、Arduinoのスケッチ(プログラム)をダウンロードし同様の回路を組む事で作成する事が可能です。ぜひダウンロードください。
今回もハードウェアとプログラム解説に関して動画を用意していますのでご参考になさってください。
それではいってみましょう。
とりあえず↓のようなものが作れます。
仕組みについて
仕組みは上図の様に輸液セットについている滴下筒に落ちる滴下を自作センサによって、検知します。
検知したら次の滴下までの時間をカウントし滴下間隔から時間あたりの流量を算出するという仕組みになります。
どうして滴下間隔から流量が算出できるのか?ですが、日本で使用されている輸液セットは大きくわけて1mlあたり20滴用と60滴用とがありますね。
ご存知ない方はおられないとは思いますが、復習。
一般的な20滴用は1ml流すのに20滴の滴下が必要になります。ですから一滴あたり1ml÷20=0.05mlになります。
60摘用は同様の計算で一滴あたり0.016667mlになります。
流量というのは 時間あたりの流れる物体量で計算できるので一滴あたりの量がわかっている点滴セットでは一粒あたりの滴下の間隔時間がわかれば流量が計算できるのです。
たとえば1秒に一回的かがあったとしましょう。
1秒ごとに0.05ml --->> 0.05ml /sec
↑ですね。
これを時間あたりの流量であるml/hになおす必要があります
sec(秒)をhour(時間)になおすには、1時間の秒数を両辺にかけなければなりません。60秒×60分=3600sec
0.05×3600 / 3600sec = 180ml/h という事になります。
実際にArduinoのプログラムでは上記のような計算で流量を算出しています。
滴下を検出するセンサにも触れておきます。
輸液療法で使用する薬剤は液体です。液体を効率よく検知するには光の吸光度を用いて液体を検出するのが最も良い方法です。
なかでも、可視光線ではなく、液体の吸光度が高く、人間の目には見えない近赤外光を用いて滴下を検出するセンサを自作しています。
近赤外線LEDを照射しておいてその反対側に近赤外光に感度をもったフォトトランジスタを配置し、その中を滴下する雫をフォトトランジスタが検知するといった具合になります。
フォトトランジスタの扱い方などは前回のライトガイドケーブルチェッカーの制作で詳細を述べています。
使用材料
- Arduino UNO R3×1
- 近赤外光LED OSI5FU5111C-40 940nm×1
- フォトトランジスタ L-31ROPT1C 940nm×1
- 液晶ディスプレイ KKHMF OLED 128×32 0.91inch×1
- 抵抗器 3kΩ ×2
詳細はクリニカルエンジニアリング 2023年9月号を参照
ハードの説明
回路図
ハードウェアに関しては図の通りです。
肝は自作の滴下センサですが、ポイントはフォトトランジスタと近赤外線LEDを直線的に配置する事が重要です。
今回は滴下を確実に検知させる為にフォトトランジスタを直列に繋いでひとつでも近赤外光が遮断されれば、検知したと判断する回路にしています。
タクトスイッチは詳細は後述していますが、プログラム上でモードを変更したりする場合に便利なスイッチになります。
スイッチを押せば接点がくっついて導通しる仕組みです。
Arduinoなどワンボードマイコンではよく使用する部品で、使用の際にはチャタリングという現象の対策が必要になります。
回路図でブザーが使用されていますが、このブザーは電源が入れば音がなるタイプのブザーです。通常圧電ブザーはプログラム上で発振させて音を鳴らすタイプがあるので、部品選びには注意が必要です。
今回は楽をする為に、電圧をくわえれば音が鳴るタイプのPB04-SE12HPRというものを使用しています。
ハードの解説(動画)
I2C接続OLEDディスプレイを使う
今回の製作物は測定データから算出した流量をディスプレイに表示するプログラムにしています。
タクトスイッチについて
タクトスイッチというのはスイッチを押した時にだけ導通するスイッチの事です。よく電子工作、特にマイコンやワンボードPCに使用されます。
arduinoで使用する場合には少しコツがいります。
それはチャタリング対策とスイッチとマイコンとの接続方法(プルアップ、プルダウン)についてです。
チャタリングについて
チャタリングとはウィキでも説明されている通り、スイッチなどの可動接点などが接触状態になる時に微細な非常に速い機械的振動を起こす現象のことです。
Arduinoでは0Vから5Vになる、もしくはその逆の電圧が変わるタイミングでスイッチが押されたと判断させることが多いのですが、そんなプログラムでチャタリング現象が起こればごく短時間のうちに、一度しかスイッチを押していないのに、何度もスイッチが押されたような挙動になってしまうのです。
ですからチャタリングを起こすような機械的な接点であるタクトスイッチを使用する際にはチャタリング対策としてプログラム上でチャタリング対策をします。
たとえば、チャタリング現象がおこるスイッチを押した後、数msecはプログラム上で任意の時間プログラムを待機させてチャタリングが収まるまで待ったりします。
このようにひとつの部品を使うにもいろいろとお作法があります。
プルアップ・プルダウン
もうひとつタクトスイッチを使用する場合に知識として知っておく必要があるのはプルアップとプルダウンという接続の方法になります。
Arduinoなどのマイコンにスイッチを接続する場合に安定的にスイッチの情報を伝える為に抵抗を使ってあらかじめ電圧を加えておくのがプルアップ、入力するマイコン側をアースに抵抗を介して接続して0Vにしておくことをプルダウンといいます。
なぜこれをしておくことが良いのかというと、マイコンは不安定な電圧を嫌がります。
たとえば、スイッチの出力を読み取る端子がスイッチを押していないのにノイズで1vや2vの不安定な入力があると、スイッチが押されているのかそうでないのか判定できなくなります。
そうならないようにするのです。
詳細は図の通りでプルダウンは入力ピンに抵抗を介してアースに接続しておきます。
タクトスイッチを押せば5Vが入力されます。
プルアップのほうは通常状態で入力ピンに抵抗を介して5Vが接続されていて、タクトスイッチが押されると入力ピンは0Vになるという仕組みです。
スイッチが押された時の入力ピンに出力される電圧がHIGHかLOWで違いがあるので、そこはプログラム上での判定をよく考えなければなりません。
プログラムの説明
プログラム解説(動画)
プログラム解説
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 |
/* 自然滴下流量計の製作 202305 takase kazunori mail:kazurock0926@gmail.com arduino UNO R3にて制作 0.91inch OLED使用 〜概要〜 自然滴下の輸液療法時に滴下筒にセンサを挟み込むだけで、簡易瞬時流量を表示するプログラムである。 滴下を検知し、10秒滴下を検知しなければ液切れと判断しNon FlowとOLEDに表示、同時にブザーを鳴らす設定とする。 とりあえず試作品は20滴セット用でプログラムした。 */ //OLED有機ディスプレイを使用するライブラリ #include<U8g2lib.h> U8G2_SSD1306_128X32_UNIVISION_F_HW_I2C u8g2(U8G2_R0, /* reset=*/ U8X8_PIN_NONE); //まずA0ポートをanalogADという変数として定義します。読み取った電圧を入れる入れ物とするとわかりやすいです。 const int analogAD = A0; int foto = 6;//フォトトランジスタの電源に使用 int IRled = 7;//近赤外光の電源に使用 int button = 2;//計測をスタート、ストップさせるボタンを2に割り当てます。 int buzzer = 3;//ブザーを3に定義 unsigned long time1;//滴下間の時間を入れる変数 float tenteki;//滴下速度を計算する為の変数 char str[10];//ディスプレイに滴下速度を表示させる為に必要 void setup() { // ここにセットアップする内容を記入します。最初に一度呼ばれるので //使用するピンを入力として使うのかアウトプットとして使うのかとかシリアル通信のスピードとかを決めます。 //とりあえずPCで動作を確認するためにシリアル通信の設定をしておきます。 Serial.begin(9600);//シリアル通信をはじめまーすという宣言とそのスピードを決めてます。 //最初に定義したanalogADを入力として使いますという宣言です。 pinMode(analogAD,INPUT); //基盤上のLEDも出力として光らせる為に宣言します。 pinMode(LED_BUILTIN,OUTPUT); //近赤外線LEDも光らせる為に出力として宣言します。 pinMode(IRled,OUTPUT); //フォトトランジスタに電源を供給する為に出力として宣言します。 pinMode(foto,OUTPUT); //ブザーを鳴らす為に出力として宣言します。 pinMode(buzzer,OUTPUT); //ボタンは入力として宣言します。回路図では1kΩの抵抗でブルダウンしています。 //プルダウンやプルアップとはボタンなどの入力の際に使う安定的な入力を得る為の手法です。 pinMode(button,INPUT); Serial.println("ハロー CE!!"); Serial.println("2023 clinical Enginireering"); Serial.println("arduinoではじめてのプログミング"); Serial.println("簡易点滴流量計の制作 by kazunori takase"); delay(2000); //OLEDをとりあえず表示させます。OLEDの表示の方法ははじめのarduinoのHPで説明しています。 u8g2.begin(); u8g2.clearBuffer(); u8g2.setFont(u8g2_font_8x13_tf); u8g2.drawStr(5, 12, "Hello CE"); u8g2.drawStr(10, 22, "clinical"); u8g2.drawStr(15, 32, "Engineering"); u8g2.sendBuffer(); delay(3000); } void loop() { /* それでは処理をはじめましょう。点滴流量計は滴下から流量を瞬時に計算する事と滴下がなくなって10秒程度で滴下切れ を報知してくれる仕様にしたいです。ですからボタンを押せば計測スタートしてLCDに表示。計測中にボタンを再度おせば計測 ストップするといった簡単な動作にします。 動作中は滴下があれば青色LEDを光らせます。 */ if(digitalRead(button)==LOW) //ボタンが押されていない時の処理 { taiki(); } else //buttonがHIGHの場合(ボタンがおされた時)の処理 { delay(70);//チャタリングという現象(オン、オフを繰り返す物理的な現象)があるので少し待ち時間を持ちます if(digitalRead(button)==HIGH) { //OLEDに今から滴下計測をする表示をします u8g2.clearBuffer(); u8g2.setFont(u8g2_font_maniac_tr); u8g2.drawStr(20, 30, "START"); u8g2.sendBuffer(); u8g2.clearBuffer(); time1 = millis(); keisoku(); } } } //待機状態の関数です。 void taiki() { digitalWrite(foto,LOW); digitalWrite(IRled,LOW); digitalWrite(buzzer,LOW); u8g2.clearBuffer(); u8g2.setFont(u8g2_font_maniac_tr); u8g2.drawStr(25, 30, "WAIT"); u8g2.sendBuffer(); u8g2.clearBuffer(); } //滴下間隔時間から滴下流量を計測します。 void keisoku() { //近赤外光LEDとフォトトランジスタに電源を供給します。 digitalWrite(IRled,HIGH); digitalWrite(foto,HIGH); //ボタンを押していない間(ボタンを押さない限り)while文の{}内プログラムを繰り返します。 while(digitalRead(button)==LOW){ //滴下時間間隔を入れる変数を定義 float tr_time; //滴下を検知した時の処理 //滴下があればフォトトランジスタが滴下で遮られて電流が流れなくなり抵抗に電圧が現れるのでA0はHIGHになります。 if(digitalRead(A0)==HIGH) { //滴下間隔をtr_timeに入れます。 tr_time = millis()-time1; //ブザーは計測中はならないように設定しておきます。 digitalWrite(buzzer,LOW); //滴下間隔が100ms以下はノイズやダブルカウントと判断して除き、100ms以上の間隔だけ計算していきます。 if(tr_time >= 100) { //滴下間隔ms からml/hを計算します。これは20滴用の計算です。 tenteki = 180000/tr_time;// 0.05*3600000/msec //シリアル通信で値の確認ができるように表示します。 Serial.print(tr_time); Serial.print(","); Serial.println(tenteki); //OLEDに表示します。 //dtostrfはOLEDは文字データしか表示できないので数値データを文字データに変換するコードです。 dtostrf(tenteki,6,2,str); //ここからOLEDに表示するコードです。 u8g2.clearBuffer(); u8g2.setFont(u8g2_font_8x13_tf); u8g2.drawStr(0, 10, "tennteki Flow"); u8g2.drawStr(20, 25, str); u8g2.drawStr(70, 25, "ml/h"); u8g2.sendBuffer(); u8g2.clearBuffer(); //最後にtim1現在の時間を入れます。次の滴下まで時間を計測する為です。 time1 = millis(); } }else{ //ここはフォトトランジスタが光を受け続けてAOがLOWになっている時の動作です。滴下がない時ですね //滴下間隔を調べます。 tr_time = millis()-time1; //10秒以上たった場合のプログラムです 10000ms=10秒 if(tr_time >= 10000) { //滴下なしの状態で10秒以上経過した時の処理 u8g2.clearBuffer(); u8g2.setFont(u8g2_font_8x13_tf); //10秒以上滴下がないとNON FLOWと判断して表示とブザーを鳴らします。 u8g2.drawStr(10, 10, "ERROR"); u8g2.drawStr(10, 25, "NON FLOW"); u8g2.sendBuffer(); u8g2.clearBuffer(); //ブザーを鳴らします digitalWrite(buzzer,HIGH); } } } } |