超圖解物聯網IoT實作入門:使用JavaScript/Node.JS/Arduino/Raspberry Pi/ESP8266/Espruino

書名很長,以下簡稱《超圖解物聯網IoT實作入門》

封面的控制板和3C裝置圖案,刻意以黑白灰階方式呈現,傳達軟體的重要性,若沒有軟體驅動,這些高科技裝置宛如沒有靈魂的軀殼;背景採用和JavaScript標誌相同的黃色系。

《超圖解 Arduino 互動設計入門》序言中的「序」字,繪製成印刷電路板風格;本書強調的是裝置之間的連結,因此「序」字也做出對應的改變。

內容簡介

本書是《超圖解 Arduino 互動設計入門》的姊妹作,強調串聯網路軟體和微電腦控制板, 以 JavaScript 為主軸,開發網路應用程式、手機 App、互動網頁、資料庫程式和操控微電腦。書中包含網頁式遠端遙控 LED 燈、即時溫濕度 、保全自動感測拍照蒐證、網頁式遠端 LED 繪圖板、即時影像監控 、影像辨識擺頭控制攝影機雲台、雲端溫濕度監控、即時資訊動態圖表、藍牙機器人遙控手機 App 等多元範例(感謝本書編輯黃昕暐先生提供文案)。

本書特色

  • 統括物聯網應用開發的全面技術
  • 前端 JavaScript 到後端 Node.JS 實踐物聯網創意
  • 結合 Arduino、Raspberry Pi 實作物聯網感測控制節點
  • 詳述 C/P 值最高的 ESP8266 Wi-Fi 模組
  • 活用 Apache Cordova 開發跨平台物聯網行動 App
  • 使用 JavaScript 即可駕馭的 Espruino 嵌入式控制板
  • 採用 MongoDB 建構後端資料庫
  • 利用 D3.js / C3.js 打造資訊圖表
  • 連結 IFTTT 串連各項雲端服務

《超圖解物聯網 IoT 實作入門》目錄

各章節導讀,請參閱「新書預告:《超圖解物聯網IoT實作入門 使用JavaScript/Node.JS/Arduino/Raspberry Pi/ESP8266/Espruino》」這篇貼文。

第0章 無所不在的 JavaScript 與物聯網裝置

  • JavaScript 與物聯網
  • MPU、MCU與SoC介紹
  • 章節導讀

第1章 JavaScript 入門

  • JavaScript 入門
  • JavaScript 語言基礎
  • 函式定義
  • 定時產生隨機數字
  • Array(陣列)物件
  • 認識 Object(物件)類型
  • BOM(瀏覽器物件模型)與 DOM(文件物件模型
  • 動手做 操作網頁物件
  • 在網頁中嵌入 JavaScript
  • 事件處理程式

第2章 認識 jQuery 程式庫

  • jQuery 簡介
  • jQuery 語法基礎
  • AJAX 技術:動態更新 HTML 內容
  • 動手做 從 Arduino 輸出純文字溫度
  • 網頁訊息交換格式
  • Arduino 輸出 JSON 訊息
  • 調整燈光亮度的網頁介面
  • 動手做 接收調光值的 Arduino 網站程式
  • 動手做 製作滑桿介面網頁
  • AJAX 的安全限制

第3章 Node.js 入門

  • 在電腦以及樹莓派安裝 Node.js
  • Node 程式設計起步
  • 使用 http 模組建立網站伺服器程式
  • 事件驅動、非阻塞 I/O 示範:讀取檔案
  • global(全域)物件與模組檔案
  • 安裝與管理模組:使用 npm 工具程式
  • 使用 Express 框架開發網站應用程式
  • 使用 package.json 管理 Node 專案的模組程式
  • 動手做 從 Arduino 傳遞溫溼度值 給 Node 網站
  • 動手做 讓 Arduino 定時上傳 DHT11 資料
  • 使用 JSONP 格式跨網域存取資訊

第4章 Node.js 序列埠通訊與樹莓派 GPIO 控制

  • 安裝編譯 Node 模組所需的軟體
  • 動手做 Node.js 序列埠通訊
  • 動手做 從 Node.js 傳送序列資料
  • 透過 Node.js 執行系統指令
  • 樹莓派的 GPIO 簡介
  • 動手做 GPIO 輸出入訊號練習:按開關閃爍 LED
  • 動手做 透過紅外線感測模組拍攝照片
  • 樹莓派 GPIO 整合 Arduino 控制板
  • 5V 和 3.3V 電壓準位轉換

第5章 使用霹靂五號操控 Arduino

  • 霹靂五號:用 JavaScript 控制 Arduino
  • 動手做 用霹靂五號指揮 Arduino 閃爍 LED
  • 動手做 啟用上拉電阻並讀取開關訊號
  • 動手做 類比輸入與 PWM 輸出程式實驗
  • 動手做 檢測溫度
  • 動手做 控制伺服馬達
  • 動手做 控制 LED 矩陣顯示圖像
  • 使用 Socket.io 建立即時連線
  • 動手做 建立即時通訊程式
  • 動手做 瀏覽器與矩陣 LED 作畫

第6章 電子郵件、串流視訊、電腦視覺與操控伺服馬達

  • 透過 Node 傳送電子郵件
  • 動手做 雲端蒐證 / 拍照自動寄送 e-mail
  • 動手做 串流視訊 / 推播即時影像
  • 使用 MJPG 壓縮與串流視訊
  • 控制伺服馬達雲台
  • 動手做 使用方向鍵操控伺服馬達雲台
  • 動手做 攝影機雲台的 Node 伺服器程式碼
  • 使用觸控螢幕虛擬搖桿操控攝影機雲台
  • 瀏覽器連接遊戲控制器(電玩把手)
  • 動手做 使用 gamepad.js 程式庫建立遊戲器操作的網頁程式
  • 機器視覺(computer vision)應用
  • 使用 tracking.js 偵測人臉
  • 動手做 臉孔偵測與伺服馬達連動
  • 動手做 偵測顏色

第7章 Espruino 控制板簡介

  • Espruino 程式開發軟體
  • Espruino 的基本硬體操作指令
  • 動手做 使用光敏電阻製作小夜燈
  • 動手做 呼吸燈效果
  • 動手做 超音波控制燈光亮度
  • Espruino 的睡眠模式
  • 動手做 深層睡眠實驗
  • 動手做 藍牙控制 LED
  • 動手做 藍牙遙控車(馬達控制)
  • 動手做 利用 SD 記憶卡紀錄溫濕度變化
  • 動手做 控制伺服馬達
  • STM32 微控器相容板
  • 動手做 替 STM32 控制板燒錄 Espruino 韌體

第8章 使用 MongoDB 資料庫以及ejs 樣版引擎建立動態網頁

  • 資料庫簡介
  • 安裝 MongoDB
  • MongoDB 的基本操作
  • 查詢資料
  • 更新與刪除資料
  • 使用 mongoose 套件連結 MongoDB 資料庫
  • 連結 MongoDB 並讀取資料的程式
  • 動手做 儲存 Arduino 上傳的溫溼資料
  • 認識樣版引擎
  • 動手做 在 ejs 樣版中顯示最近 10 筆溫濕度資料
  • 動手做 分頁顯示資料

第9章 資料視覺化:使用 C3.js 與D3.js 繪製圖表

  • 使用 C3.js 繪製圖表
  • 顯示動態平移的即時線條圖
  • 動手做 使用資料庫數據描繪折線
  • 動態顯示 Arduino 檢測類比值
  • 動手做 使用圖表動態顯示感測器數據
  • 簡易數位濾波
  • 使用 D3 程式庫
  • 認識 SVG
  • 使用 D3 繪製 SVG 圖像
  • 使用動態資料繪製折線圖
  • 結合數據動態附加 HTML 元素

第10章 使用 Cordova 開發行動裝置 APP

  • 認識 Cordova
  • 設置 Cordova 的 Android 開發環境
  • 下載與設置 Android SDK
  • 安裝 Cordova 工具程式和 Ant
  • 使用 Cordova 建立手機 App
  • 啟用 Android 手機的 USB Debug 功能
  • Cordova 網頁的基本程式架構
  • jQuery Mobile 框架入門
  • 動手做 手機 App 網路控制 Arduino

第11章 製作藍牙手機遙控 App

  • 製作藍牙遙控 LED 燈 App
  • 動手做 Arduino 端的藍牙 LED 開關程式
  • 作藍牙機器昆蟲遙控 App
  • 動手做 手機體感(加速度感測器)控制伺服馬達
  • 動手做 透過手機 USB 介面連接 Arduino 板
  • 透過返回(Back)鍵關閉 App

第12章 ESP8266 物聯網應用入門(一)

  • ESP8266 模組簡介
  • NodeMCU 開發版簡介
  • 使用 AT 指令操作通用型 ESP 模組(ESP-01)
  • 動手做 透過 Arduino 執行 ESP8266 的 AT 命令
  • Wi-Fi 無線網路簡介
  • 動手做 透過 ESP-01 的 AT 命令建立 HTTP 伺服器
  • 使用 Arduino 開發 ESP8266 程式
  • 使用 ESP8266WiFi 程式庫連接無線網路
  • 使用 ESP8266WebServer 程式庫建立 HTTP 伺服器
  • 動手做 處理 GET 或 POST 請求
  • 讓 NodeMCU 扮演網路前端上傳資料(IFTTT)

第13章 ESP8266 物聯網實作(二)

  • 設置區域網路域名
  • 動手做 使用 ESP-01 模組開發 Arduino 物聯網
  • 透過 OTA 更新 ESP8266 的韌體
  • 使用 OLED 顯示器呈現 IP 位址和溫濕度值
  • 動手做 在 OLED 顯示 IP 位址與動態溫濕度
  • 使用 JavaScript 程式開發 ESP8266 程式
  • 使用 Espruino 的 Wifi 程式庫
  • 觸發執行 IFTTT 網路程式
Posts created 469

370 thoughts on “超圖解物聯網IoT實作入門:使用JavaScript/Node.JS/Arduino/Raspberry Pi/ESP8266/Espruino

  1. 請教老師:
    第13-3節中使用NodeMCU搭配OLED及DHT11中的範例,實作完成後可正常運作,但卻也發現,nodeMCU在接上電源後,有時會出現無法正常開機現象.如OLED似乎沒過電的情形,但我感覺應該是NodeMCU OS沒正常開機,只好拔離USB電源從新再插一次才可以正常運作.我試過更換零件及nodeMCU,似乎這樣的組合都會有類似的情況發生,是否是電源供應不足所造成的呢.我也試過使用外接的直流電源模塊來供電但仍無法有效解決這個問題.
    謝謝

    1. 我在實驗時並沒有出現類似的情況,因為0.96吋OLED顯示器的消耗電流僅約20mA~30mA,不至於造成電流不足… 如果用外接電源,OLED的電源可以接5V。

      thanks,
      jeffrey

    2. 謝謝老師回答.
      另一問題是腳位不夠用的問題.
      當NodeMCU1.0 ( D0~D8 ) 腳位都用完了.
      是否還可使用那些腳位來接其他傳感器.
      如果有我該如何去使用它.

  2. 其實我是先在raspberry rev.b 上試的,以下為資訊(raspberry pi, 2)
    npm: 3.7.3
    node: 5.8.0

    npm install johnny-five

    > serialport@1.7.4 install /home/pi/ch5/five/node_modules/serialport
    > node-pre-gyp install –fallback-to-build

    make: Entering directory ‘/home/pi/ch5/five/node_modules/serialport/build’
    CXX(target) Release/obj.target/serialport/src/serialport.o
    In file included from ../src/serialport.h:5:0,
    from ../src/serialport.cpp:3:
    ../../nan/nan.h:261:25: error: redefinition of ‘template v8::Local _NanEnsureLocal(v8::Local)’
    NAN_INLINE v8::Local _NanEnsureLocal(v8::Local val) {
    ^
    ../../nan/nan.h:256:25: note: ‘template v8::Local _NanEnsureLocal(v8::Handle)’ previously declared here
    NAN_INLINE v8::Local _NanEnsureLocal(v8::Handle val) {
    ^
    :

    1. 我剛剛在Raspberry Pi 2的一個未曾安裝過Johnny-Five的系統上,測試安裝成功。
      原本系統內建的Node.js是0.10.x版本,升級到5.12.0版。
      我的安裝步驟如下:

      1. 首先升級系統軟體:
      $ sudo apt update
      $ sudo apt full-upgrade

      2. 取得Node 5.x版本:
      $ curl -sL https://deb.nodesource.com/setup_5.x | sudo -E bash –

      3. 安裝Node.js:
      $ sudo apt install nodejs

      4. 安裝Johnny-Five:
      $ npm install johnny-five

      在安裝Johnny-Five過程中,取得serialport程式庫出現錯誤,但是安裝程式會自動重新編譯。
      最後測試連接在USB埠的Arduino UNO(連接埠名稱是”/dev/ttyACM0″),測試成功。

      thanks,
      jeffrey

  3. 謝謝回答
    1. $ curl -sL https://deb.nodesource.com/setup_5.x | sudo -E bash –
    版本沒變還是5.8.0
    2. node blink.js 還是不行,請看 ( var board = new five.Board({ port: “/dev/ttyACM0” });)

    pi@raspberrypi:~/ch5/five $ ls
    basicInput.js LM35_2.js node_modules pot2.js servo.js wait.js
    blink2.js LM35.js package.json replLED2.js sw.js 檔案說明.txt
    blink.js matrix.js pot1.js replLED.js test.js
    pi@raspberrypi:~/ch5/five $ node blink.js
    module.js:341
    throw err;
    ^

    Error: Cannot find module ‘firmata’
    at Function.Module._resolveFilename (module.js:339:15)
    at Function.Module._load (module.js:290:25)
    at Module.require (module.js:367:17)
    at require (internal/module.js:16:19)
    at Board.Serial.connect (/home/pi/ch5/five/node_modules/johnny-five/lib/board.js:142:7)
    at new Board (/home/pi/ch5/five/node_modules/johnny-five/lib/board.js:324:24)
    at Object. (/home/pi/ch5/five/blink.js:4:14)
    at Module._compile (module.js:413:34)
    at Object.Module._extensions..js (module.js:422:10)
    at Module.load (module.js:357:32)

    1. 今天也碰到這個問題搞了一個上午,看來是npm套件管理程式的問題,可以試試看安裝yarn來下載Johnny-five。
      可以參考下面這篇文章,從yarn的部份開始照著做就可以,不需要init因為project.json檔案已經存在,直接add就可以。

    2. 我從超圖解arduino互動設計第一版就開始讀老師的作品,獲益良多,非常感謝老師

  4. 老師您好:

    想請問您一下目前我是照著Arduino due 的 schematic( Due-schematic ) 去自製自己的 Due Board
    目前的情況是燒錄沒問題,但是IC完全不會做我程式應要有的動作,就像是有燒錄成功,但是沒有燒進去的感覺

    “燒錄時”
    從usb port到 Atmel-16U2 量的到TX RX 訊號,16u2外接的 TX RX (16U2 ->pin 10 ,11 )的燈號也有亮,而從16U2到SAM3X的 TX RX 也有燒錄訊號的波型進入,且最後會顯示燒錄成功

    我燒了一個閃爍的程式做測試, 但在量測Pin68 (Digital 13) 腳位時 ,電位不會改變

    我又再燒錄了一個一直回傳值的程式進去,但SAM3X TX端點完全沒有訊號出來到USB PORT

    一開始想說會不會是我的IC壞掉了,我又再更換了一個IC做測試,結果是一樣的

    但能夠編譯燒錄成功,不就是代表說16U2能夠正常跟SAM3X 做交涉嗎?

    不知道是哪裡出狀況了

    有什麼其他資訊需要附上在煩請告知 感謝

    1. Wow~我未曾想過DIY一塊Arduino Due控制板…拍謝,我不清楚原因。

      have fun!
      jeffrey

  5. 請問第13章ESP-01 使用jQuery UI 程式庫連結,
    如果IP 分享器沒有連上網路,
    就會無法下載jQuery UI 介面就會出現無法送出資料 問題.
    我先載到電腦,
    改路徑為js/jquer-xxx.min.js,
    好像也不行.

    1. 在網頁裡面指定這樣的路徑:js/jquer-xxx.min.js,代表讀取和HTML檔所在相同路徑裡的js資料夾當中的jquer-xxx.min.js檔。

      你把.js檔放在電腦上,和ESP8266裡面的HTML是完全不相干的儲存路徑。如果你的IP分享器沒有連上網路,你必須將.js檔存入ESP8266的快閃記憶體。請參閱這三篇補充文章說明:

      在ESP8266的SPIFFS檔案系統存放網頁檔案(一)

      在ESP8266的SPIFFS檔案系統存放網頁檔案(二)

      在ESP8266的SPIFFS檔案系統存放網頁檔案(三):Wi-Fi無線網路燈光控制與調光器

      thanks,
      jeffrey

    1. 简体中文板由「电子工业出版社」发行,书名叫做《完美图解物联网IoT实操》,不过,简体版分成两册,这一本是包含八个章节的第一册。

      thanks,
      jeffrey

  6. 老師這本書還會再改版嗎?
    然後請問 網路有再販賣 “《超圖解物聯網IoT實作入門》實驗包(完整) ”
    價格2800元,裡面是包含書跟所有課程所需要用到的零件嗎?
    謝謝老師!

    1. 目前沒有改版的計畫,但是這個網站已經提供數個不同主題系列的補充文件。

      如果你指的實驗包是「台灣樹莓派」的零件包的話,該公司的負責人sosorry有送我一套,裡面包含所有實驗零件,但是不包含微控制板(Arduino, ESP8266, Espruino和Raspberry Pi)喔~

      thanks,
      jeffrey

  7. 老師您好,

    請問要裝mongodb 3.x 版之前要不要先把2.1.1版拆掉?

    謝謝!

    Paul Tsai / Taipei

    1. 我安裝MongoDB時就是3.x版,所以沒想過這個問題,但根據簡體中文版的「将MongoDB升级到3.0」說明,直接覆蓋應用程式檔案即可,不過要留意內文提到的相關事項。

      thanks,
      jeffrey

  8. 謝謝老師! 看起來前面的要清乾淨,而且要清得很乾淨。我昨晚一直弄到現在才好不容易把新的裝好了(3.0.14)。失敗N次,幾乎想把OS也重作了。

  9. 老師您好,我照著您書中Ch5中關於johnny-five的敘述執行但是第一個範例blink無法執行(執行的電腦是win10系統),不知道是否為版本的問題呢?
    我安裝的node.js版本為8.9.4(x64) 使用的是CH340的mega2560板子,執行光碟中的blink.js時出現以下的敘述:
    1519900760793 Device(s) COM3
    It looks like serialport didn’t compile properly. This is a common problem and its fix is well documented here https://github.com/voodootikigod/node-serialport#to-install
    (node:11036) UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 2): Missing serialport dependency

    (node:11036) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.

    不知道能不能向老師詢問,謝謝老師!!

    1. 剛剛在Windows 10上安裝Node.js 8.9.4版,並安裝6.1.1版serialport模組(直接執行 npm install serialport ),安裝過程沒發生異狀。
      根據serialport專案頁面的說明,它支援node v4.x~8.x版。這是測試序列埠通的程式碼:

      var comPort = require("serialport");
      var serialPort = new comPort('COM3');
      
      serialPort.on("open", function(){
          console.log('序列埠已開通!');
      
          serialPort.on("data", function(d){
              console.log("data: " + d);
          })
      })
      

      thanks,
      jeffrey

  10. 老師您好,謝謝您的解答,我直接執行npm install serialport (和johnny-five,keypress,serialport-win-fix)但在安裝過程中都出現下列ERR項目,不知道該如何解決呢?再麻煩老師了,謝謝您
    node-pre-gyp ERR! UNCAUGHT EXCEPTION
    node-pre-gyp ERR! stack Error: Cannot find module ‘internal/util/types’
    node-pre-gyp ERR! stack at Function.Module._resolveFilename (module.js:538:15)
    node-pre-gyp ERR! stack at Function.Module._load (module.js:468:25)
    node-pre-gyp ERR! stack at Module.require (module.js:587:17)
    node-pre-gyp ERR! stack at require (internal/module.js:11:18)
    node-pre-gyp ERR! stack at evalmachine.:31:26
    node-pre-gyp ERR! stack at Object. (D:\IoT Book\Chapt example\ch5\five\node_modules\firmata\node_modules\serialport\node_modules\node-pre-gyp\node_modules\tar\node_modules\fstream\node_modules\graceful-fs\fs.js:11:1)
    node-pre-gyp ERR! stack at Module._compile (module.js:643:30)
    node-pre-gyp ERR! stack at Object.Module._extensions..js (module.js:654:10)
    node-pre-gyp ERR! stack at Module.load (module.js:556:32)
    node-pre-gyp ERR! stack at tryModuleLoad (module.js:499:12)
    node-pre-gyp ERR! System Windows_NT 10.0.16299
    node-pre-gyp ERR! command “C:\\Program Files\\nodejs\\node.exe” “D:\\IoT Book\\Chapt example\\ch5\\five\\node_modules\\firmata\\node_modules\\serialport\\node_modules\\node-pre-gyp\\bin\\node-pre-gyp” “install” “–fallback-to-build”
    node-pre-gyp ERR! cwd D:\IoT Book\Chapt example\ch5\five\node_modules\firmata\node_modules\serialport
    node-pre-gyp ERR! node -v v8.9.4
    node-pre-gyp ERR! node-pre-gyp -v v0.6.7
    node-pre-gyp ERR! This is a bug in `node-pre-gyp`.
    node-pre-gyp ERR! Try to update node-pre-gyp and file an issue if it does not help:
    node-pre-gyp ERR!

    > serialport-win-fix@4.0.16 install D:\IoT Book\Chapt example\ch5\five\node_modules\serialport-win-fix
    > node-pre-gyp install –fallback-to-build

    node-pre-gyp ERR! Tried to download(404): https://github.com/iuriifavi/node-serialport-win-fix/releases/download/4.0.16s/serialport-win-fix-v4.0.16-node-v57-win32-x64.tar.gz
    node-pre-gyp ERR! Pre-built binaries not found for serialport-win-fix@4.0.16 and node@8.9.4 (node-v57 ABI, unknown) (falling back to source compile with node-gyp)

    另外,直接執行 npm install serialport後再測試序列埠通訊的程式碼後有顯示出以下訊息:
    序列埠已開通!
    data: _ ��

    抱歉可能要多麻煩老師了!!謝謝您

    1. 請先在D磁碟或其他路徑(如:桌面)新增一個資料夾,然後在此空白的路徑內,執行 npm install johnny-five

      johnny-five官網建議採用Node 4.2.1版,我剛剛用8.9.4測試5-7頁的程式,執行無誤。

      thanks,
      jeffrey

  11. 老師您好,想問一下課本中Ch5中以瀏覽器控制LED矩陣,課本中是直接在電腦上執行,那若是想要用手機控制(手機與電腦的網路來源均為同一個分享器),達到相同的行為(如課本中一樣使用了express,socket.io,johnny-five)課本中的程式是不是得要修改呢?另外也想請問老師若上述的行為可行的話,是不是也能跟Ch10的cordova做結合,做成一個App呢? 另外,謝謝老師前面問題的解答,已經完全解決前面的問題了,謝謝老師

    1. cordova也可以使用socket.io,建議從簡單的即時通訊開始實驗。

      thanks,
      jeffrey

  12. 老師您好,打擾您了,想請問老師關於這個網站內的程式碼:https://gist.github.com/cdugd/4471350
    在電腦上面執行時,配合Arduino,可成功控制LED燈的on/off,但我以智慧型手機連到相同的網頁(同一wifi),網頁可以成功顯示,但按下按鈕卻無法控制LED的on/off,請問這是關於server-client的問題嗎??是否跟老師書中的這部分程式碼相關呢?(Ch5-36頁 var sio = sio(server)….. )

    1. 那個例子是透過node.js的fs物件提供index.html檔給連線用戶,在index.html裡的JavaScript程式碼,有這一行連接「本機(localhost)」伺服器的敘述:

      var socket = io.connect('http://localhost');
      

      「本機」指的是「執行瀏覽器的裝置」。你在電腦上測試沒問題,是因為瀏覽器和Node.js伺服器程式都在同一台電腦上執行。
      在「手機」上開啟瀏覽器時,「本機」是「手機」,所以上面那一行JavaScript就無法建立連線了。

      解決方法:把localhost改成執行node.js的電腦IP位址,例如:

      var socket = io.connect('http://192.168.1.19');
      

      另外,socket.io的網頁通常都是放在node.js伺服器,像你提供的例子以及書本裡的範例都是如此。但是Cordova的手機App,則需要把socket.io連線程式寫在App的網頁裡面。

      我們可以這樣測試,先拿掉伺服器上的index.html,node.js改寫成:

      var app = require('http').createServer(handler),
          io = require('socket.io').listen(app),
          five = require('johnny-five');
      
      app.listen(8080);
      
      function handler (req, res) {
          res.writeHead(200);
          res.end('hello world!');
      }
      
      board = new five.Board();
      
      board.on("ready", function() {
        led = new five.Led(13);
      
        io.sockets.on('connection', function (socket) {
          socket.on('click', function () {
            led.toggle();
          });
        }); 
      });
      

      如此,當瀏覽器連線到伺服器的8080埠號時,網頁會出現”hello world!”訊息。

      原本的HTML網頁(index.html檔)當中,引用socket.io.js的敘述改成:

      <script src="http://你的電腦IP:8080/socket.io/socket.io.js"></script>
      

      建立socket物件的敘述也要修改:

      var socket = io.connect('http://你的電腦IP:8080');
      

      改好的index.html檔可以單獨儲存在任何地方,socket.io仍可正常運作。

      同樣地,假如你要把socket.io程式包在Cordova App裡面,手機App的index.html當中的JavaScript程式要改成:

      <script type="text/javascript" src="cordova.js"></script>
      <script type="text/javascript" src="js/index.js"></script>
      <script src="http://你的電腦IP:8080/socket.io/socket.io.js"></script>
      <script type="text/javascript" src="js/jquery.min.js"></script>
      <script type="text/javascript">          
          document.addEventListener('deviceready', function() {
          var socket = io.connect('http://你的電腦IP:8080');
              $('#button').click(function(e){
                  socket.emit('click');
                  e.preventDefault();
              });
          });
      </script>
      

      thanks,
      jeffrey

  13. 老師請問我在網路購買一片WeMos D1 WiFi UNO R3開發板 ESP8266
    請問ESP8266是否支援 UART讀寫921600的速度,謝謝!

  14. 老師請教您幾個問題,我有一個感測器需使用921600鮑率來做讀取,我使用arduino uno來做接收,得到的數據是錯的,想使用WeMos D1的板子來做接收測試,
    1. 不曉得老師是否有測試過這樣的組合?
    2. 以及我要如何去寫程式設定呢?(我修改過先前載入uno的程式碼,然後載入這片ESP8266晶片的板子裡,但卻讀取不到數據)
    3. 或是老師有其他推薦板子的建議呢?

    1. SoftwareSerial和「序列埠監控視窗」最高支援到115200,所以最好使用具備多個硬體UART埠的Arduino板子來測試,像是具有4個硬體UART的MEGA 2560或者兩個UART的Arduino Leonardo,另外搭配PuTTY或其他序列埠通訊軟體測試。

      thanks,
      jeffrey

  15. 老師您好,謝謝您上面的回覆,但還是有一個問題想請問:我按照您的指點順利完成了cordova app,但在執行node.js後,app介面可順利顯示index.html檔的內容,但是無法完成控制硬體的動作(以我的例子來說,之前以node指令開啟script.js檔後透過相同路徑下的index.html檔不管在伺服器或相同wifi下的手機都可以順利打開led)但將檔案變成app檔之後,node.js檔(script.js檔)的路徑是不是也因此要做變化或是程式再做修改呢?謝謝老師,多麻煩您了~

  16. 老師,不好意思,今天測試了一整天想將之前在github上的內容想將原本可以運作的網頁控制轉為app控制,但是未果,想請問老師,若想要引用index.html檔的內容但在cordova資料夾中,被修改過的index.html會被存放在www路徑下,而要執行的node.js伺服器程式是要執行在cordova底下的www/js/index.js(但如此的話index.html是在前一個路徑中)還是任意路徑皆可以呢?因為想要將原本網頁控制LED(運用socket.io johnny-five)實行在app上,另外也想問cordova底下的node_module資料夾是否也要npm install 像是johnny-five,socket.io的模組呢?麻煩老師了,謝謝您

    1. 我不太了解這句話:「要執行的node.js伺服器程式是要執行在cordova底下的www/js/index.js(但如此的話index.html是在前一個路徑中)還是任意路徑皆可以呢?」

      node.js是伺服器端程式,cordova是前端程式,cordova要連結到node.js的socket.io,就跟之前的回答一樣,填寫伺服器的IP位址即可。

      thanks,
      jeffrey

  17. 喔喔 抱歉老師沒有表達得很完整,我的想法是說之前在網頁上控制LED時在伺服器端必須以node指令先執行一個..js檔,然後在該js檔中會指定前端html檔的路徑然後完成網頁控制LED的過程。那麼現在要轉移到APP上,前端部分如同老師指點的填入www路徑下面的index.html中,那麼想問原本在伺服器端的程式應該在那個路徑去執行呢?是修改www/js/路徑下面的index.js檔為自己的控制程式,待手機那邊執行時,再執行node www/js/index.js就可以了嗎??抑或是說伺服器端的程式不需存入www/js/index.js檔中呢?另外還想問cordova路徑下面有node_module 我還需引入需要的模組(如:johnny-five socket.io)再去執行cordova build嗎?抱歉老師,多麻煩您了

    1. 我了解你的意思了。你打算把前端網頁的功能放到手機App裡面。
      node.js部份不用修改,它的網頁也照舊。
      你不能直接把原本在node.js的網頁放在cordova裡面,
      因為cordova的網頁有自己的處理架構,
      但是你可以在cordova的網頁裡面放入同樣的UI和程式邏輯。

      johnny-five是在node.js端執行的程式,跟cordova沒有直接關聯,
      你所要做的就是把cordova中,引用socket.io.js程式路徑加入你的伺服器IP,
      就像我之前的回答一樣。

      執行測試時,你要先啟動伺服器(node.js),才能讓手機App連上。

      thanks,
      jeffrey

  18. 喔喔 了解了,老師也就是說在cordova路徑下只須修改www路徑下面的index.html檔就可以了,而完成cordova build之後再到其他路徑下執行原先用於網頁控制的伺服器node.js程式即可是嗎?多謝老師了,那麼這一點還想到一個問題,因為之前用於網頁的node.js檔中有fs.readFile(__dirname + ‘/index.html 指令,那麼現在index.html被修改後放到cordova www路徑下了,那麼是否也需要複製一份到node.js檔的路徑中呢?真的萬分感謝老師!!!

    1. node.js部份不用修改,它的網頁也照舊。
      cordova的網頁有自己的處理架構,只用於cordova。

      thanks,
      jeffrey

  19. 老師,不好意思,剛剛留言發現有一些程式碼無法順利顯示出來,故重新留言一次,請老師見諒!

    老師,抱歉打擾了,測試之後發現以網頁瀏覽器方式可以開啟LED,但換成是cordova app依舊只有按鈕而LED還是無法被觸發,不知道是哪裡的問題呢? 我只有改動D:\cordova\test\www下的index.html檔,其改動的內容是刪除標頭檔的meta http-equiv=”Content-Security-Policy”…那行,其餘標頭檔部分皆保留且無變動。body部分則是自
    script type=”text/javascript” src=”cordova.js” /script (原始index.html檔就有的部分)
    script type=”text/javascript” src=”js/index.js” /script (原始index.html檔就有的部分) 之後加入以下程式碼:
    script src=”http://192.168.0.106:8080/socket.io/socket.io.js” /script
    script type=”text/javascript” src=”js/jquery.min.js” /script
    script type=”text/javascript”
    document.addEventListener(‘deviceready’, function() {
    var socket = io.connect(‘http://192.168.0.106:8080’);
    $(‘#button’).click(function(e){
    socket.emit(‘click’);
    e.preventDefault();
    });
    });
    /script

    button id=”button” href=”#” LED ON/OFF /button
    /body

    改完成後就執行platform add android和build android指令,安裝了apk

    之後啟動在其他路徑(D:\new)下的node.js程式,該程式為: https://gist.github.com/cdugd/4471350 當中的程式碼
    但已經將 https://gist.github.com/cdugd/4471350 中的第4行和第7行改為: http://192.168.0.106:8080 所以可以在本機和手機瀏覽器中觸發LED,但唯獨無法用cordova app觸發,請問老師上面的程式是哪個部份出了問題了呢?謝謝老師的幫忙!!

    1. 我測試Android Cordova socket.io連接node.js的Johnny-Five控制Arduino LED開關沒問題,這個ZIP壓縮檔包含Cordova的www檔案

      製作補充說明:

      1. 我先建立一個簡易的Hello App,在它的js資料夾存入jquery.min.js和socket.io.js(取自Node.js的\node_modules\socket.io-client\dist路徑裡的socket.io.js檔),如此,Cordova的網頁就不需要額外從伺服器下載socket.io.js檔。

      這是index.html中,引用JavaScript程式檔的標籤:

      <script type="text/javascript" src="cordova.js"></script>
      <script type="text/javascript" src="js/jquery.min.js"></script>
      <script type="text/javascript" src="js/socket.io.js"></script>
      <script type="text/javascript" src="js/index.js"></script>
      

      2. 修改index.html第31行的”Content-Security-Policy”(內容安全政策),改成:

      <meta http-equiv="Content-Security-Policy" content="default-src * gap: ws: https://ssl.gstatic.com;style-src * 'unsafe-inline' 'self' data: blob:;script-src * 'unsafe-inline' 'unsafe-eval' data: blob:;img-src * data: 'unsafe-inline' 'self' content:;">
      

      這樣才能在Android中執行socket.io程式。

      3. 在網頁內文放置切換LED開關的按鈕,命名成myBtn。

      4. 修改index.js檔,在onDeviceReady函式中加入處理myBtn的事件程式,並且在建立socket物件的敘述裡面,加入指定採用’websocket’傳輸協定的敘述,在我的測試中,若沒有加上websocket,程式會在執行時發生錯誤。

      onDeviceReady: function() {
         this.receivedEvent('deviceready');
         
         var socket = io.connect('http://你的電腦IP:8080', {transports: ['websocket']});
         // 發送socket訊息
         $('#myBtn').on('click', function(e){
            socket.emit('click');
            e.preventDefault();
         });
      },
      

      thanks,
      jeffrey

  20. 老師您好,今天試過之後,已經可以成功觸發了!謝謝老師這幾天來的幫忙,抱歉也多麻煩您了!!在此真的非常感謝老師的幫忙!!

  21. 老師,抱歉在春假期間打擾,想請問之前老師指導的部分,若是想要以jQuery Mobile編排成手機App樣式的網頁,目前所遇到的問題是在電腦瀏覽器上可以看到成功變成手機App的樣子,但以apk檔執行於手機卻無法成功顯示頁面(手機頁面會是一片灰+白色的色塊) 我的方式是:將標頭檔部分多加入這句:
    link rel=”stylesheet” href=”css/jquery.mobile-1.4.5.min.css” /
    在body的部分多加入這句:
    script type=”text/javascript” src=”js/jquery.mobile-1.4.5.min.js” /script
    不知道是不是遇到了老師課本中:Ch10-36的情況了呢?

  22. 老師您好
    想請問在 儲存 Arduino 上傳的溫溼資料 這個章節中
    如果要把資料傳到mongoose上(不是本地端)
    程式中該怎麼改呢
    是要在Arduino引入mongoose類似這種金鑰嗎?
    mongoose.connect(‘mongodb://admin:admin@xxxxxx.mlab.com:57444/filedata’);

    1. mongoose支援底下的格式,指定帳號、密碼、主機和埠號…連接MongoDB:

      mongoose.connect(‘mongodb://帳號:密碼@主機:埠號/資料庫’);

      thanks,
      jeffrey

  23. 這個我知道
    想問的是說 在Arduino傳資料這塊程式碼該怎麼寫
    可以用nodejs的寫法下去存取資料嗎

    1. 應該沒有實作MongoDB連線協定的Arduino程式庫,請使用Node.js當作中介。

      thanks,
      jeffrey

  24. 老師您好,
    特別來這邊感謝您,我花了兩個禮拜讀了這本書,之後去參加奧迪的黑克松做了一個停車管理的web app,書中的知識非常有幫助,在實作上幾乎全部都用上了,非常感謝您寫書造福大家.
    另外在這邊開源分享我參加黑克松的程式,有興趣的同學可以拿去用,程式是基於老師書中LED矩陣的部分修改的,並且用了資料庫. 另外因為硬體部分使用了RFID, Johnny-five不支援,最後選擇自己寫Arduino和序列埠通信.
    https://github.com/toby4548/Audi_Kreathon18_Parkid

    Tony

    1. BTW,程式是96小時內寫出來的,如果太過拙劣請多包涵…

  25. 老師您好,
    我使用您的物聯網內的範例,實作出了透過WIFI控制esp8266上的LED開關與PWM滑桿功能。
    我用windows系統時一切正常,
    但當我用osx裡的Arduino IDE上傳程式後,
    用戶連進esp8266時,就不會正常顯示網頁,
    而電腦的序列埠監控視窗會顯示:
    Exception(3):
    epc1=0x4020a4e4 epc2=0x00000000 epc3=0x00000000 excvaddr=0x4023b4b6 depc=0x00000000

    cox:cont
    sp: 3ffefbc0 end: 3ffefeb0 offset: 01a0

    >>>stack>>>
    3ffefd60: 3ffe8b73
    (等等一堆代碼)
    <<<stack<<<

    ets Jan 8 2013,rst cause:2, boot mode:(1,6)

    以上這些錯誤訊息。
    請問這是為什麼?以及如何修正呢?

    1. 1. 請試試用行動電源供電,看看是否為USB輸出電流不足。
      2. 嘗試使用esptool工具,清空ESP8266的快閃記憶體,再重新燒錄程式。

      esptool請在終端機執行這個命令安裝:

      pip install esptool

      然後執行這個命令清空快閃記憶體:

      esptool.py –port 你的控制板所在序列埠 erase_flash

      thanks,
      jeffrey

    2. 說實在的, 電源對ESP8266來說真的很重要. 提供一個我的實際經驗給你參考:
      之前我都使用5V 1.5A的變壓器, 經過AMS1117轉為3.3V(實際量測好像是3.28V左右)來供電給ESP8266(我使用的版本是12F)使用. 大部份的時間是正常的, 但有時候會出現類似像你提供的錯誤代碼. 我本來以為是ESP8266本身的問題, 但換了幾個都還是偶爾會發生這樣的情形. 也花了很多時間檢查電路和sketch, 但情形都沒有改善…
      後來我去查了一下AMS1117的datasheet, 上面建議的電源為12V, 改用12V 1A的變壓器, 這個情形就再也沒發生了. 所以我現在使用ESP8266都是用12V的變壓器搭配AMS1117來使用. 5V和12V經過AMS1117轉出來的電壓都是3.28V, 理論上同樣是AMS1117可接受的來源電壓範圍, 轉出來應該電壓電流會是一樣才對. 但因為我不是電子相關科系, 所以並不清楚主因到底為何, 僅提供使用經驗讓你參考.
      PS. 如果你也是改用12V電源經AMS1117轉換電源來供電給ESP8266使用的話, 記得AMS1117上面要加個散熱片… 因為蠻燙的…

  26. 兩個方法我都試了,
    結果還是一樣。
    沒關係,我再試試看,
    謝謝~。

  27. 想另外請教老師,
    在「超圖解 Python 物聯網實作入門」裡,
    有個在ESP8266架設會顯示DHT所測得溫濕度的網頁的案例,
    請問我用Adruino IDE也能對ESP8266做出一樣的功能嗎?
    我的疑惑點是:
    如果想要像「超圖解物聯網IoT實作入門」裡控制ESP8266的PIN腳一樣,將網頁寫在外部的index.h檔,
    我們有辦法在index.h裡放一個會去主程式裡抓取DHT數值的變數嗎?
    還是我只能將網頁以及變數都寫在主程式裡,然後用字串的方式發送給用戶端?
    感謝。

    1. 如果要合成MicroPython和HTML,需要把HTML嵌入MicroPython程式主體,像17-7頁的程式一樣。

      thanks,
      jeffrey

    2. 老師,
      我的意思是用Arduino IDE的c語言做到micropython 17-7頁的功能

    3. 喔喔,
      感謝。
      老師的三本大作我都有拜讀,
      因此有點錯亂了。
      我試試,謝謝。

  28. 赵老师好,大陆出版的这本书少了esp8266的相关章节,真是遗憾!还有您的第三本大作什么时候大陆出版?希望不要再少章节了。谢谢。

    1. 嗯,电子工业出版社决定把《超图解IoT物联网》拆分成两册,上周编辑告诉我,第二册终于要出版了 😛

      《超图解Python物联网》我目前没有发行简体中文版的计画。

      thanks,
      jeffrey

  29. 請問老師,mongoose要如何find()?
    我用Raspberry,mongodb版本用內建。
    用你的範例程式可以抓到欄位資料
    db.dht11.find().pretty()
    執行如下
    {
    “ts” : ISODate(“2018-10-21T03:53:24.166Z”),
    “topic” : “v1/devices/me/telemetry”,
    “message” : “{\”temperature1\”:26.60,\”humidity1\”:60.50}”,
    “json” : {
    “temperature1” : 26.6,
    “humidity1” : 60.5
    },
    “_id” : ObjectId(“5bcbf834a43773221fa8edfa”)
    }
    看起來欄位有點複雜,不懂find()抓不到溫濕度欄位資料裡?
    我用db.dht11.find({},{“json”:1,”})
    執行結果是{ “_id” : ObjectId(“5bcbf4fc9b5354102e7fe768”) }
    謝謝
    我都有買你的系列書寫得不錯~~

    1. 感謝你的支持!假設dht11有個欄位值是物件類型,像這樣:

      db.dht11.insert([
          {
              "數據":{
      	    "溫度":23,"濕度":57
        	},
              "時間":ISODate("2015-10-17T03:00:00Z"),
      	"地點":"台中"
          },
          {
              "數據":{
      	    "溫度":23,"濕度":50
        	},
              "時間":ISODate("2015-10-18T03:00:00Z"),
      	"地點":"台南"
          },
          {
              "數據":{
      	    "溫度":24,"濕度":45
        	},
              "時間":ISODate("2015-10-19T03:00:00Z"),
      	"地點":"嘉義"
          }
      ])
      

      要查詢其中的”溫度”值,欄位名稱格式寫成”物件.欄位”,例如:

      // 取出溫度等於23的資料
      db.dht11.find({"數據.溫度":{$eq:23}})
      

      thanks,
      jeffrey

    2. 謝謝老師回答,我的mongodb版本2.4.14,無法用$eq
      error: { “$err” : “invalid operator: $eq”, “code” : 10068 }

      想裝3.0版本,以前可以裝成功,現在換了版本無法相容….
      請問什麼知道欄位值是物件類型??
      還是有沒有辦法把資料庫欄位重新排列,用一般的find()指令無法抓不到我要的欄位資料裡。
      有回應但都是空值
      就是我要把溫溼度數值抓出來,放在網頁上。

  30. 我也是安裝官方的Raspbian最新版,我快被版本搞亂….看了你的回覆連結再試試看….
    之前每次安裝mongodb失敗就要重灌很多次….無法執行或找不到mongo命令…查看伺服器一直亮紅燈…
    最後裝2.4.14….安裝npm套件會遇到很多問題相容性….

    這次一樣還是遇到問題…上網查目錄權限問題,一直反覆看你的網站內容
    最後弄出來了….明明都用複製貼上…一直卡在目錄權限不給登入….
    我就把sudo chown root:root mongo* 改成pi再改回root….重啟就能用mongo….
    換了3.0.14之後,發覺不一樣欄位排序,看起來比較懂。
    {
    “_id” : ObjectId(“5bd0846892797e070a352941”),
    “ts” : ISODate(“2018-10-24T14:40:40.579Z”),
    “topic” : “v1/devices/me/telemetry”,
    “message” : “{\”temperature1\”:25.90,\”humidity1\”:64.60}”,
    “json” : {
    “temperature1” : 25.9,
    “humidity1” : 64.6
    }
    }
    打了指令真的有回傳,db.dht11.find({“json.temperature1″:{$eq:25.7}}).pretty()
    我再試試改寫find.js,還是找不到dht11的資料
    // 設置綱要
    var dht11Schema = new mongoose.Schema(
    {
    ‘temperature1’: Number,
    ‘humidity1’: Number,
    }
    );

    // 定義自訂的show()方法
    dht11Schema.methods.show = function () {
    var msg = ” *temperature1:” + this[‘temperature1’] +
    ” *humidity1:” + this[‘humidity1’];

    console.log(msg); // 在控制台輸出溫、濕度和時間資料
    }

    // 建立模型
    var DHT11 = mongoose.model(‘dht11’, dht11Schema);

    DHT11.find(function (err, docs) {
    if ( err || !docs) {
      console.log(“找不到dht11的資料!”);
    } else {
    docs.forEach(function(d) {
    var data = new DHT11(d); // 產生資料物件
    data.show();
    });
    }
    });

    1. 我用你的資料測試,輸入下列數據:

      db.dht22.insert([
          {
              "ts" : ISODate("2018-10-24T14:40:40.579Z"),
              "topic" : "v1/devices/me/telemetry",
              "message" : "{\"temperature1\":25.90,\"humidity1\":64.60}",
              "json" : {
                      "temperature1" : 25.9,
                      "humidity1" : 64.6
              }
          },
          {
              "ts" : ISODate("2018-10-25T14:40:40.579Z"),
              "topic" : "v1/devices/me/telemetry",
              "message" : "{\"temperature1\":24.90,\"humidity1\":60.60}",
              "json" : {
                      "temperature1" : 24.9,
                      "humidity1" : 60.6
              }
          },
          {
              "ts" : ISODate("2018-10-26T14:40:40.579Z"),
              "topic" : "v1/devices/me/telemetry",
              "message" : "{\"temperature1\":25.70,\"humidity1\":62.60}",
              "json" : {
                      "temperature1" : 25.7,
                      "humidity1" : 62.6
              }
          }
      ])
      

      執行find()查詢:

      db.dht22.find({"json.temperature1":{$eq:25.7}}).count()
      

      確實傳回1筆。

      thanks,
      jeffrey

  31. 謝謝老師回覆我問題
    我卡在自訂綱要的資料類型,Number都回應”undefined”,改用String就會停住很久跑不出來…

    我測試
    var temp ={‘temperature1′:55,’humidity1’:66};
    var data = new DHT11(temp);
    就能跑出來
    若改json.temperature1就回應undefined
    我查詢console.log(d);
    { json: { temperature1: 28, humidity1: 39.1 } }
    我在想是不是還要再過濾刪除,還是再轉格式類型?

    var dht11Schema = new mongoose.Schema(
    {
    ‘message’:{type:String},
    ‘json.temperature1’:{type:Number },
    ‘json.humidity1’: {type:Number}
    }
    );

    // 定義自訂的show()方法
    dht11Schema.methods.show = function (d) {
    var msg = ” temperature1:” + this[‘json.temperature1’] +
    ” *humidity1:” + this[‘json.humidity1’] +
    ” *_id :” + this[‘message’]
    // console.log(d);
    console.log(msg); // 在控制台輸出溫、濕度和時間資料
    }

    1. 你的mongoDB自訂綱要應該類似這樣:

      var dht11Schema = new mongoose.Schema({
          'ts': { type: Date, default: Date.now },
          'topic': String,
          'message': String,
          'json': {
              'temperature1': Number,
              'humidity1' : Number
          }
      });
      

      thanks,
      jeffrey

    2. 老師~是否可以再出超圖解物聯網第二版嗎?把資料庫的結構能詳細說明,像JSON欄位我搞不清楚是什麼?
      而且為什麼能夠看出我PO的資料庫架構?

      一開始用你的方法,還是無法叫出數據來…我再上網找mongoose套件相關指令…
      為什麼其他欄位都能顯示出來,唯獨JSON欄位不顯示undefined….
      我快要放棄…想想能夠建立資料庫裡,就有辦法FIND找出欄位文件數據…
      現在終於跑出顯示出來了….
      PS.最近買一本老師寫的PYTHON物聯網,真的學習不完….

      不懂this.get()用這行指令為什麼能顯示出來?
      最後真的謝謝老師請示。

      var mongoose = require(‘mongoose’);
      mongoose.connect(‘mongodb://localhost/sensors’,{ useMongoClient: true });

      // 設置綱要
      var dht11Schema = new mongoose.Schema({
      ‘ts’: { type: Date, default: Date.now },
      ‘topic’: String,
      ‘message’: String,
      ‘json’: {
      ‘temperature1’: Number,
      ‘humidity1’ : Number
      }
      });
      // 定義自訂的show()方法
      dht11Schema.methods.show = function (d) {
      var msg = ” temperature1:” + this.get(‘json.temperature1’) +
      ” *humidity1:” + this.get(‘json.humidity1’) +
      ” *_id :” + this[‘_id’] +
      ” * ts :” + this[‘ts’] +
      ” *topic :”+ this[‘topic’] +
      ” *message :” + this[‘message’];
      // console.log(d);
      console.log(msg); // 在控制台輸出溫、濕度和時間資料
      }

    3. 書本的序言有提到,這本書的許多單元都有專門的書籍,本書強調的是整合應用以及建立各個範例所需要的核心概念。

      JSON的基本架構就這樣:

      var data = {“欄1″:”值1”, “欄2″:”值2”}

      裡面可以再包含其他複雜類型資料,像這樣(請參閱2-23頁的範例):

      var data = {
      “欄1″:”值1”,
      “欄2″:”值2”,
      “欄3”: {
      “欄3_1″:”值3_1”,
      “欄3_2″:”值3_2”
      }
      }

      只要反推回去,就能建立資料綱要了:

      var schema = {
      “欄1”:類型,
      “欄2”:類型,
      “欄3”: {
      “欄3_1”:類型,
      “欄3_2”:類型
      }
      }

      讀取JSON資料時,”欄位”和”資料”之間用點或者方括號隔開,假設資料是:

      var data = {
         "產地":"台灣",
         "規格":{
            "處理器":"Z80",
            "RAM":"2KB"
         }
      }
      

      讀取”產地”資料:

      data["產地"]
      

      讀取”規格”當中的”處理器”資料:

      data["規格"]["處理器"]
      

      或者:

      data.規格.處理器
      

      thanks,
      jeffrey

  32. 請問老師
    不好意思再請教一個問題
    我做到ejs樣板,如何轉換 JSON格式呢?
    上網搜尋試驗很多次…還是無法顯示…

    ts欄位能顯示,溫溼度欄位還是顯示不出來。

    table.ejs:

    最新溫濕度數據

    溫度濕度時間

    °C
    %

    top10.JS執行如下
    [ { ts: Sat Oct 27 2018 13:10:30 GMT+0800 (CST) },
    { json: { temperature1: 23.9, humidity1: 65 },
    ts: Thu Nov 01 2018 22:02:42 GMT+0800 (CST) },
    { ts: Thu Nov 01 2018 22:02:36 GMT+0800 (CST) },
    { json: { temperature1: 23.9, humidity1: 65 },
    ts: Thu Nov 01 2018 22:02:32 GMT+0800 (CST) },
    { json: { temperature1: 23.9, humidity1: 65 },
    ts: Thu Nov 01 2018 22:02:23 GMT+0800 (CST) },
    { ts: Thu Nov 01 2018 22:02:16 GMT+0800 (CST) },
    { json: { temperature1: 23.9, humidity1: 65 },
    ts: Thu Nov 01 2018 22:02:14 GMT+0800 (CST) },
    { json: { temperature1: 23.9, humidity1: 65 },
    ts: Thu Nov 01 2018 22:02:05 GMT+0800 (CST) },
    { ts: Thu Nov 01 2018 22:01:56 GMT+0800 (CST) },
    { json: { temperature1: 23.9, humidity1: 65 },
    ts: Thu Nov 01 2018 22:01:55 GMT+0800 (CST) } ]

    1. 如同書本中提到的,ejs樣板用於產生多個相同樣式的網頁。

      JSON資料並不是「網頁」,HTTP檔頭區的訊息也不一樣,所以請直接使用3-51頁的res.json()方法輸出JSON資料,不必透過ejs樣板產生網頁。

      thanks,
      jeffrey

  33. 請問老師12-18的代碼我輸入後出現下面的警告訊息。打開192.168.4.1arduino有收到設備進來。
    但是網頁都是打不開的狀態 謝謝
    /Users/lucan/Documents/www/光碟檔案/範例檔案/ch12/AT命令/AT_server/AT_server.ino: In function ‘void loop()’:
    /Users/lucan/Documents/www/光碟檔案/範例檔案/ch12/AT命令/AT_server/AT_server.ino:34:24: warning: ISO C++ forbids converting a string constant to ‘char*’ [-Wwrite-strings]
    if (ESP.find(“IPD,”)) {
    ^

  34. 老師你好,
    我在操作mDNS的實驗時,發現我安卓手機上的Bonjour軟體找不到ESP的伺服器,
    我用的是ESP8266-12F,
    使用TTL及Arduino IDE進行燒錄,
    在拜讀13-5 mDNS的部份時,
    把光碟的mDNS.ino燒進ESP-12f之後,
    在序列埠有看到mDNS responder以及HTTP server已啟動,
    可是開啟手機的Bonjour卻找不到它(用chrome直接輸入它的IP是可以找到頁面的),
    除非直接使用Arduino IDE裡面的mDNS server範例,
    請問,我該如何修改,才可以使用老師提供的範例來開啟mDNS服務呢?

    1. 我之前在Note 4手機上測試沒問題,剛剛用Note 8手機測試不行,但蘋果的裝置沒問題。

      請在Google Play上搜尋”mdns browser”關鍵字,可下載Bonjour Browser,它將能搜尋並顯示可連線裝置的名稱和IP位址。

      thanks,
      jeffrey

  35. 趙老師您好,關於本書問題請教
    12-4的動手做,使用光碟中CH12的AT_server檔案編譯後上傳,手機開wifi可以連到監視序列阜所顯示的網址,但用手機瀏覽器輸入該網址後,都是顯示無法連上這個網站,能否請趙老師解惑?
    我是初學者,不知這樣發問有何不妥,如有冒犯請見諒

  36. 赵老师,您好。
    在阅读《超图解物联网》著作的“使用esp-01模组开发arduino物联网13-10页”,我用usb转ttl模块连接esp-01模组,具体连线如下:
    usb-ttl esp01
    gnd gnd
    tx rx
    rx tx
    3.3v vcc
    gnd gpio0
    3.3v ch_pd
    然后我通过arduino IDE 选择“开发板:Generic ESP8266 Module ”等参数,选择自带范例blink,点击上传,
    在有电源的情况下直接上传报“warning: espcomm_sync failed
    error: espcomm_open failed
    error: espcomm_upload_mem failed”错误。
    有时候,报Uploading 225840 bytes from to flash at 0x00000000
    ……………………………………..这个点一直延续下去

    不知道哪里出错了,赵老师经验丰富,水平高超,不知道能否给我指点下,谢谢

  37. 赵老师:接上条,现在上传失败错误变成如下:
    warning: espcomm_send_command: wrong direction/command: 0x01 0x03, expected 0x01 0x08
    Uploading 229168 bytes from to flash at 0x00000000
    error: failed sending 1070 bytes
    .error: failed sending 1044 bytes
    .error: failed sending 1040 bytes
    .error: failed sending 1040 bytes
    .error: failed sending 1070 bytes
    .error: failed sending 1087 bytes
    .error: failed sending 1080 bytes
    .error: failed sending 1054 bytes
    .error: failed sending 1044 bytes
    .error: failed sending 1059 bytes
    .error: failed sending 1075 bytes
    .error: failed sending 1081 bytes
    .error: failed sending 1068 bytes
    warning: espcomm_send_command: didn’t receive command response
    warning: espcomm_send_command(FLASH_DOWNLOAD_DATA) failed
    warning: espcomm_send_command: wrong direction/command: 0x01 0x03, expected 0x01 0x04
    error: espcomm_upload_mem failed

    1. 赵老师,已经解决了,我感觉是线接触不良的原因。

  38. 趙老師您好:
    近日也有把韌體往回更新較舊坂本,也有往後更新到較新版本
    但手機依然舞法顯示網頁,不知老師能否指點迷津一下問題可能出在哪?
    我是用安卓手機,瀏覽器是Chrome

  39. 趙老師您好:
    抱歉沒說明清楚。
    是關於書中的12-4動手做,先前問過老師一次,時間是顯示2019/08/158:57 上午,當時老師回覆因繁忙還沒時間測試,並建議我更新韌體試試看,後來我有事過把韌體換至較舊版本,也有換過較新版本,兩種情況手機wifi都找的到ESP開頭的AP點,但是開啟瀏覽器輸入序列監視的網址192.168.4.1,依然是顯示無法連上這個網站,所以想再請教老師還有哪些可能的因素造成無法連上的結果,謝謝。

  40. 趙老師您好:
    是的,測試AT命令後有回傳OK。
    12-18頁的程式之行後,序列監控視窗顯示以下訊息
    OK

    ets Jan 8 2013,rst cause:2, boot mode:(3,7)

    load 0x40100000,n tail 0
    chksum 0x63
    load 0x3ffe8,tail 0
    chkx8 tail 0
    7
    iI4d
    it
    e⸮⸮⸮p⸮o⸮|s⸮⸮cc⸮⸮ll`⸮⸮⸮l⸮⸮⸮
    Ai-Thinker Technology Co. Ltd/

    ready
    AR)CWS⸮TR⸮j

    O⸮C⸮AZ+CIFSS

    +CIFSR:APIP,”192.168.4.1″
    +CIFSS:APMAC,”3e:71:bf:32:0c:OAR)CIhSՊm

    O⸮C⸮AT+CIPSERVER=1,80

    OK
    然後手機開啟WIFI也有收尋到AP點,但手機開啟瀏覽器輸入序列監控視窗的IP:192.168.4.1依然無法顯示網頁

    1. 我剛剛測試沒問題,請問你的手機有先連線到ESP8266的熱點嗎?

      ESP8266 Wi-Fi熱點

      thanks,
      jeffrey

    2. 趙老師您好:
      有了,我的手機連上該熱點後,都會跳出一個提示訊息說該熱點沒有網際網路功能,是否保持連線,
      之前我都以為wifi列表顯示已連線就有連線了,所以都直接滑掉該訊息,剛剛點開那個訊息後確認保持連線,就有顯示網頁了,原來是我自己手機問題,抱歉抱歉,搞烏龍了。

  41. 趙老師您好:
    小狀況回報,本書附贈的光碟裡,範例檔案→ch3→node→basic_http_1.js
    程式內容其中一行res.writeHead(200, {“Content-Type”: “text/html;charset:utf-8”});
    utf-8前面的冒號,執行後會造成網頁內容”Node網站開工了!”這段內容的中文字變成亂碼
    冒號改成等號,網頁內容的中文字就正常顯示了。

  42. 赵老师您好:
    我在中遇到问题:
    使用范例mDNS.ino,无法用网域名称jarvis.local连接到ESP8266,
    用IP地址可以正常连接,用官方范例mDNS_Web_Server全都可以正常连接,
    浏览器已经安装扩展程序mDNS Browser,电脑也安装了官方的Bonjour Print Services for Windows v2.0.2,
    手机端(安卓)也安装了Bonjour Browser,同样的问题。
    自己弄了好几天,无果,所以来求助老师,望老师指点,谢谢!

    浏览器:Google Chrome 版本 77.0.3865.120
    ESP8266: NodeMCU ESP-12E
    ArduinoIDE: 1.6.13

    1. 我在三星Note 8手机上测试也不行,
      但是用Bonjour Browser可以搜寻到,
      在iPad上连结jarvis.local没问题。

      thanks,
      jeffrey

  43. 趙老師您好:
    我在11-2 藍芽bot程式加入接收的部份,但是執行起來
    很常第1個byte或是中間的byte會丟失,不知老師能否指點迷津一下問題可能出在哪?
    接收程式部份如下
    onConnect: function() {
    $(‘#btPanel’).hide(200);
    $(‘#botPanel’).show(200);
    app.showMsg(“已連線”);
    bluetoothSerial.subscribeRawData(function (data) {
    var bytes = new Uint8Array(data);
    logTXT.innerHTML = bytes
    });
    },

    1. 請在原始資料中加入’\n’字元分段,再用底下的程式試試:

      onConnect: function() {
         $('#btPanel').hide(200);
         $('#botPanel').show(200);
         app.showMsg("已連線");
      
         // 偵聽'\n'字元,顯示收到的整段訊息。
         bluetoothSerial.subscribe('\n', function (data) { 
            app.display(data);
         });
      },
      
      display: function(msg) {
         var display = document.getElementById("message"), // HTML裡的
      元素 br = document.createElement("br"), // 新建一個斷行元素 txt = document.createTextNode(msg); // 用收到的訊息建立新的文字節點 display.appendChild(br); // 在"message"元素中插入斷行 display.appendChild(txt); // 插入訊息文字 },

      thanks,
      jeffrey

發佈留言

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

Related Posts

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

Back To Top