bmp085.lua 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158
  1. --------------------------------------------------------------------------------
  2. -- BMP085 I2C module for NODEMCU
  3. -- NODEMCU TEAM
  4. -- LICENCE: http://opensource.org/licenses/MIT
  5. -- Christee <Christee@nodemcu.com>
  6. --------------------------------------------------------------------------------
  7. local moduleName = ...
  8. local M = {}
  9. _G[moduleName] = M
  10. --default value for i2c communication
  11. local id=0
  12. --default oversampling setting
  13. local oss = 0
  14. --CO: calibration coefficients table.
  15. local CO = {}
  16. -- read reg for 1 byte
  17. local function read_reg(dev_addr, reg_addr)
  18. i2c.start(id)
  19. i2c.address(id, dev_addr ,i2c.TRANSMITTER)
  20. i2c.write(id,reg_addr)
  21. i2c.stop(id)
  22. i2c.start(id)
  23. i2c.address(id, dev_addr,i2c.RECEIVER)
  24. local c=i2c.read(id,1)
  25. i2c.stop(id)
  26. return c
  27. end
  28. --write reg for 1 byte
  29. local function write_reg(dev_addr, reg_addr, reg_val)
  30. i2c.start(id)
  31. i2c.address(id, dev_addr, i2c.TRANSMITTER)
  32. i2c.write(id, reg_addr)
  33. i2c.write(id, reg_val)
  34. i2c.stop(id)
  35. end
  36. --get signed or unsigned 16
  37. --parameters:
  38. --reg_addr: start address of short
  39. --signed: if true, return signed16
  40. local function getShort(reg_addr, signed)
  41. local tH = string.byte(read_reg(0x77, reg_addr))
  42. local tL = string.byte(read_reg(0x77, (reg_addr + 1)))
  43. local temp = tH*256 + tL
  44. if (temp > 32767) and (signed == true) then
  45. temp = temp - 65536
  46. end
  47. return temp
  48. end
  49. -- initialize i2c
  50. --parameters:
  51. --d: sda
  52. --l: scl
  53. function M.init(d, l)
  54. if (d ~= nil) and (l ~= nil) and (d >= 0) and (d <= 11) and (l >= 0) and ( l <= 11) and (d ~= l) then
  55. sda = d
  56. scl = l
  57. else
  58. print("iic config failed!") return nil
  59. end
  60. print("init done")
  61. i2c.setup(id, sda, scl, i2c.SLOW)
  62. --get calibration coefficients.
  63. CO.AC1 = getShort(0xAA, true)
  64. CO.AC2 = getShort(0xAC, true)
  65. CO.AC3 = getShort(0xAE, true)
  66. CO.AC4 = getShort(0xB0)
  67. CO.AC5 = getShort(0xB2)
  68. CO.AC6 = getShort(0xB4)
  69. CO.B1 = getShort(0xB6, true)
  70. CO.B2 = getShort(0xB8, true)
  71. CO.MB = getShort(0xBA, true)
  72. CO.MC = getShort(0xBC, true)
  73. CO.MD = getShort(0xBE, true)
  74. end
  75. --get temperature from bmp085
  76. --parameters:
  77. --num_10x: bool value, if true, return number of 0.1 centi-degree
  78. -- default value is false, which return a string , eg: 16.7
  79. function M.getUT(num_10x)
  80. write_reg(0x77, 0xF4, 0x2E);
  81. tmr.delay(10000);
  82. local temp = getShort(0xF6)
  83. local X1 = (temp - CO.AC6) * CO.AC5 / 32768
  84. local X2 = CO.MC * 2048/(X1 + CO.MD)
  85. local r = (X2 + X1 + 8)/16
  86. if(num_10x == true) then
  87. return r
  88. else
  89. return ((r/10).."."..(r%10))
  90. end
  91. end
  92. --get raw data of pressure from bmp085
  93. --parameters:
  94. --oss: over sampling setting, which is 0,1,2,3. Default value is 0
  95. function M.getUP_raw(oss)
  96. local os = 0
  97. if ((oss == 0) or (oss == 1) or (oss == 2) or (oss == 3)) and (oss ~= nil) then
  98. os = oss
  99. end
  100. local ov = os * 64
  101. write_reg(0x77, 0xF4, (0x34 + ov));
  102. tmr.delay(30000);
  103. --delay 30ms, according to bmp085 document, wait time are:
  104. -- 4.5ms 7.5ms 13.5ms 25.5ms respectively according to oss 0,1,2,3
  105. local MSB = string.byte(read_reg(0x77, 0xF6))
  106. local LSB = string.byte(read_reg(0x77, 0xF7))
  107. local XLSB = string.byte(read_reg(0x77, 0xF8))
  108. local up_raw = (MSB*65536 + LSB *256 + XLSB)/2^(8 - os)
  109. return up_raw
  110. end
  111. --get calibrated data of pressure from bmp085
  112. --parameters:
  113. --oss: over sampling setting, which is 0,1,2,3. Default value is 0
  114. function M.getUP(oss)
  115. local os = 0
  116. if ((oss == 0) or (oss == 1) or (oss == 2) or (oss == 3)) and (oss ~= nil) then
  117. os = oss
  118. end
  119. local raw = M.getUP_raw(os)
  120. local B5 = M.getUT(true) * 16 - 8;
  121. local B6 = B5 - 4000
  122. local X1 = CO.B2 * (B6 * B6 /4096)/2048
  123. local X2 = CO.AC2 * B6 / 2048
  124. local X3 = X1 + X2
  125. local B3 = ((CO.AC1*4 + X3)*2^os + 2)/4
  126. X1 = CO.AC3 * B6 /8192
  127. X2 = (CO.B1 * (B6 * B6 / 4096))/65536
  128. X3 = (X1 + X2 + 2)/4
  129. local B4 = CO.AC4 * (X3 + 32768) / 32768
  130. local B7 = (raw -B3) * (50000/2^os)
  131. local p = B7/B4 * 2
  132. X1 = (p/256)^2
  133. X1 = (X1 *3038)/65536
  134. X2 = (-7357 *p)/65536
  135. p = p +(X1 + X2 + 3791)/16
  136. return p
  137. end
  138. --get estimated data of altitude from bmp085
  139. --parameters:
  140. --oss: over sampling setting, which is 0,1,2,3. Default value is 0
  141. function M.getAL(oss)
  142. --Altitudi can be calculated by pressure refer to sea level pressure, which is 101325
  143. --pressure changes 100pa corresponds to 8.43m at sea level
  144. return (M.getUP(oss) - 101325)*843/10000
  145. end
  146. return M