以前CO2(二酸化炭素)濃度をやってみました。今回はCO(一酸化炭素)です。
安価で反応のいいセンサーとしてMQ-7 がよく使われているようです。

Output の違い
具体的な数値が知りたい場合 : AO(Analog-Out)
設定閾値を超えたら1を出力する、という使い方をしたい場合 : DO (Digital-Out)
マイコンボードは2種類でやってみます。
Arduino
Pico
Arduino Uno で一酸化炭素(CO)濃度を測ってみる
濃度を測定する場合、AO (Analog Out) 端子を使います。
この場合、Analog – Digital コンバーターが必要ですが、Arudino Uno ならライブラリーで対応できます。
取得したアナログデータをppm単位に変換します。
まずは、Arduino に接続(実際に使ったのはUno の互換機でしたが無問題でした)。

ライブラリは以下からダウンロードしておきます。

ダウンロードしたファイルは解凍後、改名
MQ7-Library-master -> MQ7
以下のフォルダーへコピー。
Windowsの場合
C:\Program Files (x86)\Arduino\libraries\MQ7
ラズパイの場合(ユーザー名がpiの場合)
/home/pi/Arduino/libraries/MQ7
新規にスケッチを作成してライブラリをインクルードします。

こんな感じです。

センサーから得たアナログ値をppmに変換するコード
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
|
#include "MQ7.h" const int AOUTpin=0;//the AOUT pin of the CO sensor goes into analog pin A0 of the arduino const int DOUTpin=8;//the DOUT pin of the CO sensor goes into digital pin D8 of the arduino //初期化 MQ7 mq7(A0, 5.0); void setup() { Serial.begin(115200); // シリアル通信の準備をする while (!Serial); // 準備が終わるのを待つ pinMode(DOUTpin, INPUT);//sets the pin as an input to the arduino } void loop() { Serial.print(mq7.getPPM()); Serial.println(""); delay(1000); // 1秒毎に更新 } |
転送速度を115200に合わせてシリアルモニタやシリアルプロッタで表示確認してみます。
この2つは共存できませんので、どちらか一方で表示します。

シリアルプロッタを開いてみます。


シリアルモニタで見てみます。

Pico
結線
DO (Digital-Out) はとりあえずGP22に繋いでいますが、これを使用する場合はアナログ以外のピンならどこでもいいそうです。

Thonny IDE を使用してPython でコードを記述
コード
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
|
from machine import ADC, Pin, I2C from ssd1306 import SSD1306_I2C from time import sleep adc = ADC(Pin(26)) def get_gas_level(voltage): if voltage < 1.0: return "Safe(Low)" elif 1.0 <= voltage < 2.5: return "Moderate" else: return "High(Warning!)" while True: gas_value = adc.read_u16() voltage = gas_value * 3.3 / 65535 gas_level = get_gas_level(voltage) print(f"Gas Sensor Value: {gas_value}, Voltage: {voltage:.2f}V, Level: {gas_level}") sleep(1) |
こんな感じで出力されます。

出力結果を有機ディスプレイ(OLED)に表示してみます。

コード
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37
|
from machine import ADC, Pin, I2C from ssd1306 import SSD1306_I2C from time import sleep i2c = I2C(0, scl=Pin(1), sda=Pin(0)) # init OLED Display oled = SSD1306_I2C(128, 64, i2c) # gas sensor adc = ADC(Pin(26)) def get_gas_level(voltage): if voltage < 1.0: return "Safe(Low)" elif 1.0 <= voltage < 2.5: return "Moderate" else: return "High(Warning!)" while True: gas_value = adc.read_u16() voltage = gas_value * 3.3 / 65535 gas_level = get_gas_level(voltage) print(f"Gas Sensor Value: {gas_value}, Voltage: {voltage:.2f}V, Level: {gas_level}") # OLED Display oled.fill(0) oled.text("Gas Sensor Data", 0, 0) oled.text(f"Value: {gas_value}", 0, 15) oled.text(f"Voltage: {voltage:.2f}V", 0, 30) oled.text(f"Level: {gas_level}", 0, 45) oled.show() sleep(1) |
Appendix
ラズパイZero で一酸化炭素を検知してみる
MQ-7 のDO(Digital Out) 端子を使います。
DO から得られるものは「検出できた/できない」の2値で、結果はLEDの点滅(Lチカ)で示します。
こういう結線になります。
電源電圧は3.3Vでも5Vでもどちらでもいいようです。

【co.py】
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
|
import time, sys import RPi.GPIO as GPIO GPIO.setmode(GPIO.BOARD) GPIO.setup(7, GPIO.IN, pull_up_down=GPIO.PUD_DOWN) def action(pin): print ('** Carbon monoxide detected!! **') return GPIO.add_event_detect(7, GPIO.RISING) GPIO.add_event_callback(7, action) try: while True: print ('Sensor Active') time.sleep(1.0) except KeyboardInterrupt: GPIO.cleanup() sys.exit() |
Appendix2
今回はMQ-7 を使いましたがMQ は以下のようなシリーズになっているそうです。
- MQ-2: 可燃性ガス、煙
- MQ-3: アルコール、エタノール
- MQ-4: メタン
- MQ-5: 液化石油ガス、天然ガス
- MQ-6: 液化石油ガス
- MQ-7: 一酸化炭素
- MQ-8: 水素
- MQ-9: 一酸化炭素、可燃性ガス
- MQ-135: 空気の質(アンモニア、硫化物、ベンゼンなどの有害ガス)
Leave a Reply