Upgrade to Pro — share decks privately, control downloads, hide ads and more …

ESP8266-workshop

mlwmlw
September 19, 2015

 ESP8266-workshop

mlwmlw

September 19, 2015
Tweet

More Decks by mlwmlw

Other Decks in Programming

Transcript

  1. 前製作業 • Arduino IDE https://www.arduino.cc/en/Main/Software • Java https://java.com/zh_TW/download/ • Python

    https://www.python.org/downloads/release/python-279/ • 範例程式 https://github.com/mlwmlw/esp8266-workshop • cp2102 driver http://tw.silabs.com/products/mcu/Pages/ USBtoUARTBridgeVCPDrivers.aspx
  2. WHY I AM HERE That is there’s some good in

    this world, Mr. Fordo. And it’s worth fighting for.
  3. ⼤大綱 • ESP8266 • Ethernet x Web • Arduino Library

    • Arduino ESP8266 • IoT Service • 深⼊入 ESP8266 • nodeMCU & 其他韌體
  4. ESP8266 OVERVIEW ~ RMB ¥9 Arduino + WIFI • Tensilica

    Xtensa lx3 RISC CPU 32bit 80MHz • ESP8266 SoC Expressif
  5. ESP8266 HARDWARE • ROM 512KB >= Flash • GPIO •

    UART • SPI • PWM • ADC • I2C • 802.11 b/g/n 2.4GHz • 睡眠 < 10uA 規格書
  6. FIRMWARE & SDK.. • Expressif ★★★★★ • SDK • AT

    Command • AI-thinker • 出廠預設韌體 ★★★★★ • AI-Cloud • NodeMCU ★★★★☆ • LUA Interpreter • Cesanta Smart.js ★★☆☆☆ • javascript 開發環境 v7 engine
  7. FIRMWARE & SDK.. • OLIMEX • ESP8266 examples and toolchain

    setup • frankenstein • 像 AT ⼀一樣透過指令控制 • esp-open-sdk • open source toolchain • ESP8266 FreeRTOS
  8. ESP8266EX PINS • GPIO x 11 • LNA 天線 •

    TOUT(ADC) • CHIP_EN • XPD_DCDC(Wake Up) • SDIO(SD Card) • UART(TX RX) • EXT_RSTB(RESET) • VDD • GND https://github.com/esp8266/esp8266-wiki/wiki/Pin-definition
  9. ESP-01 TX GND CH_PD GPIO2 RST GPIO0 VCC RX •

    Flash 1MB • 無法直接插麵包板 • 轉接 or 公對⺟母杜邦 • GPIO x 2
  10. ESP-03 • Flash 512KB • GPIO x 7 0/2/12/13/14/15/16 VCC

    ANT GPIO14 CH_PD GPIO12 GPIO16/18 GPIO13 RX GPIO15 TX GPIO2 NC GPIO0 GND
  11. ESP-12 • Flash 4MB • GPIO x 9 • ADC

    • RST + GPIO16 (wake up) GND VCC GPIO15 GPIO13 GPIO2 GPIO12 GPIO0 GPIO14 GPIO5 GPIO16 GPIO4 CH_PD RX ADC TX REST
  12. ESP-201 Flash 512KB GPIO0 GPIO15 GPIO2 GPIO13 D2 GPIO12 CLK

    GPIO14 CMD GPIO16 D0 CH_PD D1 REST D3 ADC GPIO4 GPIO5 VCC GND VCC GND VCC RX TX GND
  13. 模式 GPIO15 GPIO0 GPIO2 Mode Description L L H UART

    Download code from UART L H H Flash Boot from SPI Flash H x x SDIO Boot from SD- card
  14. 基本配線 ESP8266 VCC RX TX GND GPIO0 CH_PD USB TO

    UART 3.3v RX TX GND 正常模式 ESP8266 UART VCC 3.3V CH_PD 3.3V RX TX TX RX GPIO2 3.3V GPIO15 GND
  15. 基本配線 ESP8266 VCC RX TX GND GPIO0 CH_PD USB TO

    UART 3.3v RX TX GND 燒錄模式 ESP8266 UART VCC 3.3V CH_PD 3.3V RX TX TX RX GPIO0 GND GPIO2 3.3V GPIO15 GND
  16. network First you hate them. Then you get used to

    them. Enough time passes, it gets so you depend on them. That’s institutionalized
  17. 網路組成元件 元件 功能 Router 路由器 轉送 IP 封包 (WAN) Switch

    交換器 轉送 ethernet 訊框(LAN) IP 分享器 Router + Switch + DHCP +NAT 無線分享器 wifi + ip 分享器
  18. ROUTER - WAN switch PC 192.168.1.3 PC 192.168.1.4 PC 192.168.1.2

    switch PC 192.168.2.3 PC 192.168.2.4 PC 192.168.2.2 Router 192.168.1.1 192.168.2.1 gateway gateway
  19. ROUTER - WAN switch PC 192.168.1.3 PC 192.168.1.4 PC 192.168.1.2

    Router 192.168.1.1 140.112.123.15 gateway Internet
  20. ROUTER - WAN switch PC 192.168.1.3 PC 192.168.1.4 PC 192.168.1.2

    Router 192.168.1.1 140.112.123.15 gateway Internet devices
  21. ROUTER - NAT switch PC 192.168.1.3 PC 192.168.1.4 PC 192.168.1.2

    Router 192.168.1.1 140.112.123.15 gateway Internet Network address translation
  22. WHAT IS Wi-Fi • 無線區域網路標準 IEEE 802.11 • v2 802.11b

    • v3 802.11g/a - 2.4GHz 5GHz • v4 801.11n bandwidth ~150 Mbit/s • v5 802.11ac bandwidth ~866.7 Mbit/s
  23. Wi-Fi 名詞 • Access Point - AP:發送網路訊號 • Station -

    Client:接收訊號的裝置 • Service Set Identifier - SSID:AP 發送訊號的 名稱
  24. ESP8266 • ESP8266 = Wi-Fi AP + Wi-Fi Client •

    韌體內含 lwip - A Lightweight TCP/IP stack • 預設 SDK 不⽀支援 Forwarding X X
  25. PROTOCOL TCP/IP Stack 對應 Protocol Application Layer(Layer 7) HTTP、DNS、FTP、MQTT Host

    to Host Transport Layer Layer 4 TCP/UDP(Port) Internet Layer Layer 3 IP Network interface Layer Layer 2 Ethernet(MAC)
  26. PACKET 四道⼯工法 data ⼀一 HTTP header data ⼆二 TCP header

    HTTP header data 三 IP header TCP header HTTP header data 四 ethernet header IP header TCP header HTTP header data
  27. 我在松⼭山⼯工農警衛室賣雞排 警衛室 - MAC Address (Layer 2) 松⼭山⼯工農住址 - IP

    Address (Layer 3) 在警衛室的窗⼾戶排隊買 - TCP Port 80(Layer 4) 悠遊卡交易 - HTTP (Layer 7) 想像對應
  28. 實際 架設⼀一個網⾴頁伺服器 電腦 A 的網卡 Mac address(56:50:7a:b0:6b:b8) ( Layer 2

    ) 192.168.1.1 - IP address ( Layer 3 ) 使⽤用 TCP 監聽 Port 1234 ( Layer 4 ) 使⽤用 HTTP 協定( Layer 7 )
  29. NAT 問題 1. 請管理室把所有包裹都送到我房間。 DMZ 轉送所有 Port 到某個 IP 140.112.123.15:*

    =>192.168.1.102:* 2. 請管理室把⿈黃⾊色包裹(Port 80)送到 102 室,綠⾊色包裹 (Port 21) 送到 103 室。 Virtual Server - Port forwarding 140.112.123.15:80 =>192.168.1.102:80 140.112.123.15:21 => 192.168.1.103:21
  30. RX to D2(TX) TX to D3(RX) VCC to 3.3V CHIP_EN

    to 3.3V GPIO02 to 3.3V GPIO15 to GND GPIO0 GPIO2 D2 CLK CMD D0 D1 D3 GPIO4 VCC VCC GPIO15 GPIO13 GPIO12 GPIO14 GPIO16 CH_PD REST ADC GPIO5 GND GND 與 ARDUINO 連接
  31. 程式 #include <SoftwareSerial.h> SoftwareSerial mySerial(3, 2); /* RX:D3, TX:D2 */

    void setup() { mySerial.begin(9600); Serial.begin(9600); Serial.println("start"); } void loop() { if (mySerial.available()) { Serial.write(mySerial.read()); } if (Serial.available()) { char chars = Serial.read(); mySerial.write(chars); } } esp8266-workshop/software-serial
  32. WHAT IS AT • 海斯命令集(Hayes command set;AT command set)原本是為了海斯智慧300數據機所開發的⼀一 種命令語⾔言

    • 指令都是 AT+ 開頭,假設有指令 CMD • AT+CMD? 查詢 CMD 的值 • AT+CMD=XXX 設定 CMD = XXX • AT+CMD 執⾏行指令 CMD
  33. ESP8266 AT COMMAND • 官⽅方提供的韌體,SDK 的功能實踐,直接透 過 Serial 操作 ESP

    • Wi-Fi 組態 • 取得網路狀態 • TCP/IP 指令 • 確保送出換⾏行符號
  34. WIFI STATION • AT+CWLAP 列出附近的 2.4G AP • AT+CWJAP 連線到某台

    AP • AT+CWJAP="TP-LINK","1234567890" • AT+CIPSTA? 查詢取得的 IP • AT+CWQAP 斷線
  35. WIFI AP • AT+CWSAP 設定 AP 參數 • SSID、密碼、頻道、加密⽅方式(0~3) •

    AT+CWSAP=“esp8266","1234567890",5,3 • AT+CWLIF 列出連到此台 AP 的裝置 • AT+CWDHCP 是否啟⽤用 DHCP • AT+CWDHCP=0,1
  36. ESPTOOL https://github.com/themadinventor/esptool ESP8266 ROM Bootloader utility 需安裝 Python 跟 easy_install

    setup.py $ python esptool.py -p /dev/tty.SLAB_USBtoUART write_flash 0x000000 ai-thinker-0.9.5.2-9600.bin
  37. WHAT IS WEEESP8266 An easy-to-use Arduino ESP8266 library besed on

    AT firmware. 把 AT Command 包裝成 arduino 的 API 就是幫你下指令啦 https://github.com/itead/ITEADLIB_Arduino_WeeESP8266
  38. 練習⼆二 透過 WeeESP8266 連接 AP #include <SoftwareSerial.h> #include "ESP8266.h" #define

    SSID "TP-LINK" #define PASSWORD "1234567890" SoftwareSerial mySerial(3, 2); ESP8266 wifi(mySerial); void setup(void) { Serial.begin(9600); Serial.print("setup begin\r\n"); Serial.print("FW Version: "); Serial.println(wifi.getVersion().c_str()); esp8266-workshop/WeeESP8266-client if (wifi.setOprToStation()) { Serial.print("to station ok\r\n"); } else { Serial.print("to station err\r\n"); } if (wifi.joinAP(SSID, PASSWORD)) { Serial.print("Join AP success\r\n"); Serial.print("IP: "); Serial.println(wifi.getLocalIP().c_str()); } else { Serial.print("Join AP failure\r\n"); } Serial.print("setup end\r\n"); }
  39. HTTP RESPONSE HTTP/1.1 200 OK Content-Length: 12 Server: Apache Date:

    Sat, 11 Jan 2015 02:44:04 GMT Content-Type: text/html Connection: keep-alive Hello World!
  40. API wifi.enableMUX() Enable IP MUX(multiple connection mode) wifi.startTCPServer(port) Start TCP

    Server(Only in multiple mode). wifi.recv(mux_id, buffer, length, timeout); Receive data from TCP or UDP builded already in multiple mode.
  41. EXAMPLE SETUP void setup(void) { if (wifi.enableMUX()) { Serial.print("multiple ok\r\n");

    } else { Serial.print("multiple err\r\n"); } if (wifi.startTCPServer(80)) { Serial.print("start tcp server ok\r\n"); } else { Serial.print("start tcp server err\r\n"); } }
  42. EXAMPLE LOOP void loop(void) { uint8_t buffer[128] = {0}; uint8_t

    mux_id; uint32_t len = wifi.recv(&mux_id, buffer, sizeof(buffer), 100); if (len > 0) { uint8_t header[] = "HTTP/1.1 200 OK\r\n" "Content-Length: 24\r\n" "Server: ESP8266\r\n" "Content-Type: text/html\r\n" "Connection: keep-alive\r\n\r\n"; uint8_t hello[] = "<h1>Hello ESP8266!!</h1>"; wifi.send(mux_id, header, sizeof(header)); wifi.send(mux_id, hello, sizeof(hello)); if (wifi.releaseTCP(mux_id)) { Serial.print("release tcp "); Serial.print(mux_id); Serial.println(" ok"); } } }
  43. WEB 組成 前端 渲染畫⾯面 HTML 資料 CSS 畫⾯面 JavaScript UI

    後端 產出 HTML 處理資料庫 Server Browser CSS HTML JavaScript HTTP DB File Sensor…
  44. 使⽤用 HTML 送出資料 <form action="http://data.sparkfun.com/input/QGxWK3RzNdslXlnoNddo"> <input type="text" name="private_key" value="JqxmeGadRlta4ajVZzzV" />

    <input type="text" name="sensor"> <input type="submit" value="送出" /> </form> esp8266-workshop/post.html
  45. 使⽤用 AT 送出資料 # 建⽴立 TCP 連線 AT+CIPSTART=“TCP","api.thingspeak.com",80 # 連線狀態

    AT+CIPSTATUS # 送出資料=資料⻑⾧長度 AT+CIPSEND=82 # 輸⼊入 HTTP Header GET /update? key=WXRLPJC4T2I1RRSP&field1=88 HTTP/1.1 Host: api.thingspeak.com # 連線結束 AT+CIPCLOSE
  46. 程式 wifi.createTCP(HOST_NAME, HOST_PORT) String http = String(); http += "GET

    /update?key="; http += KEY; http += "&field1=" + String(analogRead(7)); http += " HTTP/1.1\r\n"; http += "Host: api.thingspeak.com\r\n"; http += "Connection: close\r\n\r\n"; Serial.println(http); wifi.send((const uint8_t*)http.c_str(), http.length()); uint32_t len = wifi.recv(buffer, sizeof(buffer), 10000); if (len > 0) { for(uint32_t i = 0; i < len; i++) { Serial.print((char)buffer[i]); } Serial.print("]\r\n"); } wifi.releaseTCP(); esp8266-workshop/WeeESP8266-thingspeak
  47. 注意 我的這塊 Uno 無法讓 esp 順利建⽴立 tcp 連線.. :( 各種變異版本

    arduino LDO 採⽤用不同晶⽚片 AMS1117、AX1117 (供應電流不同)
  48. 有什麼? • Digital IO • Analog input *1 • Analog

    output • Timing • Serial • Wi-Fi • Ticker • EEPROM • I2C • SPI • ESP-specific APIs
  49. ESP-201 Flash 512KB GPIO0 GPIO15 GPIO2 GPIO13 D2 GPIO12 CLK

    GPIO14 CMD GPIO16 D0 CH_PD D1 REST D3 ADC GPIO4 GPIO5 VCC GND VCC GND VCC RX TX GND
  50. A REST 切換模式 INPUT http://192.168.0.100/mode/5/i OUTPUT http://192.168.0.100/mode/5/o 修改狀態 低電位 http://192.168.0.100/digital/5/0

    ⾼高電位 http://192.168.0.100/digital/5/1 定義變數與函式 rest.variable(“led",&led); rest.function(“led", ledControl);
  51. 程式 #include <ESP8266WiFi.h> #include <aREST.h> aREST rest = aREST(); WiFiServer

    server(80); void setup() { rest.set_id("1"); rest.set_name("esp8266"); WiFi.begin(ssid, password); while (WiFi.status() != WL_CONNECTED) { delay(500); Serial.print("."); } Serial.println("WiFi connected"); // Start the server server.begin(); // Print the IP address Serial.println(WiFi.localIP()); } void loop() { WiFiClient client = server.available(); if (!client) { return; } while(!client.available()){ delay(1); } rest.handle(client); }
  52. ADC

  53. ADC Mode ADC_MODE(ADC_VCC); 不接 AOUT 輸出量測電源電壓 ADC_MODE(ADC_TOUT); 讀取類⽐比輸⼊入 ESP8266 has

    a single ADC channel available to users. It may be used either to read voltage at ADC pin, or to read module supply voltage (VCC)
  54. 耗電情況 Mode Typical Units 802.11n, MCS7, POUT =+14dBm 135 mA

    802.11b, packet size of 1024 bytes, -80dBm 60 mA Standby 0.9 uA Deep sleep 10 mA Shutdown 0.5 uA
  55. deep sleep API #include "ESP8266WiFi.h" void setup() { Serial.begin(9600); delay(10000);

    } void loop() { Serial.println("sleep"); ESP.deepSleep(1000000 * 10); } ESP.deepSleep(μs); esp8266-workshop/deepsleep
  56. Inter-Integrated Circuit SCL SDA 因為 LCD 吃 5v 所以 I2C

    轉接板 也需供 5v 電喔! 透過 CP2102 輸⼊入 CP2102 5V
  57. LCD API #include <Wire.h> #include <LiquidCrystal_I2C.h> // set the LCD

    address to 0x20 or 0x27 for a 16 chars and 2 line display LiquidCrystal_I2C lcd(0x20, 16, 2); void setup() { lcd.init(); // initialize the lcd lcd.backlight(); lcd.print("ESP8266"); lcd.setCursor(0, 1); lcd.print("Arduino x Wi-Fi!”); }
  58. n = WiFi.scanNetworks() 掃描 Access Point SSID = WiFi.SSID(i) 取得第

    i 個 SSID SSID = WiFi.RSSI(i) 取得第 i 個 RSSI Received Signal Strength Indication 信號強度,越接近零越好 ESP8266 API 掃描 AP
  59. ESP8266 API 掃描 AP void loop() { int n =

    WiFi.scanNetworks(); if (n == 0) { Serial.println("no networks found"); return; } Serial.print(n); Serial.println(" networks found"); for (int i = 0; i < n; ++i) { // Print SSID and RSSI for each network found lcd.clear(); lcd.setCursor(0, 0); lcd.print(i + 1); lcd.print(". "); lcd.print(WiFi.SSID(i)); lcd.setCursor(0, 1); lcd.print("RSSI: "); lcd.print(WiFi.RSSI(i)); } } esp8266-workshop/i2c-lcd
  60. SPIFFS https://github.com/pellepl/spiffs Wear-leveled SPI flash file system for embedded devices

    把 EEPROM 變成檔案系統 可⽤用於儲存 config 或 log NodeMCU 與 ESP8266/Arduino 皆有
  61. SPIFFS API EXAMPLE #include “FS.h" SPIFFS.begin() File file = SPIFFS.open("/config.txt",

    "w"); file.println(“hello”); File file = SPIFFS.open("/config.txt", "r"); Serial.println(file.readStringUntil('\n'));
  62. 再論韌體 官⽅方 SDK + AT Command 1.0 以後需要 1MB Flash

    ⺫⽬目前韌體⼤大都基於 0.9.5 SDK 開發 只需 512KB Flash AT Command 沒 Open Source
  63. 再論韌體 Sming - Open Source framework for high efficiency native

    ESP8266 development ⾮非 Arduino 的 ESP8266 韌體開發環境, 應⽤用範例多,最豐富的 SDK 範例
  64. WIFI CONNECT 儲存成 init.lua 等同於 arduino setup() print("hello nodemcu"); wifi.setmode(wifi.STATION);

    wifi.sta.config("TP-LINK", "1234567890"); wifi.sta.connect(); tmr.alarm(1, 1000, 1, function() if wifi.sta.getip() == nil then print("Wating...") else tmr.stop(1) print("IP is"..wifi.sta.getip()) end end) tmr.alarm(id, interval, repeat, function do()) esp8266-workshop/wifi-connect
  65. WEB SERVER srv = net.createServer(net.TCP) srv:listen(80, function(conn) conn:on("receive", function(client, request)

    local buf = ""; local _, _, method, path, vars = string.find(request, "([A-Z]+) (.+)\?(.+) HTTP"); if(method == nil)then _, _, method, path = string.find(request, "([A-Z]+) (.+) HTTP"); end local _GET = {} if (vars ~= nil)then for k, v in string.gmatch(vars, "(%w+)=(%w+)&*") do _GET[k] = v end end buf = buf.."<h1>ESP8266 Web Server</h1>"; client:send(buf); client:close(); collectgarbage(); end) end)
  66. WEB SERVER srv = net.createServer(net.TCP) srv:listen(80, function(conn) conn:on("receive", function(client, request)

    local buf = ""; local _, _, method, path, vars = string.find(request, "([A-Z]+) (.+)?(.+) HTTP"); if(method == nil)then _, _, method, path = string.find(request, "([A-Z]+) (.+) HTTP"); end local _GET = {} if (vars ~= nil)then for k, v in string.gmatch(vars, "(%w+)=(%w+)&*") do _GET[k] = v end end buf = buf.."<h1>ESP8266 Web Server</h1>"; client:send(buf); client:close(); collectgarbage(); end) end)