IMG_1598

    不久前在 Youtube 上看到一則影片,主角只出一張嘴,就能透過 Siri 讓家裡的電器用品乖乖聽話,就像小時候的科幻片描述未來的居家生活,頗為神奇。只不過影片中並沒有說明實作的方法,只在影片下方留言中提到幾個關鍵字,引起了我的好奇。

    從 iOS 開發者的角度來看,原以為是 iOS 10 的 Sirikit 的新功能,於是我嘗試呼叫 Siri ,得到的是以下的結果:

     

    IMG_1599

    Siri 回答提到「打理這個家」,大概能猜得到,iOS 使用 Homekit 控制家電 ,而 Siri 與 Homekit 整合已經是 iOS 10 內建的功能,所以 Siri 控制家電並非使用 Sirikit ,而是用 Homekit 來實現。換言之,所謂家電用品支援 Homekit 功能,就是除了能透過 iOS 10 內建的「家庭 App」來統一管理,並可自訂使用情境、場景與配件的設定,打造個人專屬的家電運作模式之外,還能透過 iOS 的 Siri 語音助理,「用講的」操控家電的部分功能。「家庭 App 管理家電」與「Siri 語音控制家電」兩項重點功能,就是 iOS 10 的 Homekit 智慧家電平台。

    近年來有越來越多新的家電產品標榜「智慧家電」功能,但台灣民眾對這一塊的熱度不夠,目前市面上還不普及,現役家電產品也大多還能用個很多年,除非在裝修新房時就納入智慧家電的規劃,否則只有極少數的人為了享受「智慧家電生活」把家裏的電器產品全部換掉(據說有個社會名人就這樣搞,打造智慧家庭就花了四千萬台幣)。於是換個角度,有沒有辦法讓家裏面的現有家電,透過外掛手段來支援 Homekit 呢?答案是有的,價格也很低廉,只是要達到這樣的目標有一定的技術門檻,雖然不難,但也不算容易,因為不同的電器有不同的動作設定,納入 Homekit 之後更不一定支援家電原有的全部功能。

    所以我可以理解為何一堆 Youtube 影片,尤其是中文的,大多沒有教學,畢竟有些實作步驟很有可能卡關,實作方式也會牽涉到特定的知識領域,寫了教學也不可能人人都能淺顯易懂。所以這篇文章並非新手教學,只會概略提出實作方式,除了幫自己做紀錄,也提供已有以下相關基礎知識,並且有興趣想嘗試的人做參考。

    • 會使用 Arduino IDE 撰寫單晶片韌體。
    • 略懂 Linux 終端機操作指令。

    目標使用情境:以家裏運作多年的老冷氣機為例,利用 iOS 的 Homekit 功能來控制冷氣的基本功能「開」和「關」。

    市售的傳統家用冷氣都有紅外線遙控器,但並不支援無線網路。所以要達到上述目標,實作目標分成兩大部分:

    • 實作一組可支援網路操控的自製紅外線 WIFI 遙控器
    • 在家裡的區域網路內,連接 Homekit 與自製的紅外線WIFI遙控器

    一、支援 WIFI 網路操控的紅外線遙控器

    這個部分教學就不少了,搜尋「Arduino+IRremote」就會跑出一堆。這裡再細分出兩階段:材料採購與軟體撰寫。

    材料相當廉價,甚至於比你去夜市買一隻萬用遙控器還便宜。

    • MCU/SoC 晶片:首先是必須支援聯網功能的單晶片,ESP8266 系列當然是不二人選,直接用 NodeMCU V1.0 就可以了,或是使用體積更小、更便宜的 WEMOS D1 mini 也行。這東西越來越便宜,台灣一個才一百多元,對岸的淘寶更便宜,合台幣不到 80 元,CP 值爆表,屌打一堆動輒千元的物聯網模組。
    • 紅外線發射 LED :一顆才 2 元,台南市區的電子材料店約 10-15 元。因為發射時有方向性,可以併聯個2-3顆,每一顆朝不同的方向。
    • 電晶體:NPN 型,例如 2N3904,作用是放大紅外線發射訊號,一顆也是 2-5 元。

    元件接法可參考這個網頁,自製紅外線搖控器的硬體配置就這樣而已,材料費才台幣一百多元。至於運作的電源,找條 Micro-USB 線連接 NodeMCU 與帶電的 USB 埠就行了(電腦/充電器/行動電源…)。

    NodeMCU V1.0 電路接法

    687474703a2f2f667269747a696e672e6f72672f6d656469612f667269747a696e672d7265706f2f70726f6a656374732f652f657370383236362d69722d7472616e736d69747465722f696d616765732f49522532305472616e736d69747465725f62622e706e67

    WEMOS D1 mini 的電路接法,其實與 NodeMCU V1.0 相同,但體積更小。

    WEMOS_D1_mini  

    再來是軟體撰寫的階段。倘若真的不會寫程式,那…請自行 Google 市面上已整合 WIFI + 紅外線 + 軟體 APP 的產品:Broadlink RM Pro(市價約 NT 980.-),以及如何把這產品掛上 Homekit 的教學,就可以按上一頁離開本文章了。

    軟體撰寫使用 Arduino IDE + Arduino Code 開發撰寫,加掛以下三方套件,至於程式碼內容就不說明了,套件範例都有。

    • IRremoteESP8266:ESP8266 驅動紅外線的套件。
    • WiFiManager:ESP8266 超級好用的 Wifi 連線套件。
    • <ESP8266mDNS.h>、<ESP8266WebServer.h>:ESP8266 Arduino Code 內建。讓 ESP8266 變成具備 DNS Name 的 WebServer,負責接收 HTTP Request 內容。

    不過一開始我們不知道冷氣的紅外線指令的編碼內容,所以要買一顆紅外線接收器(我是買模組化的這個,理論上可以買更便宜的 LED 型),再用 IRremoteESP8266 提供的標準範例程式寫個 ESP8266 接收紅外線編碼的程式,學習原廠的搖控器就可取得紅外線的編碼內容,存成文字後就可以作為紅外線發射器的資料來源,可參考這篇文章的說明。

    這個部分最終的目標為:在家裡的網路中隨便找一台電腦/平板/手機,打開瀏覽器,輸入網址就能驅動自製的紅外線發射器進行指定的動作,例如輸入 http://esp8266.local/airconditioner/on 就能讓自製遙控器發射「開冷氣」的紅外線編碼,http://esp8266.local/airconditioner/off 讓自製遙控器發射「關冷氣」的紅外線編碼。

    當這個階段完成之後,只要把自製紅外線 WIFI 遙控器擺在冷氣(家電)可接收紅外線訊號的固定位置,就等於可以在家裡用電腦/平板/手機等裝置,用透過家裡的區域網路來控制家裡的冷氣開關,成功之後就可以寫個簡單的 App ,透過按按鈕或其他操作方式,來呼叫網址就行了。例如以下的幾個範例:

    手機端的 Widget 工具:

    IMG_1652

    macOS 電腦端的應用程式:

    2017-08-30-1.19.25

    Windows PC 端的應用程式:

    Image2 Image

    Web 版(將網頁程式上傳到 ESP8266 的 SPIFF 檔案空間)。

    esp8266local

    其實「用裝置遙控 ESP8266 聯網裝置」的動作不一定要透過 HTTP 協定,有太多方式了,例如使用 MQTT 協定搭配國外免費的 Broker 服務,預設就能直接跨越家裡區網的限制,不論人在世界的哪個地方,拿起手機或平板執行 MQTT 客戶端程式,就能控制家裏的 ESP8266 聯網裝置,但也意味別人也有機會駭入你家,所以使用網路 MQTT 服務要非常小心,這部分就不多提了。

    二、連結 iOS Homekit 與自製紅外線WIFI遙控器

    這邊就進入重點了。目前雖然有 ESP8266-Homekit 方案,但似乎並沒有 Arduino Code 的形式,所以要客製化周邊設備有不小的難度。現在看到大部分實作的方式是透過一個叫「homebridge」的服務作為橋接器,由這個橋接器負責周邊設備與 Homekit 的溝通,實作重點在軟體服務的安裝與設定。

    (1) 安裝 homebridge 橋接器服務

    知道上述動作原理之後,實作過程就是找台電腦建立「homebridge 」橋接器,並在橋接器上建立虛擬周邊與包含執行網址的設定(開/關冷氣的動作網址)。網路上大部分的教學是把 homebridge 安裝在「樹莓派(Raspberry Pi)」上,也有少部分教學是安裝在 UbuntumacOS,或 Windows 。每種作業系統安裝 homebridge 方式雖然不太相同,但也是大同小異。

    由於我沒有樹莓派(雖然便宜,但一台也要一兩千元),所以我是採用建立 Ubuntu 14.04 (VirtualBox 虛擬機)的方式,來安裝啟動 homebridge 服務。VirtualBoxUbuntu 作業系統也是免費下載,花費 0 元。與 Ubuntu 系出同門的 Debian 作業系統(正確說法為 Ubuntu 是 Debian 的一項分支),在安裝完 sudo 與 設定 sudoers 之後,也能使用以下相同的方式安裝 homebridge 服務。

    Ubuntu 作業系統開啟終端機視窗,依序執行指令如下:

    1. 執行 sudo apt-get update

    如果出現以下的錯誤訊息:
    E: 無法將 /var/lib/dpkg/lock 鎖定 – open (11: 資源暫時無法取得)
    E: Unable to lock the administration directory (/var/lib/dpkg/), is another process using it?

    可執行以下指令
    sudo rm -rf /var/lib/dpkg/lock

    2. 執行 sudo apt-get upgrade 等一段時間,這邊要等很久,14.04 虛擬機大概會跑10幾分鐘以上,甚至半個多小時。

    如果一下子跑完,又說 xx 未被升級的話,可執行
    apt-get dist-upgrade

    3. 執行以下命令

    sudo apt-get install -y samba screen git
    sudo apt-get install curl
    curl -sL https://deb.nodesource.com/setup_6.x | sudo -E bash –
    sudo apt-get install -y nodejs
    sudo npm install node-gyp
    sudo apt-get install libavahi-compat-libdnssd-dev

    4. 安裝 homebridge
    執行 sudo npm install -g –unsafe-perm homebridge

    不過 Ubuntu 14.04 很可能會遇到以下的錯誤訊息

    nas@nas:~$ sudo npm install -g –unsafe-perm homebridge
    /usr/bin/homebridge -> /usr/lib/node_modules/homebridge/bin/homebridge

    > mdns@2.3.3 install /usr/lib/node_modules/homebridge/node_modules/mdns
    > node-gyp rebuild

    make: Entering directory `/usr/lib/node_modules/homebridge/node_modules/mdns/build’
    CXX(target) Release/obj.target/dns_sd_bindings/src/dns_sd.o
    make: g++: Command not found
    make: *** [Release/obj.target/dns_sd_bindings/src/dns_sd.o] Error 127
    make: Leaving directory `/usr/lib/node_modules/homebridge/node_modules/mdns/build’
    gyp ERR! build error
    gyp ERR! stack Error: `make` failed with exit code: 2

     

    可執行以下五行指令修正問題

    sudo rm -rf /usr/lib/node_modules/
    sudo apt-get install build-essential
    sudo apt-get install libkrb5-dev
    sudo apt-get remove nodejs
    sudo apt-get install nodejs

    之後再執行一次  sudo npm install -g –unsafe-perm homebridge 試試看。

    5. 測試 homebridge
    輸入homebridge

    回應
    ……
    Scan this code with your HomeKit App on your iOS device to pair with Homebridge:

    ┌────────────┐
    │ 031-45-154 │
    └────────────┘

    [2017-08-02 16:12:05] Homebridge is running on port 43761.

    如果出現反白配對碼「 XXX-XX-XXX」的訊息,表示 homebridge 安裝完成。

    螢幕快照 2017-08-05 上午12.51.04

    這時候就可以打開 iOS 10 手機的「家庭 App」了,一路循指示開啟 iCloud 的「家庭」權限–>新增配件,就能看到有個叫「Homebridge」的裝置顯示在清單上。

    IMG_1602

    不過這個時候先別急著設定,因為橋接器還沒有掛上虛擬周邊可供選取。先按「取消」離開,回到 Ubuntu 電腦進行操作。

    (2) 安裝 homebridge 插件

    homebridge 插件的目的,就是建立虛擬周邊設備掛進 homebridge 橋接器服務,並設定虛擬周邊的動作指令。有上百種插件任君挑選,每一種插件都有不同的週邊設備作用方式。要選哪個插件可以到這裡搜尋

    homebridge-plugin

    插件的功能可說是玲瑯滿目,坦白說要搞懂插件的運作與設定方式實在不容易,因為每一種的作用與目的都不同,甚至超出「周邊家電」的既定印象。例如這個「homebridge-openweathermap-temperature」插件,就是模擬一個溫度計周邊,用來顯示 OpenWeather 天氣服務網站的某指定城市現在氣溫。

    先用這個插件為例,安裝的方式為:

    A. 開啟終端機,執行命令 sudo npm install -g homebridge-openweathermap-temperature

    B. 在 ~/.homebridge/ 建立(或修改)config.json,文字內容如下:

    {
    "bridge": {
    "name": "控制中心",
    "username": "AB:CD:EF:12:34:56",
    "port": 51826,
    "pin": "123-45-678"
    },
    "description": "HomeBridge HTTP Status Control",
    "accessories": [
    {
    "accessory": "OpenweathermapTemperature",
    "name": "台南市溫度",
    "url": "http://api.openweathermap.org/data/2.5/weather?q=Tainan&appid=[apikey需註冊OpenWeather帳號取得]"
    }
    ]
    }

    config_json

    C.終端機執行 homebridge 指令

    螢幕快照 2017-08-05 上午2.00.46

    看到 Load x accessories… 以及配對的 XXX-XX-XX 訊息時,就表示 homebridge 和配件都成功掛載啟動了。

    若要讓 homebridge 於每次 Ubuntu 開機時自動執行,請參考這裡

    D. 回到 iOS 10 的「家庭 App」,依照畫面指示設定就行了。

    IMG_1603

    最後就能在「家庭 App」看到一個配件,內容顯示 OpenWeather 查詢的城市溫度。

    也可以呼叫 Siri 用講的給你聽。不過因為是「家庭周邊配件」,問 Siri 的時候要問「家裏溫度」才會顯示配件數字,若是只問「溫度」或「室外溫度」,它就會找 iOS 內建的天氣預報服務,而不是 Homekit 。

    IMG_1609  

    搞懂如何掛載插件的方法後,接著就可以選擇適合的插件,透過 HTTP 網址來執行冷氣的開關動作了。我找到符合有「開」與「關」對應動作網址的插件是「homebridge-http

    sudo npm install -g homebridge-http

    接著編輯 config.json 內容,在「”accessories”」節點內插入以下內容:

    {
    "accessory": "Http",
    "name": "冷氣",
    "switchHandling": "realtime",
    "http_method": "GET",
    "on_url": "http://[開冷氣的網址]",
    "off_url": "http://[關冷氣的網址]",
    "status_on": "ON",
    "status_off": "OFF",
    "service": "Switch",
    "sendimmediately": "",
    "username": "",
    "password": ""
    }

    螢幕快照 2017-08-05 上午2.52.02

    重新執行 homebridge 之後,「家庭 App」就可以看到兩個配件按鈕。可以點擊冷氣配件按鈕進行開或關的動作。

    IMG_1613

    不過這個插件遇到網路問題時會發生找不到 callback 函數的 BUG 而跳出,修正方式: 

    /usr/lib/node_modules/homebridge-http/index.js
    從第 11 行加入
        function callback(error){
            if(error){
                console.log('HTTP function failed: %s', error.message);
            }
            else{
                console.log('HTTP function done with No Error...');
            }
        }
    

    插件可以一直加掛進 homebridge 橋接器內,例如再繼續加掛「homebridge-httptemperaturehumidity」就可以透過 HTTP 協定取得家裏的 ESP8266+DHT22 溫濕度數值,並透過 Siri 語音控制這些周邊。

    IMG_1598

    sudo npm install -g homebridge-http-temperature-humidity

    這個插件也有類似的問題,修正方式: 

    1. 修改 /usr/lib/node_modules/homebridge-http-temperature-humidity/index.js
    在 var res = request(this.http_method, this.url,{}); 與 if(res.statusCode > 400){ 之間加入
    var res = request(this.http_method, this.url,{});
    if (typeof res === 'undefined'){
    this.log('HTTP power function NOT succeeded : undefined');
    this.temperature = -1;
    this.humidity = -1;
    callback(null, this.temperature);
    }
    else if(res.statusCode > 400){

     

    2. 修改 /usr/lib/node_modules/homebridge-http-temperature-humidity/node_modules/sync-request/index.js ,目的是修正可能因網路問題造成 Javascript 程式錯誤或 JSON.parse 方法卡死的現象,修改內容重點在「標記 throw error 方法」與「增加 resErr 變數」的判斷,才不至於讓錯誤結果誤進 JSON 解析程序產生其他問題。

    'use strict';
    var fs = require('fs');
    var spawnSync = require('child_process').spawnSync || require('spawn-sync');
    var HttpResponse = require('http-response-object');
    require('concat-stream');
    require('then-request');
    var JSON = require('./lib/json-buffer');
    Function('', fs.readFileSync(require.resolve('./lib/worker.js'), 'utf8'));
    module.exports = doRequest;
    function doRequest(method, url, options) {
    var req = JSON.stringify({
    method: method,
    url: url,
    options: options
    });
    var res = spawnSync(process.execPath, [require.resolve('./lib/worker.js')], {input: req});
    var resErr = 0;
    if (res.status !== 0) {
    console.log('doRequest res.stderr.toString: %s',res.stderr.toString());
    resErr = 1;
    //throw new Error(res.stderr.toString());
    }
    if (res.error) {
    if (typeof res.error === 'string') res.error = new Error(res.error);
    console.log('doRequest res.error === string ');
    resErr = 1;
    //throw res.error;
    }
    if (resErr === 0){
    var response = JSON.parse(res.stdout);
    if (typeof response === 'undefined'){
    console.log('httptemperaturehumidity: response JSON is undefined');
    }
    else if (response.success) {
    return new HttpResponse(response.response.statusCode, response.response.headers, response.response.body, response.response.url);
    } else {
    console.log('response not success: %s',response.error.message);
    //throw new Error(response.error.message || response.error || response);
    }
    }
    }

    若是 iPhone 6s 以後的設備(支援免插電源線呼叫 Siri),或是家裡擺一台 Homepod ,就能實現完全不需動手,回到家出一張嘴喊個 Siri 就行了,敲方便。

    實際運作影片

    成本總結:

    • NodeMCU x 1 : NT 120.-
    • 紅外線 LED / NPN 電晶體 x1 : 10元 有找

    其他必備條件:

    • Micro USB 連接線
    • 個人電腦一台(撰寫 Arduino Code ,建置 Homebridge 環境)
    • 行動電源 或 USB 充電器 或 電腦的 USB 連接埠(可提供 5V USB 連接埠)
    • iPhone 手機一支或 iPad(需支援 iOS 10,最低要求為 iPhone 5 / iPad 4th / iPad min)
    • 家裡區域網路,與可連上 iCloud 的環境。

    補充:

    1. 電腦啟動時執行 homebridge(適用於樹莓派)

    終端機中執行

    $ sudo nano /etc/xdg/autostart/homebridge.desktop

    填入以下內容:

    [Desktop Entry]
    Name=homebridge
    Type=Application
    Exec=lxterminal -e “homebridge”
    Terminal=true
    Comment=system monitoring tool.
    Categories=Utility;

    按 Ctrl + X 存擋離開。

    2. 樹莓派升級到 Buster 版本後,nodejs 被強制升級到 10 版,npm 不會隨 nodejs 安裝。用 apt 安裝 npm 的版本是 5.x ,必須升級到 npm 6.x 才能支援 nodejs 10 。

    $ sudo apt install npm
    $ sudo npm install -g npm@6

    3. homebridge 指定網卡服務

    以樹莓派 3B/+/4 為例:樹莓派主機上有無線網路和有線網路,homebridge 只能在其中一個網路上啟動。若希望強制在指定的網卡上啟用服務時,必須在 config.json 內指定 mdns 參數,如下

    {
    "mdns":{ "interface": "網路卡的 IP 位址,例如 192.168.1.100" },
    "bridge": {
    ... 省略...
    },
    }
    

    4. 其他可用插件

    4.1 homebridge-http-temperature-sensor (網址)

    功能說明:透過網址取得溫度數字。

    安裝:
    sudo npm install -g homebridge-http-temperature-sensor

    config.json 範例

        {
    "accessory": "HTTP-TEMPERATURE",
    "name": "裝置溫度",
    "unit": "celsius",
    "getUrl": "API 網址",
    "pullInterval": 5000
    }
    

    API 網址回應:溫度浮點數

    應用:樹莓派的溫度(讀取 /sys/class/thermal/thermal_zone0/temp 內容並轉換為網址服務)。

     

    4 Comments

    1. 感謝分享,已如法炮製一個電視版出來,只是家中冷氣紅外線編碼不同,尚在努力中~
      版主回覆:(09/03/2017 12:10:39 AM)
      感謝回覆~我在考慮要不要弄一台樹莓派3,因為我把ubuntu虛擬機裝在Surface Pro的Win10內,會發生 homebridge 跑幾個小時後不明原因停止。

    2. 如果是Hyper-v的話,建議換VMware看看,還有我Homebridge是架在16.04上,目前是還沒有中斷服務過,只是NodeMCU的效能真的差了點,紅外線Data多的話就會整張板子死當XD,我也考慮要升級板子了
      版主回覆:(09/04/2017 05:13:50 PM)
      原本用的是 VMWare 會發生 homebridge 服務中斷的問題(虛擬機看似運行正常),後來我換成 VirtualBox 就解決了… 照理說 VMWare 應該會比較穩定才對,不知原因為何,。
      NodeMCU 使用的 ESP8266 常出現很多異常狀況,不過文章的自製WIFI紅外線方案倒是沒遇過怪事,運作好幾個月了。之前開發時遇過一個狀況,紅外線搭配的 IRremote 套件在某幾個 GPIO 很不穩定,發射頭溫度會熱熱的,也容易當機。現在紅外線接在 D5 腳就很穩定正常了,參考試試看囉~

    3. 實在是有困難!要怎麼連線到NodeMCU V1.0?如何安裝驅動程式?可否在講解清楚一點?或是介紹入門的教學網站。感激不盡!
      版主回覆:(12/07/2017 05:29:58 PM)
      利用 Arduino IDE 開發 NodeMCU 的正統官方教學
      https://github.com/esp8266/Arduino
      NodeMCU V1.0 使用 CP2102 晶片與電腦溝通(透過 USB 連線),所以要自行下載 CP2102 的驅動。
      坦白說要「從零到 NodeMCU」有一小段路要走(不會很長),
      我這篇教學是適合「已知如何使用 Arduino IDE + NodeMCU 開發」的用戶

    4. BEN您好:
      我對Arduino IDE + NodeMCU還是感到陌生!我現在只學會如何學習原廠的搖控器就可取得紅外線的編碼內容 ,至於之後要如何發射,如何利用WIFI和HTTP我實在是求助無門!可否分享你NodeMCU的Arduino IDE程式讓我參考?感激不盡!
      版主回覆:(01/05/2018 01:17:02 AM)
      我個人使用的程式比較複雜,所以從文章裡提到的套件範例拚拚湊湊,弄了一段比較簡單的程式碼如下:
      /* HTTP 網址控制紅外線,範例為發射 NEC 格式的紅外線編碼,對應 20 個按鈕
      *
      * http://esp8266Wifi.local/irremote?ButtonIndex=號碼(0~19)
      * 例如:
      * http://esp8266Wifi.local/irremote?ButtonIndex=0
      * 則發射 0x1FEFA05
      * ButtonIndex=1 則發射 0x1FE30CF
      * NEC編碼內容( 0xXXXXXXX ) 則透過學習原廠遙控器取得
      */
      #include <ESP8266WiFi.h>
      #include <DNSServer.h>
      #include <ESP8266WebServer.h>
      #include <WiFiManager.h>
      #include <ESP8266mDNS.h>
      //IrRemoteESP8266
      #include <IRsend.h>
      //WiFiManager
      char projName[12] = "esp8266Wifi";
      char wifiPassword[11] = "123456789";
      //WebServer
      ESP8266WebServer beWebserver(80);
      void serverSend(int num, char * datatype, String msg);
      void BeWebServer_HandleRoot();
      void BeWebServer_HandleIrRemote();
      void BeWebServer_HandleNotFound();
      //紅外線
      //紅外線發射器接在 NodeMCU 的 D5 腳位,ESP01 模組是 3 號腳位
      #if defined (ARDUINO_ESP8266_ESP01)
      const int IRSENT_PIN = 3; //ESP-01 : 3
      #else
      const int IRSENT_PIN = D2; //NodeMCU : D2
      #endif
      IRsend irsend(IRSENT_PIN);
      //紅外線按鈕對應
      unsigned long irRemoteButtons[20] = {0x1FEFA05, 0x1FE30CF, 0x1FED02F, 0x1FE6897, 0x1FE10EF,
      0x1FEE21D, 0x1FED22D, 0x1FEA05F, 0x1FE906F, 0x1FE926D,
      0x1FEA857, 0x1FE32CD, 0x1FEC837, 0x1FE28D7, 0x1FE807F,
      0x1FE20DF , 0x1FE00FF , 0x1FE8877 , 0x1FE48B7, 0x1FE08F7
      };
      void IRRemote_PressButtonIndex(int btnIndex);
      //底下為主程式
      void setup() {
      // 連線
      // put your setup code here, to run once:
      Serial.begin(115200);
      WiFiManager wifiManager;
      if (!wifiManager.autoConnect(projName, wifiPassword)) {
      //Serial.println("failed to connect and hit timeout");
      //reset and try again, or maybe put it to deep sleep
      ESP.reset();
      delay(1000);
      }
      //啟用 mDNS 服務
      if (!MDNS.begin(projName)) {
      ESP.reset();
      }
      //啟用 WebServer
      beWebserver.close();
      beWebserver.stop();
      beWebserver.on("/", BeWebServer_HandleRoot);
      beWebserver.on("/irremote", BeWebServer_HandleIrRemote);
      beWebserver.onNotFound(BeWebServer_HandleNotFound);
      // Add service to MDNS-SD
      MDNS.addService("http", "tcp", 80);
      beWebserver.begin();
      }
      void loop() {
      // put your main code here, to run repeatedly:
      if (WiFi.status() == WL_CONNECTED) {
      beWebserver.handleClient();
      }
      }
      /* 運作 Function */
      //WebServer Function
      void BeWebServer_HandleRoot() {
      serverSend(200, "text/json", " {\"Message\" : \"ESP8266 IrRemote is Working!\"} ");
      }
      void BeWebServer_HandleIrRemote() {
      boolean isSuccess = false;
      for (uint8_t i = 0; i < beWebserver.args(); i++) {
      if (beWebserver.argName(i) == "ButtonIndex") {
      int btnIndex = beWebserver.arg(i).toInt();
      IRRemote_PressButtonIndex(btnIndex);
      isSuccess = true;
      break;
      }
      }
      if (!isSuccess) {
      serverSend(200, "text/json", " {\"error\" : 500, \"ErrorMessage\" : \"IrRemote Error !\"} ");
      }
      else {
      serverSend(200, "text/json", " {\"error\" : 0, \"ErrorMessage\" : \"IrRemote Success!\"} ");
      }
      }
      void BeWebServer_HandleNotFound() {
      char urlPath[64];
      sprintf(urlPath, "/%s", beWebserver.uri().c_str());
      Serial.println(urlPath);
      Serial.print("handleNotFound ");
      String message = "Path has no definition\n\n";
      message += "URI: ";
      message += beWebserver.uri();
      message += "\nMethod: ";
      message += (beWebserver.method() == HTTP_GET) ? "GET" : "POST";
      message += "\nArguments: ";
      message += beWebserver.args();
      message += "\n";
      for (uint8_t i = 0; i < beWebserver.args(); i++) {
      message += " " + beWebserver.argName(i) + ": " + beWebserver.arg(i) + "\n";
      }
      serverSend(404, "text/plain", message);
      }
      void serverSend(int num, char * datatype, String msg) {
      beWebserver.send(num, datatype, msg + "\r\n");
      }
      //紅外線
      void IRRemote_PressButtonIndex(int btnIndex) {
      int khz = 38; // 38kHz carrier frequency for the NEC protocol
      irsend.sendNEC(irRemoteButtons[btnIndex], 32);
      }

    發佈回覆給「綜翰」的留言 取消回覆

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