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のセンサ情報を取り出す部分を関数化し、外部の関数から呼び出せるようにします。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 | 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%となっています。
1 2 | 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」になっています。