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」になっています。
