diff --git a/code/espurna/config/sensors.h b/code/espurna/config/sensors.h index 6b41cd53..d927924f 100644 --- a/code/espurna/config/sensors.h +++ b/code/espurna/config/sensors.h @@ -89,6 +89,7 @@ #define SENSOR_BMX280_ID 0x13 #define SENSOR_MHZ19_ID 0x14 #define SENSOR_SI7021_ID 0x15 +#define SENSOR_SHT3X_I2C_ID 0x16 // ============================================================================= // Specific data for each sensor @@ -294,6 +295,24 @@ #define PMS_RX_PIN 13 #define PMS_TX_PIN 15 +//------------------------------------------------------------------------------ +// SHT3X I2C (Wemos) temperature & humidity sensor +// Enable support by passing SHT3X_SUPPORT=1 build flag +//------------------------------------------------------------------------------ + +#ifndef SHT3X_I2C_SUPPORT +#define SHT3X_I2C_SUPPORT 0 +#endif + +#ifndef SHT3X_I2C_ADDRESS +#define SHT3X_I2C_ADDRESS 0x00 // 0x00 means auto +#endif + +#if SHT3X_I2C_SUPPORT +#undef I2C_SUPPORT +#define I2C_SUPPORT 1 +#endif + //------------------------------------------------------------------------------ // SI7021 temperature & humidity sensor // Enable support by passing SI7021_SUPPORT=1 build flag @@ -410,3 +429,7 @@ #if SI7021_SUPPORT #include "sensors/SI7021Sensor.h" #endif + +#if SHT3X_I2C_SUPPORT + #include "sensors/SHT3XI2CSensor.h" +#endif diff --git a/code/espurna/sensor.ino b/code/espurna/sensor.ino index bf86f50d..f074e0b6 100644 --- a/code/espurna/sensor.ino +++ b/code/espurna/sensor.ino @@ -337,6 +337,14 @@ void _sensorInit() { } #endif + #if SHT3X_I2C_SUPPORT + { + SHT3XI2CSensor * sensor = new SHT3XI2CSensor(); + sensor->setAddress(SHT3X_I2C_ADDRESS); + _sensorRegister(sensor); + } + #endif + #if SI7021_SUPPORT { SI7021Sensor * sensor = new SI7021Sensor(); diff --git a/code/espurna/sensors/SHT3XI2CSensor.h b/code/espurna/sensors/SHT3XI2CSensor.h new file mode 100644 index 00000000..4d2efefa --- /dev/null +++ b/code/espurna/sensors/SHT3XI2CSensor.h @@ -0,0 +1,137 @@ +// ----------------------------------------------------------------------------- +// SHT3X Sensor over I2C (Wemos) +// Copyright (C) 2017 by Xose PĂ©rez +// ----------------------------------------------------------------------------- + +#pragma once + +#include "Arduino.h" +#include "BaseSensor.h" +#if I2C_USE_BRZO +#include +#else +#include +#endif + +class SHT3XI2CSensor : public BaseSensor { + + public: + + // --------------------------------------------------------------------- + // Public + // --------------------------------------------------------------------- + + SHT3XI2CSensor(): BaseSensor() { + _sensor_id = SENSOR_SHT3X_I2C_ID; + } + + // --------------------------------------------------------------------- + + void setAddress(unsigned char address) { + if (_address == address) return; + _address = address; + _dirty = true; + } + + // --------------------------------------------------------------------- + + unsigned char getAddress() { + return _address; + } + + // --------------------------------------------------------------------- + // Sensor API + // --------------------------------------------------------------------- + + // Initialization method, must be idempotent + void begin() { + + if (!_dirty) return; + _dirty = false; + + // I2C auto-discover + unsigned char addresses[] = {0x45}; + _address = lock_i2c(_address, sizeof(addresses), addresses); + if (_address == 0) return; + + } + + // Descriptive name of the sensor + String description() { + char buffer[25]; + snprintf(buffer, sizeof(buffer), "SHT3X @ I2C (0x%02X)", _address); + return String(buffer); + } + + // Descriptive name of the slot # index + String slot(unsigned char index) { + return description(); + } + + // Type for slot # index + magnitude_t type(unsigned char index) { + if (index < _count) { + _error = SENSOR_ERROR_OK; + if (index == 0) return MAGNITUDE_TEMPERATURE; + if (index == 1) return MAGNITUDE_HUMIDITY; + } + _error = SENSOR_ERROR_OUT_OF_RANGE; + return MAGNITUDE_NONE; + } + + // Pre-read hook (usually to populate registers with up-to-date data) + void pre() { + + unsigned int buffer[6]; + + #if I2C_USE_BRZO + buffer[0] = 0x2C; + buffer[1] = 0x06; + brzo_i2c_start_transaction(_address, I2C_SCL_FREQUENCY); + brzo_i2c_write(buffer, 2, false); + #else + Wire.beginTransmission(_address); + Wire.write(0x2C); + Wire.write(0x06); + if (Wire.endTransmission() != 0) { + _error = SENSOR_ERROR_TIMEOUT; + return; + } + #endif + + delay(500); + + #if I2C_USE_BRZO + brzo_i2c_read(buffer, 6, false); + brzo_i2c_end_transaction(); + #else + Wire.requestFrom(_address, (unsigned char) 6); + for (int i=0; i<6; i++) buffer[i] = Wire.read(); + delay(50); + if (Wire.available() != 0) { + _error = SENSOR_ERROR_CRC; + return; + } + #endif + + // cTemp msb, cTemp lsb, cTemp crc, humidity msb, humidity lsb, humidity crc + _temperature = ((((buffer[0] * 256.0) + buffer[1]) * 175) / 65535.0) - 45; + _humidity = ((((buffer[3] * 256.0) + buffer[4]) * 100) / 65535.0); + + } + + // Current value for slot # index + double value(unsigned char index) { + _error = SENSOR_ERROR_OK; + if (index == 0) return _temperature; + if (index == 1) return _humidity; + _error = SENSOR_ERROR_OUT_OF_RANGE; + return 0; + } + + protected: + + double _temperature = 0; + unsigned char _humidity = 0; + +};