1. 程式人生 > >8. ESP8266使用Mongoose-os初體驗(使用bh1750感測器)

8. ESP8266使用Mongoose-os初體驗(使用bh1750感測器)

隨著ESP8266的流行,基於ESP8266的FW發展也愈發興旺,除了樂鑫原廠的AT、RTOS韌體外,為促進IoT開發的效率,尤其是原型開發,基於各種指令碼、動態語言的韌體越來越受到歡迎。比如,nodemcu支援lua,各種micro python的韌體,各種javascript韌體等。

一、 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": 100000,
    "debug": false,
    "sda_gpio": 12,
    "scl_gpio": 14
  },

可以看到,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, 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.
如下圖:
這裡寫圖片描述