温度測定

2022年10月 6日 (木)

5chサーミスタ温度計のA/D入力、map関数を使って補正

スカタンな応用例ばかり出てくるArduinoのmap関数
サーミスタ103JTで計った温度をシリアル出力 でのA/D変換値補正
で使ってみました。

まず、A/D入力電圧実測値と基準電圧値から真のA/D値を計算します。
  ツールはデジタルテスター。
  それと電圧発生器、あるいは抵抗を組み合わせて
  安定した入力電圧を得ます。
マイコンにはその時のA/D値をシリアル出力させます。
0に近いある値と1023に近いある値の2点をチェック。
どちらも同じなら補正の必要はありません。
ちょっとのズレなら「直線補間」の出番です。

今回の回路、サーミスタをつなぐch1~ch4はポートAでしたが
ch5だけがポートB。
この間でちょっとズレが出ていました。
まず0Vに近い方。
正値20に対してch1~4が17と-3。
ch5が16と-4と低めの値が出ていました。
フルスケールに近い方は、正値991に対して
ch1~4が992にと+1。ch5は誤差なし。

パラメータのテーブルにはこれらの値を10倍して設定します。
  ※浮動小数点にするとメモリーを食うので。
読み込んだA/D値も10倍してmap関数に食わせて補正を
行い、出てきた値の1の位を見て四捨五入。
10倍することで四捨五入の処理ができます。

これで、ずいぶんと温度測定の調子が良くなりました。
サーミスタの抵抗が低くなる高温域ではA/D値が小さくなります。
A/D入力電圧の低いところで誤差が生じていたのでこの補正が
うまく働いたのでしょう。
80℃付近ではA/D値の1bitが0.3~0.4℃の差になります。

map関数の応用例ということで、ご覧下さい。

//  A/D補正パラメータ
// 四捨五入のためA/D値を10倍にして
// x0とx1に実測値を設定する
// Rs = 10kΩで
// Lo側 200Ωでy0=20  Hi側 300kΩでy1=991
const struct{
const word x0; // in min (Lo)
const word x1; // in max (Hi)
const word y0; // out min
const word y1; // out max
}adj_tbl[] PROGMEM = {
{ 170, 9920, 200, 9910 }, // ch1 ADC1 PA1
{ 170, 9920, 200, 9910 }, // ch2 ADC2 PA2
{ 170, 9920, 200, 9910 }, // ch3 ADC3 PA3
{ 170, 9920, 200, 9910 }, // ch4 ADC7 PA7
{ 160, 9910, 200, 9910 }, // ch5 ADC8 PB0
};
/***** 線形補間 *****/
long map(long x, long in_min, long in_max, long out_min, long out_max)
{
return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
}
/***** A/D値補正 *****/
// in ad : 0~1023 A/D値
// ch : 0~4 ch1~ch5
// 10bitの範囲でリターン
word adadj(word ad, byte ch)
{
long a, d;
a = map((long)ad * 10L, // 線形補間
(long)pgm_read_word(&adj_tbl[ch].x0), // in_min
(long)pgm_read_word(&adj_tbl[ch].x1), // in_max
(long)pgm_read_word(&adj_tbl[ch].y0), // out_min
(long)pgm_read_word(&adj_tbl[ch].y1)); // out_max
d = a / 10; // 1の位で四捨五入 10の位を+0か+1,-1
if(a >= 0){ // プラス
if((a % 10) >= 5) d++;
}
else{ // マイナス
if(((-a) % 10) >= 5) d--; // 正にして1の位で判定
}
if(d < 0) d = 0; // マイナスは0に
else if(d > 1023) d = 1023; // 最大は1023
return (word)d; // wordにしてリターン
}


5chの温度測定で重要なのが「Rs」=「神様抵抗」。
今回の製作では「0.1%」精度のを使ったので、
補正テーブルの「y0、y1」(out_min、out_max)は5chとも
同じになっています。
Rsの誤差は、この値の変更で吸収できます。

使っているAVRマイコンは14ピンのATtiny841。
ROMが8kバイトにRAMが512バイト。
現在のプログラムサイズが3826バイト。
このうち2048バイトが10bit ADC→0.1℃温度データ
の変換テーブル。
プログラムは実質1778バイト。BSSエリアが58バイト。

浮動小数点使わず。sprintf使わず。
この結果だと。

ROM、RAM容量半分のATtiny441にも入るかしら。

| | コメント (0)

2022年10月 5日 (水)

サーミスタ103JTで計った温度をシリアル出力

サーミスタ103JTで計った温度をアナログ出力
この製作で使ったマイコンは8ピンのATtiny85
内蔵タイマーが8ビットで、PWM出力でD/Aするには
分解能不足。
そこで、DACを使ってアナログ電圧を出力しました。

今回の「ダイソー ミニケース 5個組」を使った工作
やはりサーミスタ103JTを使った温度計なのですが、
シリアル出力でデータを得ようと目論見ました。

14ピンのATtiny841を使って、5つのサーミスタを
つなげられるようにしています。

ブロックダイヤグラム
C51_20221005170901
1秒間隔で測定値を出力します。
先頭が6桁数字が連番。
  データ抜けをチェックできます。
スペース区切りで5つの温度を出力。

セミテックの103JT温度・抵抗値表が元データ。
-30.0℃~125.0℃をテーブルにしています。

  ※10bit A/D値から温度データテーブルを
   直に呼び出すことで、浮動小数点関数計算
   を使わなくて済みます。
   ATtiny841のROMサイズは8kバイトしかあり
   ません。
   浮動小数点や「sprintf」による数値→文字列
   変換関数を使うと、ROM領域が足らなくなって
   しまいます。
   可能ならROM半分のATtiny441でも動くようにと。

ところが・・・ここでも失敗に遭遇。
  ATmega328Pを使ったピピちゃん温度計
では、外に取り出した内蔵基準電圧1.1Vを使っての
サーミスタ抵抗測定がうまく行ったので、ATtiny841でも
大丈夫だろうと考えたのです。

  ※ATtiny841と同じ14ピンのATtiny84は
   内蔵基準電圧を外に取り出せない。
   そして、外部からの基準電圧も2.0Vが
   最低というスペックで断念。
   ・回路設計はデータシートの熟読から。 スペックをちゃんと調べろ!

こんな接続をしたかった。 (ATmega328Pでは実績あり)
C52_20221005171201
ATtiny841のAREFピンからちゃんと1.1Vは出てきました。
これを低オフセット電圧のオペアンプでバッファします。
しかし、この出力を「神様抵抗」のプラス側としてA/D変換
すると・・・オープンにしても(10kΩでAREF電圧につながる)
フルスケールの「1023」が出てこないのです。
5つのチャンネルとも、計算値より低い値が出るのです。
フルスケールに近い電圧の高い所だと2~3。
電圧が低い所だと、3~4、出てくるA/D値が小さいのです。

全体に下へシフトしてる感じです。
  ※ATmega328Pではこんなことには
   ならなかった・・・

そこで、外部から基準電圧を供給してみることに
しました。
  ※基準電圧を出力するAREF端子。
   ノイズ低減のためにパスコンを入れる
   ためのもの。この電圧出力を利用
   できるとは、データシートには記され
   てない。
  ※ATtiny85や84では2.0Vが最低電圧
   という制限あり。
C53
そうすると大丈夫に。
  ※完璧に誤差がないというわけではく
   そこそこエエ感じ。

ということで、
 「同じシリーズのチップでうまいこと行った
  経験があっても、始めて使うチップは、何が
  あるかわからへんでぇ」
と、あたりまえの結果に。

ダイソーのプラケースに入れるとこんな感じ。
Cc1_20221005171601

  ※L型ダブルのピンヘッダーが無かったんで、
   オムロンのツメ付ヘッダーを切断改造。

| | コメント (0)

2022年10月 3日 (月)

サーミスタ103JTで計った温度をアナログ出力

失敗談、2022年9月28日:回路設計はデータシートの熟読から。 スペックをちゃんと調べろ!
この発端の製作物です。

「温度→電圧」変換はLM35やTMP35あたりのセンサーが
便利なんですが、ブツに接触させて温度を測るときにちょいと
問題があるんです。
 ・形状のせいか応答が遅い。(TO-92パッケージ)
 ・足から熱が逃げるのか、低い目の温度が出る

  ※型番、LM35は、昔はナショセミ。今はTIに。
   そしてTMP35はアナログ・デバイセズに。
   ややこしいぞ。

応答が早くて間違いなくブツに接触できる温度センサーという
ことで、「セミテックのサーミスタ103JT」を使って、
 ・センサーの抵抗値から温度を算出。
 ・温度をD/A出力。
という方法で、アナログ値を得るようにしました。
  ※単純なことをするのに、むちゃたいそうな回路。

Tn85_thm1

ATtiny85を選んだんがそもそも失敗。
でも、作りかけたんで、完成形に仕上げてみました。

測定温度範囲は0~80℃。
10bit分解能のA/Dで温度を得てますんで、分解能は
ざっと0.1℃。
これを0.0V~4.0Vの電圧に変換します。
1℃あたり0.05Vのスケールです。

AVR studioでプログラムを組んでます。
フォルダーごと圧縮。
   ・ダウンロード - thm_85_da1.zip

10bitのA/D値から2kバイトのテーブルで温度に変換
という手抜き手法。
複雑な算術関数は使っていません。

回路を組み込んだプラケースはダイソーの「ミニケース5個組」
M31
M32

この回路の電源は、
Arduino-UNO 12bit×4chアナログ SDカードデータロガー完成形
から供給します。

さて、温度センサーIC:LM35(TMP35)とサーミスタ103JTの
違い、どんなもんかと調べますと・・・

15Ωのホーロー抵抗の側面にセンサーをくっつけて、
抵抗を通電して発熱させます。
その時の温度変化を電圧として記録しました。

M11_20221003101301

M12_20221003101301

まずは、センサーを軽く貼り付けした状態から。
M13_20221003101301
すると・・・
Cap004_20221003101401
センサーICとサーミスタの出力に差が生じます。
時間が経過してもそれが埋まりません。

M14_20221003101301
テープでぐるぐる巻きにして、温度が逃げないように
したつもりでも・・・
Cap005_20221003101401
途中で段ボール箱をかぶせましたが、時間が経っても
2℃くらいの差が埋まりません。

そこで、2017年11月6日:液晶表示器「焼き鈍し」
で使った「保温箱」で試してみました。
この2種以外にも、センサーICとサーミスタを加えます。
M21
2と4が今回のセンサー。
1はセンサーICの外周を熱収縮チューブで覆っています。
4は同じ103JTですが、先端近くまで熱収縮チューブが来ています。

センサー部分はむき出しのまま、電線のところでマスキングテープを
巻いてまとめました。

65℃で保温された箱の中に投入しますと、数分で4つとも温度が
安定、収束します。
  ※電線部分、およそ20cmは保温箱の中に入っていて、
   先端のセンサー部と同じ温度になっているかと。
Cap006_20221003103401

また、4つのセンサーを箱に入れたまま、箱を室温
から加熱した場合も20分ほどで65℃に到達し、
その後の温度差はそれほど感じません。

Cap007_20221003103401
  赤:保温箱温度制御センサー
  緑:サーミスタ 4
  青:サーミスタ 3
  マゼンタ:センサIC 2
  シアン: センサIC 1

発熱体に直接接触させて温度を測る場合と、周囲の空気ごと
温度を測るということで差が生じるのでしょう。

このあたりをもうちょい勉強しようとすれば、何を
調べれば良いでしょうか?

| | コメント (6)

2022年9月29日 (木)

103JTサーミスタの自己発熱。 5Vで10kΩはちょっとなぁ

前記事2022年9月28日:回路設計はデータシートの熟読から。 スペックをちゃんと調べろ!
は、サーミスタを使った温度測定に絡みます。

Arduinoにサーミスタをつないで温度測定・・・
複雑な計算式も入るし、サーミスタを指で触れば温度変化が
出てくるし。
マイコンを活用してる気分になれます。

しかし・・・ちょっと待てぇ
  そのやり方は正しくない。
  サーミスタが持つ性能をつぶしているぞ。
という例を見かけるのです。
  ネットでも初心者向けの本でも。

安価で入手しやすいからとよく出てくるのが
セミテックの「103JT」
  応答性が良いので私も愛用しています。

このサーミスタの特性を分かって「こんなもんだ」と
使っているのなら仕方ないのですが、きっと分かって
ないのだろうなぁというスペックが「熱放散定数」。

サーミスタに電流を流した時、その消費電力で自分が
発熱してしまい、測定温度に誤差が生じます。
その影響度合いで、単位が「mW/℃」。
「ンmWの測定電力で1℃上がる」という指標です。
103JTだと「約0.7mW/℃」というスペックが出ています。

  ※形状の大きな103AT-11だと3mW/℃、
   103AT-2だと2mW/℃。
   大きくなると頑丈になりますが、応答が
   遅くなります。

103JTの約0.7mW/℃、これ、なかなかキツいスペックなんです。
よく出てくる例がこの図のような接続。
【図1】
T1_20220929114401
サーミスタに直列に10kΩの抵抗を入れて5V電源に接続。
ArduinoのADCは、基準電圧=5Vで変換。
   ※
サーミスタを使って温度測定という解説記事、
    たいていはこれ。

これだとどうなるか。
サーミスタの抵抗値とRsが同じ値になったときが
最大の消費電力になります。
   ※103JTだったら10kΩの25℃
どれだけの発熱があるかをグラフに。
Cap036
各温度での抵抗値からサーミスタの消費電力を算出し、
熱放散定数で温度上昇を計算しました。
  ※5Vだけでなく、3.3V、2.5V、2.0V、1.25Vの
   電圧の時も示しています。

測定電圧=5V、Rs=10kΩだと10~40℃の温度域で
およそ0.8℃の温度上昇が生まれると。
Arduino UNOの10bit ADCだと、0.1~0.2℃が
分解能です。
それに0.8℃が積み重なるのは・・・ちょっとなぁ。です。
  ※これをどうにかしたいと思うか、
   こんなもんでエエやんと置いとくか・・・

この温度測定方法でサーミスタの消費電力=発熱を
減らすには・・・
 ・測定するときだけ通電する
 ・測定電圧を下げる
 ・Rsを大きくする
この3つです。

Rsを変えた時の様子がこのグラフ。
15kΩと20kΩにした時の発熱です。
Cap037
Cap038
Rsを大きくするより、サーミスタへの供給電圧を
下げる方が効果があります。
   (電力の計算式 ExE/R、IxIxR)

※Rsを4.7kΩにしたら・・・
Cap001_20220930145401
40~50℃あたりで、自己発熱が1.9℃ほど積み
上がってしまいます。

~~~~~~~~~~~~~~~~~~~~~~~~
サーミスタへの供給電圧を下げての測定方法、
どんなのが・・・
例えば、こんな回路。
【図2】
T2_20220929114901

サーミスタへの供給電圧とA/Dコンバータの基準電圧
を分けてやると、測定温度範囲が自由に決められます。
ところが、この回路だとやっかいな問題が出てくるの
です。
VthmとVzが変動したら、それが測定系の誤差に
つながります。
サーミスタの抵抗値を正しく算出するにはVthmとVzの
絶対値が必要なのです。
どちらかの電圧が動くとアウト。誤差が生じます。
  ※動くなら二つが比例して。
  ※VthmをそのADC測定系で計るのも方法。

それを改善するのがこの方法。
【図3】
T3

【図1】は5V電源でしたが、ADCの基準電圧と
サーミスタへの供給電圧を両方とも下げて発熱を
防ぎます。
二つを同じ電圧にというのが重要で、サーミスタの
抵抗値はRsを基準に算出でき、Vzは計算式から除け
ます。
このRsは「神様抵抗」(俺が正しい!)となります。

Arduino UNOで使っているATmega328Pマイコンのように
Vref電圧が外に取り出せるなら、こんな方法も可能です。
【図4】
T4
Arduino UNOだと「1.1V」が取り出せます。
  ※測定電圧が低い方が自己発熱が小さくできる。


サーミスタを使った測定で、もう一つのグラフを示しておきます。
ADCの分解能を変えた時、測定温度の最小値がどう変化するかを
描いています。
神様抵抗Rsを10k、15k、20kにした時を計算してみました。
Cap039_20220929115501
Cap040_20220929115501
Cap041_20220929115601

Arduino UNOの10bit A/Dだと、常温域で0.1~0.2℃の
分解能がギリギリになることが見えます。
発熱の影響を小さくしようと、Rsを大きくすると、
サーミスタの抵抗値が小さくなる高温域での分解能が
落ちてしまいます。
  ※Vz=ADCの基準電圧=Vthmとしてのグラフです。
   Vz=Vthmが変わっても分解能は変わりません。

 

※関連
2021年8月11日:サーミスタ温度計、何ビットのA/Dコンバータがいるか?
2021年7月31日:16bit A/Dコンバータ LTC2460 サーミスタ103JTを使った温度測定で・・・
2018年2月13日:ピピちゃん温度計・ヒータ制御

※ネット検索
ラジオペンチ:Arduiono を使ってサーミスタで温度を測る(2019-11-08)
ラジオペンチ:ペルチェ温度コントローラーの製作 (温度センサーをサーミスタに変更)(2019-11-11)
セッピーナの趣味の天文計算:サーミスタで正確な温度を測るコツ - 基準抵抗(R0)、B定数、熱拡散係数(2015年2月18日)
マカロニペンギンの健忘録:#arduino で温度測定-自己発熱対応版(2011年11月17日)

あれこれ見てますと・・・
サーミスタの抵抗測定の手順で、A/D電圧を求める時、
件の「1/1023」 が多く出現しています。
例えば、
Decent dress:Arduino Nano と NTCサーミスタで温度計測 (2018/11/29)

本来、Rsを神様抵抗としての測定系では、A/D変換の
基準電圧値は数式から除外されます。
しかし、電圧計算の1/1024を1/1023にしてしまうと
「‰」単位の誤差が生じます。   ※10bitのADCで

jh4vaj:Arduinoでサーミスタを使って温度計を作るのに、電圧を求める必要はない(2021/3/9)
jh4vaj:ArduinoのADコンバータ、1023?1024?( )

| | コメント (0)

2022年9月28日 (水)

回路設計はデータシートの熟読から。 スペックをちゃんと調べろ!

8ピンのATtiny85、14ピンのATtiny84のA/D入力絡みで
ちょいと失敗。

◆状況
・テスト用ジグ作り。
・内蔵のADCを使ってアナログ電圧を測定。
   サーミスタで温度測定
・基準電圧はできるだけ低くしたい。
   サーミスタの自己発熱の防止
・内蔵基準電圧の1.1Vを外に引っ張り出せれれば
 良いんだが、tiny85もtiny84もそれはできない。
   Arduino UNOのATmega328Pは可能
・基準電圧を外部に持たせて、Arefピンに供給か。

こんな考えで回路を組んだのです。

◆参考:基準電圧の切換
ATtiny85の場合
VccかArefか、内部の1.1Vあるいは2.56V。
85_0

ATtiny84の場合
VccかArefか、内部の1.1V
84_0

この基準電圧選択で
 「内部の1.1Vが使えるんだから、Arefピンに外部の
  基準電圧として1.1Vを加えてもかまわないだろう」
と、勝手に推測。

これが間違い。
A/D変換のスペック表を見ますと・・・
ATtiny85
85_1

ATtiny84
84_1

いずれのチップもAref:外部基準電圧の最小値は「2.0V」

外部から1.1Vを入れると・・・
  A/Dから全ビットHのデータが出てきます。

Arefに入れてる電圧が低いんやぁ」の原因に到達するのに
えらく手間取りました。
I/Oの初期化ルーチンで、A/Dの基準電圧をVccや内部電圧に
切り替えると正しく変換。
おもわく通りのデータが出てきます。
ところがArefにして外部からの1.1Vだとアウト。

その後、データシートを熟読したら「最小2.0V」という
記述を発見
したという次第です。
  Aref電圧も徐々にアップすると、1.5Vくらいから
  データが出始め、2.0Vのちょい手前から安定になる
  という挙動でした。

 

| | コメント (0)

2021年8月11日 (水)

サーミスタ温度計、何ビットのA/Dコンバータがいるか?

サーミスタで温度測定するとき、
 ・A/Dコンバータの分解能の違いで、何度の桁まで測れるか?
あるいは、
 ・何度の桁まで計りたい時は何ビットのA/Dが必要か?

この答えのグラフがトランジスタ技術2012年1月号p89
図3に出ていました。
 ●特集:エレクトロニクス格言集
  3-6 抵抗分圧比をA-D変換する時の
  基準電源ICは無駄遣い  著者:星聡

Ad01
8ビット分解能でも1℃ステップで測れないことはない
というキャプション。

先日作った温度計で使った「103JT」サーミスタの
温度特性から、これと同じような表を作ってみました。

セミテック103JTの温度:抵抗値表

#SEMITEC 103JT 温度・抵抗特性
#温度 抵抗値
#℃ Ω
-20 71020.0
-10 43670.0
0 27700.0
10 18070.0
20 12110.0
25 10000.0
30 8301.0
40 5811.0
50 4147.0
60 3011.0
70 2224.0
80 1668.0
85 1451.0
90 1267.0
100 975.3
110 759.7
120 598.1


それを「gawk」に食わせて1℃ごとのテーブルを作成

#####   サーミスタ抵抗値計算プログラム    #####
# 下間憲行  jh3dbo@jarl.com
# 10℃ごとの温度,抵抗値テーブルから
# 1℃ごとの抵抗値データを作成
# メモ awkのlogは自然対数

BEGIN{
# 定数指定
K_273 = 273.15 # ケルビン温度
Rref = 10.0e3 # 直列抵抗 10kΩ
Aref = 65536 # 16bit A/D max
# タイトル表示
print("* サーミスタ抵抗値計算 (2015-06-10)\n") > "/dev/stderr"
nbr = 1 # 読み込みデータ数
}
# 「BEGIN」おわり (以下、ファイル読み出し処理)

##### 温度,抵抗値テーブルを読み出す #####
# 10℃ごとの温度と抵抗値を順に読む
{
if( $0 ~/^#/ ) next # 先頭文字が「#」ならコメント
# 数値入力
temp[nbr] = $1 # 温度
ohm[nbr] = $2 # 抵抗値
# printf("%d %s %s\n", nbr , temp[nbr], ohm[nbr])
nbr++ # 配列 +1
}
# ファイル処理おわり (以下、END処理)

##### 10℃ごとのB定数計算して1℃ごとの処理 #####
# ※基準は25℃なので、20~25~30℃となっているので注意
END{
# B定数計算 10℃ごと
print("# B定数")
for(i = 1; i < (nbr - 1); i++){
t1 = temp[i]
t2 = temp[i+1]
r1 = ohm[i]
r2 = ohm[i+1]
B[i] = (log(r1 / r2)) / ((1 / (t1+K_273)) - (1 / (t2+K_273)))
printf("# %d℃~%d℃ %3.1fΩ~%3.1fΩ B=%3.1f\n",
t1, t2, r1, r2, B[i])
}
# 1℃ごとの抵抗値を計算
print("# ℃ Ω")
m = 1 # 1℃ごと (0.1℃ステップなら10に)
for(i = 1; i < (nbr - 1); i++){ # 10℃のテーブル
n = (temp[i+1] - temp[i]) * m # 表の温度差
for(j = 0; j < n; j++){ # 1℃ピッチで
R = tohm(temp[i] + (j / m), temp[i], ohm[i], B[i])
ad = Aref * (R / (Rref + R)) # A/D値
printf("%6.1f %12.2f %6d", # 温度と抵抗値
temp[i] + (j / m), R, ad)
if(f){
printf(" %8.2f %8.2f", # 抵抗値とA/D値の差分
r0 - R, ad0 - ad)
}
printf("\n")
r0 = R;
ad0 = ad;
f = 1;
}
}
}

##### 温度による抵抗値計算 #####
# T1 = 計算する温度
# Tm = 基準温度
# Rm = 基準温度での抵抗値,
# Bconst:B定数, 273:ケルビン温度
# 1 1
# R = Rm * exp( Bconst * (--------- - -----------) )
# t1 + 273 Tm + 273
function tohm(T1, Tm, Rm, Bconst){
return(Rm * exp(Bconst*((1.0 / (T1 + K_273)) - (1.0 / (Tm + K_273)))))
}


その結果を「gnuplot」で処理

set term wxt 0
set ytics nomirror
set y2tics
set xrange [-20:110]
set yrange [0.001:10]
set y2range [0:800]
set title "A/D値が1LSB変化したときの温度変化 【サーミスタ103JT Rs=10kΩ】"
set xlabel "温度 (℃)"
set ylabel "1LSB変化したときの温度変化(℃)"
set y2label "16 bit A/Dでの1℃あたりの変換値変化"
set grid
set xtics 10
#set ytics 500
set key right top
set pointsize 0.5
set logscale y
set label "" at second -8, 770
set label "16bit A/D値変化(右目盛)" at second 2, 660
set label "8bit A/D" at second 11, 560
set label "10bit A/D" at second 12, 440
set label "12bit A/D" at second 13, 320
set label "14bit A/D" at second 14, 200
set label "16bit A/D" at second 15, 80
plot "ohm3.txt" using 1:5 with line lw 2 ti "" axes x1y2,\
"ohm3.txt" using 1:(1 / ($5/256)) with line lw 2 ti "",\
"ohm3.txt" using 1:(1 / ($5/64)) with line lw 2 ti "",\
"ohm3.txt" using 1:(1 / ($5/16)) with line lw 2 ti "",\
"ohm3.txt" using 1:(1 / ($5/4)) with line lw 2 ti "",\
"ohm3.txt" using 1:(1 / $5) with line lw 2 ti ""


こんなグラフが得られます。
Cap005_20210811095101
8,10,12,14,16ビットのA/Dコンバータを使った
時の分解能の変化を示しています。
   ※A/D変換器や周辺回路の精度が加味されますんで、
    1bitの変動でもきびしい状態が浮かんでくるかと。

10℃~25℃あたりが良くて、1℃あたりのA/D変換値変化量
が減る高温域(70℃を越える)になると分解能が悪化するのが
見えます。
  ※8bitA/Dで「水温・湯温」を計ろうとしたとき、
   0℃~40℃くらいまでは0.5℃ピッチで読めます。
   しかし、80℃を越えると1℃ピッチでの読みが
   しんどくなります。
   昔々・・・4bitマイコンで電気温水器の仕事をした
   ときは(東芝の8bit A/D内蔵品)、出てきた
   8bit値(256バイト)をそのまま1℃単位の温度に変換する
   テーブルを作って処理しました。
     水温が正しくない上下の値はエラー処理
     (氷温以下と沸騰温度以上)

分解能16bitのA/Dを使っても、A/Dの誤差を考えると「0.01℃」の
測定はなかなかむつかしいということで。


| | コメント (0)

2021年8月 4日 (水)

103JTサーミスタ対応温度計 ArduinoとLTC2460を使って

なんとかものになりました。
温度表示最小桁は欲張らずに「0.1」℃で。

・回路図
Thm_ltc2460_2a
  (ちょっと修正、追記しました)

・ハードウェアの補足・・・省けるところ
  ・5Vで動かすのならQ1とQ2、電池は不要。
  ・別個のシリアル出力が不要(Arduino-UNO環境で使う)なら
   Q3、J4は不要。
  ・D/A出力(0~100℃をアナログ0~5Vで出力)が不要なら
   IC4、IC5は不要。
  ・ちょっとした誤差を許容するならIC1は不要。

・外観
T11_20210804152801

T12_20210804152801

T13

●step by step
・電源回り
秋月の5V出力昇圧DC-DCコンバータXCL102が起動に失敗 その原因追求

・A/Dコンバータ
16bit A/Dコンバータ LTC2460 サーミスタ103JTを使った温度測定で・・・

・ケースとスイッチ
タカチのプラケース「SW-125」に回路を組み込む

・液晶表示器
秋月の液晶表示器 ACM0802C-NLW-BBW-IIC、I2Cのプルアップ抵抗
秋月のI2C液晶表示器 ACM0802C-NLW-BBW-IIC 文字表示ライブラリ

■メニュー画面 一覧
==========
|"0 Mesure"|
|"1 Sensor"|
|"2 TxCyc "|
|"3 TxStyl"|
|"4 Vref "|
|"5 Rs "|
|"6 Cal R0"|
|"7 Cal R1"|
|"8 Cal R2"|
|"9 Cal R3"|
|"a CalAD0"|
|"b CalAD1"|
|"c CalAD2"|
|"d CalAD3"|
|"e Bat L "|
|"f Bat M "|
|"g PWM 4V"|
|"h Ck A/D"|
|"i Ck D/A"|
|"j Ck Bat"|
==========
■パラメータ設定値
# 1 Sensor 103JT
# 2 TxCyc 1sec
# 3 TxStyl TempData
# 4 Vref 1.2494V
# 5 Rs 10005.0ohm
# 6 Cal R0 1000.5ohm
# 7 Cal R1 3004.1ohm
# 8 Cal R2 10004.0ohm
# 9 Cal R3 20020.0ohm
# a CalAD0 5923
# b CalAD1 15136
# c CalAD2 32769
# d CalAD3 43691
# e Bat L A/D 313
# f Bat M A/D 345
# g PWM 4V D/A 3276

Cal R0~R3の抵抗値とCalAD0~AD3のA/D値が4点calデータ。
出てきた16bit A/D値がCalAD1より小さいときは、CalAD0~CalAD1の
値で線形補完。
CalAD2より大きいときはCalAD2~CalAD3で線形補完。
CalAD1とCalAD2の間にある時はCalAD1~CalAD2で線形補完。

入れてあるサーミスタのデータは3種。
 セミテックの103JT・・・応答が良い
 103AT-11・・・頑丈
 103AP-2・・・高精度

IC1を入れた理由。
 R3を通して直に信号をA/Dに入れた場合、サーミスタの抵抗値で
 この間の微少な電流が変化してA/D値にオフセットが生じる。
   A/Dコンバータの変換時の電流。
 R3両端の電圧値で±60uVくらい変動する。
 1kΩなので60nAの電流。 それがRs=10kΩにも流れるので
 10倍の0.6mVくらいの変動がA/D値に出てくる。
 Vref=1.25Vで16bitなので1bitは約20uV。
 0.6mVだとA/D値で30くらいの変動になる。
 IC1を入れるとこの変動がなくなる。

テスターで計ったRs、Cal R0~R3の抵抗値が神様データ
  ※測定したA/D値からRsとの比を計算してサーミスタの抵抗値
   を求めている。だもんで正確なVref値は不要。
   16bit A/Dのmax値65536を入れていてもOK。
   モニターモードでA/D入力電圧を表示しているので、
   そこで必要。

スケッチ:とりあえず  (ファイルタイプをtxtにしてます)
   ダウンロード - thm_103jt2.txt (UTF8Nで)

※この液晶表示ライブラリが必要
  http://igarage.cocolog-nifty.com/blog/2021/07/post-78a365.html


※続き 誤差原因の探求 あれこれ
シミュレーテッド・インダクタを使った60Hzノッチ・フィルタ:これから
AD620を使った計装アンプとシミュレーテッド・インダクタを使ったノッチフィルタ

| | コメント (2)

2021年7月31日 (土)

16bit A/Dコンバータ LTC2460 サーミスタ103JTを使った温度測定で・・・

502ATサーミスタを使った温度計は基準電圧外付けの
LTC1864 16bit A/Dコンバータを使っていました。
その後、応答速度の速いサーミスタ「103JT」に対応
させようとしたところ、
A-DコンバータのVref値が精度に影響をという問題が
出てきたのです。

Vrefを下げたかった理由・・・サーミスタの自己発熱
による温度測定値への影響を少なくしたかったから。

103JTの熱放散定数=0.7mW/℃
形状の大きな103AT-11では3mW/℃
高精度品103APだと1.2mW/℃
と、103JTが圧倒的に発熱に敏感なんです。
   ※そのかわりに応答が早い。

2.5VだったVrefを1.25Vにすると、サーミスタの発熱
(電力消費)は1/4に。
直列抵抗を10kΩとして、基準電圧を変えた時の発熱を
グラフにしてみました。

Cap046
直列抵抗10kΩの値が25℃のサーミスタ抵抗値と同じに
なるんで、その時が電力消費のピーク。
25℃から離れると発熱は小さくなります。
5Vで使うなんてもってのほか
2.5Vでも0.2℃ほど発熱による積み上がりが発生します。
0.1℃内に押さえようとすると、Vref=1.25Vで使いたくな
るのです。
ところがA/Dコンバータが1.25Vでは言うことを聞いてくれ
ません。

そこで、1.25Vの基準電圧を内蔵した16bit A/Dコンバータ
LTC2460を試したのですが、今度は・・・
電源電圧を5Vで使うと誤差が大きくなる」という問題に
当たります。
データシートにはこんなグラフが出ていて、
  2.7Vなら誤差は大きくないぞ
っと、訴えています。

Ltc2460_err1

しかたなしに、この温度計、A/D部をこんな具合にしました。

Tt1

A/Dのために2.7V電源を作り、5Vで動くArduinoのATmega328Pと
のインターフェースのためにレベル変換ICを入れました。

サーミスタの直列抵抗Rsに0.1%品を使うことで、無調整
(Vrefの値に関係なく)A/D値からサーミスタの抵抗値を
計算できます。
抵抗値が分かればサーミスタの「温度-抵抗値表」から
温度を求められます。
これで、無調整でそこそこの精度が出ています。

しかし「2.7Vの別電源を用意する」というのが面白くあり
ません。
Vref=1.25Vで使える5V動作の「安いA/Dコンバータ」、
これがなかなか無いんです。

試しと、LTC2460を5Vで使って「補正を行ってみる」
という方法を試してみました。

これが電源電圧を変えた時の変動です。
Ltc2460
2.7Vなら「0を中心に5LSBくらい」なのが、
5Vにすると傾きが大きくなり、60LSBくらい。
60/65536はざっと1/1000。
これでは、16bit A/Dコンバータの値打ちがありません。

結論を出すには早いのですが、ざっと・・・
 ・2点キャリブレーションでは、ちょいと精度が不足。
 ・1kΩ:20kΩで合わせると、25℃に近いところの0.1℃桁
  はピッタリだが、60℃ほどのところで0.1℃ほど低くなる。
   ※温度が高くなるということは抵抗値が小さくなって
    A/D値の読みも小さくなる。
 ・サーミスタの精度を生かすためにも、抵抗値として0.1℃
  は合わせ込みたいけれど、ちょい能力不足か。

cal点を4点くらいにするか、無理に16bit A/Dを使うより、
素性の良い12bit A/Dを使う方が良いかもしれません。

※参
ピピちゃん温度計・ヒータ制御 (Arduino  103JT  Vref=1.1V)

・103JTサーミスタの抵抗値変化と16bit A/Dで取り込んだ
 時のA/D値の変化
2a
抵抗値は「対数グラフ」で右肩下がりに。
温度が上がるほど、A/D値のちょっとの変化が
温度の変化につながります。

25℃~26℃の1℃差だと
 「10000.00Ω~9629.63Ω」で 抵抗値差370Ω
 A/D値が「32768~32149」で 差は619

温度が上がって70℃~71℃だと
  抵抗値が「2224.00Ω~2159.31Ω」で 差は65Ω。
  A/D値が「11923~11638」で 差は285

25℃付近だと0.1℃変化するときのA/D値の変動は「60」くらい。
それが70℃あたりになると「28」ほどで0.1℃変化しちゃいます。
温度が高いほうがA/D値の変化に敏感になるわけです。

16bit A/Dですんで60だとフルスケールの0.1%ほど。
28だと0.04%。 なかなかシビアです。
  12bit A/Dの1LSBが0.024%ですんで。

| | コメント (2)

2018年2月13日 (火)

ピピちゃん温度計・ヒータ制御

コザクラインコのピピちゃん の鳥カゴ温度のチェックに
使っていたデジタル温度計。
女房が「調子悪い」っと言うので見てみたら、温度センサー
(サーミスタ)の電線をかじられていました。
長年使っていたものでして、液晶の接触もおかしいし、
廃棄に。

 

寒い夜を過ごす、ピピちゃんの鳥カゴ、厳重に保温してます。

 

11

 

 

 

夜になると、電気座布団 をオンして保温。
鳥カゴの周囲も暖かく。
いつもチャートレコーダーをつないでおくわけには
いかないので、壊されたデジタル温度計を置いてい
たのです。

 

で、こんな温度計+ヒータ制御回路を作ってみました。

12

 

現在温度と最高最低温度、それに確認後の経過時間を表示します。
箱左上の赤ボタンを押すと、時間をクリアして最高最低を現在温度に初期化。

設定したon/off温度でSSRを制御しながら、その後の最高最低温度を記録します。
翌朝、温度を確認したらボタンを押して時間クリアという手順。

回路図  (クリックで拡大↓)
A1

 

「Arduino UNO」のチップを乗せて制御しています。
電源はダイソーのACアダプタT362
これを殻割りして内部基板を取り出して、むき出しで使っています。

 

14

 

 

 

温度センサーはサーミスタ「103JT」。
「かじり」に負けないよう、熱収縮チューブで保護。
  (それでも負けそう… 金属管がいるかも)

 

制御温度(on温度、off温度)は半固定VRで設定。
on温度、off温度をそれぞれEEPROMに保存。

制御の「スケッチ」、アップしておきました。

※スケッチのアップ先↓
http://act-ele.c.ooco.jp/jisaku/pipiheater/pipi_heater1.zip

※回路の解説 かいつまんで

 

特徴的なのがサーミスタの接続。
ATmega328のVref=1.1VをOP-AMPでバッファして出力。
0.1%、10kΩの高精度抵抗との分圧比でサーミスタの抵抗値を測定。
電源電圧としなかったのは、サーミスタへの印加電圧が低い方が
自己発熱の影響を避けられるから。
   ※小型で応答が早い103JTだと自己発熱の影響が大きい
on/off温度設定用VRの読み出しもVrefに合わさないといけないので、
これもOP-AMPでバッファ。
使ったMCP6072 はレールtoレール入出力のOP-AMP。
オフセット電圧、0.15mVと優秀。
10bit A/Dなので、常温(25℃)付近だとざっと0.1℃分解能で測定
できるけど、表示と制御は1℃単位。
  (液晶表示器サイズで。8文字×2行なもんで)
抵抗値から温度への計算は、サーミスタの「温度-抵抗値表」から、
各ポイントでの「B定数」を毎回計算して温度を算出。

サーミスタのB定数
温度測定:サーミスタでの予備実験

EEPROMの読み書きルーチン、ネットから引っ張ってきたのが便利かも。
https://projectgus.com/2010/07/eeprom-access-with-arduino/
http://forum.arduino.cc/index.php?topic=128816.0

| | コメント (4) | トラックバック (0)