ArduinoとWindowsPCによる簡易ロガー製作

企業や研究所で実験データをとる場合、温度センサやロードセルなどのセンサをキーエンスや横川電機などのロガーに接続して記録をとります。音や振動だと小野測器などの機器をつかうことが多いと思います。
家で簡易実験をしたいときに、これらの機器は高額で手がだしずらいと思います。
インターネットで調べたところ、実験用にArduinoとサーミスタセンサを用いて温度を測定できることがわかったため作りました。

1.概略構成

パソコンとArduinoをUSBケーブルで接続し、温度センサとArduinoを接続します。
USBケーブルは、Arduinoへの電力供給とArduinoのプログラムデータ(スケッチ)の書き込み、Arudinoからの情報の送受信に使用します。Arduinoと温度センサ間は電子回路が必要なため、別途説明をします。
温度は、温度センサからの情報をArduino内部で計算を行い、パソコンにデータを転送して、データを取得します。

図 全体の構成

2.Arudinoと電子回路の構成

2.1 使用する部品と使用ソフト

1)使用部品
温度センサは、サーミスタセンサを使用します。温度センサは他にはPtセンサ、熱電対センサもありますが、測定範囲を室温-20~室温+80℃ぐらいを想定しているため、安価なサーミスタセンサを使用しました。
電子回路に使用する部品を下表に示します。
サーミスタ1個200円、抵抗線も100本200円程度のため、Arduinoとフレッドボードがあれば1000円以下で温度を測定できます。

部品名数量購入先備考
フレッドボード1市販品ならなんでもOK
サーミスタ 10kΩ(平行線タイプ)103AT-112秋月電子商品URL:サーミスタ 10kΩ(平行線タイプ): センサ一般 秋月電子通商-電子部品・ネット通販 (akizukidenshi.com)
カーボン抵抗(炭素皮膜抵抗) 1/4W10kΩ 2秋月電子他商品URL:カーボン抵抗(炭素皮膜抵抗) 1/4W10kΩ (100本入): パーツ一般 秋月電子通商-電子部品・ネット通販 (akizukidenshi.com)
Arduino Uno1アナログ入力ピンがあれば、ほかのArduinoでも可能

2)使用ソフト

・Arduino IDE
 Arduinoのプログラミング作成とプログラムデータの書き込みに使用します。
・Teraterm ポータブル版
 Arduinoからのデータを受け取り、ログデータに変換します。
・Python環境 またはExcel
 ログデータをグラフにして結果を見やすくします。

2.2 電子回路

サーミスタと抵抗とArduinoを下図のような構成で配線をおこないます。今回、Arduinoに付随しているアナログ入力方式を使って測定を行います。アナログ入力は電圧の値をA/D変換により数値化を行います。

2.3 温度の計算

温度の計算は、アナログ入力の電圧値からサーミスタの抵抗値を求め、サーミスタの抵抗値を温度に換算します。

1)サーミスタの抵抗値の計算
$$ {\Large Rt = \frac{DEVIDER \times Aout}{1024-Aout}}$$
Rt:任意の温度の時のサーミスタ、DEVIDER:10kΩ抵抗の実測値
Aout:アナログピンに入る電圧値の2進数10ビット値、1024:基準電圧値の2進数10ビット値
計算方法の詳細は、Arduinoとサーミスタで温度測定 (101010.fun)
を見てください。

2)温度の計算
サーミスタの抵抗値から温度を計算します。
計算式は、メーカーのページに掲載されているので資料から計算します。

$${\Large Rt = R0 \times e^{(B \times(\frac{1}{T1}-\frac{1}{T2})}}$$

Rt:任意の温度時の抵抗値(Ω)、B:B定数、T1:基準温度(K)、T2:測定温度(K)、R0:10kΩ抵抗の実測値
この式をT2の変形すると、
$${\Large {T2= \frac{\frac{B}{T1} +\ln{\frac{Rt}{R0}}}{B}}}$$
T2をK表示から℃表示にするには273.15を引きます。

2.4 プログラム

ロガーは5秒単位でデータを取得しています。
データは同時に3個の温度データを測定できるプログラムとしました。テスト時は、センサは2個しか使わなかったので3個目のセンサの値はダミー値を入れています。(黄色セル部)
電子部品は、必要です。
抵抗値は、規格値(今回は10kΩ)に対して±10%ばらつきがあるため確認をします。サーミスタも使用した部品により特性が違うため、測定が必要です。
ソースコードは、Arduinoとサーミスタで温度測定 (101010.fun)
コードを使って一部編集を行いました。アナログ入力の考え方はこのページにありますのでご興味がある方はお読みください。

#include <math.h>

#define THERMISTOR_PIN0 0
#define THERMISTOR_PIN1 1
#define THERMISTOR_PIN2 2

//ヘッダの出力有無
bool header_send = false; //ヘッダの出力
unsigned long initial_time;//初期時間
unsigned long current_time;//試験時間-初期時間
float current_sec = 0;

//電子部品
const float DIVIDER0 = 9950.0; // 分圧抵抗10kΩ
const float DIVIDER1 = 9920.0; // 分圧抵抗10kΩ
const float DIVIDER2 = 9920.0; // 分圧抵抗10kΩ

//サーミスタによって違う
const float T0 = 298.15;
const float R0 = 10000.0;
const float B = 3435.0;

//抵抗値の計算 使うサーミスタにより違う
float calcTemp(float Rt) {
  float T_bar= ( B/T0 + log(Rt/R0))/B;
  return 1.0/T_bar - 273.15;
}

//セットアップ
void setup() {
  Serial.begin(9600);
  pinMode(THERMISTOR_PIN0, INPUT);
  pinMode(THERMISTOR_PIN1, INPUT);
  pinMode(THERMISTOR_PIN2, INPUT); 
  
  Serial.println("This program is measureing register value");
}

//繰り返し
void loop() {

  //測定時間の取得
  float current_sec = 0;
  if (!header_send) {
    initial_time = millis();
    current_time = 0;
  }
  else {
    current_time = millis() - initial_time;
    current_sec = current_time / 1000; //msからsに換算
  }

  //データの取得
  int Aout = analogRead(THERMISTOR_PIN0);
  float Rt = DIVIDER0 * Aout / (1024.0 - Aout);
  float temp = calcTemp(Rt);

  int Aout1 = analogRead(THERMISTOR_PIN1);
  float Rt1 = DIVIDER1 * Aout1 / (1024.0 - Aout1);
  float temp1 = calcTemp(Rt1);
  
  int Aout2 = analogRead(THERMISTOR_PIN2);
  Aout2 = 512;//設定用
  float Rt2 = DIVIDER2 * Aout2 / (1024.0 - Aout2);
  float temp2 = calcTemp(Rt2);

//getting data ヘッダの出力
  if (!header_send) {
    Serial.println("time,temp0,temp1,temp2");
    header_send = true;
  }
  
  //シリアルデータの出力
    
  Serial.print (current_time); // シリアルポートに書き出す処理
  Serial.print (","); // シリアルポートにカンマを書き出す処理
  Serial.print (temp); // シリアルポートに書き出す処理
  Serial.print (","); // シリアルポートにカンマを書き出す処理
  Serial.print (temp1); // シリアルポートに書き出す処理
  Serial.print (","); // シリアルポートにカンマを書き出す処理
  Serial.print (temp2); // シリアルポートに書き出す処理
  Serial.println(""); // 改行
 
  //  Delay timsstepで設定した時間だけ遅らせる //時間補正付き
  unsigned long delaytime = current_time % STEP_TIME;
  delay(STEP_TIME - delaytime);
  //delay(STEP_TIME);  
}

2.5 動作確認

Arduinoとパソコンを接続してArduinoIDEのシリアルモニタから値を確認します。
サーミスタを接続したのは、temp0とtemp1です。測定時の部屋の温度計は28℃程度でしたので測定できていることがわかります。値と値の間に”,”を入れているのはcsvファイル形式にすることでExcelやPythonなどのデータの入出力が容易です。

図 測定結果をシリアルモニタで見る

3.測定データをログとして保存をする。

Tera Term ポータブル版を使用してログデータをテキストファイルに保存します。

3.1 Teratermの環境セットアップ

1)Tera Term ポータブル版をダウンロードして任意のフォルダに回答します。
ダウンロード先:「Tera Term」定番のターミナルエミュレーター – 窓の杜 (impress.co.jp)

2)Teratermを起動します。

3)保存設定を行います。
設定(S)をクリックし、TCP/IPをクリックします。

ログのタブをクリックし、ログのファイル名、保存先、オプションを設定します。
この設定では拡張子をlogとしていますが、csvに設定しておくとpythonやExcelで読み込むときは便利です。

最後に設定をクリックし、さらに保存の設定をクリックします。この操作でログの設定を保存することで次回起動しても設定結果が反映されます。

3.2 ログデータの取得

1)ファイルをクリックし、さらに新しい接続を選択します。

2)接続設定をシリアル(シリアル接続)とポートをCOM3とします。なお、ポートの番号はArduinoUnoと同じ設定にします。

3)ファイルからログを選択することで記録が開始されます。

4)記録を終了したいときは、ファイルをクリックし、さらに接続断をクリックします。

5)保存先からlogファイルを開くと測定データが取れていることがわかります。
temp0とtemp1の値を見ると、28.5℃から28.6℃で市販の温度計も28.7℃と近いことから大きなずれはなく測定できるとものと思います。
サーミスタの動きを確かめるため手でサーミスタの先端をさわったところ、temp0の温度が徐々に温度上昇しているのがわかります。

図 測定時

3.3 ログをグラフにした

3.2で取得したログファイルをpythonを使ってグラフにしました。
青線がtemp0、橙線がtemp1、緑線がtemp2(ダミーデータ)です。手で触ったtempのサーミスタの温度が上がっているのがグラフからも読み取れます。
ここではpythonを使いましたが、csv形式にログをとっているので、Excelからでもグラフにできます。

4.まとめ

厳密な精度を求めない場合は、Arduinoで温度測定が十分可能です。
今回は温度のみとしていますが、湿度計や照度計などの各種センサをTeraTeamに転送することも可能ため、ロガーとしても使えます。

参考にしたサイト
第4回 電圧を読む(その1:ArduinoのADC機能を使う) | geotechlab-workshopのブログ (ameblo.jp)

Arduinoでサーミスタを使って温度計を作るのに、電圧を求める必要はない (jh4vaj.com)

「Tera Term」定番のターミナルエミュレーター – 窓の杜 (impress.co.jp)

Arduinoとサーミスタで温度測定 (101010.fun)