-
Notifications
You must be signed in to change notification settings - Fork 3.1k
/
bmp085.lua
158 lines (146 loc) · 4.92 KB
/
bmp085.lua
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
156
157
158
--------------------------------------------------------------------------------
-- BMP085 I2C module for NODEMCU
-- NODEMCU TEAM
-- LICENCE: http://opensource.org/licenses/MIT
-- Christee <Christee@nodemcu.com>
--------------------------------------------------------------------------------
local moduleName = ...
local M = {}
_G[moduleName] = M
--default value for i2c communication
local id=0
--default oversampling setting
local oss = 0
--CO: calibration coefficients table.
local CO = {}
-- read reg for 1 byte
local function read_reg(dev_addr, reg_addr)
i2c.start(id)
i2c.address(id, dev_addr ,i2c.TRANSMITTER)
i2c.write(id,reg_addr)
i2c.stop(id)
i2c.start(id)
i2c.address(id, dev_addr,i2c.RECEIVER)
local c=i2c.read(id,1)
i2c.stop(id)
return c
end
--write reg for 1 byte
local function write_reg(dev_addr, reg_addr, reg_val)
i2c.start(id)
i2c.address(id, dev_addr, i2c.TRANSMITTER)
i2c.write(id, reg_addr)
i2c.write(id, reg_val)
i2c.stop(id)
end
--get signed or unsigned 16
--parameters:
--reg_addr: start address of short
--signed: if true, return signed16
local function getShort(reg_addr, signed)
local tH = string.byte(read_reg(0x77, reg_addr))
local tL = string.byte(read_reg(0x77, (reg_addr + 1)))
local temp = tH*256 + tL
if (temp > 32767) and (signed == true) then
temp = temp - 65536
end
return temp
end
-- initialize i2c
--parameters:
--d: sda
--l: scl
function M.init(d, l)
if (d ~= nil) and (l ~= nil) and (d >= 0) and (d <= 11) and (l >= 0) and ( l <= 11) and (d ~= l) then
sda = d
scl = l
else
print("iic config failed!") return nil
end
print("init done")
i2c.setup(id, sda, scl, i2c.SLOW)
--get calibration coefficients.
CO.AC1 = getShort(0xAA, true)
CO.AC2 = getShort(0xAC, true)
CO.AC3 = getShort(0xAE, true)
CO.AC4 = getShort(0xB0)
CO.AC5 = getShort(0xB2)
CO.AC6 = getShort(0xB4)
CO.B1 = getShort(0xB6, true)
CO.B2 = getShort(0xB8, true)
CO.MB = getShort(0xBA, true)
CO.MC = getShort(0xBC, true)
CO.MD = getShort(0xBE, true)
end
--get temperature from bmp085
--parameters:
--num_10x: bool value, if true, return number of 0.1 centi-degree
-- default value is false, which return a string , eg: 16.7
function M.getUT(num_10x)
write_reg(0x77, 0xF4, 0x2E);
tmr.delay(10000);
local temp = getShort(0xF6)
local X1 = (temp - CO.AC6) * CO.AC5 / 32768
local X2 = CO.MC * 2048/(X1 + CO.MD)
local r = (X2 + X1 + 8)/16
if(num_10x == true) then
return r
else
return ((r/10).."."..(r%10))
end
end
--get raw data of pressure from bmp085
--parameters:
--oss: over sampling setting, which is 0,1,2,3. Default value is 0
function M.getUP_raw(oss)
local os = 0
if ((oss == 0) or (oss == 1) or (oss == 2) or (oss == 3)) and (oss ~= nil) then
os = oss
end
local ov = os * 64
write_reg(0x77, 0xF4, (0x34 + ov));
tmr.delay(30000);
--delay 30ms, according to bmp085 document, wait time are:
-- 4.5ms 7.5ms 13.5ms 25.5ms respectively according to oss 0,1,2,3
local MSB = string.byte(read_reg(0x77, 0xF6))
local LSB = string.byte(read_reg(0x77, 0xF7))
local XLSB = string.byte(read_reg(0x77, 0xF8))
local up_raw = (MSB*65536 + LSB *256 + XLSB)/2^(8 - os)
return up_raw
end
--get calibrated data of pressure from bmp085
--parameters:
--oss: over sampling setting, which is 0,1,2,3. Default value is 0
function M.getUP(oss)
local os = 0
if ((oss == 0) or (oss == 1) or (oss == 2) or (oss == 3)) and (oss ~= nil) then
os = oss
end
local raw = M.getUP_raw(os)
local B5 = M.getUT(true) * 16 - 8;
local B6 = B5 - 4000
local X1 = CO.B2 * (B6 * B6 /4096)/2048
local X2 = CO.AC2 * B6 / 2048
local X3 = X1 + X2
local B3 = ((CO.AC1*4 + X3)*2^os + 2)/4
X1 = CO.AC3 * B6 /8192
X2 = (CO.B1 * (B6 * B6 / 4096))/65536
X3 = (X1 + X2 + 2)/4
local B4 = CO.AC4 * (X3 + 32768) / 32768
local B7 = (raw -B3) * (50000/2^os)
local p = B7/B4 * 2
X1 = (p/256)^2
X1 = (X1 *3038)/65536
X2 = (-7357 *p)/65536
p = p +(X1 + X2 + 3791)/16
return p
end
--get estimated data of altitude from bmp085
--parameters:
--oss: over sampling setting, which is 0,1,2,3. Default value is 0
function M.getAL(oss)
--Altitudi can be calculated by pressure refer to sea level pressure, which is 101325
--pressure changes 100pa corresponds to 8.43m at sea level
return (M.getUP(oss) - 101325)*843/10000
end
return M