bluething IoT Sensor based on ESP8266
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

mcp9808.py 3.6KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129
  1. # micropython-mcp9808
  2. from machine import I2C
  3. R_CFG = const(1)
  4. R_B_UP = const(2)
  5. R_B_LOW = const(3)
  6. R_B_CRIT = const(4)
  7. R_A_TEMP = const(5)
  8. R_M_ID = const(6)
  9. R_D_ID = const(7)
  10. R_T_RES = const(8)
  11. T_RES_MIN = const(0)
  12. T_RES_LOW = const(1)
  13. T_RES_AVG = const(2)
  14. T_RES_MAX = const(3)
  15. class MCP9808(object):
  16. """
  17. This class implements an interface to the MCP9808 temprature sensor from
  18. Microchip.
  19. """
  20. def __init__(self, i2c=None, addr=0x18):
  21. """
  22. Initialize a sensor object on the given I2C bus and accessed by the
  23. given address.
  24. """
  25. if i2c == None or i2c.__class__ != I2C:
  26. raise ValueError('I2C object needed as argument!')
  27. self._i2c = i2c
  28. self._addr = addr
  29. self._check_device()
  30. def _send(self, buf):
  31. """
  32. Sends the given bufer object over I2C to the sensor.
  33. """
  34. if isinstance(buf, int):
  35. b = bytearray()
  36. b.append(buf)
  37. else:
  38. b = buf
  39. self._i2c.writeto(self._addr, b)
  40. def _recv(self, n):
  41. """
  42. Read bytes from the sensor using I2C. The byte count must be specified
  43. as an argument.
  44. Returns a bytearray containing the result.
  45. """
  46. return self._i2c.readfrom(self._addr, n)
  47. def _check_device(self):
  48. """
  49. Tries to identify the manufacturer and device identifiers.
  50. """
  51. self._send(R_M_ID)
  52. self._m_id = self._recv(2)
  53. if not self._m_id == b'\x00T':
  54. raise Exception("Invalid manufacturer ID: '%s'!" % self._m_id)
  55. self._send(R_D_ID)
  56. self._d_id = self._recv(2)
  57. if not self._d_id == b'\x04\x00':
  58. raise Exception("Invalid device or revision ID: '%s'!" % self._d_id)
  59. def set_shutdown_mode(self, shdn=True):
  60. """
  61. Set sensor into shutdown mode to draw less than 1 uA and disable
  62. continous temperature conversion.
  63. """
  64. if shdn.__class__ != bool:
  65. raise ValueError('Boolean argument needed to set shutdown mode!')
  66. self._send(R_CFG)
  67. cfg = self._recv(2)
  68. b = bytearray()
  69. b.append(R_CFG)
  70. if shdn:
  71. b.append(cfg[0] | 1)
  72. else:
  73. b.append(cfg[0] & ~1)
  74. b.append(cfg[1])
  75. self._send(b)
  76. def get_temp(self):
  77. """
  78. Read temperature in degree celsius and return float value.
  79. """
  80. self._send(R_A_TEMP)
  81. raw = self._recv(2)
  82. u = (raw[0] & 0x0f) << 4
  83. l = raw[1] / 16
  84. if raw[0] & 0x10 == 0x10:
  85. temp = 256 - (u + l)
  86. else:
  87. temp = u + l
  88. return temp
  89. def get_temp_int(self):
  90. """
  91. Read a temperature in degree celsius and return a tuple of two parts.
  92. The first part is the decimal patr and the second the fractional part
  93. of the value.
  94. This method does avoid floating point arithmetic completely to support
  95. plattforms missing float support.
  96. """
  97. self._send(R_A_TEMP)
  98. raw = self._recv(2)
  99. u = (raw[0] & 0xf) << 4
  100. l = raw[1] >> 4
  101. if raw[0] & 0x10 == 0x10:
  102. temp = 256 - (u + l)
  103. frac = 256 - (raw[1] & 0x0f) * 100 >> 4
  104. else:
  105. temp = u + l
  106. frac = (raw[1] & 0x0f) * 100 >> 4
  107. return temp, frac
  108. def set_resolution(self, r):
  109. """
  110. Sets the temperature resolution.
  111. """
  112. if r not in [T_RES_MIN, T_RES_LOW, T_RES_AVG, T_RES_MAX]:
  113. raise ValueError('Invalid temperature resolution requested!')
  114. b = bytearray()
  115. b.append(R_T_RES)
  116. b.append(r)
  117. self._send(b)