前回は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である。
グラフ中の点が測定したデータ、赤い破線が直線近似の値である。右上に近似式の数値が出ている通り、
温度=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("");
}