Fork of the espurna firmware for `mhsw` switches
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.

132 lines
4.0 KiB

  1. // -----------------------------------------------------------------------------
  2. // SHT3X Sensor over I2C (Wemos)
  3. // Copyright (C) 2017 by Xose Pérez <xose dot perez at gmail dot com>
  4. // -----------------------------------------------------------------------------
  5. #pragma once
  6. #include "Arduino.h"
  7. #include "BaseSensor.h"
  8. #if I2C_USE_BRZO
  9. #include <brzo_i2c.h>
  10. #else
  11. #include <Wire.h>
  12. #endif
  13. class SHT3XI2CSensor : public BaseSensor {
  14. public:
  15. // ---------------------------------------------------------------------
  16. // Public
  17. // ---------------------------------------------------------------------
  18. SHT3XI2CSensor(): BaseSensor() {
  19. _sensor_id = SENSOR_SHT3X_I2C_ID;
  20. }
  21. // ---------------------------------------------------------------------
  22. void setAddress(unsigned char address) {
  23. if (_address == address) return;
  24. _address = address;
  25. _dirty = true;
  26. }
  27. // ---------------------------------------------------------------------
  28. unsigned char getAddress() {
  29. return _address;
  30. }
  31. // ---------------------------------------------------------------------
  32. // Sensor API
  33. // ---------------------------------------------------------------------
  34. // Initialization method, must be idempotent
  35. void begin() {
  36. if (!_dirty) return;
  37. _dirty = false;
  38. // I2C auto-discover
  39. unsigned char addresses[] = {0x45};
  40. _address = lock_i2c(_address, sizeof(addresses), addresses);
  41. if (_address == 0) return;
  42. }
  43. // Descriptive name of the sensor
  44. String description() {
  45. char buffer[25];
  46. snprintf(buffer, sizeof(buffer), "SHT3X @ I2C (0x%02X)", _address);
  47. return String(buffer);
  48. }
  49. // Type for slot # index
  50. magnitude_t type(unsigned char index) {
  51. if (index < _count) {
  52. _error = SENSOR_ERROR_OK;
  53. if (index == 0) return MAGNITUDE_TEMPERATURE;
  54. if (index == 1) return MAGNITUDE_HUMIDITY;
  55. }
  56. _error = SENSOR_ERROR_OUT_OF_RANGE;
  57. return MAGNITUDE_NONE;
  58. }
  59. // Pre-read hook (usually to populate registers with up-to-date data)
  60. void pre() {
  61. unsigned char buffer[6];
  62. #if I2C_USE_BRZO
  63. buffer[0] = 0x2C;
  64. buffer[1] = 0x06;
  65. brzo_i2c_start_transaction(_address, I2C_SCL_FREQUENCY);
  66. brzo_i2c_write(buffer, 2, false);
  67. #else
  68. Wire.beginTransmission(_address);
  69. Wire.write(0x2C);
  70. Wire.write(0x06);
  71. if (Wire.endTransmission() != 0) {
  72. _error = SENSOR_ERROR_TIMEOUT;
  73. return;
  74. }
  75. #endif
  76. delay(500);
  77. #if I2C_USE_BRZO
  78. brzo_i2c_read(buffer, 6, false);
  79. brzo_i2c_end_transaction();
  80. #else
  81. Wire.requestFrom(_address, (unsigned char) 6);
  82. for (int i=0; i<6; i++) buffer[i] = Wire.read();
  83. delay(50);
  84. if (Wire.available() != 0) {
  85. _error = SENSOR_ERROR_CRC;
  86. return;
  87. }
  88. #endif
  89. // cTemp msb, cTemp lsb, cTemp crc, humidity msb, humidity lsb, humidity crc
  90. _temperature = ((((buffer[0] * 256.0) + buffer[1]) * 175) / 65535.0) - 45;
  91. _humidity = ((((buffer[3] * 256.0) + buffer[4]) * 100) / 65535.0);
  92. }
  93. // Current value for slot # index
  94. double value(unsigned char index) {
  95. _error = SENSOR_ERROR_OK;
  96. if (index == 0) return _temperature;
  97. if (index == 1) return _humidity;
  98. _error = SENSOR_ERROR_OUT_OF_RANGE;
  99. return 0;
  100. }
  101. protected:
  102. double _temperature = 0;
  103. unsigned char _humidity = 0;
  104. };