BME280を用いたPro Microの温湿度・気圧測定 プログラムで環境センサモジュール「BME280」を用いたPro Microのアプリを作成しましたが、NodeMCUで動作するアプリをLuaで作成しました。
温湿度・気圧測定 プログラムの作成
BME280のプログラムは、ESP8266 NodeMCU mini WiFi module ESP-12 data logger with BME280を使用しています。ビン番号とI2Cポートを次に示します。それぞれのBME280の仕様に従って変更してください。
local sda = 2 local scl = 1 local i2cport = 0x76
bme280.lua
bme280.luaは、BME280のセンサ情報を取り出す部分を関数化し、外部の関数から呼び出せるようにします。
local M do -- cache local i2c, tmr = i2c, tmr local sda = 2 local scl = 1 local i2cport = 0x76 -- helpers local function r8(reg) local r = { } i2c.start(0) i2c.address(0, i2cport, i2c.TRANSMITTER) i2c.write(0, reg) i2c.stop(0) i2c.start(0) i2c.address(0, i2cport, i2c.RECEIVER) r = i2c.read(0, 1) i2c.stop(0) return r:byte(1) end local function w8(reg, val) i2c.start(0) i2c.address(0, i2cport, i2c.TRANSMITTER) i2c.write(0, reg) i2c.write(0, val) i2c.stop(0) end local function r16u(reg) local r = { } i2c.start(0) i2c.address(0, i2cport, i2c.TRANSMITTER) i2c.write(0, reg) i2c.stop(0) i2c.start(0) i2c.address(0, i2cport, i2c.RECEIVER) r = i2c.read(0, 2) i2c.stop(0) return r:byte(1) + r:byte(2) * 256 end --return r8(reg) + r8(reg + 1) * 256 --end local function r16(reg) local r = r16u(reg) if r > 32767 then r = r - 65536 end return r end local function rRaw() local t, p, h local r = { } i2c.start(0) i2c.address(0, i2cport, i2c.TRANSMITTER) i2c.write(0, 0xF7) i2c.stop(0) i2c.start(0) i2c.address(0, i2cport, i2c.RECEIVER) r = i2c.read(0, 8) i2c.stop(0) p = r:byte(1) * 4096 + r:byte(2) * 16 + r:byte(3) / 16 t = r:byte(4) * 4096 + r:byte(5) * 16 + r:byte(6) / 16 h = r:byte(7) * 256 + r:byte(8) r = nil return t, p, h end -- calibration data local T1, T2, T3, P1, P2, P3, P4, P5, P6, P7, P8, P9, H1, H2, H3, H4, H5, H6 -- read t, p, h [mC, Pa, m%] local function read() print ("start") i2c.setup(0, sda, scl, i2c.SLOW) -- Initial setup w8(0xF2, 0x01) -- H oversampling x1 w8(0xF4, 0x27) -- P oversampling x1, T oversampling x1, mode Normal w8(0xF5, 0xA8) -- 1000ms, IIR 4, I2C -- Calibration coefficients T1 = r16u(0x88) T2 = r16(0x8A) T3 = r16(0x8C) P1 = r16u(0x8E) P2 = r16(0x90) P3 = r16(0x92) P4 = r16(0x94) P5 = r16(0x96) P6 = r16(0x98) P7 = r16(0x9A) P8 = r16(0x9C) P9 = r16(0x9E) H1 = r8(0xA1) H2 = r16(0xE1) H3 = r8(0xE3) H4 = (r8(0xE4) * 16) + (r8(0xE5) % 16) H5 = (r8(0xE6) * 16) + (r8(0xE5) / 16) H6 = r8(0xE7) -- Raw Data local t, p, h t, p, h = rRaw() -- Temperature --print("T=",T1,T2,T3) --local t = r8(0xFA) * 4096 + r8(0xFB) * 16 + r8(0xFC) / 16 --print("t",t) local v1 = ((t/8 - T1*2) * T2) / 2048 local v2 = ((((t/16 - T1) * (t/16 - T1)) / 4096) * T3) / 16384 local tfine = v1 + v2 --print("tf",tfine) --t = (tfine * 5 + 128) / 256 t = (tfine * 5 + 128) / 256 t = 10 * t --print("t=",t) -- Pressure (32bit version) --print("P=",P1,P2,P3,P4,P5,P6,P7,P8,P9) --local p = r8(0xF7) * 4096 + r8(0xF8) * 16 + r8(0xF9) / 16 --print("p",p) v1 = (tfine - 128000) / 2 v2 = (((v1 / 4) * (v1 / 4)) / 2048) * P6 v2 = v2 + v1 * P5 * 2 v2 = v2 / 4 + P4 * 65536 v1 = ((P3 * (((v1 / 4) * (v1 / 4)) / 8192)) / 8 + (P2 * v1) / 2) / 262144 v1 = ((32768 + v1) * P1) / 32768 p = ((1048576 - p) - (v2 / 4096)) * 3125; if v1 ~= 0 then p = (p / v1) * 2 else p = 0 end v1 = (P9 * (((p / 8) * (p / 8)) / 8192)) / 4096 v2 = ((p / 4) * P8) / 8192 p = p + (v1 + v2 + P7) / 16 --print("p=",p) -- Humidity --print("H=",H1,H2,H3,H4,H5,H6) --local h = r8(0xFD) * 256 + r8(0xFE) --print("h",h) v1 = tfine - 76800 v1 = ((h * 16384 - H4 * 1024 * 1024 - H5 * v1 + 16384) / 32768) * ((((((v1 * H6 / 1024) * (v1 * H3 / 2048) + 32768) / 1024) + 2097152) * H2 + 8192) / 16384) v1 = v1 - ((((v1/32768) * (v1/32768)) / 128 ) * H1) / 16 if v1 < 0 then v1 = 0 end if v1 > 419430400 then v1 = 419430400 end h = v1 / 4096 --print("h=",h) return t, p, h end -- expose M = { read = read } end return M
main.lua
BME280のセンサ情報を取り出すbme280.luaを呼び出し、取り出したセンサ情報を表示します。Tは温度、Pは気圧、Hは湿度を示します。各単位は、温度はm°C、気圧はPa、湿度は、m%となっています。
t, p, h = dofile("bme280.lua").read() print (string.format("T:%d P:%d H:%d",t,p,h))
プログラムの実行結果
作成したプログラムをESPlorerで実行した結果を次に示します。温湿度・気圧が、「T:18440 P:101958 H:50611」になっています。