寫在前面的話:個人學習筆記,拋磚引玉,希望有興趣的人加入QQ羣415469069一起討論,歡迎有共同愛好的人。
本教程以ESP-12N,CP2102開發板爲例進行講解。
- 代碼。
--wifi_light.lua wifi.setmode(wifi.STATION) wifi.sta.config("YOUR_NETWORK_NAME","YOUR_NETWORK_PASSWORD") print(wifi.sta.getip()) led1 = 0 gpio.mode(led1, gpio.OUTPUT) 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>"; buf = buf.."<p>GPIO16 <a href=\"?pin=ON1\"><button>ON</button></a> <a href=\"?pin=OFF1\"><button>OFF</button></a></p>"; if(_GET.pin == "ON1")then gpio.write(led1, gpio.LOW); elseif(_GET.pin == "OFF1")then gpio.write(led1, gpio.HIGH); end client:send(buf); client:close(); collectgarbage(); end) end) |
二、說明:
- ,wifi模式爲station,輸入wifi名和密碼進行配置。
句法:wifi.setmode(mode[, save]) 作用:配置WiFi模式使用 參數: mode 價值應該是其中之一 wifi.STATION:當設備連接到WiFi路由器時。這通常是爲了讓設備訪問互聯網。 wifi.SOFTAP: 因爲當設備只作爲一個接入點。這將允許您在WiFi網絡列表中查看設備(當然,除非您隱藏SSID)。在這種模式下,您的計算機可以連接到設備,創建一個局域網。除非您更改該值,否則NodeMCU設備將被分配一個本地IP地址192.168.4.1,併爲您的計算機分配下一個可用的IP地址,例如192.168.4.2。 wifi.STATIONAP:是的組合wifi.STATION和wifi.SOFTAP。它允許您創建本地WiFi連接並連接到另一個WiFi路由器。 wifi.NULLMODE:將WiFi模式更改爲NULL_MODE將使wifi進入與MODEM_SLEEP類似的低功耗狀態,但未提供wifi.nullmodesleep(false)。 save 選擇是否將wifi模式保存到閃存 true:WiFi模式配置將在電源週期中保留。(默認) false:WiFi模式配置將不會通過重新啓動進行保留。 |
- led = 0,對應的是GPIO16,開發板上這個引腳外焊了個led,可以利用。
- 創建服務器,監聽80端口。
句法:net.createServer([type[, timeout]]) 作用:創建一個服務器。 參數: type: net.TCP (默認)或 net.UDP Timeout: 對於TCP服務器,超時時間爲1〜28'800秒,默認30秒(非活動客戶端斷開連接) 返回: net.TCP 時返回: net.server子模塊 net.UDP時返回: net.udpsocket子模塊 |
句法:net.server:listen([port],[ip],function(net.socket)) 作用:從IP地址偵聽端口。 參數: port: 端口號,可以省略(隨機端口將被選中) ip: IP地址字符串,可以省略 function(net.socket): 回調函數,如果連接成功創建,則傳遞給調用者函數 第一個參數: 回調的第一個參數是套接字(即socket)。 第二個參數: 如果事件是“接收”,則第二個參數是以字符串形式接收的數據。 如果事件是“斷開”或“重新連接”,則第二個參數是錯誤代碼。 如果指定了重新連接事件,則斷開只接收“正常關閉”事件。 否則,所有連接錯誤(正常關閉)傳遞到斷開連接事件。 |
句法:net.socket:on(event, function()) 作用:註冊特定事件的回調函數 參數: event: 字符串,可以是“連接”,“重新連接”,“斷開”,“接收”或“發送” function(net.socket[, string]):回調函數。可以nil刪除回調。 |
句法:net.socket:send(string[, function(sent)]) 參數: string: 字符串中的數據將被髮送到服務器 function(sent): 用於發送字符串的回調函數 |
句法:net.socket:close() 作用:關閉嵌套字 |
- 處理接收的數據(即字符串request的內容)
關鍵字local:定義局部變量。 |
|||||||||||||||||||||||||||||||||||||||||||||
_, 指聲明虛變量,說白了就是我不想要前兩個返回值,給他個虛變量名,以後不會調用此數據。 |
|||||||||||||||||||||||||||||||||||||||||||||
string.find (str, substr, [init, [end]]) 第一個返回值:起始位置。 第二個返回值:終止位置。 |
|||||||||||||||||||||||||||||||||||||||||||||
string.gmatch(s, pattern) 會返回一個迭代器函數,通過這個函數可以遍歷到一個字符串中所有出現指定模式的地方。這個函數可以通過泛型for提取數據。 |
|||||||||||||||||||||||||||||||||||||||||||||
匹配模式 Lua 中的匹配模式直接用常規的字符串來描述。 它用於模式匹配函數 string.find, string.gmatch, string.gsub, string.match。 你還可以在模式串中使用字符類。 字符類指可以匹配一個特定字符集合內任何字符的模式項。比如,字符類%d匹配任意數字。所以你可以使用模式串 '%d%d/%d%d/%d%d%d%d' 搜索 dd/mm/yyyy 格式的日期:
下面的表列出了Lua支持的所有字符類: 單個字符(除 ^$()%.[]*+-? 外): 與該字符自身配對。 當上述的字符類用大寫書寫時, 表示與非此字符類的任何字符配對. 例如, %S表示與任何非空白字符配對.例如,'%A'非字母的字符。
在模式匹配中有一些特殊字符,他們有特殊的意義,Lua中的特殊字符如下: ( ) . % + - * ? [ ^ $ '%' 用作特殊字符的轉義字符,因此 '%.' 匹配點;'%%' 匹配字符 '%'。轉義字符 '%'不僅可以用來轉義特殊字符,還可以用於所有的非字母的字符。 模式條目可以是:
模式 指一個模式條目的序列。 在模式最前面加上符號 '^' 將錨定從字符串的開始處做匹配。 在模式最後面加上符號 '$' 將使匹配過程錨定到字符串的結尾。 如果 '^' 和 '$' 出現在其它位置,它們均沒有特殊含義,只表示自身。 捕獲:模式可以在內部用小括號括起一個子模式; 這些子模式被稱爲 捕獲物。 當匹配成功時,由 捕獲物 匹配到的字符串中的子串被保存起來用於未來的用途。 捕獲物以它們左括號的次序來編號。 例如,對於模式 "(a*(.)%w(%s*))" , 字符串中匹配到 "a*(.)%w(%s*)" 的部分保存在第一個捕獲物中 (因此是編號 1 ); 由 "." 匹配到的字符是 2 號捕獲物, 匹配到 "%s*" 的那部分是 3 號。 作爲一個特例,空的捕獲 () 將捕獲到當前字符串的位置(它是一個數字)。 例如,如果將模式 "()aa()" 作用到字符串"flaaap" 上,將產生兩個捕獲物: 3 和 5 。 |
- 數據類型Table(表)
在 Lua 裏,table 的創建是通過"構造表達式"來完成,最簡單構造表達式是{},用來創建一個空表。也可以在表裏添加一些數據,直接初始化表:
-- |
|||||
泛型 for 迭代器: 泛型 for 在自己內部保存迭代函數,實際上它保存三個值:迭代函數、狀態常量、控制變量。 泛型 for 迭代器提供了集合的 key/value 對,語法格式如下:
上面代碼中,k, v爲變量列表;pair(t)爲表達式列表。 以上實例中我們使用了 Lua 默認提供的迭代函數 ipairs。 下面我們看看泛型 for 的執行過程: 首先,初始化,計算in後面表達式的值,表達式應該返回泛型 for 需要的三個值:迭代函數、狀態常量、控制變量;與多值賦值一樣,如果表達式返回的結果個數不足三個會自動用nil補足,多出部分會被忽略。 第二,將狀態常量和控制變量作爲參數調用迭代函數(注意:對於for結構來說,狀態常量沒有用處,僅僅在初始化時獲取他的值並傳遞給迭代函數)。 第三,將迭代函數返回的值賦給變量列表。 第四,如果返回的第一個值爲nil循環結束,否則執行循環體。 第五,回到第二步再次調用迭代函數。 |
三、Tips。
將代碼保存爲wifi_light.lua,下載到ESP中,如果想上電就運行這個程序,可以在第一課的init.lua文件中加上紅色標註的代碼:
--本程序爲初始化程序init.lua,ESP8266上電後會默認從此程序開始運行。 -- -- --開發板上藍色小燈閃爍3下,表明程序已經運行,調試收到信息“success” gpio.mode(0,gpio.OUTPUT) for i = 1, 3 ,1 do gpio.write(0,gpio.LOW) --tmr.delay(s)中s單位爲微秒,1000000微秒=1秒 tmr.delay(500000) gpio.write(0,gpio.HIGH) tmr.delay(500000) end print("success","\n") --運行子程序 --內網控制LED程序。 dofile("wifi_light.lua") |
使用遠程控制。
1、ESP上電後配置好wifi連接之後就調用print(wifi.sta.getip()),由於連接上路由器需要一定的時間,因此,在小燈閃過三次,控制檯顯示success後,print(wifi.sta.getip())會打印出字符串nil,意思是沒有獲取到ip的信息。這時,就需要我們重新獲取了。
等待幾秒鐘,待ESP成功連接路由器後,在開發軟件的右下角,向ESP發送單條命令print(wifi.sta.getip())。得到返回信息,如果是nil,過幾秒後再嘗試,直到看到需要的信息。
返回的信息“192.168.100.130 255.255.255.0 192.168.100.1”中:
192.168.100.130爲ESP的IP地址,255.255.255.0爲子網掩碼,
192.168.100.1爲網關。
2、打開瀏覽器(手機瀏覽器、電腦瀏覽器均可),保證打開瀏覽器的設備與ESP連接的是同一個路由器。輸入ESP的IP地址(即192.168.100.130),我們配置的簡單服務器將顯示出來。
3、點擊按鈕ON,開發板上的小燈將亮起。
點擊按鈕OFF,開發板上的小燈將熄滅。