本篇文章詳細講解了如何利用SDS011激光式PM2.5傳感器、HC-06藍牙模塊和Windows 10設備完成一個簡單的PM2.5檢測器及其應用程序的開發。該檢測器使用藍牙完成數據輸出,方便設備連接,使用UWP模板創建的應用可以運行在Window 10 for PC、Window 10 for Mobile和樹莓派(Window 10 IoT Core)平台,通過該應用查看PM2.5和PM10的動態數據。
1. 使用的硬件
首先,我們需要選擇一款PM2.5的傳感器,通過淘寶搜索發現,PM2.5傳感器主要有兩種,一種是利用紅外原理,另一種是利用激光散射原理。使用紅外原理的傳感器價格相對便宜,如夏普GP2Y1010AU0F,其價格在20元以內,但是校准相對較難。激光散射原理的傳感器在測量准確性和數據的一致性上較好,也無需用戶進行數據校准的工作,使用簡單方便。因此,這里選用了激光式的PM2.5傳感器:SDS011。其外觀如下。
SDS011的輸出有串口數據和PWM波兩種形式,一般來說,使用串口比較方便,以下是其通信的數據協議。
其次,淘寶上拿到的SDS011是通過TTL-USB的方式輸出信號的,在PC上只要有USB接口就可以虛擬一個串口出來,接收其輸出的信號。但是,這對於很多應用場景都不大適合,原因就在於受限其USB的接口,需要設備具備該USB接口。目前,很多手機、PC和平板都具有藍牙模塊,因此,我考慮使用一個成本較低的藍牙模塊來替換原來的TTL-USB模塊,將SDS011的TTL-UART輸出直接接藍牙模塊,由藍牙來發送數據。這樣一來,很多沒有USB接口的設備都可以連接檢測器了。而且,藍牙是短距離無線連接,可以在室內視距情況下完成數據的發送和接收,不受限於有線連接的形式。經過調研,發現HC-06模塊可以滿足要求,淘寶上價格一般在20元以下,可以拿來直接當串口藍牙模塊使用。其模塊圖如下。
2. 硬件連接
這里的硬件連接主要是SDS011和藍牙模塊的連接,以及整體的供電電源。通過查看模塊說明得知,這兩個模塊的電源電壓可以在一定范圍內。手頭正好有一個Arduino Uno R3,提供5V的輸出。因此,這里就直接使用Arduino模塊的電源作為整體的電源。另外一個需要注意的地方就是,HC-06模塊的UART和SDS011的UART數據收發需要交叉,即其中一個的Tx需要連接另一個模塊的Rx,Rx需要連接另一個模塊的Tx。已經連接好的實物圖如下,這里使用了一個小面包板和跳線。
目前,很多PC、平板和手機都包含了藍牙模塊,因此就可以直接與我們設計的模塊通信,獲取數據了。如果用戶需要在沒有藍牙模塊的PC上獲取數據,需要在PC上插一個藍牙USB Dongle,淘寶上也有的是,價格也不貴。另外,如果用戶在Windows 10 IoT Core上運行應用程序,如樹莓派2、MBM板子(高通410c除外,自帶了藍牙4.0模塊),同樣需要另加一個藍牙USB Dongle。
3. UWP應用程序開發
Windows 10 提供了通用應用模板,支持包含PC、Mobile和IoT平台的通用應用開發,真正做到了一次開發,全平台運行。因此,這里使用通用應用模板來開發程序,可以部署到多個Windows 10內核的平台。事實上,微軟在Github平台上給出了通用應用的很多示例,拿來就能用。比如這里,我們可以直接下載IoT Core的串口示例,其鏈接為:https://github.com/ms-iot/samples/tree/develop/SerialSample。在該示例程序中,已經包含了串口設備的獲取、參數的設置、數據的接收、數據的發送等基本功能。本應用中不同之處在於以下幾點:首先,接收的數據編碼不同,示例程序中默認是字符串,而SDS011模塊發送的是16進制的數據;其次,SDS011的串口參數為9600波特率,每個一秒發送一次數據,我們的應用程序只負責打開串口,接收並處理數據就可以。因此,其具體處理如下:
在數據接收任務ReadAsync中,關鍵代碼如下:
private async Task ReadAsync(CancellationToken cancellationToken)
{
Task<UInt32> loadAsyncTask;
。。。。 //此處省略已有代碼
UInt32 bytesRead = await loadAsyncTask;
if (bytesRead > 0)
{
byte[] fileContent = new byte[dataReaderObject.UnconsumedBufferLength];
try
{
//讀取數據
dataReaderObject.ReadBytes(fileContent);
//數據轉換為16進制
for(int i=0;i< fileContent.Length;i++)
{
string recvdtxt1 = fileContent[i].ToString("X2");
recvdtxt += recvdtxt1;
}
System.Diagnostics.Debug.WriteLine(recvdtxt);
this.textBoxRecvdText.Text = recvdtxt;
}
catch (Exception ex)
{
System.Diagnostics.Debug.WriteLine("ReadAsync: " + ex.Message);
}
}
}
在數據處理的定時Tick中,獲取字符串數據,並進行數據解析和轉換,同時顯示到界面上,其關鍵代碼如下:
private async void dataProcessTick(ThreadPoolTimer timer)
{
//分別獲取PM2.5和PM10數據字符串
string str1 = recvdtxt.Substring(4,2);
string str2 = recvdtxt.Substring(6,2);
string str3 = recvdtxt.Substring(8, 2);
string str4 = recvdtxt.Substring(10, 2);
//完成數據計算
double pm25 = (Convert.ToInt32(str1,16) + (Convert.ToInt32(str2,16)) * 256) / 10.0;
double pm10 = (Convert.ToInt32(str3,16) + (Convert.ToInt32(str4,16)) * 256) / 10.0;
//完成數據顯示
await textBoxPM25Text.Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () =>
{
textBoxPM25Text.Text = Convert.ToString(pm25);
}
);
await textBoxPM10Text.Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () =>
{
textBoxPM10Text.Text = Convert.ToString(pm10);
}
);
。。。。。
}
4. 程序調試和部署
在PC上調試時,先打開藍牙模塊,與HC-06進行綁定,默認密碼為1234,對象選擇x86,local machine,就可以部署到PC上進行調試了。我這里使用了SP3(自帶藍牙),其界面如下,
其中,1處為原始接收的16進制數據,2處為計算得到的PM2.5數據,3處為PM10的數據。
在Mobile上調試時,選擇ARM-Device,其運行效果如前面2.硬件連接一節所示。
在樹莓派上調試時,先插上藍牙USB Dongle,如下圖所示,
然后,參考《Pairing a BLE Device and GATT Attribute Table Dump Tool》,利用SSH或者Powershell與樹莓派建立連接,使用指令將樹莓派與HC-06建立綁定,綁定以后,可以通過設備頁面查看,其效果如下,
之后,選擇ARM,Remote Machine,輸入樹莓派的IP地址,點擊調試,就可以看到應用程序在樹莓派上運行了。其輸出界面如下圖所示。
參考鏈接:
1. https://github.com/ms-iot/samples/tree/develop/SerialSample