物联网之NodeMCU
2017年10月24日星期二
《使用mongoos-os系列》
目 录
一、 NodeMCU的选择 3
二、 固件的选择 3
三、 UI(用户界面) 4
四、 进一步 12
五、 代码修改 15
一、NodeMCU的选择
1、NodeMCU V2
核心是ESP-12E,CPU速度80MHZ和160MHZ,SRAM包括64KB指令和96KB数据,外接4MB字节的Flash存储。
2、NodeMCU-32S
核心是ESP-32S,双核CPU,SRAM总数是520KB,接有4MB字节的Flash存储。
以上配置的硬件,价格便宜,内存却是很大,用来运行http server绰绰有余。
NodeMCU V2价格一般为23元,NodeMCU-32S价格为39元,配合I2C接口的IO板,完全可以用于小型应用。
二、固件的选择
选择Mongoose-OS,它以Mongoose库为基础实现了常用的网络服务:http,mqtt,sntp,rpc。最终商业化时,编程语言应选C,它速度快,占用RAM空间少。mJs用于快速产品原型和做Demo演示。
如下资源剩余,是在开启http, mqtt, sntp, rpc服务之后,并周期读取sth10温湿度数据。
如果使用lua固件,运行http server很容易内存不足,甚至注释都要占用内存。使用eLua的好处是,不必考虑内存管理,只管用,不用考虑回收。
Mongoose-OS的example,混杂着mongoos lib函数,官方的社区文档不齐全。若是查看其lib,可以发现它只是对mongoos库做了一个封装,我们可以根据业务情况,写自己的lib,譬如读取sht20温湿度数据。进一步功夫可花在mongoos库的使用上,它是背后的神仙。
三、UI(用户界面)
以NodeMCU为例,其4MB的FLAH存储空间,足够我们挥霍代码和HTML页面。当前应用,只使用到纯文本,尚未使用图文并茂的形式。
2014年10月29,W3C正式发布html5标准,它带来许多新特性和便利性,至今已经是扔掉IE这个包袱,使用新技术来开发页面的时候了。
尽管大胆使用新技术,因为在我们中国,智能手机基本人均1部,而且更换频率基本上是两年1部,手机操作系统不断升级,浏览器版本也是日新月异,支持最新的HTML技术。
利用现有ESP8266的硬件,不额外增加SRAM和外置FLASH,通过HTML技术,你仍然可以把NodeMCU装扮的珠翠罗绮,把你的小清新风格展示的完完整整。
页面需要css样式美化界面,使用ajax与NodeMCU进行交互。
官方有一个wifi-setup-web例子,用来设置wifi的信息。它使用了XMLHttpRequest来进行ajax读写,在文件<head>标签内做css定义。
<style>
...
.form-control { margin: 0.5em 0; }
.form label { min-width: 8em; display: inline-block; }
...
</style>
<script>
var ajax = function(opts) {
var xhr = window.XMLHttpRequest ? new XMLHttpRequest() : new ActiveXObject("Microsoft.XMLHTTP");
xhr.onreadystatechange = function() {
if (xhr.readyState != 4) return;
if (xhr.status == 200) {
(opts.success || function() {})(xhr.responseText, xhr);
} else {
(opts.error || function() {})(xhr.responseText, xhr);
}
};
...
</script>
这种写法,单个文件的响应时间要快,上面这个html才5.9KB。
但是要做的完善一些,要考虑加上正则验证,原始写法的繁琐还是比较令人头疼。
我们决定使用bootstrap框架和jquery,可以在网站上进行定制,去掉不必要的组件。
最节省内存和存储空间,而且页面响应速度最快的做法是使用CDN加速,在/fs目录下的html页面文件中引用:
<head>
...
<link href="https://cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap.min.css rel="stylesheet">
...
若是NodeMCU总是可以连入互联网,那么本文至此就可以阅读结束了。UI框架可随心所愿的选择,怎一个爽快了得。
不过,考虑到非Internet连接下,还要有一个好看的界面,则要把样式文件拷贝到/fs目录下。而后咱html中引用即可,mongoose的filesystem(文件系统)会响应http请求,将.css和.js文件发送给客户端。
大小合计167KB,esp8266的无线传输速度够快,慢在从flash读取文件数据,第1次加载耗时20多秒,以后再调用会使用缓存,基本上是秒开。
最初的想法是,寻找它们的迷你版本,既有其效果、功能,又有小尺寸。
还真是可以找到:
miinicss,网站:http://minicss.org/
可以使用它的预定义版本(http://minicss.org/flavors)。文档很齐全,有在线预览效果功能,漂亮度小于bootstrap。但比pure等要好看,而且全面。
zeptojs, 网站:http://zeptojs.com/
有中文版本的网页可以看:http://www.css88.com/doc/zeptojs_api/
这个js的使用,和jquery差别不大,很容易迁移。但不支持伪选择部分功能,在调试时,使用firefox或者chrome浏览器,按F12调出调试页面,可以看到响应、错误。
这两个文件尺寸小许多,而且minicss不需要jqeruy来支持:
尺寸小了2/3,页面载入速度已经可以接受了,毕竟我们是个32位小单片机模样。
四、进一步
在minicss和zeptojs官方页面上:
但是上图可以看到它是39KB。
那就是,把它们压缩一下,做到gzip格式。
压缩工具,就是gzip,下载地址:http://www.gzip.org/#exe
我们是win7系统,从列表第1个下载。
在运行里键入cmd,进入命令窗口,敲入:
gzip zepto.js
即可,它自动生成.gz文件。有个-9最好压缩的选项,没有多大影响,因为js文件已经是mini版本了。
我们自己生成的文件比官方标的尺寸大小基本一致。
现代浏览器,应支持gzip,不支持的浏览器弃用。正常做法是维护两个版本的文件,压缩和未压缩的,判断浏览器header,不支持gzip的,发送原版;支持gzip的,则发送压缩版本。我们采用非正常做法,只是使用gzip版本文件。
第一步,修改html文件中的引用,在原先的引用代码文件名后面加上.gz即可,如:
...
<script src="zepto.js.gz"></script>
<link rel="stylesheet" href="mini-nord.css.gz">
...
第二步,修改http_server初始化函数。
我们只对js和css进行压缩,而且文件只有2个。所以只需要在HTTP事件中判断到,客户端请求的是zepto.js.gz和mini-nord.css.gz,响应对应的content-type和conten-encoding即可。
来看一下,Chrome的调试台(F12调出):
General下,请求了http://192.168.100.102/zepto.js.gz,状态码是200,成功。有时是304,这是系统缓存,强制更新按Ctrl+F5。响应头Reponse Headers里面,可以看到正确的返回了内容类型和内容编码。
而第3项请求头里,说了接受任何类型的文件,接受的编码有gzip。
这样mongoose-os, js的gzip文件和浏览器,三者达成一致,页面正常没有错误。页面初次载入速度也很快。基本上和引用CDN加速效果相当(后者还是要快点,网络快于flash读取)。
那么mongoose-os服务端,怎么处理呢?
它几个模块之间耦合性大,松散性不足。
若你用过STM32的HAL库,会发现它有的函数使用weak定义,可以进行覆盖(Override),但是mongoose-os不行,或者是它想着让大家用它的企业版。
五、代码修改
http_server模块中的全局变量s_listen_conn是静态的,不能外部extern引用,而RPC模块要注册mgos_rpc_http_handler这个事件处理,我们才能使用/rpc这个URL来做一些操作,包括websocket。
所以,拷贝http_server到项目目录下,做代码修改;关闭http.enable,手动调用函数mgos_http_server_init,http服务可以用,但是websocket等不可以用。
而且其他库里都有库依赖,依赖github上的链接。在项目的mos.yml使用name: http-server-1.18指定使用本地lib,编译上,mos总去调用https://github.com/mongoose-os-libs/http-server,然后就提示no rule make http-server。
...
至此,NodeMCU 即可以随心所欲的更换自己的服装,其他UI框架定制并压缩以后,尺寸也是大幅度变小。Html文件也可以压缩,/fs目录下都是.gzip时,可以省却判断语句。
这种做法简单、粗暴,若是想同时提供未压缩版,也是在这个位置上做判断,截获并修改path即可。
利用成品的UI框架,牺牲一点速度,得到的效果还是很不错的。
龙口
2017年10月24日星期二