随着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的下載下傳和運作
Mongoose-os的架構go語言寫的(固件本身當然還是C),最簡單的辦法是用官方提供的二進制包,隻有一個mos.exe檔案(windows環境),也沒有安裝,直接運作即可。
Mongoose-os使用界面是web,這一點不太尋常。不過考慮到Mongoose本身是個嵌入式的webserver,那麼基于其的Mongoose-os使用web界面管理也就顯得頗有道理了。Mongoose的功能相當多,感覺比lighthttp之類的要好,其收費版本功能更強,但價格實惠,商用也是不錯的。
二、Mongoose-os的使用
執行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": ,
"debug": false,
"sda_gpio": ,
"scl_gpio":
},
可以看到,I2C的預設SDA pin是12,SCL pin是14,對應着nodeMCU的D6和D5。
接線的時候,會發現這2個預設pin是經過精心挑選的。
三、bh1750驅動
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, , '\x10', , true);
print('i2c write result:', ret);
Timer.set( /* 1 sec */, true /* repeat */, function() {
let value = GPIO.toggle(led);
// read bh1750 lux data
let data = I2C.read(i2cbus, , , true);
if (data) {
let lux = (data.at()* + data.at())/
print("lux:", lux);
let message = 'tp=l&ep=99&l=' + JSON.stringify(lux);
let ok = MQTT.pub('l', message, );
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.
如下圖: