前回は6つのセンサーのばらつきを校正するところまで紹介した。今回は実際に温度との校正である。前回も触れたとおり、センサーのばらつきの測定のために、いろいろな温度の水を用意して、それぞれの温度におけるセンサーの値をとるわけだが、同時に温度計を使って実際の水温と、その際のセンサーの値を記録しておく。といっても、全センサーの値を記録するのは大変なので、Analog 0の値のみを取得した。実際の結果を示すと、

水温 Analog 0の値
27.0℃ 155
40.5℃ 181
44.0℃ 189
51.0℃ 203
59.5℃ 220
76.5℃ 256
85.0℃ 274

といった結果になる。これをプロットしたのがグラフ1である。

グラフ1:

グラフ中の点が測定したデータ、赤い破線が直線近似の値である。右上に近似式の数値が出ている通り、

温度=0.4855×センサー値-47.731

といった関係にあるようだ。この計算で行くと、0℃の場合のセンサーの値は、概ね98.31といったところになる。今回利用しているMPC9700の典型値は384回にも記したが、

Vout=Tc×TA+V0℃

で、Tcが10mV/℃、V0℃が400mVということになっている。Arduinoは5Vを1023段階に分割するから、400mVは81.84になる計算で、標準値よりもやや高い数値になるが、その差は0.08Vといったところで、これは誤差の範囲とみなして差し支えないだろう。

この値を基準に、Analog 1~5の値も補正をかけてみる。Analog 1~5の値は(前回のグラフ2~6に示されるように)、補正後の値Y=aX+b(X:補正前のセンサーの値)とした場合、

a b
Analog 1 1.017 -2.026
Analog 2 1.012 0.578
Analog 3 1.019 -4.301
Analog 4 1.014 0.803
Analog 5 0.995 2.047

といった補正をかければほぼAnalog 0と同じ値になるとみなせるわけで、それに今回のグラフ1から得られた、T=cY+d(T:温度、Y:センサーの値)を加味することで、

c d
Analog 0 0.486 -47.731
Analog 1 0.494 -48.716
Analog 2 0.492 -47.450
Analog 3 0.495 -49.821
Analog 4 0.493 -47.341
Analog 5 0.484 -46.736

といった補正値が得られる。

さて、この補正値をArduino側に持たすか、それともホスト側に持たすかというのは使い勝手に結構影響してくる問題だが、今回はArduino側にもたせることにした。384回で紹介したSketchをちょっと修正して、List 1の様なSketchを作った。補正値は、Sketch先頭にCoff[6]とConst[6]という2つの配列を用意して、ここに格納している。この補正値は、analogValueでデータを読み込んだ直後のSerial.print()の中で計算を行い、その結果をシリアルに送り出している仕組みだ。実際にこれを動かすと、シリアルコンソールにはPhoto01の様に、直接温度が出力される仕組みだ。

Photo01: 全センサーを扇風機の前に「大体」均等にブラさげて風を当てた状態。温度差はほぼ1℃以内に収まっているのが判る。もともと誤差1℃のセンサーだから、ここまで追い込めれば十分で、これ以上の精度が必要だとセンサーそのものを見直す必要があるだろう。

ということで、比較的現実的に温度を測定する仕組みが整ったので、これに対応するPC側のプログラムを次回は紹介したい。

(続く)

List 1:

#define BAUDRATE 9600
#define WAIT  2000

static float Coff[6]={0.486, 0.494, 0.492, 0.495, 0.493, 0.484};
static float Const[6]={-47.731, -48.716, -47.45, -49.821, -47.341, -46.736};

void  setup()
{
  Serial.begin(BAUDRATE);
}

void  loop()
{
  int  lpCnt;
  int  analogValue;

  delay(WAIT);

  for(lpCnt = 0; lpCnt < 6; lpCnt++)
  {
    analogValue = analogRead(lpCnt);
    Serial.print((float)analogValue*Coff[lpCnt]+Const[lpCnt],1);
    Serial.print("\t");
  }
  Serial.println("");
}