猛禽洛的程式筆記庫

[MicroPython] 在Raspberry PI PICO上使用MQ4 天然氣、甲烷感測器

感測器規格:

電氣性能

  • Detecting Concentration: 300 to 10000 ppm
  • Input Voltage: 5 VDC
  • Power: 150 mA
  • Digital Output Voltage: TTL digital 0 and 1 (0.1 V and 5 V)
  • Analog Output Voltage (relatively clean): 0.1 V to 0.3 V

輸入電壓:DC5V 功耗(電流):150mA
DO輸出:TTL數字量0和1(0.1和5V)
AO輸出:0.1-0.3V(相對無污染),最高濃度電壓4V左右
特別提醒:感測器通電後,需要預熱20S左右,測量的資料才穩定,感測器發熱屬於正常現象,因為內部有電熱絲,如果燙手就不正常了。

此感測器使用方式很簡單,電源使用5v,然後讀取AO腳位的ADC值即可,或是讀取DO腳位的狀態判過是否超標(使用上面的可變電阻調整閥值),但如果有讀取ADC值,那就沒必要使用DO了。

接線方式:

Raspberry PI PICOMQ4
ADC (2)AO
GNDGND
5VVCC

以下是讀取MQ4並轉為ppm數值的方法。

首先需要計算R0穩定值,由一定筆數的ADC值平均後計算得出,之後再根據文件的斜率資料計算出ppm。

import math
from machine import Timer, ADC

# 參考來源https://honeststore.com.tw/iot-wifi-example-mq4-gas-detection-notification-line/

# MQ4感測器
mq_adc = ADC(2)  # 設定ADC腳位
conversion_factor = 3.3 / 65535  # 電壓比
r0_count = 0
r0_max_count = 100  # r0最大平均筆數
r0_value = 0
r0_timer = Timer()
mq_timer = Timer()
# 是否進入測量氣體
tag_clac_r0 = False
tag_measure_mq = False


# 計算r0值
def clac_r0():
    global r0_value, r0_count
    r0_value = r0_value + mq_adc.read_u16()
    r0_count = r0_count+1
    if r0_count >= r0_max_count:
        v = (r0_value/r0_max_count) * conversion_factor
        rs_air = ((5.0*10.0) / v) - 10.0
        r0_value = rs_air / 4.4
        print("R0計算完成= " + str(r0_value))
        r0_timer.deinit()
        # 開始量測
        mq_timer.init(mode=Timer.PERIODIC, period=1000, callback=start_measure_mq)


# MQ4氣體感測器計算
def measure_mq_sensor():
    b = 1.17  # 感測器圖表y軸截距
    m = -0.329  # 感測器圖表斜率
    adc_value = mq_adc.read_u16()
    v_current = adc_value * conversion_factor
    rs_gas = ((5.0*10.0) / v_current) - 10.0  # RS電阻
    ratio = rs_gas / r0_value
    ppm_log = (math.log10(ratio) - b) / m
    ppm = math.pow(10, ppm_log)

    # ppm大於2000可警告
    print("MQ4 瓦斯濃度= " + str(ppm) + " ppm")


def start_clac_r0(t):
    global tag_clac_r0
    tag_clac_r0 = True


def start_measure_mq(t):
    global tag_measure_mq
    tag_measure_mq = True


def main():
    global tag_measure_mq, tag_clac_r0

    print("感測器準備中,需要10秒")
    # 計算R0初始值,共100筆10秒
    r0_timer.init(mode=Timer.PERIODIC, period=100, callback=start_clac_r0)

    # 不斷檢查Tag是否被觸發,觸發後才去執行耗時處理,避免程式卡死
    while True:
        if tag_clac_r0:
            clac_r0()
            tag_clac_r0 = False
        if tag_measure_mq:
            measure_mq_sensor()
            tag_measure_mq = False


# 開始執行
main()

輸出結果:

MQ4 瓦斯濃度= 23.35297 ppm
MQ4 瓦斯濃度= 23.82965 ppm
MQ4 瓦斯濃度= 23.35297 ppm
MQ4 瓦斯濃度= 23.63808 ppm

-END-

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *