※已刊登在《無線電》04月刊上 搭建屬於你的在線實時採集系統
——HTML5 在嵌入式系統中的應用
做者:劉琛,徐洋
摘要: 本應用擺脫了以往嵌入式系統的數據採集方式,藉助於最新的HTML5的Canvas API及WebSocket API兩大特性,實現了數據的在線實時採集功能。提高了嵌入式採集系統的性能及體驗。爲嵌入式開發工做者提供參考。
關鍵字:HTML5;HTTP Server;Canvas;WebSocket;W5500;實時;採集系統;
當今信息社會,信息就是金錢,而但凡是信息便必然承載着時效性,過期的信息將不具備任何價值。因而可知,信息實時性的重要性。
隨着近幾年物聯網在各行各業的迅猛發展,愈來愈多的終端設備連入網絡,實現遠程交互及控制;各式傳感器的普遍普及,使得數據節點分佈愈來愈多。而這些交互數據自己也屬於一種原始信息,這些數據量須要咱們採集、分析、處理、反饋,其數據真實有效性,準確性,以及實時性保證了整個工做的效率,質量以及價值。
在此,咱們基於W5500實現了一個在線採集系統,而且爲其引入了一個新鮮的元素——HTML5。經過這種最新的Web語言,爲你們呈現一種更爲實時、高效的在線實時採集系統。相信隨着HTML5在嵌入式領域的不斷深刻推廣,必然對產業效能及價值提高產生不小的做用。
在具體介紹這種實時採集系統前,讓咱們先簡單的來認識一下HTML5。
HTML5和HTML的區別
HTML爲建立網頁Web使之可以在網絡瀏覽器呈現而設計的一種標記語言。
HTML5爲HTML的下一個修訂版本。而廣義的HTML5,包括了新的以及加強的HTML,CSS3,JavaScript API和事件的一套技術組合。
圖1HTML5 Logo
如下爲HTML5較HTML新加強的主要功能:
html
Canvas API及Web Socket API
其實,實現該在線實時採集系統,得益於HTML5新增的2個API函數:Canvas及WebSocket。
Canvas,由04年蘋果公司爲MAC OS X儀表板開發的像素繪圖元素髮展而來。由Canvas元素和相應的JavaScript組成。使得開發者可以無需藉助其餘第三方插件,利用JavaScript的Canvas圖形工具,在Canvas元素畫板上實現動態繪製圖形。
Websocket,提供了一個直接與服務器通信的Socket。使得在通信創建以後,客戶端(瀏覽器)可以與網頁服務器實現雙向通信,而無需客戶端頻繁輪詢服務器實現。這樣可以減小Http請求的額外開銷,減輕數據包負擔,並且通信更加實時。
經過對於這2個API函數的靈活應用,咱們實現了經過HTTP Server,實時的接收數據量,並在網頁Web上動態模擬的功能。
在線實時採集系統演示
前端
a) 單片機:STM32F103RC,256K字節Flash,48K字節SRAM,2K字節EEPROM
b) 以太網控制器:W5500,SPI接口與單片機相連
c) 電源:USB供電
2. 開發工具: IAR for ARM v5.41,這是咱們工程所使用的版本。若是使用不一樣版本的IAR,請對STM的庫稍做調整。
看代碼以前,咱們仍是先來了解一下整個的程序流程,以下圖所示。在硬件初始化完成以後,將進行網絡參數配置,這是要根據本身網絡的狀況來配置W5500的IP地址等網絡參數,確保W5500能連網;本程序中,咱們會使用W5500的兩個socket資源,一個用來建立Http Server,這樣在瀏覽器上輸入配置的IP地址,就能遠程訪問咱們的硬件了;另外一個用來建立Web Socket Server,與網頁端創建通訊鏈路,用來傳輸咱們的溫溼度數據。
圖2硬件運行流程
當咱們在瀏覽器上訪問硬件的IP地址,會向W5500發送http請求,W5500在收到請求後將html5的網頁信息發送給瀏覽器,這樣瀏覽器上就能顯示咱們的溫溼度檢測系統的主界面了。在網頁的代碼中,瀏覽器會主動鏈接W5500的Web Socket Server,在完成握手操做後,數據通訊通道即創建了。這樣硬件就能夠無障礙的將溫溼度數據發送給瀏覽器端,瀏覽器在收到溫溼度數據後,使用畫布功能,在指定位置畫出溫溼度示數的點和曲線。如下是html5中Web Socket(網絡套接字)和Canvas(畫布)代碼、W5500的Web Socket握手和數據幀協議、溫溼度採集程序的介紹。
圖3網頁顯示界面
Canvas和Web Socket
在瀏覽器端咱們使用HTML5的Canvas繪製工具和WebSocket API搭建咱們的web界面。當有新的溫溼度數據來臨時,在畫布的座標系裏會有畫點顯示,並標識示數,而且隨着採集次數的增長,多個數據連線,就能夠看到曲線變化。網頁程序步驟以下:
1) 建立頁面和canvas所屬的style、body標記
2) 繪製座標軸,添加標題;創建WebSocket鏈接
3) 新數據到來,繪製點和線
利用Canvas繪圖
下面先介紹如何建立一張畫布以及代碼中使用到的繪製函數。
1) 創建一張600×400的畫布,單位是像素
2) 定義畫布的邊框寬度、顏色和內邊距大小。
#graph {
border: 1px solid #03F;
margin:0 40px 0 80px;
}
3) 爲了在JavaScript中對canvas進行繪製,首先須要經過目標canvas的id獲取繪製環境。代碼須要經過id獲取canvas元素,而後使用此元素的getContex方法獲取其二維繪製環境的引用
canvas = document.getElementById ( ‘graph’ );
context = canvas.getContext ( ’2d’ );
4) 繪製一條線段
context.lineWidth = 2 ;// 設置線寬
context.strokeStyle = ‘#999′ ;// 設置線的顏色
context.moveTo ( x1,y1 );// 移動到起點
context.lineTo ( x2,y2 );// 建立到終點的路徑
context.stroke ();// 實際繪出這段直線
5) 繪製圓
context.fillStyle = ‘#000′ ;// 設置填充色
context.beginPath ();
context.arc ( x,y , 2 , 0 , Math.PI * 2 , true );// 在座標 (x,y) 處繪製半徑 2 的圓
context.closePath ();
context.fill ();// 在圓內填充顏色
6) 在指定位置寫標題文字
context.fillText ( text , x , y , maxWidth );
使用以上函數組合便可繪製以下的圖了,若是您以爲這還不夠炫,html5的canvas中還提供了漸變色、旋轉、插圖等函數,發揮你的設計才能動手製做屬於本身的前端界面吧。
圖4畫布示例圖
WebSocket的使用 接下來咱們介紹html5中WebSocket的使用以及相關函數
1) 爲了建立一個websocket鏈接,代碼須要建立一個WebSocket接口實例,傳入Web服務URL地址,sensorWebSocket對象會試圖鏈接監聽於相應的URL的服務
var wsUri = ‘ws:192.168.10.111:1818′ ;
sensorWebSocket = new WebSocket ( wsUri );
2) 註冊事件併爲事件連接相應處理函數,例如,在瀏覽器頁面收到來自服務器端的數據後,觸發onmessage事件,進而調用onMessage函數,代碼中咱們註冊了onopen、onmessage、onclose和onerror四個事件
sensorWebSocket.onmessage = function ( evt ){ onMessage ( evt )};
3) 消息處理函數,在硬件上咱們將採集來的溫溼度數據用‘.’號鏈接,在瀏覽器端,接收到數據後,使用字符串分割函數將溫度和溼度數據分割,存儲在一個數組對象裏。以後的代碼就是將示數轉化成座標值在畫布上顯示出來,這裏再也不贅述。
function onMessage ( evt ){
vararrayTH=new Array(2);
arrayTH = evt.data.split ( ‘.’ );
……
}
4) 主動關閉websocket鏈接
sensorWebSocket.close ();
怎麼樣,websocket的使用很簡單吧,有了這個利器,就能夠與遠程服務器鏈接並接受和發送消息,該功能在雙向通訊方面十分有用,特別是在服務器須要主動向瀏覽器頁面發送消息時。
Web Socket握手和數據幀
在服務器端建立好socket後,首先要與客戶端完成握手才能開始數據通訊,那麼這個握手在程序上市如何實現的呢,先看下握手的流程:
表1握手流程
客戶端的代碼在上面已經介紹,下面是硬件中服務器一、2的代碼:
#define WS_SERVER_PORT 1818//定義服務器監聽的端口號
socket ( s , Sn_MR_TCP , WS_SERVER_PORT , 0×20 );//W5500 中創建 socket 鏈接
listen ( s );// 開啓偵聽 s 變量爲 W5500 的 socket 序號,此例程中使用 2 號
如下是給W5500配置的網絡信息,其中IP地址即爲咱們瀏覽器頁面程序websocket對象的監聽地址。
uint8 mac [ 6 ]={ 0×00 , 0×08 , 0xdc , 0×11 , 0×11 , 0×11 };
uint8 lip [ 4 ]={ 192 , 168 , 10 , 111 };
uint8 sub [ 4 ]={ 255 , 255 , 255 , 0 };
uint8gw [ 4 ]={ 192 , 168 , 10 , 1 };
setSHAR ( mac );
setSUBR ( sub );
setGAR ( gw );
setSIPR ( lip );
硬件中有關服務器五、六、7流程的代碼:
charsec_ws_key [ 32 ]={ 0×00 ,};
characcept_key [ 32 ]={ 0×00 ,};
//get Sec-WebSocket-Key:
if ( strstr (( charconst *) wsRxBuf , 「Sec-WebSocket-Key: 「 ))
{
mid (( char *) wsRxBuf , 「Sec-WebSocket-Key: 「 , 「rn」 , sec_ws_key );// 截取 sec_key
calc_accept_key ( sec_ws_key , accept_key );// 編碼函數
sprintf (( char *) wsTxBuf , 「HTTP/1.1 101 SwitchingProtocolsrnUpgrade: WebSocketrnConnection:UpgradernSec-WebSocket-Accept: %srnrn」 , accept_key );// 生成握手消息
send ( s , wsTxBuf , strlen (( char *) wsTxBuf ));// 發送給客戶端
}
handshaked = 1 ;
這樣看起來可能有點抽象,咱們看看實際的數據包吧,上邊紅色字體爲瀏覽器頁面的握手請求,Sec-websoket-Key後即爲咱們截取的sec_key,後邊的藍色字體爲服務器端的握手回覆,Sec-websoket-Accept後爲咱們編碼後的accept_key,怎麼樣,一目瞭然了吧。 html5
圖5握手過程抓包信息
在握手成功後,在硬件端就能夠將每隔一段時間採集來的溫溼度數據發送給瀏覽器頁面。WebSocket協議的數據包很是輕量,下面介紹數據包的幀格式:
圖6WebSocket數據幀格式
上圖是官方提供的結構圖,第一個字節,第一位是FIN,後面三位是RSV1到3。RSV是預留的空間,用 0填充,那麼前4位只有第一位的FIN須要設置。接着後面的四位是儲存opcode的值,opcode定義負載數據的解釋。FIN用來指示消息的最後片斷,若是隻有一條消息,那麼FIN就是1;這裏咱們用opcode定義數據是文本-0×1,這樣第一個字的二進制是1000001(0×81),第一個1是FIN的值,最後一個1是opcode的值。
接着是第二個字節的數據,它由1位的MASK和7位的PayloadLen組成,MASK標識這個數據幀的數據是否使用掩碼,PayloadLen表示數據部分的長度。可是PayloadLen只有7位,換成無符號整型的話只有0到127的取值,這麼小的數值固然沒法描述較大的數據,所以規定當數據長度小於或等於125時候它才做爲數據長度的描述,若是這個值爲126,則時候後面的兩個字節來儲存儲存數據長度,若是爲127則用後面八個字節來儲存數據長度。這裏咱們每次發送的溫溼度數據只有5個字節,而且不使用掩碼,因此配置爲0×05。
再接着是上面圖表中的MaskingKey,它佔四個字節,儲存掩碼的實體部分。可是隻有在前面的MASK被設置爲1時候才存在這個數據,不然不使用掩碼也就沒有這個數據了。 最後是數據部分,若是掩碼存在,那麼全部數據都須要與掩碼作一次異或運算。若是不存在掩碼,那麼後面的數據就能夠直接使用。
看看咱們數據發送的代碼是如何實現的吧:
wsTxBuf [ 0 ]= 0×81 ;
wsTxBuf [ 1 ]= 0×05 ;
wsTxBuf [ 2 ]= Temp / 10 + 0×30 ;
wsTxBuf [ 3 ]= Temp % 10 + 0×30 ;
wsTxBuf [ 1 ]= 0x2E ;// 分隔符‘ . ’
wsTxBuf [ 2 ]= Humi / 10 + 0×30 ;
wsTxBuf [ 3 ]= Humi % 10 + 0×30 ;
send ( s , wsTxBuf , strlen (( char *) wsTxBuf ));
是否是代碼很easy!
數據採集
那麼另外簡述一下數據的採集過程。 咱們選用的是溫溼度傳感器DHT11,進行對室內溫溼度數據的實時採集與上傳。這裏就用DHT11與單片機鏈接(W5500),它與單片機的通訊只須要一個I/O口,使用很簡單。 具體DHT11與單片機的鏈接 與相關調試,這裏就不詳細講解了。能夠搜索相關資料。
相信隨着HTML5的不斷成熟,它帶來的不只僅是PC環境的Web革命。對於嵌入式領域來講,也可以帶來更好的客戶體驗及產品性能。固然,咱們仍然還須要藉助W5500這個頗具特點的以太網芯片。其全硬件TCP/IP協議棧不只大大節約了頗爲珍貴的嵌入式資源,並且節省了不少開發步驟及難度,從而能讓咱們可以更多的資源與精力去實現更爲精彩的Web功能。
若是你感興趣的話,趕快來作一個屬於你的在線實時採集系統吧。web