tsl2561.lua 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240
  1. -- ***************************************************************************
  2. -- tsl2561.lua
  3. -- Module for ESP8266 with nodeMCU
  4. -- Ported from github.com/Seeed-Studio/Grove_Digital_Light_Sensor
  5. --
  6. -- Copyright (c) 2012 seeed technology inc.
  7. -- Website : www.seeed.cc
  8. -- Author : zhangkun
  9. -- Create Time:
  10. -- Change Log : 2015-07-21: Ported original code to Lua
  11. -- by Marius Schmeding (skybus.io)
  12. --
  13. -- MIT License, http://opensource.org/licenses/MIT
  14. -- ***************************************************************************
  15. local TSL2561_Control = 0x80
  16. local TSL2561_Timing = 0x81
  17. local TSL2561_Interrupt = 0x86
  18. local TSL2561_Channel0L = 0x8C
  19. local TSL2561_Channel0H = 0x8D
  20. local TSL2561_Channel1L = 0x8E
  21. local TSL2561_Channel1H = 0x8F
  22. local TSL2561_Address = 0x29 -- device address
  23. local LUX_SCALE = 14 -- scale by 2^14
  24. local RATIO_SCALE = 9 -- scale ratio by 2^9
  25. local CH_SCALE = 10 -- scale channel values by 2^10
  26. local CHSCALE_TINT0 = 0x7517 -- 322/11 * 2^CH_SCALE
  27. local CHSCALE_TINT1 = 0x0fe7 -- 322/81 * 2^CH_SCALE
  28. -- Scale table
  29. local S = {}
  30. S.K1T = 0x0040 -- 0.125 * 2^RATIO_SCALE
  31. S.B1T = 0x01f2 -- 0.0304 * 2^LUX_SCALE
  32. S.M1T = 0x01be -- 0.0272 * 2^LUX_SCALE
  33. S.K2T = 0x0080 -- 0.250 * 2^RATIO_SCA
  34. S.B2T = 0x0214 -- 0.0325 * 2^LUX_SCALE
  35. S.M2T = 0x02d1 -- 0.0440 * 2^LUX_SCALE
  36. S.K3T = 0x00c0 -- 0.375 * 2^RATIO_SCALE
  37. S.B3T = 0x023f -- 0.0351 * 2^LUX_SCALE
  38. S.M3T = 0x037b -- 0.0544 * 2^LUX_SCALE
  39. S.K4T = 0x0100 -- 0.50 * 2^RATIO_SCALE
  40. S.B4T = 0x0270 -- 0.0381 * 2^LUX_SCALE
  41. S.M4T = 0x03fe -- 0.0624 * 2^LUX_SCALE
  42. S.K5T = 0x0138 -- 0.61 * 2^RATIO_SCALE
  43. S.B5T = 0x016f -- 0.0224 * 2^LUX_SCALE
  44. S.M5T = 0x01fc -- 0.0310 * 2^LUX_SCALE
  45. S.K6T = 0x019a -- 0.80 * 2^RATIO_SCALE
  46. S.B6T = 0x00d2 -- 0.0128 * 2^LUX_SCALE
  47. S.M6T = 0x00fb -- 0.0153 * 2^LUX_SCALE
  48. S.K7T = 0x029a -- 1.3 * 2^RATIO_SCALE
  49. S.B7T = 0x0018 -- 0.00146 * 2^LUX_SCALE
  50. S.M7T = 0x0012 -- 0.00112 * 2^LUX_SCALE
  51. S.K8T = 0x029a -- 1.3 * 2^RATIO_SCALE
  52. S.B8T = 0x0000 -- 0.000 * 2^LUX_SCALE
  53. S.M8T = 0x0000 -- 0.000 * 2^LUX_SCALE
  54. S.K1C = 0x0043 -- 0.130 * 2^RATIO_SCALE
  55. S.B1C = 0x0204 -- 0.0315 * 2^LUX_SCALE
  56. S.M1C = 0x01ad -- 0.0262 * 2^LUX_SCALE
  57. S.K2C = 0x0085 -- 0.260 * 2^RATIO_SCALE
  58. S.B2C = 0x0228 -- 0.0337 * 2^LUX_SCALE
  59. S.M2C = 0x02c1 -- 0.0430 * 2^LUX_SCALE
  60. S.K3C = 0x00c8 -- 0.390 * 2^RATIO_SCALE
  61. S.B3C = 0x0253 -- 0.0363 * 2^LUX_SCALE
  62. S.M3C = 0x0363 -- 0.0529 * 2^LUX_SCALE
  63. S.K4C = 0x010a -- 0.520 * 2^RATIO_SCALE
  64. S.B4C = 0x0282 -- 0.0392 * 2^LUX_SCALE
  65. S.M4C = 0x03df -- 0.0605 * 2^LUX_SCALE
  66. S.K5C = 0x014d -- 0.65 * 2^RATIO_SCALE
  67. S.B5C = 0x0177 -- 0.0229 * 2^LUX_SCALE
  68. S.M5C = 0x01dd -- 0.0291 * 2^LUX_SCALE
  69. S.K6C = 0x019a -- 0.80 * 2^RATIO_SCALE
  70. S.B6C = 0x0101 -- 0.0157 * 2^LUX_SCALE
  71. S.M6C = 0x0127 -- 0.0180 * 2^LUX_SCALE
  72. S.K7C = 0x029a -- 1.3 * 2^RATIO_SCALE
  73. S.B7C = 0x0037 -- 0.00338 * 2^LUX_SCALE
  74. S.M7C = 0x002b -- 0.00260 * 2^LUX_SCALE
  75. S.K8C = 0x029a -- 1.3 * 2^RATIO_SCALE
  76. S.B8C = 0x0000 -- 0.000 * 2^LUX_SCALE
  77. S.M8C = 0x0000 -- 0.000 * 2^LUX_SCALE
  78. local moduleName = ...
  79. local M = {}
  80. _G[moduleName] = M
  81. -- i2c interface ID
  82. local id = 0
  83. -- local vars
  84. local ch0,ch1,chScale,channel1,channel0,ratio1,b,m,temp,lux = 0
  85. -- Wrapping I2C functions to retain original calls
  86. local Wire = {}
  87. function Wire.beginTransmission(ADDR)
  88. i2c.start(id)
  89. i2c.address(id, ADDR, i2c.TRANSMITTER)
  90. end
  91. function Wire.write(commands)
  92. i2c.write(id, commands)
  93. end
  94. function Wire.endTransmission()
  95. i2c.stop(id)
  96. end
  97. function Wire.requestFrom(ADDR, length)
  98. i2c.start(id)
  99. i2c.address(id, ADDR,i2c.RECEIVER)
  100. c = i2c.read(id, length)
  101. i2c.stop(id)
  102. return string.byte(c)
  103. end
  104. local function readRegister(deviceAddress, address)
  105. Wire.beginTransmission(deviceAddress)
  106. Wire.write(address) -- register to read
  107. Wire.endTransmission()
  108. value = Wire.requestFrom(deviceAddress, 1) -- read a byte
  109. return value
  110. end
  111. local function writeRegister(deviceAddress, address, val)
  112. Wire.beginTransmission(deviceAddress) -- start transmission to device
  113. Wire.write(address) -- send register address
  114. Wire.write(val) -- send value to write
  115. Wire.endTransmission() -- end transmission
  116. end
  117. function M.getLux()
  118. local CH0_LOW=readRegister(TSL2561_Address,TSL2561_Channel0L)
  119. local CH0_HIGH=readRegister(TSL2561_Address,TSL2561_Channel0H)
  120. --read two bytes from registers 0x0E and 0x0F
  121. local CH1_LOW=readRegister(TSL2561_Address,TSL2561_Channel1L)
  122. local CH1_HIGH=readRegister(TSL2561_Address,TSL2561_Channel1H)
  123. ch0 = bit.bor(bit.lshift(CH0_HIGH,8),CH0_LOW)
  124. ch1 = bit.bor(bit.lshift(CH1_HIGH,8),CH1_LOW)
  125. end
  126. function M.init(sda, scl)
  127. i2c.setup(id, sda, scl, i2c.SLOW)
  128. writeRegister(TSL2561_Address,TSL2561_Control,0x03) -- POWER UP
  129. writeRegister(TSL2561_Address,TSL2561_Timing,0x00) --No High Gain (1x), integration time of 13ms
  130. writeRegister(TSL2561_Address,TSL2561_Interrupt,0x00)
  131. writeRegister(TSL2561_Address,TSL2561_Control,0x00) -- POWER Down
  132. end
  133. function M.readVisibleLux()
  134. writeRegister(TSL2561_Address,TSL2561_Control,0x03) -- POWER UP
  135. tmr.delay(14000)
  136. M.getLux()
  137. writeRegister(TSL2561_Address,TSL2561_Control,0x00) -- POWER Down
  138. if(ch0/ch1 < 2 and ch0 > 4900) then
  139. return -1 -- ch0 out of range, but ch1 not. the lux is not valid in this situation.
  140. end
  141. return M.calculateLux(0, 0, 0) -- T package, no gain, 13ms
  142. end
  143. function M.calculateLux(iGain, tInt, iType)
  144. if tInt == 0 then -- 13.7 msec
  145. chScale = CHSCALE_TINT0
  146. elseif tInt == 1 then -- 101 msec
  147. chScale = CHSCALE_TINT1
  148. else -- assume no scaling
  149. chScale = bit.lshift(1,CH_SCALE)
  150. end
  151. if (not iGain) then chScale = bit.lshift(chScale,4) end -- scale 1X to 16X
  152. -- scale the channel values
  153. channel0 = bit.rshift((ch0 * chScale),CH_SCALE)
  154. channel1 = bit.rshift((ch1 * chScale),CH_SCALE)
  155. ratio1 = 0
  156. if channel0 ~= 0 then ratio1 = bit.lshift(channel1,(RATIO_SCALE+1))/channel0 end
  157. -- round the ratio value
  158. ratio = bit.rshift((ratio1 + 1),1)
  159. if iType == 0 then -- T package
  160. if ratio >= 0 and ratio <= S.K1T then
  161. b=S.B1T
  162. m=S.M1T
  163. elseif ratio <= S.K2T then
  164. b=S.B2T
  165. m=S.M2T
  166. elseif ratio <= S.K3T then
  167. b=S.B3T
  168. m=S.M3T
  169. elseif ratio <= S.K4T then
  170. b=S.B4T
  171. m=S.M4T
  172. elseif ratio <= S.K5T then
  173. b=S.B5T
  174. m=S.M5T
  175. elseif ratio <= S.K6T then
  176. b=S.B6T
  177. m=S.M6T
  178. elseif ratio <= S.K7T then
  179. b=S.B7T
  180. m=S.M7T
  181. elseif ratio > S.K8T then
  182. b=S.B8T
  183. m=S.M8T
  184. end
  185. elseif iType == 1 then -- CS package
  186. if ratio >= 0 and ratio <= S.K1C then
  187. b=S.B1C
  188. m=S.M1C
  189. elseif ratio <= S.K2C then
  190. b=S.B2C
  191. m=S.M2C
  192. elseif ratio <= S.K3C then
  193. b=S.B3C
  194. m=S.M3C
  195. elseif ratio <= S.K4C then
  196. b=S.B4C
  197. m=S.M4C
  198. elseif ratio <= S.K5C then
  199. b=S.B5C
  200. m=S.M5C
  201. elseif ratio <= S.K6C then
  202. b=S.B6C
  203. m=S.M6C
  204. elseif ratio <= S.K7C then
  205. b=S.B7C
  206. m=S.M7C
  207. end
  208. end
  209. temp=((channel0*b)-(channel1*m))
  210. if temp<0 then temp=0 end
  211. temp = temp + bit.lshift(1,(LUX_SCALE-1))
  212. -- strip off fractional portion
  213. lux = bit.rshift(temp,LUX_SCALE)
  214. return lux
  215. end
  216. return M