===== AT2051(數位溫度計) & UR485(RS-485 to USB) @ FreeBSD with PHP ===== 今天下午拿到的新玩具~ * AT2051 , 數位溫度計 over RS485 * UR485, RS-485 轉換成 USB 介面同時模擬成 RS-232 ===== 前言 ===== 希望可以拿來偵測機房的溫度, 進而做些告警之類的事情,雖然有 VB 的程式, 但是 VB 不利於後續的使用, 因為需要能夠把記錄到的溫度丟到資料庫存起來 或是用 mrtg 進行長期之溫度監控, 所以就開始研究怎麼用 PHP 去取得 Serial port 的資料. 重點還要能好好利用 RS-485 的特性, RS-485 其實很常用於監控或是控制, 在大型的監控裡, 經常可以見到 RS-485 的蹤跡, 因為它可以遠距離的傳輸及控制. 且又可以多個偵測器使用同一條線路, 類似電話線這樣, 搭上線即可. 但是每個偵測器或是控制器又可以設定 ID 來區隔, 一路 RS-485 上可以擁有多個 ID 每個偵測器不可以重複 ID, 不然會出錯. 詳細資料可翻一下 Wikipedia 有關 [[http://zh.wikipedia.org/zh-tw/EIA-485|RS-485]] 的資料 第一次接觸到 RS-485 是在某大型展覽館, 其空調及風扇等開關幾乎都用 RS-485 來控制, 且於每層樓使用 RS-485 轉 Ethernet 來減少所有樓層到中控室的線路數量.又兼具遠距監控控制的需求, 很佩服一開始想出來的人啊~. ===== 實作 ===== 實作的部份可分三個部份: - AT2051 及 UR485 的接線 - UR485 on FreeBSD - PHP get UR485 data ===== 實作開始 ===== - AT2051 及 UR485 的接線 * 這部份我不想著墨太多, 因為網路上有很多說明跟你說怎麼做, 且原廠網站上的說明更是詳細又清楚, 所以我直接略過這部份. 而我在這部份僅用了該公司的 VB on Windows XP 來檢查我線有沒有接錯而已.\\ * [[http://www.chipware.com.tw/|旗威科技]] - UR485 on FreeBSD * 我使用的 FreeBSD 是 7.2 Stable 版, UR485 一接上去之後就會偵測到 ucom0 (kernel 裡頭的 ucom 等 USB 的 device 要留著)網路上一些比較舊的文章都會寫它的 device 路徑為 /dev/ucom0, but 我在 7.2 一直都失敗, 最後用土法煉鋼的方式, 直接 ls /dev/ 看拔掉跟接上去的差別, 進而找到該裝置的位置是 /dev/cuaU0 一個很怪的名稱, 我也不知道為什麼~ - PHP get AT2051 data over UR485 * 接下來就是最重點的部份了, 這部份我研究了大約一個多鐘頭, 從PHP Manual 去翻有關 RS-232 的資訊, 結果我找到了 DIO(Direct I/O) 這個函式, 在 FreeBSD 的 ports 位置為 /usr/ports/devel/php4-dio/ 安裝它之後才可以使用 dio 的相關函式. 下面為 UR485 使用 dio 取得資料的一個簡單程式內容PHP程式碼 9600, 'bits' => 8, 'stop' => 1, 'parity' => 0) ); // 按照 AT2051 說明書所說的, 要抓 ID 1 的偵測器 // 就輸入給 01H, ID 2 給 02H 以此類推 dio_write($fd,"\x01H",1); // write 0x01H to /dev/cuaU0 for($i=1 ; $i<=7 ; $i++) { // AT2051 最多只會輸出 7 個字 $data = dio_read($fd, 2); // 從 AT2051 取得資料, 由於它最多一次 // 只會有 2 個字元, 所有只需要 2 即可 if($data == "T" || $go){ // 一開始的字元偶爾會出現多餘的換行字元, // 所以從抓到 T 才開始 $go=1; // 給個抓到 T 之後都要跑的 tag $temp .= $data; // 把抓到的字通通串起來 // for debug 用, 顯示每次的回傳值 if ($debug) echo "$i => $data\n"; } } if ($debug) echo "ALL => $temp\n"; // 把我不要的字通通取代掉 $temp = str_replace("T1=+", "", $temp); if ($debug) echo "$temp\n"; $temp = str_replace("C", "", $temp); if ($debug) echo "$temp\n"; $up = "不知道"; // 以下這邊是給 mrtg 畫圖輸出用的, 共輸出四行 echo "0" . "\n"; // 綠色線 echo $temp . "\n"; // 藍色線 echo $up . "\n"; // 運作時間 echo "AT2051 溫度\n"; // 註解 // 養成關閉連線的好習慣 dio_close($fd); ?> * 其實能抓內容的就代表, 要丟進資料庫就超級簡單的了, 這我就不實作了. * 最後, mrtg 畫出來的結果就不提供了。 \\