Arduino網路遠端遙控家電開關(一)

本文旨在補充《超圖解Arduino互動設計入門》第十六章「網路家電控制」單元,增加另一個網頁控制範例。

下圖是本單元的預期成果,使用者透過點選頁面上的文字,即可控制遠端家電的開關:

在說明Arduino端的網路和控制程式碼之前,先在電腦上撰寫此網頁所需要的HTML碼:

<!doctype html>
<html>
  <head>
    <meta charset="utf-8">
    <title>arduino@home</title>
    <meta name="viewport" content="width=device-width; initial-scale=1.0; maximum-scale=1.0; user-scalable=0;">
  </head>
  <body>
    <h1>遙控家電</h1>
    <div id="lights">
      <ul>
        <li><a href="sw?id=0"><span class='sw on'>ON</span>檯燈</a></li>
        <li><a href="sw?id=1"><span class="sw on">ON</span>壁燈</a></li>
        <li><a href="sw?id=2"><span class="sw off">OFF</span>吊燈</a></li>
        <li><a href="sw?id=3"><span class="sw off">OFF</span>落地燈</a></li>
        <li><a href="sw?id=4"><span class="sw off">OFF</span>熔岩燈</a></li>
        <li><a href="sw?id=5"><span class="sw off">OFF</span>藤球燈</a></li>
      </ul>
    </div>
 </body>
</html>

以上的HTML將在瀏覽器呈現如下的結果:

每個項目清單元素都包含一個超連結,用來連結到Arduino的sw程式,並傳遞控制腳位的參數,例如:

設定手機瀏覽器的viewport(視界)參數

iOS和Android裝置的瀏覽器預設會以980和800像素的虛擬顯示寬(viewport,視界)來呈現網頁,假設Android手機螢幕實際是480像素寬,瀏覽器用800像素寬來呈現,網頁將整個被縮小顯示:

為了讓iOS與Android裝置的瀏覽器,以實際的螢幕解析度來呈現網頁,請在網頁的檔頭區加入底下的<meta>標籤設定:

建立網頁的CSS樣式表

HTML的用途是制定網頁的結構和內文,頁面的外觀樣式則是由CSS決定。

為了方便在小螢幕上觀看並點選超連結,我們將使用CSS樣式調整項目清單文字的大小,並加大字行的高度(擴大字行之間的間距),以及其他美化樣式。

在檔頭區插入底下的CSS樣式:

<style type="text/css">
  body {
    /* 內文採用非襯線字體 */
    font-family:"微軟正黑體", "黑體-繁", sans-serif;
    /* 灰色背景 */
    background-color:#CCC;
  }
  
  .sw {
    /* 上下不留白,左右留白半個字體高 */
    margin:0 0.5em;
    /* 以粗體字樣式呈現 */
    font-weight:bolder;
    }
  
  .on {
    color:#F00;  /* 紅色字體 */
  }
  
  .off {
    color:#090;	/* 綠色字體 */
  }
  
  /* 設定lights區塊 */
  #lights {
    /* 邊框圓角半徑 10像素 */
    border-radius:10px;
    -moz-border-radius:10px;
    -webkit-border-radius:10px;
    /* 白色背景 */
    background-color:#FFF;
    /* 內距 1像素 */
    padding:1px;
  }
  
  /* 設定lights 區塊裡的清單樣式 */
  #lights ul {
    /* 不顯示圓點 */
    list-style-type:none;
    /* 左邊內距為 0(取消預設的清單元素縮排)*/
    padding-left:0px;
    /* 字體大小:24點 */
    font-size:24pt;
  }
  
  /* 設定lights 區塊裡的清單項目樣式 */
  #lights ul li {
    /*  上下留白10像素,左右不留白。 */
    margin:10px 0;
    /*  1像素點狀灰色底線  */
    border-bottom:1px dotted #CCC;
    /*  底部內距 5像素  */
    padding-bottom:5px;
  }
  
  /* 設定lights 區塊裡的清單超連結樣式 */
  #lights ul li a {
    /* 讓超連結感應整個區塊 */
    display:block;
    /* 消除底線 */
    text-decoration:none;
    /* 黑色字體 */
    color:#000;
  }
</style>

最後呈現的外觀如下:

讀者可按此連結下載本單元的網頁原始碼(ZIP格式壓縮)。

延伸閱讀

Posts created 467

27 thoughts on “Arduino網路遠端遙控家電開關(一)

  1. 老師你好

    請問這樣如何運用在Arduino上呢?
    有買你的書 書上是使用選擇開或關 再點送出
    而我想用Button方式應該要如何做呢

    1. 剛剛看了一下你的程式,我不知道你有沒有讀懂原作者的程式碼以及了解JavaScript。你不需要重複建立多個不同名稱,但是功能類似的函式來處理AJAX。只要加入參數即可,例如,假設網頁上的按鈕id分別是btn1, btn2和btn3,用底下的敘述呼叫send2arduino()函式:

      send2arduino(“btn2″);

      底下的函式將送出”?onbtn2″或者”?offbtn2″給Arduino:

      function send2arduino(obj){
              var xmlhttp;
              if (window.XMLHttpRequest)
              {// code for IE7+, Firefox, Chrome, Opera, Safari
                      xmlhttp=new XMLHttpRequest();
              }
              else
              {// code for IE6, IE5
                      xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
              }
      
              element=document.getElementById(obj);
              if (element.innerHTML.match("Turn on"))
                {
                        element.innerHTML="Turn off";
                        xmlhttp.open("GET","?on" + obj, true);
                }
              else
                {
                        element.innerHTML="Turn on";
                        xmlhttp.open("GET","?off" + obj, true);
                }
              xmlhttp.send();       
      }
      

      然後,你的Arduino程式再修改成判斷接收值”?onbtn2″, “?onbtn3”,… 做出相應的控制。

      have fun!
      jeffrey

  2. 感謝老師的回覆 ^_^

    對於這JavaScript完全不是很懂= =”,我也覺得我寫很冗長,有試著去簡化這個程式 努力中…

    雖然看老師寫的程式,研究了…..一下 還是不會運用><' 真的太糟糕了

  3. 老師你好:
    請問老師我設的網頁語法如下:
    “”
    點下按鈕 網址顯示:
    192.168.xx.xx/sw?0=&start.x=42&start.y=21&start=i

    為什麼會多了”start.x=42&start.y=21&” 亂數
    而不是顯示 192.168.xx.xx/sw?0=&start=i

    用button可以解決上面的問題,不過圖片是顯示在button上,感覺多了一個框框給他包住,不能單獨只有圖片嗎?

    1. 你可以透過JavaScript來發送表單內容,如此就不一定要用按鈕。請搜尋JavaScript submit form之類的關鍵字。

      thanks,
      jeffrey

  4. 老師你好:
    我是初學者近期想研究網頁控制Arduino,
    想請問一下Arduino網路遠端遙控家電需要哪些硬體設備呢?

    1. hi EIEN:

      最基本的實驗只需要Arduino UNO控制板,加上一片採用W5100晶片的乙太網路擴充介面卡,這樣就能讓Arduino連上家裡的有線網路。

      實驗成功之後,你再視需求組裝或添購相關模組。例如,用繼電器模組控制家電開、關(要留意繼電器的耐電流量,不要嘗試控制超過規範值以上的電器),或者用溫濕度感測器模組監控遠端的溫濕度變化。

      have fun!
      jeffrey

  5. 老師您好,我希望可以把這些程式運用在我學校的專題上,想要事先徵求您的同意,請問我如果要加上電壓(瓦數消耗)監控Arduino可不可以實現?需要用到甚麼樣的元件?或是延伸其他功能,希望老師能指點。
    謝謝

    1. hi tony:

      可以。監測消耗的電流量,可將「鉗型交流電感測器(CT Sensor)」裝在連接設備的電源線上,搜尋關鍵字”arduino monitor power consumption”,可找到許多相關範例。

      thanks,
      jeffrey

  6. 老師你好 可以跟你請問一下~要如何用 WEB端 幫 ESP8266 去設定帳號密碼呢!?(比方說 今天到不同環境 我不用再開程式碼手動修改 這樣~)

  7. 老師您好:
    以下是我的程式碼我想請教一下回首頁這行超連結該加在哪?(我想在家庭自動化那個網頁裏顯示)
    #define WEBDUINO_FAIL_MESSAGE “”
    #include
    #include
    #include
    static byte mac[] = {0xBC,0xAE,0xC5,0xAF,0x44,0x8E};
    IPAddress ip(10,0,1,7);
    IPAddress subnet(255,255,255,0);
    IPAddress gateway(10,0,1,1);
    WebServer webserver(“”,80);
    P(homePage) =””
    “”
    “Arduino家庭自動化”
    “”
    “okok”
    “”;
    P(faqPage) = “”
    “”
    “FAQ微網站”
    “”
    “FAQ網頁”
    “”;

    void defaultCmd(WebServer &server, WebServer::ConnectionType type,
    char *, bool)
    {
    server.httpSuccess();
    if(type != WebServer::HEAD)
    {
    server.printP(homePage);
    }
    }
    void faqCmd(WebServer &server, WebServer::ConnectionType type,
    char *, bool)
    {
    server.httpSuccess();
    if(type != WebServer::HEAD)
    {
    server.printP(faqPage);
    }
    }
    void setup() {
    Ethernet.begin(mac,ip,gateway,subnet);

    webserver.setDefaultCommand(&defaultCmd);
    webserver.addCommand(“faq.html”, &faqCmd);
    webserver.begin();
    }

    void loop() {
    webserver.processConnection();

    }

    1. hi jacky:

      以動手做16-4的遠端燈光開關控制程式為例,該Arduino網站提供兩個頁面,當使用者在表單頁面輸入資料,按下「送出」鈕,網頁將切換到回應表單處理結果頁,如果要加上「回首頁」的連結,就要加在第二頁。

      它的程式位於16-30頁,你可以把「回首頁」的敘述,加在顯示「燈光已經打開或關閉」的訊息後面,也就是藍色底的條件敘述後面:

      if (strcmp(name, "light") == 0) {
         // 中間省略
      }
      // 加入回首頁的超連結段落文字:
      server << "<p><a href='/'>回首頁</a></p>";
      

      thanks,
      jeffrey

  8. 你好 我想用ARDUINO透過繼電器控制12V門鎖 請問該如何設計
    像是接一個按鈕然後按一下門就開 再按一下門就鎖上 該如何去設計

    1. 你要了解如何接按鈕(開關)、消除按鈕的彈跳的訊號、如何用變數儲存開關的狀態、如何透過電晶體驅動繼電器(或使用現成的模組)、如何輸出訊號控制繼電器,這些內容書本都有提到。

      thanks,
      jeffrey

  9. 老師您好,想請問在書中寫到使用webduino來架設網頁伺服器,那麼一些原本arduino支援的第三方程式webduino也會支援嗎,例如使用max31855等晶片。

    1. 我查了一下max31855的資料,它採用的是SPI介面,Arduino的乙太網路卡也是用SPI介面,所以你只要留意max31855的晶片選擇腳不要使用乙太網路卡預設的10和4(接SD記憶卡),這樣就沒問題了。附帶說明,書本提到的是webduino是「網路程式庫」而不是微控制板喔~

      thanks,
      jeffrey

  10. 老师您好,我在使用strcmp函数的时候报错了,报错如下:
    Arduino:1.8.3 (Windows 10), 开发板:”Arduino/Genuino Uno”

    C:\Users\admin\Documents\Arduino\sketch_sep11a\sketch_sep11a.ino: In function ‘void loop()’:

    sketch_sep11a:34: error: cannot convert ‘String’ to ‘const char*’ for argument ‘1’ to ‘int strcmp(const char*, const char*)’

    if(strcmp(comdata,”msg”)==0)

    ^

    exit status 1
    cannot convert ‘String’ to ‘const char*’ for argument ‘1’ to ‘int strcmp(const char*, const char*)’

    我的代码如下:

    #include
    #include “stdio.h”

    //软件串口库

    SoftwareSerial wifi(A4, A5);
    int led=13;
    String comdata=””,buf=””;
    String ledon = “ledon”, ledoff = “ledoff”;

    void setup()
    {
    Serial.begin(9600);
    wifi.begin(9600);
    pinMode(led,OUTPUT);
    }

    void loop()
    {
    wifi.listen();
    if(wifi.available())
    {
    while(wifi.available()>0)
    {
    comdata+=char(wifi.read());
    delay(2);
    }
    buf=comdata;

    if(strcmp(comdata,”ledon”)==0)
    {
    Serial.println(“ON”);
    digitalWrite(led,HIGH);
    }
    // int a=comdata.compareTo(str1);//good
    // Serial.println(a);//good
    // if(a==0) //good
    // digitalWrite(led,HIGH);
    if(!buf.compareTo(“ledoff”))
    {
    Serial.println(“OFF”);
    digitalWrite(led,LOW);
    }
    Serial.println(buf);
    comdata=””;

    }

    }

  11. 老師您好, 請教雙 SPI 裝置問題
    目前使用 arduino DUE 這塊板子, 搭配 W5100 (CS:10) + webduino 沒問題,
    因需要讀寫檔案故加入 SD (CS:4), 但發現插上此模組後就無法連網, 若拔掉, 連網正常…
    請教老師在程式或接線上有需要注意的地方嗎? Thanks.

    1. 對 SD 模組的 PIN 腳做實驗, 發現只要把 MISO 拔除就不會影響 LAN, 如果是線路訊號問題, 有甚麼建議嗎?

    2. 我沒有DUE這塊板子,但我記得在Arduino UNO上使用乙太網路和SD卡是沒問題的,我明天再確認一下。

      thanks,
      jeffrey

    3. 如果使用 Shield 我認為應該是沒問題,
      目前是覺得兩張模組的相容性問題, 應該會朝硬體訊號去解… Thanks.

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *

Related Posts

Begin typing your search term above and press enter to search. Press ESC to cancel.

Back To Top