随着ESP8266的流行,基于ESP8266的FW发展也愈发兴旺,除了乐鑫原厂的AT、RTOS固件外,为促进IoT开发的效率,尤其是原型开发,基于各种脚本、动态语言的固件越来越受到欢迎。比如,nodemcu支持lua,各种micro python的固件,各种javascript固件等。
Mongoose-os是一个基于javascript的固件和IDE环境,其支持ESP8266、ESP32、以及CC3200。
Mongoose-os的官方站点是:https://mongoose-os.com/
其github地址是:https://github.com/cesanta/mongoose-os
Mongoose-os的框架go语言写的(固件本身当然还是C),最简单的办法是用官方提供的二进制包,只有一个mos.exe文件(windows环境),也没有安装,直接运行即可。
Mongoose-os使用界面是web,这一点不太寻常。不过考虑到Mongoose本身是个嵌入式的webserver,那么基于其的Mongoose-os使用web界面管理也就显得颇有道理了。Mongoose的功能相当多,感觉比lighthttp之类的要好,其收费版本功能更强,但价格实惠,商用也是不错的。
执行mos.exe后,在浏览器中访问如下URL: http://localhost:1992
即可看到如下界面:
硬件这里使用nodemcu,依次选择和填入串口、esp8266、和wifi信息,wifi信息可以选填。注意第一次使用时,必须要更新固件,且因固件需要在线获取的,要确保网络正常。
更新完固件,点击【start coding】,就进入主界面了。
首先点击左侧的【device config】,进行系统设置,log level默认是1,调试时建议改为3,调试JS时颇有帮助。如果有MQTT Broker,可以设置MQTT的相关信息。
点击上方的【Expert View】即可直接编辑设定文件本身,能设置很多高级选项,
这里我们主要关注I2C部分,如下:
"i2c": {
"enable": true,
"freq": 100000,
"debug": false,
"sda_gpio": 12,
"scl_gpio": 14
},
可以看到,I2C的默认SDA pin是12,SCL pin是14,对应着nodeMCU的D6和D5。
接线的时候,会发现这2个默认pin是经过精心挑选的。
Mongoose-os内置的传感器驱动较少,不支持bh1750,但是Mongoose-os提供了js接口的I2C库,
可利用其写一个简单的bh1750驱动。(bh1750的I2C协议比较简单)
1)I2C.scan
Mongoose-os还有一个颇为有趣的功能,称之为【Device Service】,其把常用的功能通过service的形式提供出来,其中有一个I2C.scan,可以用来测试I2C总线上挂的设备,如下图,bh1750接线后,显示有一个设备的地址是35,正是bh1750的默认I2C地址0x23。
2) init.js的修改
回到【Device file】,可以看到nodeMCU上的所有文件。和nodeMCU的默认lua固件一样,Mongoose-os也具备文件系统,同样类似于user.lua,也有一个名为init.js的初始执行文件。
默认情况下,这个init.js的功能是闪烁板载led灯,简单起见,直接修改这个文件如下:
load('api_config.js');
load('api_gpio.js');
load('api_mqtt.js');
load('api_sys.js');
load('api_timer.js');
load('api_i2c.js');
// Helper C function get_led_gpio_pin() in src/main.c
// returns built-in LED GPIO
// Blink built-in LED by timer
let led = ffi('int get_led_gpio_pin()')();
GPIO.set_mode(led, GPIO.MODE_OUTPUT);
// bh1750 H mode
let i2cbus = I2C.get();
let ret = I2C.write(i2cbus, 0x23, '\x10', 1, true);
print('i2c write result:', ret);
Timer.set(5000 /* 1 sec */, true /* repeat */, function() {
let value = GPIO.toggle(led);
// read bh1750 lux data
let data = I2C.read(i2cbus, 0x23, 2, true);
if (data) {
let lux = (data.at(0)*256 + data.at(1))/1.2
print("lux:", lux);
let message = 'tp=l&ep=99&l=' + JSON.stringify(lux);
let ok = MQTT.pub('l', message, 0);
print('Published:', ok ? 'yes' : 'no', 'topic:', 'l', 'message:', message);
}
}, null);
**需要注意,这里使用的javascript是所谓的mjs,功能有大幅的裁剪,不支持任何js的库,语法的限制更加严格。比如不支持var,只支持let,没有String库等。
具体可以参考:
https://github.com/cesanta/mjs**
另外,考虑到扩展的缘故,mongoose-os利用ffi,可直接调用C函数,大大提高了扩展性,不需要像lua需要写语言包裹层,非常的便利,很有JS与C齐飞,便利共功能一色的感觉。缺点是调用时函数签名太繁琐。
MQTT的消息的topic和内容都可以根据自身要求修改。
点击上方的【Save + Reboot】,就可以看到照度的数据被采集(lux),
如果设置过wifi和MQTT,则启动后会先进行wifi和MQTT的连接,并且将数据送至MQTT Broker.
如下图: