はじめに
データシート
通信方式は 1-Wire bus方式です。
目的
温度制御に利用するうえで、以下の点を調べました。
- 最小制御周期
- 測定結果の精度
- センサ同士の誤差
- 時間的なブレ
- 電源電圧の影響
- 温度応答性
結論
- 最小制御周期 → 1秒周期で可能(センサ自体の熱容量からして、もっと粗くてもいいけど)
- 測定結果の精度
- センサ同士の誤差 → 測定単位1でブレる。ほぼないと見ていい
- 時間的なブレ → 測定単位1でブレる。ほぼないと見ていい
- 電源電圧の影響 → 測定単位1でブレる。ほぼないと見ていい
- 温度応答性
- 7秒遅れがあるとみなして良い
通信について:1-Wire bus
通信は以下の流れになります。
- バスリセット(スレーブの存在確認)
- データ送信・受診
バスリセット
マスタ:480us以上LOW → スレーブ:60~240usLOWにして返す
スレーブが存在することを確認します。
データ送受信
スロット時間幅(1bitデータ時間幅)を60~120usとして、HIGH/LOWを使用して送受信する。
時間定義
通信プロトコル
以下の順にデータを送信します。
1.バスリセット
2. ROMコマンド
3. ファンクションコマンド
コマンド
信号測定
#include <OneWire.h>
OneWire ds(8); // This is where DQ of your DS18B20 will connect.
void setup(void) {
Serial.begin(9600);
getDeviceAddress();
}
void getDeviceAddress(void) {
byte i;
byte addr[8];
Serial.println("Getting the address...\n\r");
/* initiate a search for the OneWire object we created and read its value into
addr array we declared above*/
while (ds.search(addr)) {
Serial.print("The address is:\t");
//read each byte in the address array
for ( i = 0; i < 8; i++) {
Serial.print("0x");
if (addr[i] < 16) {
Serial.print('0');
}
// print each byte in the address array in hex format
Serial.print(addr[i], HEX);
if (i < 7) {
Serial.print(", ");
}
}
// a check to make sure that what we read is correct.
if ( OneWire::crc8( addr, 7) != addr[7]) {
Serial.print("CRC is not valid!\n");
return;
}
}
ds.reset_search();
return;
}
void loop(void) {
// do nothing
}
-
センサ接続していないとき
480usLOWに落としている。本来はスレーブがHIGHにして返すため、それがない今はこれ以上の通信は起きない -
センサを接続すると
センサがLOWにすることでバスリセットに返答している。
こんな感じで読み取れる。長=0,短=1であるため、これはB00001111=0x0F=サーチコマンド
全部読み解くのは大変
実測:温度測定
#include <OneWire.h>
#include <DallasTemperature.h>
#define ONE_WIRE_BUS 8 // データ(黄)で使用するポート番号
#define SENSER_BIT 9 // 精度の設定bit
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);
DeviceAddress temp0 = { 0x28, 0x61, 0x64, 0x0B, 0x4A, 0x1E, 0xED, 0x0F }; //1つ目のDS18B20のアドレス
DeviceAddress temp1 = { 0x28,0xFF,0xDC,0x12,0x86,0x16,0x04,0x9C }; //2つ目のDS18B20のアドレス
void setup(void){
Serial.begin(9600);
while (!Serial) {
; // wait for serial port to connect. Needed for native USB port only
}
sensors.setResolution(SENSER_BIT);
delay(1000);
}
void loop(void){
sensors.requestTemperatures(); // 温度取得要求
delay(800);
Serial.println(sensors.getTempC(temp0)); //1つ目のDS18B20から温度の取得、シリアルモニタに表示
delay(1000);
}
温度測定開始コマンドにかかる時間
約12ms
サンプリング等にかかる時間は分解能によって変わるが、以下の通り。
測定結果読み込みコマンドにかかる時間
約34ms(精度によらない、読み込み2byteは変わらないため)
結論
温度測定周期1秒間隔は可能。
分解能を落とせばもう少し可能。
9bit分解能では、以下合計140ms周期が最短である。
- 測定要求コマンド:12ms
- サンプリング:94ms
- 読み込み:34ms
センサの温度変化
熱容量の大きい、室温放置された水にセンサを入れて測定した。測定精度は12bitとした。
測定期間10分:測定回数312回
標準偏差→0.0287℃
ただし、測定分解能の影響が強いですね。
測定単位1の前後で変化していると見て良さそうです。
<補足>
センサは$2^{-4} = 0.0625℃$単位で測定しています。
センサ同士の誤差
DS18B20の測定結果+シンワ製温度計2つの温度を比較した。
結果
シンワ温度計→28.0℃(目視)
センサ同士にズレはほぼない
センサ電源電圧を変化させても測定単位1でブレる(USB電源3.9Vと外部電源5Vの2パターンで比較)→電源によらない
温度応答性
温水にセンサを突っ込むことで応答性を確認する。
#include <MsTimer2.h>
#include <OneWire.h>
#include <DallasTemperature.h>
#define ONE_WIRE_BUS 8 // データ(黄)で使用するポート番号
#define SENSER_BIT 12 // 精度の設定bit
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);
DeviceAddress temp0 = {0x28, 0x61, 0x64, 0x0B, 0x4A, 0x1E, 0xED, 0x0F};
volatile bool flag_t = false;
void setup(void) {
Serial.begin(9600);
while (!Serial) {
; // wait for serial port to connect. Needed for native USB port only
}
sensors.setResolution(SENSER_BIT);
MsTimer2::set(1000, mejure);
MsTimer2::start();
delay(1000);
}
void mejure() {
flag_t = true;
sensors.requestTemperatures();
}
void loop(void) {
if (flag_t == true) {
flag_t = false;
delay(800);
Serial.println(sensors.getTempC(temp0), 5);
}
}
指数関数的に応答していることがわかると思います。
水槽内の温度は$T_{con}$一定であるとして、温度計(熱容量$C[J/K]$,初期温度$T_0$)に対して、伝熱係数$k$,表面積$A$で熱流束$q$で伝熱したと考えられる。
q = kA(T_{con}-T)
温度計の温度は以下の微分方程式に従うといえる。
C \frac{dT}{dt} = q
上記の方程式を解くと
T= -( T_{con} - T_0) e^{- \frac{kA}{C} t} + T_{con}
温度計の応答性を表している時定数$\tau$は以下のように求められると考えられる。
\tau = \frac{C}{kA}
$1-e^{-1} = 63.2%$となる時刻は、
水中では7秒
気中では82秒
気中は伝熱係数が低いからしょうがないが、結構長いね。12倍ぐらいか。
熱伝導性は20倍ぐらいある。
伝導だけではなく対流もあるから、なんとも言えないけども。
応答性
水中での時定数が7秒であることから、計測されるまでに7秒遅れがあると考えて良い。
→ 制御周期によっては発振の原因となるため、注意
結論
- 最小制御周期 → 1秒周期で可能(センサ自体の熱容量からして、もっと粗くてもいいけど)
- 測定結果の精度
- センサ同士の誤差 → 測定単位1でブレる。ほぼないと見ていい
- 時間的なブレ → 測定単位1でブレる。ほぼないと見ていい
- 電源電圧の影響 → 測定単位1でブレる。ほぼないと見ていい
- 温度応答性
- 7秒遅れがあるとみなして良い