2端子温度センサLMT01を試す(12)延長してみると・・・。
2016-02-22

データシートによるとLMT01は2mまで延長できるとなってます。
やってみました、ただし手持ちに適当な電線がなかったので1.3mですが。

動作しましたが、線をまっすぐ伸ばしてみるとカウントがばたつきます。
それも延長した側ではなく、Arduinoの近くにあるLMT01のパスルカウント表示が数カウントばたつくのです。
これが動作中は、延長した側のLMT01はフローティング状態、要するに1.3mのアンテナが付いているような状態です。

そこでArduinoのD7(コンパレータ入力)にCRによるフィルタを入れることにしました。
実際は手近にあった33KΩを入れるだけでばたつきは収まりました。入力容量とでフィルタになったようです。
あとで数十ピコ程度のコンデンサを入れればOKと思ったのですが・・・。
この実験には上の写真のように電源としてモバイルバッテリーを使いました。
電源をパソコンのUSBポートから取ると今度は延長した側のパルスカウント表示が1カウントばたつきます。モバイルバッテリーを使ってるときにはばたつかなかったのですが。
実は前から気にはなっていたのですが、ArduinoのというよりATmegaのコンパレータにはヒステリシスがないのです。
これが問題なのかな?
さてどうしたものやら。
スポンサーサイト
2端子温度センサLMT01を試す(11)電源投入時の始動電流
2016-02-20
前の記事のようにLMT01をオン/オフしてみると、連続動作の時のスケッチでは動作しないことがありました。
その状態を再現するために、前の記事のスケッチのloop()を次のように書き換えて、オシロで観測しました。
観測しやすいように D5 をフロートにしてから10mSのディレイを入れてあります。
オシロがどうも具合が悪く輝度を落とせません。(寿命かな?)
VPの立ち上がりでVNに約4.4Vのパルスが出ています。

LMT01が始動するときに必要な電流でしょう。

以前試したCRのディレイによるパルス終了検出方法では問題にはならないのですが、ソフトでパルス終了を検出する方法だと、この予期せぬパルスのために連続動作時のスケッチでは動作しませんでした。
今は書き換えて動作してます。
その状態を再現するために、前の記事のスケッチのloop()を次のように書き換えて、オシロで観測しました。
観測しやすいように D5 をフロートにしてから10mSのディレイを入れてあります。
void loop()
{
pinMode(5, OUTPUT);
digitalWrite(5, 1); // D5をオンにしてLMT01-no.1をスタート
delay(1);
countpulse();
dtostrf(count, 6, 0, s); // パルス数表示
lcd.setCursor(0, 0) ;
lcd.print(s) ;
temp = count / 16.0 - 50.0; // 温度表示
dtostrf(temp, 6, 1, s);
lcd.setCursor(0, 1) ;
lcd.print(s) ;
lcd.print("c") ;
pinMode(5, INPUT); // D5をオフ(フロート状態)にしてLMT01-no.1をストップ
delay(10);
}
オシロがどうも具合が悪く輝度を落とせません。(寿命かな?)
VPの立ち上がりでVNに約4.4Vのパルスが出ています。

LMT01が始動するときに必要な電流でしょう。

以前試したCRのディレイによるパルス終了検出方法では問題にはならないのですが、ソフトでパルス終了を検出する方法だと、この予期せぬパルスのために連続動作時のスケッチでは動作しませんでした。
今は書き換えて動作してます。
2端子温度センサLMT01を試す(10)多チャンネル化・続き
2016-02-18
LMT01のデータシートFig..33に複数のLMT01をつなぐ方法が載せられてます。

注意すべき点は使わないLMT01のVPはローレベルにするのではなくフローティングにすることです。
ローレベルにすると逆バイアスされるからです。
絶対最大定格です。逆バイアス許容値は0.3V、これは低いですねぇ。

Arduinoでポートをフローティングにするには
pinMode(N , INPUT)
とします、Nはポート番号です。
ここでは2つのLMT01をつないで見ましたが、プログラムとしては
2つのポートをフローティングにしておく。
1つのポートを出力モードにしてHレベルを出力する、これで計測が開始されます。
温度測定が終わったらポートをフローティングにする。
他のポートも同様にして測定する。
の繰り返し。
とりあえずのスケッチです。
実験なのでパルス数も表示してます。

注意すべき点は使わないLMT01のVPはローレベルにするのではなくフローティングにすることです。
ローレベルにすると逆バイアスされるからです。
絶対最大定格です。逆バイアス許容値は0.3V、これは低いですねぇ。

Arduinoでポートをフローティングにするには
pinMode(N , INPUT)
とします、Nはポート番号です。
ここでは2つのLMT01をつないで見ましたが、プログラムとしては
2つのポートをフローティングにしておく。
1つのポートを出力モードにしてHレベルを出力する、これで計測が開始されます。
温度測定が終わったらポートをフローティングにする。
他のポートも同様にして測定する。
の繰り返し。
とりあえずのスケッチです。
実験なのでパルス数も表示してます。
// LMT01をArduinoにつなぐ
// edy
//
// 2016/02/13:内部コンパレータを使う
// 2016/02/14:内部基準電圧を使う
// 2016/02/16:2つのLMT01を使う
//
//参考にしたサイト:コンパレータ割り込み minori246さん
//http://minori246.blog.fc2.com/blog-entry-15.html
//
//参考にしたサイト:パルス列終了検出 ラジオペンチさん
//http://radiopench.blog96.fc2.com/blog-entry-640.html
//
#ifndef cbi
#define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit)) //clear
#endif
#ifndef sbi
#define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit)) //set
#endif
#include <LiquidCrystal.h>
LiquidCrystal lcd(4, 3, 8, 9, 10, 11); //LiquidCrystal(rs, enable, d4, d5, d6, d7)
volatile unsigned int count = 0;
unsigned int LASTcount = 0;
char s[16];
float temp;
void setup()
{
pinMode(5, INPUT);
pinMode(6, INPUT);
lcd.begin(16, 2);
initComp();
lcd.setCursor(0, 0);
lcd.print("Start LMT01");
delay(1000);
lcd.setCursor(0, 0);
lcd.print(" ");
}
void loop()
{
pinMode(5, OUTPUT);
digitalWrite(5, 1); // D5をオンにしてLMT01-no.1をスタート
delay(1);
countpulse();
dtostrf(count, 6, 0, s); // パルス数表示
lcd.setCursor(0, 0) ;
lcd.print(s) ;
temp = count / 16.0 - 50.0; // 温度表示
dtostrf(temp, 6, 1, s);
lcd.setCursor(0, 1) ;
lcd.print(s) ;
lcd.print("c") ;
pinMode(5, INPUT); // D5をオフ(フロート状態)にしてLMT01-no.1をストップ
delay(1);
pinMode(6, OUTPUT);
digitalWrite(6, 1); // D6をオンにしてLMT01-no.2をスタート
delay(1);
countpulse();
dtostrf(count, 6, 0, s); // パルス数表示
lcd.setCursor(8, 0) ;
lcd.print(s) ;
temp = count / 16.0 - 50.0; // 温度表示
dtostrf(temp, 6, 1, s);
lcd.setCursor(8, 1) ;
lcd.print(s) ;
lcd.print("c") ;
pinMode(6, INPUT); // D6をオフ(フロート状態)にしてLMT01-no.2をストップ
delay(1);
}
void initComp()
{
cbi(ACSR, ACD); // Analog Comparator Disable : コンパレータを使う設定にする
sbi(ACSR, ACBG); // Analog Comparator Bandgap Select : 内部基準電圧(1.1V)を使う設定にする
sbi(ACSR, ACIE); // Analog Comparator Interrupt Enable : コンパレータ割り込みを許可する
cbi(ACSR, ACIC); // Analog Comparator Input Capture Enable
sbi(ACSR, ACIS1); // Analog Comparator Interrupt Mode Select1 : コンパレータの立下りで割り込み設定
cbi(ACSR, ACIS0); // Analog Comparator Interrupt Mode Select0 : コンパレータの立下りで割り込み設定
sbi(PRR, PRADC); // オリジナルではcbi(PRR0, PRADC);だったがエラーになった。
cbi(ADCSRB, ACME); //Analog Comparator Multiplexer Enable : コンパレータ反転入力をAIN1にする
}
void countpulse()
{
count = 0;
LASTcount = 0;
while (count == 0) {}
if (count != 0) {
// カウンタがゼロではない場合、つまりカウント中なら
while (count != LASTcount) { // もし数値が変わっていたらまだ測定中なので以下を繰り返す
LASTcount = count; // 次回の比較用に値を保存
delay(1); // ちょっと待つ
}
}
}
ISR(ANALOG_COMP_vect) {
count++;
}
2端子温度センサLMT01を試す(9)多チャンネル化
2016-02-16
2端子温度センサLMT01を試す(8)Arduinoとの接続・最終編(多分)
2016-02-14
前回の記事で表示がばたつくと書きましたがスケッチのミスでした。
最初にLMT01を試したのはPSoC1でした、抵抗1本で割りと簡単に繋がったので、Arduinoでも出来るのではないかと思ったのですが、結構振り回されました。
ようやく抵抗1本で繋がりました。
写真では抵抗を3本使ってますが、必要な値のが見つからなかったので直並列してます。

回路図、というほどのことはありませんが・・・。
D7につなぎます、スケッチを変更すればアナログ入力も使えるようになりますが、そうすると多分analogRead()が使えなくなると思います(未確認)
ついでにトランジスタによる接続も試してみました(回路図右)。この場合任意のデジタル入力に接続できます。内臓コンパレータは使いません。

最初にLMT01を試したのはPSoC1でした、抵抗1本で割りと簡単に繋がったので、Arduinoでも出来るのではないかと思ったのですが、結構振り回されました。
ようやく抵抗1本で繋がりました。
写真では抵抗を3本使ってますが、必要な値のが見つからなかったので直並列してます。

回路図、というほどのことはありませんが・・・。
D7につなぎます、スケッチを変更すればアナログ入力も使えるようになりますが、そうすると多分analogRead()が使えなくなると思います(未確認)
ついでにトランジスタによる接続も試してみました(回路図右)。この場合任意のデジタル入力に接続できます。内臓コンパレータは使いません。

2端子温度センサLMT01を試す(7)Arduinoとの接続・内臓コンパレータを使う
2016-02-13

ATmega328にはコンパレータが内蔵されています。これを使えばコンパレータを外付けしなくてすみます。
ネットで探したら、ArduinoでAVR内臓コンパレータを使うと言う記事が見つかりました。作者のminori246に感謝します。
minori246さんのスケッチを参考にしながらATmegaのデータシートと格闘(^^;;)し、動かす目処が立ちました。
さらにラジオペンチさんがArduinoの外部割込み限界周波数を調べたと言う記事をアップしてくださいました。
そのスケッチにはパルス列終了検出の方法が載ってました、私には思いつきませんでした。ラジオペンチさんにも感謝します。
とりあえずの回路、前の回路から、コンパレータを外しただけです。


このために、自作LCDシールドのピン配置を換えました。
2端子温度センサLMT01を試す(6)Arduinoとの接続・PULLUP
2016-02-11
ATmegaにはプルアップ抵抗が内蔵されています。これを使うとR3とR4を省略できます。

スケッチのsetup()を次のようにします。
attachInterrupt()はコメントアウトしたように書いてもいいのですが、digitalPinToInterrupt()を使って明示的に割り込みピンを書いたほうがわかりやすいかと思います。
PULLUP抵抗の値を調べてみました。
日本語のATmegaデータシートを見つけました、これは有志の方々によって作成されたものだそうです、感謝します。
データシート193ページから引用します。
PULLUP抵抗は20~50KΩとなっています、コンデンサCの値は計算上では300pF以上となります、余裕を見て数倍の値にしておくといいでしょう。


スケッチのsetup()を次のようにします。
void setup()
{
lcd.begin(16, 2);
pinMode(9, INPUT_PULLUP);
pinMode(2, INPUT_PULLUP);
attachInterrupt(digitalPinToInterrupt(2), periodIrq, FALLING);
// attachInterrupt(0, periodIrq,FALLING);
}
attachInterrupt()はコメントアウトしたように書いてもいいのですが、digitalPinToInterrupt()を使って明示的に割り込みピンを書いたほうがわかりやすいかと思います。
PULLUP抵抗の値を調べてみました。
日本語のATmegaデータシートを見つけました、これは有志の方々によって作成されたものだそうです、感謝します。
データシート193ページから引用します。
PULLUP抵抗は20~50KΩとなっています、コンデンサCの値は計算上では300pF以上となります、余裕を見て数倍の値にしておくといいでしょう。

2端子温度センサLMT01を試す(5)Arduinoにつながりました。
2016-02-09
変換回路を作りました。
コンパレータには手持ちのLM2903を使いました。
【追記】
コンデンサCは抵抗R4が10Kオームの時、計算上は600pF以上となります。(計算ついては後述・・・多分^^;;)
パルス列の周期他のばらつきがあるので大きめにしておきます。ここで使った0.012uFは手持ちにあったから使っただけです。
なおダイオードはシリコンです。

実験基板です。
金属皮膜抵抗を使ってますが、前にAVR DDSファンクションジェネレーターキットを改造したときに外した抵抗です。カーボン抵抗で充分です。

実験の様子、どうやら無事動作しているようです。
PSoC1みたいに抵抗一本だけで出来ないか?とは思うんですが、残念ながら勉強不足です。
まぁ動いたのだからよしとしましょう。

コンパレータには手持ちのLM2903を使いました。
【追記】
コンデンサCは抵抗R4が10Kオームの時、計算上は600pF以上となります。(計算ついては後述・・・多分^^;;)
パルス列の周期他のばらつきがあるので大きめにしておきます。ここで使った0.012uFは手持ちにあったから使っただけです。
なおダイオードはシリコンです。

実験基板です。
金属皮膜抵抗を使ってますが、前にAVR DDSファンクションジェネレーターキットを改造したときに外した抵抗です。カーボン抵抗で充分です。

実験の様子、どうやら無事動作しているようです。
PSoC1みたいに抵抗一本だけで出来ないか?とは思うんですが、残念ながら勉強不足です。
まぁ動いたのだからよしとしましょう。

2端子温度センサLMT01を試す(4)Arduinoにつなぐ
2016-02-08
LMT01をArduinoにつないでみようと思ったのですが、LMT01のパルス列をカウントする方法がわかりません。
Arduinoに載ってるATmega328には16ビットのカウンタがあるのですが、その操作方法がATmega初心者な私にはわからないのです。
ちゃんとデータシートを読んで勉強すればいいのでしょうけど、ここでは内臓のカウンタは使わず、割り込みで処理することにしました。
LMT01のパルス列の周期は約11μSです。パルスの立ち上がりで割り込みをかけてカウント値をインクリメントすることにしました。
処理が間に合うかどうか心配でしたが、やってみるとあっさり動作しました。
前に実験したPSoC1の回路から、ロジックレベルに変換したパルス列とパルス列終了信号を読み取ってArduinoで処理してます。
右がArduinoとLCDシールドです、LCD上の桁がパルス列の数、下が温度、急いでスケッチを書いたので小数点が入ってませんが、PSoC1のと同じです。

Arduinoに載ってるATmega328には16ビットのカウンタがあるのですが、その操作方法がATmega初心者な私にはわからないのです。
ちゃんとデータシートを読んで勉強すればいいのでしょうけど、ここでは内臓のカウンタは使わず、割り込みで処理することにしました。
LMT01のパルス列の周期は約11μSです。パルスの立ち上がりで割り込みをかけてカウント値をインクリメントすることにしました。
処理が間に合うかどうか心配でしたが、やってみるとあっさり動作しました。
前に実験したPSoC1の回路から、ロジックレベルに変換したパルス列とパルス列終了信号を読み取ってArduinoで処理してます。
右がArduinoとLCDシールドです、LCD上の桁がパルス列の数、下が温度、急いでスケッチを書いたので小数点が入ってませんが、PSoC1のと同じです。

2端子温度センサLMT01を試す(3)
2016-02-06
ネット上でLMT01の接続例を探してますが、今のところ見つかりません。
ちゃんとした接続例ではないですが、参考になるページを見つけました。
Help a newbie connect the PSOC 5 dev kit to a digital temperature sensor!
なんとPSoC Developer Communityじゃあ~りませんか^^;;
残念ながらPSoc1ではなくPSoC5でしたが。
ちゃんとした接続例ではないですが、参考になるページを見つけました。
Help a newbie connect the PSOC 5 dev kit to a digital temperature sensor!
なんとPSoC Developer Communityじゃあ~りませんか^^;;
残念ながらPSoc1ではなくPSoC5でしたが。
2端子温度センサLMT01を試す(2)
2016-02-06
LMT01の出力パルス。ロジックレベルに変換し、手持ちのロジックアナライザで観測。
約1秒間隔でパルス列が出力されてます。この時の温度は16度、パルス数は約1000でした。

PSoC1でパルス数を数えるにはカウンタモジュールを使います。他のマイコンでもカウンタはあると思いますが、詳しくは知りません。
問題なのはパルス列の終わりを知る方法です。
次のパルス列が来るまで間隔があいていますから、一定時間以上 L レベルが続いたらパルス列の終わりと判定します。
プログラムとしては
パルス列の終わりを待つ。
カウンタを読み出し、リセット。
読み出した値から温度を計算し、表示。
次のパルス列を待つ。
の繰り返し、となります。
当初考えたのは下図の回路です。秋月電子のLMT01回路例をみて思いつきました。
パルス列が出力されている間、コンデンサCの電圧がGPIOの閾値を超えないように R3 と C の値を設定します。

実際には同等の動作をPSoC1のユーザーモジュールで実現できたので、作ってません。定数の計算もしていません。
LM393のようなコンパレータを使ったほうが簡単だと思います。
パルス列の終わりを判定するのにこのような回路を使わず、ソフトで処理できればいいでしょうが、ちょっと思いつきません。
約1秒間隔でパルス列が出力されてます。この時の温度は16度、パルス数は約1000でした。

PSoC1でパルス数を数えるにはカウンタモジュールを使います。他のマイコンでもカウンタはあると思いますが、詳しくは知りません。
問題なのはパルス列の終わりを知る方法です。
次のパルス列が来るまで間隔があいていますから、一定時間以上 L レベルが続いたらパルス列の終わりと判定します。
プログラムとしては
パルス列の終わりを待つ。
カウンタを読み出し、リセット。
読み出した値から温度を計算し、表示。
次のパルス列を待つ。
の繰り返し、となります。
当初考えたのは下図の回路です。秋月電子のLMT01回路例をみて思いつきました。
パルス列が出力されている間、コンデンサCの電圧がGPIOの閾値を超えないように R3 と C の値を設定します。

実際には同等の動作をPSoC1のユーザーモジュールで実現できたので、作ってません。定数の計算もしていません。
LM393のようなコンパレータを使ったほうが簡単だと思います。
パルス列の終わりを判定するのにこのような回路を使わず、ソフトで処理できればいいでしょうが、ちょっと思いつきません。
2端子温度センサLMT01を試す(1)
2016-02-05
秋月電子から2端子デジタルIC温度センサ LMT01を購入しました。

接続は下図のように簡単です。
電流出力でH レベル125μA、L レベル34μAです(いずれもtyp)。
抵抗で電圧に変換しマイコンなどでパルス数を数え温度を求めます。

データシートによると、
温度=(出力パルス数/16)-50
で計算しますが、私はデータシートのLookup Table の TYP値から近似式をエクセルで求め、
温度=(出力パルス数/16)-50.6
で計算しています。ここまでする必要があるかどうかは別ですが^^;;

PSoC1 で実験してみました。

手持ちのサーミスタ温度計のセンサを LMT01にセロテープで密着させて温度測定中。
以前SEMITEC(旧・石塚電子)のサーミスタ103ATを使った温度計を自作したことがありますが、今回使ったサーミスタ温度計はそれと比べて1度ほど高めに出ることを確認しています。
LCDの表示、上の桁は出力パルス数、下の桁は温度です。


接続は下図のように簡単です。
電流出力でH レベル125μA、L レベル34μAです(いずれもtyp)。
抵抗で電圧に変換しマイコンなどでパルス数を数え温度を求めます。

データシートによると、
温度=(出力パルス数/16)-50
で計算しますが、私はデータシートのLookup Table の TYP値から近似式をエクセルで求め、
温度=(出力パルス数/16)-50.6
で計算しています。ここまでする必要があるかどうかは別ですが^^;;

PSoC1 で実験してみました。

手持ちのサーミスタ温度計のセンサを LMT01にセロテープで密着させて温度測定中。
以前SEMITEC(旧・石塚電子)のサーミスタ103ATを使った温度計を自作したことがありますが、今回使ったサーミスタ温度計はそれと比べて1度ほど高めに出ることを確認しています。
LCDの表示、上の桁は出力パルス数、下の桁は温度です。
