樹莓派學習筆記——webiopi網頁統制LED

轉自:http://www.myexception.cn/web/1615075.html


樹莓派學習筆記——webiopi網頁控制LED

0.前言
    webiopi是一個可控制樹莓派GPIO的web框架,該框架面向物聯網IoT開發。該項目託管於google,並可在sourceforge上下載到源代碼。現在webiopi已經發展到0.7版本,webiopi支持REST Server,CoAP server,並提供python庫和javascript庫,毫無疑問的說webiopi是一個優秀的框架。
     雖然webiopi是一個優秀的框架,但是webiopi由python,javacript語言編寫,並提供了REST和CoAP形式訪問方式,學習和掌握webiopi需要不少的基礎知識。對於那些認爲C語言、寄存器操作、16進制協議可以解決一切問題的嵌入式工程師來說,python和javacript,REST和CoAP協議顯得臃腫不堪並毫無用處。但是事實並非如此。
    【webiopi和其他網頁控制LED的區別】
    1.後臺,完善的RESTAPI可實現GPIO端口的方向控制、輸出控制和輸入檢測。
    2.前臺,完整的javascript API,方便用戶創建標籤並和後臺API相聯繫。
    【有用的博文】
    【樹莓派學習筆記——webiopi安裝與入門】
    【樹莓派學習筆記——webiopi配置文件說明】

    【代碼和配置文件倉庫】
    config文件中,請修改
    doc-root = /home/pi/webiopi_works/simple
    【運行本例】
    cd進入html文件和config文件所在目錄
    輸入以下指令
    sudo webiopi -c config
    瀏覽器中輸入(請根據樹莓派的具體IP地址修改)
    192.168.1.107:8000

1.最終效果
LED1按鈕,鼠標按下LED1點亮,鼠標鬆開LED1熄滅。類似於無自鎖功能開關。
LED2按鈕,鼠標按下LED2狀態翻轉。類似帶自鎖功能開關。

圖1 最終效果


2.實現代碼
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <meta name="viewport" content = "height = device-height, width = 420, user-scalable = no" /> 
    <title>WebIOPi | Demo</title>
    <script type="text/javascript" src="/webiopi.js"></script>
    <script type="text/javascript">
    webiopi().ready(function() {
        // GPIO24和GPIO25爲輸出
        webiopi().setFunction(24, "out");
        webiopi().setFunction(25, "out");
        
        var content, button;
        content = $("#content");
        
        // 創建一個不同按鈕,按鈕ID爲hold,名稱爲LED1,並綁定按下和鬆開事件
        button = webiopi().createButton("hold", "LED1", mousedown, mouseup);
        content.append(button);
        
        // 創建一個GPIO按鈕,編號爲GPIO24,按鈕名稱爲LED2
        button = webiopi().createGPIOButton(25, "LED2");
        content.append(button); // append button to content div
               
        // 不自動刷新界面
        webiopi().refreshGPIO(false);
    });
        
    function mousedown() {
        // GPIO24 輸出高電平
        webiopi().digitalWrite(24, 1);
    }
    
    function mouseup() {
        // GPIO24 輸出低電平
        webiopi().digitalWrite(24, 0);
    }
    
    </script>
    <style type="text/css">
        button {
            display: block;
            margin: 5px 5px 5px 5px;
            width: 160px;
            height: 45px;
            font-size: 24pt;
            font-weight: bold;
            color: black;
        }
        
        .LOW {
            background-color: White;
        }
        
        .HIGH {
            background-color: Red;
        }
    </style>
</head>
<body>
    <div id="content" align="center"></div>
</body>
</html>

3.代碼分析
【1】
<body>
    <div id="content" align="center"></div>
</body>
一個ID爲content的div,可使用jquery語法 #content選擇該div。可通過$("#content").append加入其他windows DOM。

【2】
webiopi().setFunction(24, "out");
setFunction爲webiopi中javascritp部分提供的API函數,該函數利用jquery中的$.post方法調用REST API。實現setFunction部分的代碼——webiopi.js:
GPIOPort.prototype.setFunction = function(channel, func, callback) {
 var name = this.name;
 $.post(this.url + "/" + channel + "/function/" + func, function(data) {
  callback(name, channel, data);
 });
}
訪問REST API爲 /24/function/out。意爲GPIO24端口爲輸出狀態。

【3】
content = $("#content");
創建一個jquery對象,選擇ID爲content的div

【4】
button = webiopi().createButton("hold", "LED1", mousedown, mouseup);
創建一個按鈕,按鈕的ID爲hold,名稱爲LED1,並註冊鼠標按下和鼠標鬆開事件。
createButton實現部分代碼——webiopi.js
WebIOPi.prototype.createButton = function (id, label, callback, callbackUp) {
 var button = $('<button type="button" class="Default">');
 button.attr("id", id);
 button.text(label);
 if (callback != undefined) {
  button.bind(BUTTON_DOWN, callback);
 }
 if (callbackUp != undefined) {
  button.bind(BUTTON_UP, callbackUp);
 }
 return button;
}
該代碼可創建一個button標籤——<button type="button" class="Default" id="hold">LED1</button>

【5】
content.append(button);
把button標籤加入content中。

【6】
button = webiopi().createGPIOButton(25, "LED2");
創建一個按鈕,按鈕和GPIO25相關聯,名稱爲LED2。
createGPIOButton實現部分代碼——webiopi.js
WebIOPi.prototype.createGPIOButton = function (gpio, label) {
 var button = w().createButton("gpio" + gpio, label);
 button.bind(BUTTON_DOWN, function(event) {
  w().toggleValue(gpio);
 });
 return button;
}
從實現代碼中可以看出,GPIOButton本質爲一個Button,只是這個Button的ID變爲gpio25。除此之外還給該button綁定了一個mousedown事件。
toggleValue實現部分——webiopi.js
WebIOPi.prototype.createGPIOButton = function (gpio, label) {
 var button = w().createButton("gpio" + gpio, label);
 button.bind(BUTTON_DOWN, function(event) {
  w().toggleValue(gpio);
 });
 return button;
}
實現部分的代碼調用了digitalWrite。(見【8】)

【7】
webiopi().refreshGPIO(false);
定時刷新界面,如果選擇false
refreshGPIO實現代碼——webiopi.js
WebIOPi.prototype.refreshGPIO = function (repeat) {
 $.getJSON(w().context + "*", function(data) {
  w().updateALT(w().ALT.I2C, data["I2C"]);
  w().updateALT(w().ALT.SPI, data["SPI"]);
  w().updateALT(w().ALT.UART, data["UART"]);
  w().updateALT(w().ALT.ONEWIRE, data["ONEWIRE"]);
 
  $.each(data["GPIO"], function(gpio, data) {
      w().updateFunction(gpio, data["function"]);
      if ( ((gpio != 4) && ((data["function"] == "IN") || (data["function"] == "OUT"))
       || ((gpio == 4) && (w().ALT.ONEWIRE["enabled"] == false)))){
       w().updateValue(gpio, data["value"]);
      }
      else if (data["function"] == "PWM") {
       w().updateSlider(gpio, "ratio", data["ratio"]);
       w().updateSlider(gpio, "angle", data["angle"]);
      }
     
  });
 });
 if (repeat === true) {
  setTimeout(function(){w().refreshGPIO(repeat)}, 1000);
 }
}
該部分實現較爲複雜,請注意updateValue函數——webiopi.js
WebIOPi.prototype.updateValue = function (gpio, value) {
 w().GPIO[gpio].value = value;
 var style = (value == 1) ? "HIGH" : "LOW";
 $("#gpio"+gpio).attr("class", style);
}
選擇一個ID爲gpio??的標籤,然後加入一個class,樣式名爲HIGH或者LOW。
所以和createButton創建的Button不同,createButton創建的Button標籤如下
<button type="button" class="HIGH" id="gpio25">LED2</button>
class="HIGH"或class=“LOW”
使用這樣的方法可以方便修改按鈕的樣式,例如按下背景爲紅色,鬆開背景爲白色。

【8】
LED1 Button註冊的鼠標按下和鼠標鬆開事件處理
    function mousedown() {
        // GPIO24 輸出高電平
        webiopi().digitalWrite(24, 1);
    }
    function mouseup() {
        // GPIO24 輸出低電平
        webiopi().digitalWrite(24, 0);
    }
其中digitalWrite實現部分如下
WebIOPi.prototype.digitalWrite = function (gpio, value, callback) {
 if (w().GPIO[gpio].func.toUpperCase()=="OUT") {
  $.post(w().context + 'GPIO/' + gpio + "/value/" + value, function(data) {
   w().updateValue(gpio, data);
   if (callback != undefined) {
    callback(gpio, data);
   }
  });
 }
 else {
  //console.log(w().GPIO[gpio].func);
 }
}
使用jquery中的$.post方法,REST API爲
GPIO/24/value/1    表示打開LED
GPIO/24/value/0    表示關閉LED

【9】
Button按鈕樣式
        button {
            display: block;
            margin: 5px 5px 5px 5px;
            width: 160px;
            height: 45px;
            font-size: 24pt;
            font-weight: bold;
            color: black;
        }
【10】
LED爲點亮時和熄滅時 Button樣式。在refreshGPIO中給Button加入了一個class,該class只有兩個值HIGH和LOW。其中LOW和GIHT的".",爲CSS樣式中的選擇符號,以爲選擇class爲LOW的標籤。使用這種方法可以方便的修改按鈕的背景顏色,大小等參數,真正實現定製。
        .LOW {
            background-color: White;
        }
        
        .HIGH {
            background-color: Red;
        }

圖2 GPIOButton LED熄滅時

圖3 GPIOButton LED點亮時

4.總結
學習過很多網頁控制LED的例子,但是webiopi給我留下最爲深刻的影響。可總結爲兩點
1.後臺,完善的RESTAPI可實現GPIO端口的方向控制和輸出控制,輸入檢測。
2.前臺,完整的javascript API,方便用戶創建標籤並和後臺API相聯繫。
這樣,用戶只需關心業務和UI即可,大大方便了IoT開發。

發佈了15 篇原創文章 · 獲贊 13 · 訪問量 9萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章