-
Notifications
You must be signed in to change notification settings - Fork 0
/
bmp180.lua
143 lines (125 loc) · 3.76 KB
/
bmp180.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
local moduleName = ...
local M = {}
_G[moduleName] = M
local ADDR = 0x77 --BMP180 address
local REG_CALIBRATION = 0xAA
local REG_CONTROL = 0xF4
local REG_RESULT = 0xF6
local COMMAND_TEMPERATURE = 0x2E
local COMMAND_PRESSURE = {0x34, 0x74, 0xB4, 0xF4}
-- calibration coefficients
local AC1, AC2, AC3, AC4, AC5, AC6, B1, B2, MB, MC, MD
-- temperature and pressure
local t,p
local init = false
-- i2c interface ID
local id = 0
-- 16-bit two's complement
-- value: 16-bit integer
local function twoCompl(value)
if value > 32767 then value = -(65535 - value + 1)
end
return value
end
-- read data register
-- reg_addr: address of the register in BMP180
-- lenght: bytes to read
local function read_reg(reg_addr, length)
i2c.start(id)
i2c.address(id, ADDR, i2c.TRANSMITTER)
i2c.write(id, reg_addr)
i2c.stop(id)
i2c.start(id)
i2c.address(id, ADDR,i2c.RECEIVER)
c = i2c.read(id, length)
i2c.stop(id)
return c
end
-- write data register
-- reg_addr: address of the register in BMP180
-- reg_val: value to write to the register
local function write_reg(reg_addr, reg_val)
i2c.start(id)
i2c.address(id, ADDR, i2c.TRANSMITTER)
i2c.write(id, reg_addr)
i2c.write(id, reg_val)
i2c.stop(id)
end
-- initialize module
-- sda: SDA pin
-- scl SCL pin
function M.init(sda, scl)
i2c.setup(id, sda, scl, i2c.SLOW)
local calibration = read_reg(REG_CALIBRATION, 22)
AC1 = twoCompl(string.byte(calibration, 1) * 256 + string.byte(calibration, 2))
AC2 = twoCompl(string.byte(calibration, 3) * 256 + string.byte(calibration, 4))
AC3 = twoCompl(string.byte(calibration, 5) * 256 + string.byte(calibration, 6))
AC4 = string.byte(calibration, 7) * 256 + string.byte(calibration, 8)
AC5 = string.byte(calibration, 9) * 256 + string.byte(calibration, 10)
AC6 = string.byte(calibration, 11) * 256 + string.byte(calibration, 12)
B1 = twoCompl(string.byte(calibration, 13) * 256 + string.byte(calibration, 14))
B2 = twoCompl(string.byte(calibration, 15) * 256 + string.byte(calibration, 16))
MB = twoCompl(string.byte(calibration, 17) * 256 + string.byte(calibration, 18))
MC = twoCompl(string.byte(calibration, 19) * 256 + string.byte(calibration, 20))
MD = twoCompl(string.byte(calibration, 21) * 256 + string.byte(calibration, 22))
init = true
end
-- read temperature from BMP180
local function read_temp()
write_reg(REG_CONTROL, COMMAND_TEMPERATURE)
tmr.delay(5000)
local dataT = read_reg(REG_RESULT, 2)
UT = string.byte(dataT, 1) * 256 + string.byte(dataT, 2)
local X1 = (UT - AC6) * AC5 / 32768
local X2 = MC * 2048 / (X1 + MD)
B5 = X1 + X2
t = (B5 + 8) / 16
return(t)
end
-- read pressure from BMP180
-- must be read after read temperature
local function read_pressure(oss)
write_reg(REG_CONTROL, COMMAND_PRESSURE[oss + 1]);
tmr.delay(30000);
local dataP = read_reg(0xF6, 3)
local UP = string.byte(dataP, 1) * 65536 + string.byte(dataP, 2) * 256 + string.byte(dataP, 1)
UP = UP / 2 ^ (8 - oss)
local B6 = B5 - 4000
local X1 = B2 * (B6 * B6 / 4096) / 2048
local X2 = AC2 * B6 / 2048
local X3 = X1 + X2
local B3 = ((AC1 * 4 + X3) * 2 ^ oss + 2) / 4
X1 = AC3 * B6 / 8192
X2 = (B1 * (B6 * B6 / 4096)) / 65536
X3 = (X1 + X2 + 2) / 4
local B4 = AC4 * (X3 + 32768) / 32768
local B7 = (UP - B3) * (50000/2 ^ oss)
p = (B7 / B4) * 2
X1 = (p / 256) * (p / 256)
X1 = (X1 * 3038) / 65536
X2 = (-7357 * p) / 65536
p = p +(X1 + X2 + 3791) / 16
return (p)
end
-- read temperature and pressure from BMP180
-- oss: oversampling setting. 0-3
function M.read(oss)
if (oss == nil) then
oss = 0
end
if (not init) then
print("init() must be called before read.")
else
read_temp()
read_pressure(oss)
end
end;
-- get temperature
function M.getTemperature()
return t
end
-- get pressure
function M.getPressure()
return p
end
return M