===== 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程式碼
// 要顯示 debug 就改 1;
$debug=1;
// /dev/cuaU0
$fd = dio_open('/dev/cuaU0',O_RDWR | O_NOCTTY | O_NDELAY);
dio_fcntl($fd,F_SETFL,0);
// 設定傳輸速率, 也就是 RS-232 常聽到的 9600 N 8 1
dio_tcsetattr(
$fd, array(
'baud' => 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 畫出來的結果就不提供了。
\\