tsl2591.py 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186
  1. # tsl2591 lux sensor interface
  2. import time
  3. VISIBLE = 2
  4. INFRARED = 1
  5. FULLSPECTRUM = 0
  6. ADDR = 0x29
  7. READBIT = 0x01
  8. COMMAND_BIT = 0xA0
  9. CLEAR_BIT = 0x40
  10. WORD_BIT = 0x20
  11. BLOCK_BIT = 0x10
  12. ENABLE_POWERON = 0x01
  13. ENABLE_POWEROFF = 0x00
  14. ENABLE_AEN = 0x02
  15. ENABLE_AIEN = 0x10
  16. CONTROL_RESET = 0x80
  17. LUX_DF = 408.0
  18. LUX_COEFB = 1.64
  19. LUX_COEFC = 0.59
  20. LUX_COEFD = 0.86
  21. REGISTER_ENABLE = 0x00
  22. REGISTER_CONTROL = 0x01
  23. REGISTER_THRESHHOLDL_LOW = 0x02
  24. REGISTER_THRESHHOLDL_HIGH = 0x03
  25. REGISTER_THRESHHOLDH_LOW = 0x04
  26. REGISTER_THRESHHOLDH_HIGH = 0x05
  27. REGISTER_INTERRUPT = 0x06
  28. REGISTER_CRC = 0x08
  29. REGISTER_ID = 0x0A
  30. REGISTER_CHAN0_LOW = 0x14
  31. REGISTER_CHAN0_HIGH = 0x15
  32. REGISTER_CHAN1_LOW = 0x16
  33. REGISTER_CHAN1_HIGH = 0x17
  34. INTEGRATIONTIME_100MS = 0x00
  35. INTEGRATIONTIME_200MS = 0x01
  36. INTEGRATIONTIME_300MS = 0x02
  37. INTEGRATIONTIME_400MS = 0x03
  38. INTEGRATIONTIME_500MS = 0x04
  39. INTEGRATIONTIME_600MS = 0x05
  40. GAIN_LOW = 0x00
  41. GAIN_MED = 0x10
  42. GAIN_HIGH = 0x20
  43. GAIN_MAX = 0x30
  44. def _bytes_to_int(data):
  45. return data[0] + (data[1]<<8)
  46. from machine import I2C, Pin
  47. class SMBusEmulator:
  48. __slots__ = ('i2c',)
  49. def __init__(self, scl_pinno=5, sda_pinno=4):
  50. self.i2c = I2C(scl=Pin(scl_pinno, Pin.IN),
  51. sda=Pin(sda_pinno, Pin.IN))
  52. def write_byte_data(self, addr, cmd, val):
  53. buf = bytes([cmd, val])
  54. self.i2c.writeto(addr, buf)
  55. def read_word_data(self, addr, cmd):
  56. assert cmd < 256
  57. buf = bytes([cmd])
  58. self.i2c.writeto(addr, buf)
  59. data = self.i2c.readfrom(addr, 4)
  60. return _bytes_to_int(data)
  61. SENSOR_ADDRESS=0x29
  62. class Tsl2591:
  63. def __init__(
  64. self,
  65. sensor_id='tsl2591',
  66. integration=INTEGRATIONTIME_100MS,
  67. gain=GAIN_LOW
  68. ):
  69. self.sensor_id = sensor_id
  70. self.bus = SMBusEmulator()
  71. self.integration_time = integration
  72. self.gain = gain
  73. self.set_timing(self.integration_time)
  74. self.set_gain(self.gain)
  75. self.disable()
  76. def get_i2c(self):
  77. return self.bus.i2c
  78. def set_timing(self, integration):
  79. self.enable()
  80. self.integration_time = integration
  81. self.bus.write_byte_data(
  82. SENSOR_ADDRESS,
  83. COMMAND_BIT | REGISTER_CONTROL,
  84. self.integration_time | self.gain
  85. )
  86. self.disable()
  87. def set_gain(self, gain):
  88. self.enable()
  89. self.gain = gain
  90. self.bus.write_byte_data(
  91. SENSOR_ADDRESS,
  92. COMMAND_BIT | REGISTER_CONTROL,
  93. self.integration_time | self.gain
  94. )
  95. self.disable()
  96. def calculate_lux(self, full, ir):
  97. if (full == 0xFFFF) | (ir == 0xFFFF):
  98. return 0
  99. case_integ = {
  100. INTEGRATIONTIME_100MS: 100.,
  101. INTEGRATIONTIME_200MS: 200.,
  102. INTEGRATIONTIME_300MS: 300.,
  103. INTEGRATIONTIME_400MS: 400.,
  104. INTEGRATIONTIME_500MS: 500.,
  105. INTEGRATIONTIME_600MS: 600.,
  106. }
  107. if self.integration_time in case_integ.keys():
  108. atime = case_integ[self.integration_time]
  109. else:
  110. atime = 100.
  111. case_gain = {
  112. GAIN_LOW: 1.,
  113. GAIN_MED: 25.,
  114. GAIN_HIGH: 428.,
  115. GAIN_MAX: 9876.,
  116. }
  117. if self.gain in case_gain.keys():
  118. again = case_gain[self.gain]
  119. else:
  120. again = 1.
  121. cpl = (atime * again) / LUX_DF
  122. lux1 = (full - (LUX_COEFB * ir)) / cpl
  123. lux2 = ((LUX_COEFC * full) - (LUX_COEFD * ir)) / cpl
  124. return max([lux1, lux2])
  125. def enable(self):
  126. self.bus.write_byte_data(
  127. SENSOR_ADDRESS,
  128. COMMAND_BIT | REGISTER_ENABLE,
  129. ENABLE_POWERON | ENABLE_AEN | ENABLE_AIEN
  130. )
  131. def disable(self):
  132. self.bus.write_byte_data(
  133. SENSOR_ADDRESS,
  134. COMMAND_BIT | REGISTER_ENABLE,
  135. ENABLE_POWEROFF
  136. )
  137. def get_full_luminosity(self):
  138. self.enable()
  139. time.sleep(0.120*self.integration_time+1)
  140. full = self.bus.read_word_data(
  141. SENSOR_ADDRESS, COMMAND_BIT | REGISTER_CHAN0_LOW
  142. )
  143. ir = self.bus.read_word_data(
  144. SENSOR_ADDRESS, COMMAND_BIT | REGISTER_CHAN1_LOW
  145. )
  146. self.disable()
  147. return full, ir
  148. def get_luminosity(self, channel):
  149. full, ir = self.get_full_luminosity()
  150. if channel == FULLSPECTRUM:
  151. return full
  152. elif channel == INFRARED:
  153. return ir
  154. elif channel == VISIBLE:
  155. return full - ir
  156. else:
  157. return 0
  158. def sample(self):
  159. full, ir = self.get_full_luminosity()
  160. return self.calculate_lux(full, ir)