├── .gitattributes ├── .gitignore ├── 1.构建、刷入固件,上传代码 ├── README.md ├── img │ ├── esplorer-ok.png │ ├── esplorer-open.png │ ├── esplorer-upload.png │ ├── flasher-config.png │ ├── flasher-finished.png │ ├── flasher-flashing.png │ └── nodemcu.jpg └── source │ └── init.lua ├── 2.断线自动重连,闪烁连接状态 ├── README.md └── source │ └── init.lua ├── 3.响应配置按钮 ├── README.md ├── img │ └── wiring.jpg └── source │ └── init.lua ├── 4.实现Web配置页面 ├── README.md ├── img │ └── config.png └── source │ ├── httpServer.lua │ ├── index.html │ ├── init.lua │ ├── spectre.min.css.gz │ └── zepto.min.js.gz └── 相关资源 ├── ESPlorer ├── ESPlorer.Log ├── ESPlorer.bat ├── ESPlorer.jar ├── README.TXT ├── _lua │ └── test100lines.lua ├── _micropython │ ├── MicroPython-1.7-130.bin │ └── gpio.py └── lib │ ├── AbsoluteLayout.jar │ ├── beansbinding-1.2.1.jar │ ├── jssc.jar │ └── rsyntaxtextarea-2.5.6.jar ├── NODEMCU-DEVKIT-INSTRUCTION-CN.pdf ├── NodeMCU ESP12.png ├── nodemcu-flasher-master ├── .gitignore ├── Clean.bat ├── DataChest.pas ├── DelphiZXIngQRCode.pas ├── ESP8266Flasher.dpr ├── ESP8266Flasher.dproj ├── ESP8266Flasher.res ├── LICENSE ├── README.md ├── Resource.rc ├── Resource.res ├── Resources │ ├── Binaries │ │ ├── 0x00000.bin │ │ ├── 0x10000.bin │ │ ├── blank.bin │ │ ├── esp_init_data_default.bin │ │ └── nodemcu_integer_0.9.5_20150318.bin │ ├── Images │ │ ├── File.png │ │ ├── Logo.ico │ │ ├── Logo.png │ │ ├── No.png │ │ ├── Setting.png │ │ ├── Wait.GIF │ │ └── Yes.png │ └── Webpages │ │ └── index.php ├── SPComm.pas ├── SerialPortsCtrl.pas ├── UnitESP8266Protocol.pas ├── UnitFormMain.dfm ├── UnitFormMain.pas ├── UnitFrameConfigLine.dfm ├── UnitFrameConfigLine.pas ├── Win32 │ └── Release │ │ └── ESP8266Flasher.exe └── Win64 │ └── Release │ └── ESP8266Flasher.exe └── nodemcu-master-12-modules-2016-07-05-07-20-39-float.bin /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | 4 | # Custom for Visual Studio 5 | *.cs diff=csharp 6 | 7 | # Standard to msysgit 8 | *.doc diff=astextplain 9 | *.DOC diff=astextplain 10 | *.docx diff=astextplain 11 | *.DOCX diff=astextplain 12 | *.dot diff=astextplain 13 | *.DOT diff=astextplain 14 | *.pdf diff=astextplain 15 | *.PDF diff=astextplain 16 | *.rtf diff=astextplain 17 | *.RTF diff=astextplain 18 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Windows image file caches 2 | Thumbs.db 3 | ehthumbs.db 4 | 5 | # Folder config file 6 | Desktop.ini 7 | 8 | # Recycle Bin used on file shares 9 | $RECYCLE.BIN/ 10 | 11 | # Windows Installer files 12 | *.cab 13 | *.msi 14 | *.msm 15 | *.msp 16 | 17 | # Windows shortcuts 18 | *.lnk 19 | 20 | # ========================= 21 | # Operating System Files 22 | # ========================= 23 | 24 | # OSX 25 | # ========================= 26 | 27 | .DS_Store 28 | .AppleDouble 29 | .LSOverride 30 | 31 | # Thumbnails 32 | ._* 33 | 34 | # Files that might appear in the root of a volume 35 | .DocumentRevisions-V100 36 | .fseventsd 37 | .Spotlight-V100 38 | .TemporaryItems 39 | .Trashes 40 | .VolumeIcon.icns 41 | 42 | # Directories potentially created on remote AFP share 43 | .AppleDB 44 | .AppleDesktop 45 | Network Trash Folder 46 | Temporary Items 47 | .apdisk 48 | -------------------------------------------------------------------------------- /1.构建、刷入固件,上传代码/README.md: -------------------------------------------------------------------------------- 1 | # NodeMCU之旅(一):构建、刷入固件,上传代码 2 | 3 | ## 扬帆起航 4 | 5 | 本系列文章将试图实现,使用Web页面远程点亮led。具体包括: 6 | 7 | * 在NodeMCU上搭建HTTP服务器,使其可以通过Web页面配置要接入的网络。 8 | 9 | * 在配置页面可以显示附近中英网络名与信号强度。 10 | 11 | * 使用MQTT协议与Node.js服务端的通信。 12 | 13 |  14 | 15 | 16 | 17 | ## 构建固件 18 | 19 | [Building the firmware](http://nodemcu.readthedocs.io/en/master/en/build/)提供了三种构建你自己固件的方式。 20 | 21 | 这里推荐使用简单的云构建服务[NodeMCU custom builds](http://nodemcu-build.com/)来定制自己的固件,只需要在该网站选择你需要的库,留下邮箱,不一会就能收到编译好的固件。 22 | 23 | 我选择了这些库:cjson,crypto,file,gpio,http,mqtt,net,node,pwm,tmr,uart,wifi 24 | 25 | 26 | 27 | ## 刷入固件 28 | 29 | 下载[nodemcu-flasher](https://github.com/nodemcu/nodemcu-flasher)的**Release**版本,注意操作系统位数。 30 | 31 | 连接NodeMCU到电脑,运行**flasher**。 32 | 33 | 在**Config**选项卡下,配置好自己固件的路径。 34 | 35 |  36 | 37 | 然后回到**Operation**下,点击**Flash(F)**,稍等片刻即可。 38 | 39 |  40 | 41 |  42 | 43 | 44 | 45 | ## 上传代码 46 | 47 | [Uploading code](http://nodemcu.readthedocs.io/en/master/en/upload/)同样提供了多种工具来上传代码与文件到NodeMCU。 48 | 49 | 推荐使用**ESPlorer**,需要**Java环境**。下载[ESPlorer.zip](http://esp8266.ru/esplorer/#download)。 50 | 51 | 解压后,运行**ESPlorer.jar**。 52 | 53 | 在ESPlorer窗口右上部,设置端口号。 54 | 55 | 点击**Open**,按下NodeMCU上的**RST**按钮重启。如果一切正常,会有这些输出: 56 | 57 |  58 | 59 | NodeMCU会在启动后立即运行**init.lua**,但是现在我们还没有上传这个文件。 60 | 61 | 用你喜爱的编辑器保存下面代码为**init.lua**。这些代码会使NodeMCU连接到一个AP(Access Point),通过修改第四行代码来配置SSID和密码。对于开放网络,使用空文本作为密码。 62 | 63 | ``` lua 64 | -- init.lua 65 | print('Setting up WIFI...') 66 | wifi.setmode(wifi.STATION) 67 | wifi.sta.config('MY_SSID', 'MY_PASSWORD') 68 | wifi.sta.connect() 69 | 70 | tmr.alarm(1, 1000, tmr.ALARM_AUTO, function() 71 | if wifi.sta.getip() == nil then 72 | print('Waiting for IP ...') 73 | else 74 | print('IP is ' .. wifi.sta.getip()) 75 | tmr.stop(1) 76 | end 77 | end) 78 | ``` 79 | 80 | 保存后,点击ESPlorer窗口左下区域的**Upload ...**来上传。如果上传失败,尝试重启NodeMCU再试。 81 | 82 |  83 | 84 | 上传完毕后重启NodeMCU。如果一切正常,你将看到NodeMCU成功连入你的AP。 85 | 86 |  87 | 88 | 89 | 90 | ## 相关资源 91 | 92 | [NodeMCU文档](http://nodemcu.readthedocs.io/) 93 | 94 | [NodeMCU custom builds](http://nodemcu-build.com/) 95 | 96 | [nodemcu-flasher](https://github.com/nodemcu/nodemcu-flasher) 97 | 98 | [ESPlorer.zip](http://esp8266.ru/esplorer/#download) 99 | 100 | 你也可以在[NodeMCU-Tutorial](https://github.com/wangzexi/NodeMCU-Tutorial)下载到本文的相关资源和代码。 -------------------------------------------------------------------------------- /1.构建、刷入固件,上传代码/img/esplorer-ok.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangzexi/NodeMCU-Tutorial/87a4268833cad7cb9da71eac28cfb88c8fa0fdc5/1.构建、刷入固件,上传代码/img/esplorer-ok.png -------------------------------------------------------------------------------- /1.构建、刷入固件,上传代码/img/esplorer-open.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangzexi/NodeMCU-Tutorial/87a4268833cad7cb9da71eac28cfb88c8fa0fdc5/1.构建、刷入固件,上传代码/img/esplorer-open.png -------------------------------------------------------------------------------- /1.构建、刷入固件,上传代码/img/esplorer-upload.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangzexi/NodeMCU-Tutorial/87a4268833cad7cb9da71eac28cfb88c8fa0fdc5/1.构建、刷入固件,上传代码/img/esplorer-upload.png -------------------------------------------------------------------------------- /1.构建、刷入固件,上传代码/img/flasher-config.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangzexi/NodeMCU-Tutorial/87a4268833cad7cb9da71eac28cfb88c8fa0fdc5/1.构建、刷入固件,上传代码/img/flasher-config.png -------------------------------------------------------------------------------- /1.构建、刷入固件,上传代码/img/flasher-finished.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangzexi/NodeMCU-Tutorial/87a4268833cad7cb9da71eac28cfb88c8fa0fdc5/1.构建、刷入固件,上传代码/img/flasher-finished.png -------------------------------------------------------------------------------- /1.构建、刷入固件,上传代码/img/flasher-flashing.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangzexi/NodeMCU-Tutorial/87a4268833cad7cb9da71eac28cfb88c8fa0fdc5/1.构建、刷入固件,上传代码/img/flasher-flashing.png -------------------------------------------------------------------------------- /1.构建、刷入固件,上传代码/img/nodemcu.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangzexi/NodeMCU-Tutorial/87a4268833cad7cb9da71eac28cfb88c8fa0fdc5/1.构建、刷入固件,上传代码/img/nodemcu.jpg -------------------------------------------------------------------------------- /1.构建、刷入固件,上传代码/source/init.lua: -------------------------------------------------------------------------------- 1 | print('Setting up WIFI...') 2 | wifi.setmode(wifi.STATION) 3 | wifi.sta.config('MY_SSID', 'MY_PASSWORD') 4 | wifi.sta.connect() 5 | 6 | tmr.alarm(1, 1000, tmr.ALARM_AUTO, function() 7 | if wifi.sta.getip() == nil then 8 | print('Waiting for IP ...') 9 | else 10 | print('IP is ' .. wifi.sta.getip()) 11 | tmr.stop(1) 12 | end 13 | end) -------------------------------------------------------------------------------- /2.断线自动重连,闪烁连接状态/README.md: -------------------------------------------------------------------------------- 1 | # NodeMCU之旅(二):断线自动重连,闪烁连接状态 2 | 3 | ## 事件监听器 4 | 5 | NodeMCU采用了事件响应的方式。也就是说,只需为事件设置一个回调函数,当事件发生时,回调函数就会被调用。 6 | 7 | > 注册事件监听器 8 | > [wif.sta.eventMonReg()](http://nodemcu.readthedocs.io/en/master/en/modules/wifi/#wifistaeventmonreg) 9 | > 10 | > 开始监听 11 | > [wifi.sta.eventMonStart()](http://nodemcu.readthedocs.io/en/master/en/modules/wifi/#wifistaeventmonstart) 12 | 13 | ### 通过监听器获知wifi连接状态 14 | 15 | ```lua 16 | -- init.lua 17 | print('Setting up WIFI...') 18 | wifi.setmode(wifi.STATION) 19 | wifi.sta.config('MY_SSID', 'MY_PASSWORD') 20 | wifi.sta.connect() 21 | 22 | status = nil 23 | 24 | wifi.sta.eventMonReg(wifi.STA_GOTIP, function() 25 | status = 'STA_GOTIP' 26 | print(status, wifi.sta.getip()) 27 | end) 28 | 29 | wifi.sta.eventMonStart(1000) 30 | ``` 31 | 32 | `wifi.sta.eventMonStart(1000)`函数表明检测网络状态的间隔是一秒。 33 | 34 | 不止如此,常用的监听器还有: 35 | 36 | ```lua 37 | wifi.sta.eventMonReg(wifi.STA_WRONGPWD, function() 38 | status = 'STA_WRONGPWD' 39 | print(status) 40 | end) 41 | 42 | wifi.sta.eventMonReg(wifi.STA_APNOTFOUND, function() 43 | status = 'STA_APNOTFOUND' 44 | print(status) 45 | end) 46 | 47 | wifi.sta.eventMonReg(wifi.STA_CONNECTING, function(previous_State) 48 | status = 'STA_CONNECTING' 49 | print(status) 50 | end) 51 | ``` 52 | 53 | 54 | 55 | ## 断线自动重连 56 | 57 | 有时因为路由器重启等原因,NodeMCU可能会掉线,好在NodeMCU可以设置自动连接: 58 | 59 | > 自动连接 60 | > [wifi.sta.autoconnect()](http://nodemcu.readthedocs.io/en/master/en/modules/wifi/#wifistaautoconnect) 61 | 62 | 替换上节代码中的`wifi.sta.connect()`为 63 | 64 | 65 | ```lua 66 | wifi.sta.autoconnect(1) 67 | ``` 68 | 69 | 这样,当配置的wifi有效时,NodeMCU便能自动连入。 70 | 71 | 72 | 73 | ## 控制LED闪烁 74 | 75 | 在NodeMCU上有一个LED可用。可以用它来显示当前的连接状态。经测试,控制该LED的引脚为D4。 76 | 77 | 这是一个控制LED以特定延迟序列闪烁的函数。 78 | 79 | ```lua 80 | IO_BLINK = 4 81 | TMR_BLINK = 5 82 | 83 | gpio.mode(IO_LED_BLINK, gpio.OUTPUT) 84 | 85 | blink = nil 86 | tmr.register(TMR_BLINK, 100, tmr.ALARM_AUTO, function() 87 | gpio.write(IO_BLINK, blink.i % 2) 88 | tmr.interval(TMR_BLINK, blink[blink.i + 1]) 89 | blink.i = (blink.i + 1) % #blink 90 | end) 91 | 92 | function blinking(param) 93 | if type(param) == 'table' then 94 | blink = param 95 | blink.i = 0 96 | tmr.interval(TMR_BLINK, 1) 97 | running, _ = tmr.state(TMR_BLINK) 98 | if running ~= true then 99 | tmr.start(TMR_BLINK) 100 | end 101 | else 102 | tmr.stop(TMR_BLINK) 103 | gpio.write(IO_BLINK, param or gpio.LOW) 104 | end 105 | end 106 | ``` 107 | 108 | `blinking()`函数需要传入一个数组,数组元素依次表示LED亮灭的延迟。例子: 109 | 110 | ```lua 111 | blinking({300, 300}) -- 循环闪烁:亮300ms,灭300ms 112 | blinking({100, 100 , 100, 500}) -- 循环闪烁:亮100ms,灭100ms,亮100ms,灭500ms 113 | 114 | blinking() -- 常亮 115 | blinking(gpio.LOW) -- 常亮 116 | blinking(gpio.HIGH) -- 常灭 117 | ``` 118 | 119 | 120 | 121 | ## 闪烁显示连接状态 122 | 123 | 现在就可以结合监听器用LED显示连接状态了。 124 | 125 | 在上一节的监听器事件里,各添加一行闪烁的即可。 126 | 127 | ```lua 128 | wifi.sta.eventMonReg(wifi.STA_WRONGPWD, function() 129 | blinking({100, 100 , 100, 500}) 130 | status = 'STA_WRONGPWD' 131 | print(status) 132 | end) 133 | 134 | wifi.sta.eventMonReg(wifi.STA_APNOTFOUND, function() 135 | blinking({2000, 2000}) 136 | status = 'STA_APNOTFOUND' 137 | print(status) 138 | end) 139 | 140 | wifi.sta.eventMonReg(wifi.STA_CONNECTING, function(previous_State) 141 | blinking({300, 300}) 142 | status = 'STA_CONNECTING' 143 | print(status) 144 | end) 145 | 146 | wifi.sta.eventMonReg(wifi.STA_GOTIP, function() 147 | blinking() 148 | status = 'STA_GOTIP' 149 | print(status, wifi.sta.getip()) 150 | end) 151 | ``` 152 | 153 | 154 | 155 | ## 相关资源 156 | 157 | 你可以在[NodeMCU-Tutorial](https://github.com/wangzexi/NodeMCU-Tutorial)下载到本文的相关资源和代码。 -------------------------------------------------------------------------------- /2.断线自动重连,闪烁连接状态/source/init.lua: -------------------------------------------------------------------------------- 1 | ------------- 2 | -- define 3 | ------------- 4 | IO_BLINK = 4 5 | TMR_BLINK = 5 6 | 7 | gpio.mode(IO_BLINK, gpio.OUTPUT) 8 | 9 | ------------- 10 | -- blink 11 | ------------- 12 | blink = nil 13 | tmr.register(TMR_BLINK, 100, tmr.ALARM_AUTO, function() 14 | gpio.write(IO_BLINK, blink.i % 2) 15 | tmr.interval(TMR_BLINK, blink[blink.i + 1]) 16 | blink.i = (blink.i + 1) % #blink 17 | end) 18 | 19 | function blinking(param) 20 | if type(param) == 'table' then 21 | blink = param 22 | blink.i = 0 23 | tmr.interval(TMR_BLINK, 1) 24 | running, _ = tmr.state(TMR_BLINK) 25 | if running ~= true then 26 | tmr.start(TMR_BLINK) 27 | end 28 | else 29 | tmr.stop(TMR_BLINK) 30 | gpio.write(IO_BLINK, param or gpio.LOW) 31 | end 32 | end 33 | 34 | ------------- 35 | -- wifi 36 | ------------- 37 | print('Setting up WIFI...') 38 | wifi.setmode(wifi.STATION) 39 | wifi.sta.config('MY_SSID', 'MY_PASSWORD') 40 | wifi.sta.autoconnect(1) 41 | 42 | status = nil 43 | 44 | wifi.sta.eventMonReg(wifi.STA_WRONGPWD, function() 45 | blinking({100, 100 , 100, 500}) 46 | status = 'STA_WRONGPWD' 47 | print(status) 48 | end) 49 | 50 | wifi.sta.eventMonReg(wifi.STA_APNOTFOUND, function() 51 | blinking({2000, 2000}) 52 | status = 'STA_APNOTFOUND' 53 | print(status) 54 | end) 55 | 56 | wifi.sta.eventMonReg(wifi.STA_CONNECTING, function(previous_State) 57 | blinking({300, 300}) 58 | status = 'STA_CONNECTING' 59 | print(status) 60 | end) 61 | 62 | wifi.sta.eventMonReg(wifi.STA_GOTIP, function() 63 | blinking() 64 | status = 'STA_GOTIP' 65 | print(status, wifi.sta.getip()) 66 | end) 67 | 68 | wifi.sta.eventMonStart(1000) 69 | -------------------------------------------------------------------------------- /3.响应配置按钮/README.md: -------------------------------------------------------------------------------- 1 | # NodeMCU之旅(三):响应配置按钮 2 | 3 | ## 引言 4 | 在之前的代码中,要连接的WIFI信息都已写死在代码里,这显然不能适应我们的需求。所以需要想个办法让用户可以配置这些信息。 5 | 6 | 7 | 8 | ## WIFI工作模式 9 | 10 | NodeMCU支持STATION,SOFTAP,STATIONAP,NULLMODE四种模式。 11 | > 设置WIFI模式 12 | > [wifi.setmode()](http://nodemcu.readthedocs.io/en/master/en/modules/wifi/#wifisetmode) 13 | > 14 | > * `wifi.STATION` 当设备需要连接到WIFI路由器时使用。常在访问Internet时使用。 15 | > * `wifi.SOFTAP` 当设备需要作为热点时使用。在此模式下你的设备会创建一个本地局域网,并出现在WIFI列表。在默认情况下,NodeMCU在本地局域网地址为192.168.4.1,其他设备将被分配为下一个的可用IP,比如192.168.4.2。 16 | > * `wifi.STATIONAP` 同时应用以上两者。在此模式下你可以在创建一个热点的同时连接到其他WIFI路由器。 17 | > * `wifi.NULLMODE` 关闭WIFI。 18 | 19 | 所以可以添加一个按钮,当按钮按下时,转换模式为`WIFI.STATIONAP`,然后通过手机接入NodeMCU的热点,进入设置页面配置WIFI信息。就像配置路由器一样。 20 | 21 | 22 | 23 | ## 接线 24 | 25 |  26 | 27 | * 绿色的LED就是未来被远程控制的那颗,正极连接D1。 28 | 29 | * 黄色的LED用于显示当前的WIFI工作模式,正极连接D2。 30 | 31 | * 白色的按钮连接D3。 32 | 33 | * 负极连接GND。 34 | 35 | 接线完成后,定义这些引脚: 36 | 37 | ```lua 38 | IO_LED = 1 39 | IO_LED_AP = 2 40 | IO_BTN_CFG = 3 41 | 42 | gpio.mode(IO_LED, gpio.OUTPUT) 43 | gpio.mode(IO_LED_AP, gpio.OUTPUT) 44 | gpio.mode(IO_BTN_CFG, gpio.INT) 45 | ``` 46 | 47 | 注意,`IO_BTN_CFG`被设置为了`gpio.INT`模式,也就是中断模式。 48 | 49 | 50 | 51 | ## 响应按钮 52 | 53 | 通过`gpio.trig()`设置响应中断的回调函数。 54 | 55 | > 设置响应中断的回调函数 56 | > [gpio.trig()](http://nodemcu.readthedocs.io/en/master/en/modules/gpio/#gpiotrig) 57 | 58 | 响应按钮抬起时的事件: 59 | 60 | ```lua 61 | function onBtnEvent() 62 | print('up~') 63 | end 64 | gpio.trig(IO_BTN_CFG, 'up', onBtnEvent) 65 | ``` 66 | 67 | 上传代码。测试按下按钮,发现输出正常。 68 | 69 | 但存在一个问题:有时只按了一次,输出却不止一次。因为按钮的信号会有抖动。 70 | 71 | 这里提供一种去抖方法: 72 | 73 | ```lua 74 | TMR_BTN = 6 75 | 76 | function onBtnEvent() 77 | gpio.trig(IO_BTN_CFG) 78 | tmr.alarm(TMR_BTN, 500, tmr.ALARM_SINGLE, function() 79 | gpio.trig(IO_BTN_CFG, 'up', onBtnEvent) 80 | end) 81 | 82 | print('up~') 83 | end 84 | gpio.trig(IO_BTN_CFG, 'up', onBtnEvent) 85 | ``` 86 | 87 | 思路是,在首次触发之后,清除按钮的回调函数,在0.5秒后,恢复回调。 88 | 89 | 90 | 91 | ## 开始与结束配置 92 | 93 | 正如之前所讲,平常运行时WIFI模式为`wifi.STATION`,当按下按钮后,WIFI模式转为`wifi.STATIONAP`,再次按下后恢复`wifi.STATION`。 94 | 95 | ```lua 96 | gpio.write(IO_LED_AP, gpio.LOW) 97 | 98 | function switchCfg() 99 | if wifi.getmode() == wifi.STATION then 100 | wifi.setmode(wifi.STATIONAP) 101 | gpio.write(IO_LED_AP, gpio.HIGH) 102 | else 103 | wifi.setmode(wifi.STATION) 104 | gpio.write(IO_LED_AP, gpio.LOW) 105 | end 106 | end 107 | ``` 108 | 109 | 注意,`gpio.write(IO_LED_AP, gpio.LOW)`在函数外部,目的是在NodeMCU开机时,重置AP信号灯为熄灭状态。 110 | 111 | 之后,修改上节按钮事件函数里的`print('up~')`为: 112 | 113 | ```lua 114 | switchCfg() 115 | ``` 116 | 117 | 这样就可以通过按钮来控制AP的开启关闭了。 118 | 119 | 120 | 121 | ## 配置热点信息 122 | 123 | 在`print('Setting up WIFI...')`后添加下行代码,来配置热点名为 **'mymcu'** ,安全性为**开放**。 124 | 125 | ```lua 126 | wifi.ap.config({ ssid = 'mymcu', auth = AUTH_OPEN }) 127 | ``` 128 | 关于`wifi.ap.config()`的更多细节,请参阅: 129 | 130 | >配置热点信息 131 | >[wifi.ap.config()](http://nodemcu.readthedocs.io/en/master/en/modules/wifi/#wifiapconfig) 132 | 133 | 最后,删去之前写死在代码里的WIFI连接配置`wifi.sta.config('MY_SSID', 'MY_PASSWORD')`。 134 | 135 | 因为随后,我们将提供操作界面,让用户自己来设置它们。 136 | 137 | 138 | 139 | ## 相关资源 140 | 141 | 你可以在[NodeMCU-Tutorial](https://github.com/wangzexi/NodeMCU-Tutorial)下载到本文的相关资源和代码。 -------------------------------------------------------------------------------- /3.响应配置按钮/img/wiring.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangzexi/NodeMCU-Tutorial/87a4268833cad7cb9da71eac28cfb88c8fa0fdc5/3.响应配置按钮/img/wiring.jpg -------------------------------------------------------------------------------- /3.响应配置按钮/source/init.lua: -------------------------------------------------------------------------------- 1 | ------------- 2 | -- define 3 | ------------- 4 | IO_LED = 1 5 | IO_LED_AP = 2 6 | IO_BTN_CFG = 3 7 | IO_BLINK = 4 8 | 9 | TMR_BLINK = 5 10 | TMR_BTN = 6 11 | 12 | gpio.mode(IO_LED, gpio.OUTPUT) 13 | gpio.mode(IO_LED_AP, gpio.OUTPUT) 14 | gpio.mode(IO_BTN_CFG, gpio.INT) 15 | gpio.mode(IO_BLINK, gpio.OUTPUT) 16 | 17 | ------------- 18 | -- button 19 | ------------- 20 | function onBtnEvent() 21 | gpio.trig(IO_BTN_CFG) 22 | tmr.alarm(TMR_BTN, 500, tmr.ALARM_SINGLE, function() 23 | gpio.trig(IO_BTN_CFG, 'up', onBtnEvent) 24 | end) 25 | 26 | switchCfg() 27 | end 28 | gpio.trig(IO_BTN_CFG, 'up', onBtnEvent) 29 | 30 | gpio.write(IO_LED_AP, gpio.LOW) 31 | 32 | function switchCfg() 33 | if wifi.getmode() == wifi.STATION then 34 | wifi.setmode(wifi.STATIONAP) 35 | gpio.write(IO_LED_AP, gpio.HIGH) 36 | else 37 | wifi.setmode(wifi.STATION) 38 | gpio.write(IO_LED_AP, gpio.LOW) 39 | end 40 | end 41 | 42 | ------------- 43 | -- blink 44 | ------------- 45 | blink = nil 46 | tmr.register(TMR_BLINK, 100, tmr.ALARM_AUTO, function() 47 | gpio.write(IO_BLINK, blink.i % 2) 48 | tmr.interval(TMR_BLINK, blink[blink.i + 1]) 49 | blink.i = (blink.i + 1) % #blink 50 | end) 51 | 52 | function blinking(param) 53 | if type(param) == 'table' then 54 | blink = param 55 | blink.i = 0 56 | tmr.interval(TMR_BLINK, 1) 57 | running, _ = tmr.state(TMR_BLINK) 58 | if running ~= true then 59 | tmr.start(TMR_BLINK) 60 | end 61 | else 62 | tmr.stop(TMR_BLINK) 63 | gpio.write(IO_BLINK, param or gpio.LOW) 64 | end 65 | end 66 | 67 | ------------- 68 | -- wifi 69 | ------------- 70 | print('Setting up WIFI...') 71 | wifi.sta.config('MY_SSID', 'MY_PASSWORD') 72 | wifi.ap.config({ ssid = 'mymcu', auth = AUTH_OPEN }) 73 | wifi.setmode(wifi.STATION) 74 | wifi.sta.autoconnect(1) 75 | 76 | status = nil 77 | 78 | wifi.sta.eventMonReg(wifi.STA_WRONGPWD, function() 79 | blinking({100, 100 , 100, 500}) 80 | status = 'STA_WRONGPWD' 81 | print(status) 82 | end) 83 | 84 | wifi.sta.eventMonReg(wifi.STA_APNOTFOUND, function() 85 | blinking({2000, 2000}) 86 | status = 'STA_APNOTFOUND' 87 | print(status) 88 | end) 89 | 90 | wifi.sta.eventMonReg(wifi.STA_CONNECTING, function(previous_State) 91 | blinking({300, 300}) 92 | status = 'STA_CONNECTING' 93 | print(status) 94 | end) 95 | 96 | wifi.sta.eventMonReg(wifi.STA_GOTIP, function() 97 | blinking() 98 | status = 'STA_GOTIP' 99 | print(status, wifi.sta.getip()) 100 | end) 101 | 102 | wifi.sta.eventMonStart(1000) 103 | -------------------------------------------------------------------------------- /4.实现Web配置页面/README.md: -------------------------------------------------------------------------------- 1 | # NodeMCU之旅(四):实现Web配置页面 2 | 3 | ## 引言 4 | 5 | 利用Web页面做配置可以轻松适应用户的多种设备,如Android, IOS等。本文将介绍如何在NodeMCU中实现配置页面。 6 | 7 | ## 配置页面后端 8 | 9 | ### HTTP服务 10 | 11 | NodeMCU的可用运存大约只有32KB,非常小。 12 | 13 | 这里推荐一个轻量的HTTP服务库[NodeMCU-HTTP-Server](https://github.com/wangzexi/NodeMCU-HTTP-Server)。下载**httpServer.lua**即可。 14 | 15 | ### 服务静态文件 16 | 17 | 在**init.lua**的尾部添加: 18 | 19 | ```lua 20 | dofile('httpServer.lua') 21 | ``` 22 | 23 | 并在`switchCfg()`中启动和关闭监听: 24 | 25 | ```lua 26 | function switchCfg() 27 | if wifi.getmode() == wifi.STATION then 28 | -- ... 29 | httpServer:listen(80) 30 | else 31 | -- ... 32 | httpServer:close() 33 | end 34 | end 35 | ``` 36 | 37 | ### 测试HTTP服务 38 | 39 | 可以通过以下方法来测试服务器是否正常。 40 | 41 | 保存以下代码为**index.html**: 42 | 43 | ```html 44 | 45 |
46 | 47 | 48 |这是我的配置页面。
52 | 53 |