ESP32 / ESP8266 & BME280 / SHT2x sensor with InfluxDB support
選択できるのは25トピックまでです。 トピックは、先頭が英数字で、英数字とダッシュ('-')を使用した35文字以内のものにしてください。

SHT2x.cpp 5.1KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156
  1. /*
  2. SHT2x - Humidity Library for Arduino.
  3. Get humidity and temperature from the HTU21D/SHT2x sensors.
  4. Hardware Setup:
  5. Attach the SDA pin to A4, SCL to A5.
  6. Software:
  7. Call SHT2x.Begin() in setup.
  8. SHT2x.ReadHumidity() will return a float containing the humidity. Ex: 54.7
  9. SHT2x.ReadTemperature() will return a float containing the temperature in Celsius. Ex: 24.1
  10. SHT2x.SetResolution(byte: 0b.76543210) sets the resolution of the readings.
  11. Copyright (C) 2015 Nuno Chaveiro nchaveiro[at]gmail.com Lisbon, Portugal
  12. Copyright (C) 2020 Thomas Buck <thomas@xythobuz.de>
  13. */
  14. #include <Wire.h>
  15. #include "SHT2x.h"
  16. SHT2x::SHT2x(uint8_t _addr, TwoWire* _wire) {
  17. addr = _addr;
  18. wire = _wire;
  19. }
  20. void SHT2x::begin(void) {
  21. wire->begin();
  22. }
  23. bool SHT2x::GetAlive(void) {
  24. uint16_t r = readSensor(TRIGGER_TEMP_MEASURE_HOLD);
  25. if ((r == ERROR_TIMEOUT) || (r == ERROR_CRC)) {
  26. return false;
  27. }
  28. return true;
  29. }
  30. /**********************************************************
  31. * GetHumidity
  32. * Gets the current humidity from the sensor.
  33. *
  34. * @return float - The relative humidity in %RH
  35. **********************************************************/
  36. float SHT2x::GetHumidity(void) {
  37. return (-6.0 + 125.0 / 65536.0 * (float)(readSensor(TRIGGER_HUMD_MEASURE_HOLD)));
  38. }
  39. /**********************************************************
  40. * GetTemperature
  41. * Gets the current temperature from the sensor.
  42. *
  43. * @return float - The temperature in Deg C
  44. **********************************************************/
  45. float SHT2x::GetTemperature(void) {
  46. return (-46.85 + 175.72 / 65536.0 * (float)(readSensor(TRIGGER_TEMP_MEASURE_HOLD)));
  47. }
  48. /**********************************************************
  49. * Sets the sensor resolution to one of four levels:
  50. * 0/0 = 12bit RH, 14bit Temp
  51. * 0/1 = 8bit RH, 12bit Temp
  52. * 1/0 = 10bit RH, 13bit Temp
  53. * 1/1 = 11bit RH, 11bit Temp
  54. * Power on default is 0/0
  55. **********************************************************/
  56. void SHT2x::setResolution(uint8_t resolution) {
  57. uint8_t userRegister = read_user_register(); //Go get the current register state
  58. userRegister &= B01111110; //Turn off the resolution bits
  59. resolution &= B10000001; //Turn off all other bits but resolution bits
  60. userRegister |= resolution; //Mask in the requested resolution bits
  61. //Request a write to user register
  62. wire->beginTransmission(addr);
  63. wire->write(WRITE_USER_REG); //Write to the user register
  64. wire->write(userRegister); //Write the new resolution bits
  65. wire->endTransmission();
  66. }
  67. uint8_t SHT2x::read_user_register(void) {
  68. uint8_t userRegister;
  69. //Request the user register
  70. wire->beginTransmission(addr);
  71. wire->write(READ_USER_REG); //Read the user register
  72. wire->endTransmission();
  73. //Read result
  74. wire->requestFrom(addr, 1);
  75. userRegister = wire->read();
  76. return userRegister;
  77. }
  78. uint16_t SHT2x::readSensor(uint8_t command) {
  79. uint16_t result;
  80. wire->beginTransmission(addr); //begin
  81. wire->write(command); //send the pointer location
  82. wire->endTransmission(); //end
  83. //Hang out while measurement is taken. 50mS max, page 4 of datasheet.
  84. delay(55);
  85. //Comes back in three bytes, data(MSB) / data(LSB) / Checksum
  86. wire->requestFrom(addr, 3);
  87. //Wait for data to become available
  88. int counter = 0;
  89. while (wire->available() < 3) {
  90. counter++;
  91. delay(1);
  92. if(counter > 100) return ERROR_TIMEOUT; //Error timout
  93. }
  94. //Store the result
  95. result = ((wire->read()) << 8);
  96. result |= wire->read();
  97. //Check validity
  98. uint8_t checksum = wire->read();
  99. if(check_crc(result, checksum) != 0) return(ERROR_CRC); //Error checksum
  100. //sensorStatus = rawTemperature & 0x0003; //get status bits
  101. result &= ~0x0003; // clear two low bits (status bits)
  102. return result;
  103. }
  104. //Give this function the 2 byte message (measurement) and the check_value byte from the HTU21D
  105. //If it returns 0, then the transmission was good
  106. //If it returns something other than 0, then the communication was corrupted
  107. //From: http://www.nongnu.org/avr-libc/user-manual/group__util__crc.html
  108. //POLYNOMIAL = 0x0131 = x^8 + x^5 + x^4 + 1 : http://en.wikipedia.org/wiki/Computation_of_cyclic_redundancy_checks
  109. #define SHIFTED_DIVISOR 0x988000 // This is the 0x0131 polynomial shifted to farthest left of three bytes
  110. uint8_t SHT2x::check_crc(uint16_t message_from_sensor, uint8_t check_value_from_sensor) {
  111. // Pad with 8 bits because we have to add in the check value
  112. uint32_t remainder = (uint32_t)message_from_sensor << 8;
  113. // Add on the check value
  114. remainder |= check_value_from_sensor;
  115. uint32_t divsor = (uint32_t)SHIFTED_DIVISOR;
  116. // Operate on only 16 positions of max 24.
  117. // The remaining 8 are our remainder and should be zero when we're done.
  118. for (int i = 0; i < 16; i++) {
  119. // Check if there is a one in the left position
  120. if (remainder & ((uint32_t)1 << (23 - i))) {
  121. remainder ^= divsor;
  122. }
  123. // Rotate the divsor max 16 times so that we have 8 bits left of a remainder
  124. divsor >>= 1;
  125. }
  126. return (uint8_t)remainder;
  127. }