以前、においセンサーTGS2450をArduinoで実験に使ってみたことがありました。
今回、同じセンサーをESP32で利用しようとしたのですが、このセンサーを使うためには回路やプログラムのみならず、運用まで割と面倒くさいのです。
仕様上
ヒーター:DC1.6V (約138mA) 8msON/242msOFFの繰り返し
センサ:5.62〜56.2KΩ(15mW以下)5msON/245msOFFの繰り返し
これらのタイミングは絶対厳守で、ヒーターのみでなく、センサーも読み取る時だけ電圧印加して抵抗値を読み取ります。連続して通電していると簡単に破壊されるそうです。なので普通のテスターで直接抵抗値を図ろうとすると焼損する可能性がありますので測れませんね。おそろしい・・・
加えて火入れしてからセンサーが安定するまで数分〜数十分必要とします。(初回は数時間かかるということも)
前回の実験回路ではArduinoから33Ωの抵抗を介して直接ヒーターに給電していましたが、138mAも消費するので、一瞬とはいえGPIOでMAXで40mA程度しか給電出来ないArduinoの仕様では本来であれば完全アウトです。
今回使うESP32はGPIO3.3V、電流はMAXで12mA。前回通りの回路では絶対に駄目です。
<秋月掲載のサンプル回路>
参考回路ではヒーター用としてPNP型トラジスタのこちらが使われています。
センサー内部の回路は割とシンプルなのでヒーター電流さえきちんと制御できれば壊れることはなさそうですが、いかんせん面倒くさいです。
<参考データ>
こちらは汎用トランジスタ2SC1815を使った例で、電源電圧5Vでトランジスタのエミッタ側に25Ω抵抗を界して供給している作例です。NPNトランジスタでも工夫すればいけるものなんですね?
5Vで25Ωならヒーターへの給電は140mAになるけど、エミッタからの帰還作用が働くから2mAぐらいオーバーしても(電源電圧によってはもっとオーバーしますよね)大丈夫ということなのでしょうか?
この辺のアナログ回路の知見が無いのが悔しいです。
僕も残念ながら手持ちにPNP型トランジスタがないので、同じように2SC1815でどうにか出来ないだろうかと奮闘しました。
トランジスタ2SC1815はMAXが150mAなので140mA程度の制御は問題ないはずです。
問題は「ベースが3.3Vの場合にエミッタフォロワでうまくドライブできるのか?」ですが、2SC1815のベース3.3Vを入力としたエミッタフォロワ回路はなかなか難しく、いろいろ調べて参考にしても、計算ツールで計算してもヒーターへの電力不足で狙った制御ができませんでした。(というかアナログ回路わからねぇ。。。)
GPIOから電力を引きすぎることなく、トランジスタでエミッタへ最大電力を流せるようベース抵抗は最小に、且つヒーターへはしっかり定格内の電流を送らないといけません。
この調整がめちゃ難しい。失敗したら1つしか無いセンサーが一瞬で焼損しておしまいというプレッシャーの中、いろいろ試した結果、最終的にこのような試験回路の構成でうまく動きました。
【試験回路】
ヒーターへの電力はオーバーしているように見えますが、これ以上抵抗値を上げるとヒーターが機能せず使い物になりませんでした。また、トランジスタも発熱することもなく使えています。
個体差があると思うのでこれが正解とは言えませんので、あくまで僕の環境ではうまく動いた実験回路だということだけ報告しておきます。
はい、
素直にPNP型トランジスタを買ったほうが楽です!
ウォームアップ中の抵抗値の変化の様子
プログラムコード全容
GPIOはマイコンの立ち上がりとか書き込み時のヒーターやセンサーの焼損が怖いのでESP32のデフォルトで(起動時に)プルダウンになるピンを選択して使っています。
#include <Arduino.h>
#define TGS_heat 2
#define TGS_pw 4
#define TGS_sens 12void setup() {
pinMode(TGS_heat, OUTPUT);
pinMode(TGS_pw, OUTPUT);
pinMode(TGS_sens, INPUT);
digitalWrite(TGS_heat, LOW);
digitalWrite(TGS_pw, LOW);
Serial.begin(115200);
}void heatTGS(){
digitalWrite(TGS_heat, HIGH);
delay(8);
digitalWrite(TGS_heat, LOW);
delay(242);
}int readTGS(){
heatTGS();
digitalWrite(TGS_pw, HIGH);
delay(5);
int sensorValue = analogRead(TGS_sens); //12bit 4096step
digitalWrite(TGS_pw, LOW);
delay(245);
return sensorValue;
}void loop() {
int valOdor = readTGS();
Serial.print("val:");
Serial.println( valOdor );
delay(1);
}
環境によると思いますが、僕の実験環境ではセンサ値、2450~2470ぐらいで安定しました。(安定するまで4時間ぐらいかかりました。)
ちなみに、省エネ化を目論んで安定したら3秒間隔ぐらいで読もうとしましたが失敗。
間隔が空くとすぐにセンサーの抵抗値が落ちてしまうようで、常にセンサーにはヒーターで新鮮な酸素を取り入れておかないといけないようです。
<参考>
臭気計測器・においセンサーの測定原理と仕組み - 金属酸化物半導体センサー
アルコールの反応の様子
2400 →300ぐらい変化して良い反応です。
アルコールを遠ざけても周囲にアルコール臭が漂っているためか、回復はゆっくりです。
今回は、ひとまず動作しました。とだけ報告しておきます。
追記:WiFiで臭度レベルを送信する場合はセンサーのピンを変更しないと使えません↓
もっと簡単なにおいセンサーは無いものか?と調べているとこちらを発見しました。
MQ135というセンサーモジュールです。
モジュール化されていて、連続通電OKなのでTGS2450単体より断然使いやすそうですが、匂いとなる検知物質が少し違うようなので注意です。
TGS2450
検知物質:メチルメルカプタン(排泄臭),硫化水素、アンモニア、アルコール
検知範囲:0.1ppm以上
MQ135
検知物質:アンモニア、芳香族化合物(ベンゼン等)、硫黄
検知範囲:10〜1000ppm
使い道次第なのでしょうけれど、生ゴミのような汚臭にはメチルメルカプタンが検出されたほうが良いようです。