github:https://github.com/maplesugarr/raspberrypi-nodemcu
![]()
使用教程
简介
NodeMCU,是一个开源的物联网平台。 它使用Lua脚本语言编程。该平台基于eLua开源项目,底层使用ESP8266 sdk 0.9.5版本。该平台使用了很多开源项目, 例如 lua-cjson, spiffs. NodeMCU包含了可以运行在 esp8266 Wi-Fi SoC芯片之上的固件,以及基于ESP-12模组的硬件。
购买
大概十多块一个。
构建固件
这个网站:https://nodemcu-build.com/ 提供构建固件的服务,只要选好模块,构建完成后,就会发邮件通知。不过我使用一次后,就再也没有收到构建成功的邮件了。
还是自己手动编译,搜索github,有人已经做好了docker。 https://github.com/marcelstoer/docker-nodemcu-build/blob/master/README-CN.md
1.克隆nodemcu固件仓库
git clone https://github.com/nodemcu/nodemcu-firmware.git
2.拉取docker镜像
docker pull marcelstoer/nodemcu-build
3.更改编译配置
查找 https://nodemcu.readthedocs.io/en/master/en/build/ 文档,更改固件目录下的app/include/user_modules.h,app/include/user_config.h。
1 2 3 4 5 6 7 8 9
| user_modules.h中编译的模块:LUA_USE_MODULES_CRYPTO、LUA_USE_MODULES_ENCODER、 LUA_USE_MODULES_FILE、LUA_USE_MODULES_GPIO、LUA_USE_MODULES_HTTP、LUA_USE_MODULES_NET、 LUA_USE_MODULES_NODE、LUA_USE_MODULES_SJSON、LUA_USE_MODULES_TLS、LUA_USE_MODULES_TMR、 LUA_USE_MODULES_WIFI
user_config.h制定的特性: #define BIT_RATE_DEFAULT BIT_RATE_115200(波特率,连接nodemcu也要使用这个波特率)、 #define LUA_NUMBER_INTEGRAL(指定支持整数运算,减小内存占用,默认是浮点运算。)、 #define CLIENT_SSL_ENABLE(支持tls,后来证明一直报错,只能使用http)
|
4.进入克隆好的固件目录,进行编译。
1 2 3 4
| docker run --rm -ti -v `pwd`:/opt/nodemcu-firmware marcelstoer/nodemcu-build build 最后一个build是命令,还可以使用lfs-image命令,把lua直接写到固件中: docker run --rm -ti -v `pwd`:/opt/nodemcu-firmware -v {PathToLuaSourceFolder}:/opt/lua marcelstoer/nodemcu-build lfs-image 这将编译并存储给定文件夹及其目录中中的所有 Lua 文件。
|
5.进入固件目录/bin中,得到编译完成后的固件。
刷入固件
为了避免不必要的麻烦,就不要尝试其他的烧录软件了。
flashmode需要根据芯片型号选择。
上传代码
推荐使用ESPlorer,需要Java环境。下载ESPlorer.zip。
注意连接的波特率根据刷入的固件不同而有所不同,就是上面编译固件时候规定的波特率。
lua代码教程
参考:https://github.com/wangzexi/NodeMCU-Tutorial ,由于api的变化,它的代码已经不适合自己编译好的固件了,对应改一下就可以,看我的github仓库也可以。思路是没问题的。
api文档(nodemcu documentation):https://nodemcu.readthedocs.io/en/master/
配置wifi的原理
nodemcu可以作为一个station连接到wifi,同时又能作为一个ap,为其他设备提供wifi连接。由于没有网线连接,被称为soft-ap。同时它还可以ap和station共存,可以实现中继的功能。
按一下按键,设置nodemcu为station和ap共存状态,手机脸上nodemcu的ap就可以配网了。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| wifi.setmode(wifi.STATION)
wifi.sta.sethostname("NodeMCU-raspi2") wifi.sta.autoconnect(1)
function switchCfg() if wifi.getmode() == wifi.STATION then tmr.stop(TMR_CHECK_NETWORK) wifi.setmode(wifi.STATIONAP) wifi.ap.config({ssid='NodeMCUConfig'}) httpServer:listen(80) blinking({1000, 1000}) else tmr.start(TMR_CONNECT) wifi.setmode(wifi.STATION) httpServer:close() blinking() end end
|
树莓派远程开关
买了一个路由器的ups,用来给树莓派供电,防止突然关机损坏树莓派sd卡。
nodemcu通过http协议去请求服务器的json数据,来控制继电器开关,进而控制树莓派电源。根据文档导入证书后,使用https协议连接不上,找毛病浪费时间,就不用https了。要用mqtt协议的自行研究。
实际上nodemcu连接两个继电器,控制树莓派电源和树莓派引脚的通断。
第一个继电器控制树莓派的一个GPIO信号。树莓派的这个GPIO拉高后,接地,平时是不通的,也就是GPIO一直是高电平。第一个继电器闭合后,树莓派的这个GPIO接地,变成低电平。树莓派通过检测这个GPIO变成低电平来执行shutdown命令关闭树莓派。等待二分钟后,保证树莓派已经关机,就控制第二个继电器关闭树莓派电源。
同时,由于树莓派不能读取ups剩余电量,就由nodemcu控制ups断电使用时间了。nodemcu检查网络断掉后,就认为已经断电,维持适当时间后,关闭树莓派。当来电后,nodemcu检查到网络联通后,就认为来电了,打开树莓派。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100
| function forceShutdownRaspi() gpio.write(IO_RELAY_RASPI_OFF_SIGNAL, gpio.HIGH) tmr.alarm(TMR_RELAY, 120000, tmr.ALARM_SINGLE, function() gpio.write(IO_RELAY_RASPI_POWER_SUPPLY, gpio.LOW) is_raspi_on = false tmr.start(TMR_CHECK_NETWORK) end) end
function closeRaspi() is_raspi_on = false gpio.write(IO_RELAY_RASPI_POWER_SUPPLY, gpio.LOW) gpio.write(IO_RELAY_RASPI_OFF_SIGNAL, gpio.HIGH) end
function openRaspi() is_raspi_on = true gpio.write(IO_RELAY_RASPI_POWER_SUPPLY, gpio.HIGH) gpio.write(IO_RELAY_RASPI_OFF_SIGNAL, gpio.LOW) end
function bootRaspi() gpio.write(IO_RELAY_RASPI_POWER_SUPPLY, gpio.LOW) gpio.write(IO_RELAY_RASPI_OFF_SIGNAL, gpio.LOW) tmr.alarm(TMR_RELAY, 5000, tmr.ALARM_SINGLE, function() gpio.write(IO_RELAY_RASPI_POWER_SUPPLY, gpio.HIGH) is_raspi_on = true end) end
fail_count = 0
is_raspi_on = false
tmr.alarm(TMR_CHECK_NETWORK, 60000, tmr.ALARM_AUTO, function() http.get("http://xxx.com/xxx", nil, function(code, data) if is_raspi_on==false then if (code ~= 200) then print("HTTP request failed") else fail_count = 0 local result = sjson.decode(data) print(result["switch"]) if (result["switch"]) then bootRaspi() else closeRaspi() end end else if (code ~= 200) then fail_count = fail_count + 1 print(fail_count) if(fail_count >= 5) then fail_count = 0 tmr.stop(TMR_CHECK_NETWORK) forceShutdownRaspi() end print("HTTP request failed") else fail_count = 0 local result = sjson.decode(data) print(result["switch"]) if (result["switch"]) then openRaspi() else tmr.stop(TMR_CHECK_NETWORK) forceShutdownRaspi() end end end end) end)
|