M5StickC PLUSと匂いセンサ(TGS2450)

 

M5StickC PLUSと匂いセンサ(TGS2450)
M5StickC PLUSと匂いセンサ(TGS2450)

この記事では、匂いセンサTGS2450を使ってM5StickC PLUSで匂いを測定する方法をご紹介します。他のArduinoやラズパイなどでも匂いセンサは扱えますので、ぜひこの記事をご参考になさってみてください。

TGS2450は、メチルメルカプタン(玉ねぎの腐ったような匂い)やアルコールなどのガスに反応するガスセンサのひとつです。このセンサを使えば、カンタンな匂いチェッカーのようなものを作ることができます。

今回は、Arduino互換機のM5StickC PLUSを使用し、匂いセンサのHATを作ってみました。ぜひご参考になさってみてください。

はじめに

M5StickC PLUSとは、ESP32 PICOに液晶ディスプレイやバッテリー、ボタンなどが内蔵された超小型なArduino互換機です。 M5Stackシリーズの製品のひとつであります。

M5StickC PLUSでは、手持ちサイズで測定したデータをカンタンにモニター表示できるので、今回のような匂いチェッカーにはぴったりのマイコンです。

M5StickC PLUSの詳しい使い方はM5StickC PLUSでArduinoをはじめよう!をご参考になさってみてください。Arduino IDEを使ってArduino言語でプログラミングできます。

また、匂いセンサのTGS2450は、 秋月電子通商 で入手できます。Amazonで探す場合は、フィガロ技研の TGS2602 あたりが似たような動作をするかもしれません。

匂いセンサTGS2450の使い方

TGS2450は空気中に含まれるガスの濃度に応じて抵抗値が変化するセンサです。検知しやすいガスは次の通りです。

項目感度
メチルメルカプタン
硫化水素
アルコール
アンモニア

TGS2450を下からみた図
TGS2450を下からみた図

4つのピン端子はそれぞれ次の役割になっています。

ピン番号名称備考
1CommonGNDへ繋ぐ
2N.C.何も接続しない
3Sensor electrodeガス濃度に応じて約5Ω〜50kΩで変化する
4Heaterパルスで1.6Vの電圧を印加する

TGS2450をArduinoなどで扱うにあたっては、ピン3番と4番がポイントになります。

アナログ出力(3番ピン)

まず、3番ピンの説明です。このピンは、空気中に含まれるガス成分の量に応じて、抵抗値が変化するセンサ抵抗になっています。よって、センサの抵抗値を測定すればガス濃度を知ることができます。

抵抗値の変化を読み取るには、基準となる抵抗を用意して分圧し、ADコンバータで読み取ってセンサの抵抗値を算出します。

ちなみに、裏ワザでステップ応答を使うと、ADコンバータのないマイコンでも抵抗値を読み取れます。詳しくはラズパイでステップ応答で抵抗値の測定をご参考になさってみてください。

ヒータ抵抗(4番ピン)

次に、4番ピンの説明です。4番ピンは10Ω程度のヒータ抵抗につながっているようです。ここへ電圧を一定間隔の時間で印加します。具体的には、250msecを1周期として8msのあいだだけ1.6Vを印加し、のこり242msは0Vとします。

簡単なPWMなのでプログラミング的にはたいしたことないです。定格が1.6Vになっていることと、またヒータ抵抗が非常に低い値のため安全を考えてトランジスタを使いました。今回はもっとも入手がカンタンな2SC1815を使用しました。

配線

こちらが今回使用した匂いセンサの配線図です。

匂いセンサの配線図
匂いセンサの配線図

いろいろな方のTGS2450を使った記事を拝見したところ、人によってさまざまでした。トランジスタを使わない方もいらっしゃいました。匂いの絶対値を測るわけではないので、結構アバウトでもなんとかなりそうです。私の回路も参考の一つとしてください。

この回路を元に、銅基板をエッチングして、M5StickC PLUSで使えるHATモジュールを作ってみました。

エミッタに10Ωの抵抗直列に通して、4番ピンのヒータ抵抗へつなぎました。コレクタには5V電源を接続しました。オシロスコープで観察したところ、この設計でだいたい1.5Vの電圧がヒータ抵抗に印加されました。

ちなみに、2SC1815のコレクタ電流定格は150mAです。常時コレクタ電流を流す場合は定格オーバーで危険ですが、今回は一瞬電圧を印加するだけなので2SC1815で目をつむりました。余裕のある方は、もう少し体圧の高いトランジスタかMOSFETをお勧めします。実際の動作に必要な平均消費電力は、全体で7mW程度になるそうです。抵抗も1/4Wのもので済ませました。

MOSFETの使い方はラズパイでMOSFETを使おうあたりをご覧ください。

プログラム

それでは最後にM5StickC PLUSに書き込むスケッチを紹介します。

匂いに応じて100点満点評価の表示ができるように工夫してみました。センサに反応する匂いを検知すれば点数が下がります。また、点数に応じて画面の色が緑色から赤色に変化させています。

#include <M5StickCPlus.h>

#define PIN_HEATER 0
#define PIN_SENSOR 26
#define PIN_OUTPUT 36

uint16_t getColor(uint8_t red, uint8_t green, uint8_t blue){
  return ((red>>3)<<11) | ((green>>2)<<5) | (blue>>3);
}

const int SMELL_BAD = 1000;
const int SMELL_NORMAL = 2600;
const int SMELL_DIFF = SMELL_NORMAL - SMELL_BAD; // // 2500 - 2000

void setup() {
    M5.begin();
    M5.Axp.ScreenBreath(9);
    M5.Lcd.setRotation(3);
    M5.Lcd.fillScreen(BLACK);
    M5.Lcd.setTextColor(WHITE);


    pinMode(PIN_HEATER,OUTPUT);
    pinMode(PIN_SENSOR,OUTPUT);
    digitalWrite(PIN_HEATER,LOW); // Heater Off
    digitalWrite(PIN_SENSOR,LOW); // Sensor Pullup Off
    
    pinMode(PIN_OUTPUT, INPUT);
    gpio_pulldown_dis(GPIO_NUM_25); // Disable pull-down on GPIO.
    gpio_pullup_dis(GPIO_NUM_25); // Disable pull-up on GPIO.

//    analogSetAttenuation(ADC_6db);

    Serial.begin(115200);

}

void loop() {

    int val = 0;
    int val_origin = 0;
    float rate = 0.0;
    
    delay(237);
    digitalWrite(PIN_SENSOR,HIGH); // Sensor Pullup On
    delay(3);
    val = analogRead(PIN_OUTPUT); // Get Sensor Voltage
    delay(2);
    digitalWrite(PIN_SENSOR,LOW); // Sensor Pullup Off
    
    digitalWrite(PIN_HEATER,HIGH); // Heater On
    delay(8);
    digitalWrite(PIN_HEATER,LOW); // Heater Off

//    Serial.println(val);
    val_origin = val;

    if (SMELL_BAD > val) {
        val = SMELL_BAD;
    } else if (SMELL_NORMAL < val) {
        val = SMELL_NORMAL;
    }
    val -= SMELL_BAD;
    rate = float(val) / float(SMELL_DIFF);
    Serial.println(rate);
    int red = int((1.0 - rate) * 255.0);
    int green = int(rate * 255.0);
//    Serial.println(red);
    M5.Lcd.fillScreen(getColor(red,green,0));
    M5.Lcd.setTextSize(2);
    M5.Lcd.setCursor(10, 10);
    M5.Lcd.printf("%d", val_origin);
    M5.Lcd.setTextSize(6);
    M5.Lcd.setCursor(80, 40);
    M5.Lcd.printf("%d", (int)(rate * 100.0));
    
}

▼G36をアナログ入力として使ったので、必ずG25をフローティングしてください。

gpio_pulldown_dis(GPIO_NUM_25); // Disable pull-down on GPIO.
gpio_pullup_dis(GPIO_NUM_25); // Disable pull-up on GPIO.

フローティングをしなければならない理由は、M5StickC PLUSの内蔵ADコンバータで電圧測定で解説しました。

さて、プログラムをデバックするにあたって、センサの値をシリアルプロッターでモニター表示するとやりやすいです。マジックペンなどを近づけますと、このように値がグンと下がります。

匂いセンサの値をシリアルプロッターでグラフ化
匂いセンサの値をシリアルプロッターでグラフ化

TGS2450では慣らし運転が必要なようです。とくに初めて使用する際は、数値が安定するまで数十分以上かかるのでご注意ください。

▼ 匂いセンサを操作するプログラムは、[秋月電子通商電子の使用例](tgs2450_sample.pdf) を参考にしました。センサーの出力電圧を読み取りつつ、ヒーターをオンオフしています。秋月電子の回路ではPNPトランジスタを使っていましたが、ここではNPNのトランジスタを使ったので、ヒータのHIGH、LOWは秋月電子のプログラムとは逆になってます。ご注意ください。

delay(237);
digitalWrite(PIN_SENSOR,HIGH); // Sensor Pullup On
delay(3);
val = analogRead(PIN_OUTPUT); // Get Sensor Voltage
delay(2);
digitalWrite(PIN_SENSOR,LOW); // Sensor Pullup Off

digitalWrite(PIN_HEATER,HIGH); // Heater On
delay(8);
digitalWrite(PIN_HEATER,LOW); // Heater Off

また、読み取ったアナログ値では分かりずらいので、0〜100点評価に換算(正規化)しています。評価点数を調整したい場合は、SMELL_BADSMELL_NORMALの値を変更してみてください。

M5StickC PLUSでTGS2450を使って匂いの検知
M5StickC PLUSでTGS2450を使って匂いの検知

写真のように、マジックペンを近づけると値がグンと下がります。TGS2450は、アルコールに対してかなり敏感に反応するようです。玉ねぎスライスに近づけると、なんと点数は0点。即死亡状態といった感じになります(笑)

その他、いろいろ匂いを測定して遊んでみましたが、意外と部屋の中が臭うということに気づきました>< 人間の嗅覚はなれてしまうので、一人暮らしだと怖いですねぇ。。。

トイレなどでも数値は変動しますので、掃除の目安にもなりますね!ただし「必ずしも人間にとって臭いもの」に反応するとは限らないので、過度に数字を気にしすぎても仕方なさそうです。

匂いセンサはなかなか楽しいので、みなさんもぜひ作ってみてくださいね(^_^)

記事に関するご質問などがあればTwitterへお返事ください。
この記事で紹介した商品
M5Stackのオススメ参考書
M5Stack製品
M5StickCで使えるHat
関連記事