首页 | 新闻 | 新品 | 文库 | 方案 | 视频 | 下载 | 商城 | 开发板 | 数据中心 | 座谈新版 | 培训 | 工具 | 博客 | 论坛 | 百科 | GEC | 活动 | 主题月 | 电子展
返回列表 回复 发帖

构建实用的 IoT 应用程序 - 一个空气质量监视器(1)

构建实用的 IoT 应用程序 - 一个空气质量监视器(1)

在我以前的文章中,我们讨论了 IBM Watson IoT Platform,具体来讲,讨论了该平台用于收集和分析来自 IoT 设备的数据的  服务。我们还介绍了开源的 ,使用该平台可以轻松地设计原型和生成 IoT                设备应用程序。本文将所有这些组件整合到一个监视空气质量的实用 IoT 应用程序中。
空气污染已成为当今世界人类健康的最大威胁之一。据估计,雾霾每年导致 550                万人死亡,成为了一个主要死亡原因。在像中国北京这样的地方,据估计生活在那里相当于每天抽两包香烟。此外,不仅仅是像中国和印度这样的国家存在这个问题。事实上,伦敦在                2017 年的头 5 天内均已达到了其全年的空气污染限额,巴黎现在每天都笼罩在雾霾中。
应对雾霾的最有趣方式之一是自行监视空气质量。在本文中,我将展示只需不到 35 美元,就能构建一个基于 NodeMCU                    的空气质量监视设备(参见图 1)。因为该设备拥有自己的电源(USB                电池),所以它可以放在任何有 WiFi                信号的地方。我通常将它放在房间里监视户内空气,或者放在打开的窗户旁边监视户外空气。这不仅是一个科学项目,也是医疗领域(包括公共卫生研究)的一个潜在的变革潮流,因为我们现在能跟踪个人对雾霾的准确接触量,并研究该接触量与健康问题有何关联。
图 1. 组装的带电源的原型设备。第 1 步:为 IoT 设备选择并设置硬件这个物理过程称为。它作用于大于红外线波长的 1/10 的粉尘。所以,该设备只能测量超过某个大小的粉尘。大多数商用传感器都能测量大小超过                    1um(1 微米)的粉尘,它们应能提供 PM2.5 密度读数(PM 是指颗粒物,PM2.5 表示小于 2.5um                    的颗粒物)。这类低廉传感器的准确性存在诸多争议。但是,它们通常被认为非常准确,尤其是在户内。(甚至还有一篇关于这个主题的哲学博士论文!)

对于空气质量传感器,有各种各样的传感器可供选择。网站                 对这些传感器进行了一些很好的评测分析。较低廉的传感器采用了相同的工作原理:它们有一个红外光源(LED                或激光器)和一个放在气室对面的光探测器。该探测器测量气室中的粉尘或雾霾颗粒散射的光。

在本项目中,我选择了使用  空气传感器。据证实,它能准确测量低污染环境(即户内)的 PM2.5                水平。

传感器模块有 3 条线:两条电源线,一条数据线。电源线(GND 和 VCC)连接到 NodeMCU 开发板上的 GND(黑色)和                Vin(红色),因为它们要从 NodeMCU 获取 5V 电源。数据线(黄色)连接到 NodeMCU 上的一个数字引脚。我选择连接到                D5。将传感器线连接到 NodeMCU 开发板的最简单方法是使用电路试验板。连线如上面的 图 1所示(带颜色的线是从照片顶部的空气质量传感器连出的线)。
NodeMCU 开发板可使用常规 USB 连接进行供电。所以,我将一个可充电的 USB 电池连接到原型来用作电源。
第 2 步:读取传感器数据来自传感器的数据输出是一个具有随机波峰和波谷的波形。每个波峰表示传感器检测到大于 1um 的颗粒物 (PM)。
要从传感器读取 PM 水平,NodeMCU 应用程序需要计算某个给定时间单位内的低脉冲占用时间(LPO                时间)。它需要确定数据线处于低电压状态多长时间(百分比)。然后可使用产品规格中提供的响应曲线,将 LPO 值转换为每升空气中的颗粒物数(或每 m³                的颗粒物数)。
对于我们的样本空气污染应用程序,需要修改 NodeMCU 上的 init.lua 应用程序。在 init.lua 应用程序中,NodeMCU 首先连接                WiFi 网络。然后每 10 分钟循环执行一次测量。测量本身会花费 30 秒。在这 30 秒中,每当 D5                上的数据线在高和低电压状态之间跳跃,就会将一个 INT(中断)信号发送给 NodeMCU。NodeMCU 测量 D5                处在高和低电压状态下的时间量,以计算 LPO。
下面列出了 init.lua 的代码。每隔 10 分钟,主计时器就会循环激活 D5 引脚进入“中断模式” (gpio.trig(dpin,                "both", dpin_cb))。激活后,只要该引脚改变状态,就会调用 dpin_cb 函数。dpin_cb                函数维护了一个计时器,以便计算该引脚处在高和低电压状态下占用的时间,并在 30 秒后停用“中断模式”,以便可以计算 LPO                (gpio.trig(dpin, "none"))。
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
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
-- 1.Setup the device ID and access credential.See later.

-- PIN assignment
-- D5 is the driver PIN for the dust detector
dpin = 5
-- D0 is the LED on the NodeMCU board
lpin = 0
gpio.mode(dpin, gpio.INT)
-- The current pulse params
rising_ts = 0
falling_ts = 0
-- aggregated timing vars
high_time = 0
low_time = 0
-- determine if the INT is legit
prev_level = -1

-- setup Wifi
wifi.setmode(wifi.STATION)
wifi.sta.config("SSID","password")
wifi.eventmon.register(wifi.eventmon.STA_GOT_IP, connected)

-- This is the main application loop
-- It starts after the network is up
function connected (e)
    -- 2.Connect to the MQTT service.See later.
-- Timer to take a measurement and send data
-- every 10 minutes.
    tmr.alarm(1, 600000, tmr.ALARM_AUTO, function()
        -- Trigger the “dpin_cb” function (defined below)
        -- when a pulse comes in.
        -- dpin_cb will turn off the trigger after 30s
        gpio.trig(dpin, "both", dpin_cb)
    end)
end

-- Define the INT callback function
function dpin_cb (level, when)
    -- current_level = gpio.read(dpin)
    if prev_level == level then
        -- there is no change. ignore
        return
    else
        prev_level = level
    end
if level == 1 then
        rising_ts = tmr.now()
        print ("raising edge : " .. rising_ts)
        -- turn on the red LED
        gpio.write(lpin, gpio.LOW)
    else
        falling_ts = tmr.now()
        print ("falling edge : " .. falling_ts)
        -- turn off the red LED
        gpio.write(lpin, gpio.HIGH)
    end
    -- Start aggregated timer after a complete pulse is detected
    if falling_ts > 0 and rising_ts > 0 then
        if falling_ts > rising_ts then
            high_time = high_time + falling_ts - rising_ts
        else
            low_time = low_time + rising_ts - falling_ts
        end
    end
    -- Sampling period is 30*1,000,000 macroseconds
    total_time = high_time + low_time
    if total_time > 30000000 then
        lpo = low_time / total_time
        -- remove the INT and reset timers
        gpio.trig(dpin, "none")
        rising_ts = 0
        falling_ts = 0
        high_time = 0
        low_time = 0
        -- turn off the red LED
        gpio.write(lpin, gpio.HIGH)
        -- Very rough estimate.More calibration needed
        pm25 = lpo * 100.0 * 1.5
        -- 3.Send data to the MQTT server.See later.
    end
end




请注意,代码段中有 3 条“see later”注释(这些行已突出显示)。这些注释是将数据发送到 MQTT                服务的附加代码的占位符,我接下来将讨论这些代码。
返回列表