Datalogger IoT 實戰教學:PMS5003 空氣品質 (PM2.5) 感測器完整指南

Datalogger IoT 實戰教學:
PMS5003 空氣品質 (PM2.5) 感測器完整指南

從硬體防呆接線、機構風道設計到 Arduino 程式解析

在智慧城市與環境監測的應用中,空氣品質 (尤其是 PM2.5 細懸浮微粒) 是非常關鍵的指標。本篇教學將帶您使用 Datalogger IoT 開發板,一步步完成 PMS5003 感測器的整合與數據讀取!

🛠️ 第一部分:硬體連接與通訊原理

1. 極簡的隨插即用設計

傳統開發板在使用 PMS5003 時,常需要額外的轉接板與複雜的飛線,還要處理電壓轉換的問題(感測器風機需 5V,但通訊邏輯為 3.3V TTL)。

Datalogger IoT 主板完美解決了這個痛點:主板上已內建專用的 PMS5003 連接器,無須轉接,直接插入排線即可。在 Datalogger (RTL8720DF 核心) 的定義中,與之對接的 UART 腳位為:RX = 2,TX = 3

Datalogger IoT 接頭 UART (RX:17, TX:16) PMS5003 接頭 專用排線直連 5V電源 + 3.3V資料通訊

▲ 圖 1:Datalogger 與 PMS5003 硬體連接示意圖,實現供電與通訊無縫對接。

2. 機構安裝:「空氣盒子」的 3 大設計關鍵

若您打算將設備裝入自製的塑膠外殼或 3D 列印盒中,請務必遵守以下機構設計原則:

  • 避免短路: PMS5003 的金屬外殼與內部 GND 是導通的,請確保它不會碰到其他裸露電路。
  • 安裝高度: 建議離地 20 公分以上,避免吸入近地面的大顆粒塵埃或毛絮導致風扇卡死。
  • 風道實體隔離: 這是最重要的一點!進風口與出風口之間必須有結構隔開,防止排出的氣流在盒子內部「迴流」到進風口,造成數據嚴重失真。
自製外殼 (空氣盒子) PMS5003 感測器 實體隔離牆 外界空氣 (IN) 排出氣流 (OUT)

▲ 圖 2:正確的風道設計。利用隔離牆防止排出氣流在殼內迴流至進風口。


💻 第二部分:通訊協定與程式碼解析

封包結構與通訊參數

PMS5003 預設為「主動輸出模式」,只要通電就會以 9600 bps 的速率不斷傳送資料。每次完整的資料封包長度固定為 32 Bytes,且固定以 0x420x4D 作為起始特徵字元 (Header)。

Arduino 範例程式碼

請將 Datalogger 接上 UPC-01 上傳工具,並在 Arduino IDE 中燒錄以下程式:

#include <SoftwareSerial.h>

// 定義軟體序列埠,Datalogger (RTL8720DF) 對應腳位:RX = 2, TX = 3
SoftwareSerial mySerial(2, 3); 

#define pmsDataLen 32        // 封包總長度為 32 Bytes
uint8_t buf[pmsDataLen];     // 陣列用來存放封包
int pm10 = 0;   // PM1.0 數值
int pm25 = 0;   // PM2.5 數值
int pm100 = 0;  // PM10 數值

void setup() {
  Serial.begin(115200);      // 電腦監控窗輸出
  mySerial.begin(9600);      // PMS5003 通訊波特率 9600
  Serial.println("PMS5003 初始化完成,等待數據...");
}

void loop() {
  uint8_t c = 0;
  int idx = 0;
  memset(buf, 0, pmsDataLen); // 清空陣列

  // 步驟一:捕捉起始特徵字元 (0x42 與 0x4D)
  while (true) {
    while (c != 0x42) {
      while (!mySerial.available()); // 阻塞等待資料
      c = mySerial.read();           // 尋找 0x42
    }
    while (!mySerial.available());
    c = mySerial.read();
    if (c == 0x4d) {                 // 確認下一個是否為 0x4D
      buf[idx++] = 0x42;
      buf[idx++] = 0x4d;
      break;                         // 捕捉成功,準備接收後續資料
    }
  }

  // 步驟二:讀取剩餘的 30 Bytes
  while (idx != pmsDataLen) {
    while(!mySerial.available());
    buf[idx++] = mySerial.read();
  }

  // 步驟三:還原高低八位元數據 (讀取大氣環境下的標準濃度)
  pm10  = (buf << 8) | buf;  
  pm25  = (buf << 8) | buf;  
  pm100 = (buf << 8) | buf; 

  // 步驟四:列印至序列埠
  Serial.print("空品數據 -> PM1.0: "); Serial.print(pm10); 
  Serial.print(" | PM2.5: "); Serial.print(pm25); 
  Serial.print(" | PM10: "); Serial.println(pm100);
}

💡 程式設計 3 大關鍵解析

  1. 阻塞等待機制 while (!mySerial.available());
    微控制器的運算速度遠快於 9600 bps 的傳輸速度。這行程式碼確保「緩衝區確實有資料進來後,才執行讀取」,避免讀出空值或亂碼。
  2. 數據位元還原 (High << 8) | Low
    感測器傳送的濃度數值是 16 位元,它會拆成「高八位」與「低八位」發送。程式需將高位元向左位移 8 位,再與低位元進行「或(|)」運算來還原真實數值。
  3. 大氣環境 vs. 工業標準數值
    PMS5003 封包內提供兩組標準數據。程式中索引 10~15 擷取的是「大氣環境下」的濃度,適合室內外空氣盒子;若用於工廠高粉塵環境,則應改讀取索引 4~9 的「標準顆粒物」濃度。
🎉 恭喜您! 完成上述步驟後,開啟 Arduino IDE 的「序列埠監控窗 (Serial Monitor)」,您就能即時看見當下的 PM2.5 數據。接下來,您可以嘗試結合 Datalogger 的 Wi-Fi 模組與 MQTT 協議,將數據推送到手機 APP,打造專屬的遠端空氣盒子!