Generic Si7021 Temp/Hum sensor library
Dependents: Turtle_RadioShuttle
Diff: HELIOS_Si7021.cpp
- Revision:
- 0:19633f4a946b
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/HELIOS_Si7021.cpp Fri Mar 29 13:24:58 2019 +0000
@@ -0,0 +1,221 @@
+/*
+ * Copyright (c) 2019 Helmut Tschemernjak
+ * 30826 Garbsen (Hannover) Germany
+ * Licensed under the Apache License, Version 2.0);
+ */
+
+#include "main.h"
+
+#ifdef FEATURE_SI7021
+
+#include <HELIOS_Si7021.h>
+
+
+#define SI7021_MEASRH_HOLD_CMD 0xE5 // Measure Relative Humidity, Hold Master Mode
+#define SI7021_MEASRH_NOHOLD_CMD 0xF5 // Measure Relative Humidity, No Hold Master Mode
+#define SI7021_MEASTEMP_HOLD_CMD 0xE3 // Measure Temperature, Hold Master Mode
+#define SI7021_MEASTEMP_NOHOLD_CMD 0xF3 // Measure Temperature, No Hold Master Mode
+#define SI7021_READPREVTEMP_CMD 0xE0 // Read Temperature Value from Previous RH Measurement
+#define SI7021_RESET_CMD 0xFE
+#define SI7021_WRITERHT_REG_CMD 0xE6 // Write RH/T User Register 1
+#define SI7021_READRHT_REG_CMD 0xE7 // Read RH/T User Register 1
+#define SI7021_WRITEHEATER_REG_CMD 0x51 // Write Heater Control Register
+#define SI7021_READHEATER_REG_CMD 0x11 // Read Heater Control Register
+#define SI7021_ID1_CMD 0xFA0F // Read Electronic ID 1st Byte
+#define SI7021_ID2_CMD 0xFCC9 // Read Electronic ID 2nd Byte
+#define SI7021_FIRMVERS_CMD 0x84B8 // Read Firmware Revision
+
+#define SI7021_REV_1 0xff
+#define SI7021_REV_2 0x20
+
+
+
+/**************************************************************************/
+
+HELIOS_Si7021::HELIOS_Si7021(PinName sda, PinName scl)
+{
+ sernum_a = sernum_b = 0;
+ _model = SI_7021;
+ _revision = 0;
+ _foundDevice = false;
+ _i2c = new I2C(sda, scl);
+
+ reset();
+
+ _data[0] = SI7021_READRHT_REG_CMD;
+ _i2c->write(_i2caddr, _data, 1);
+ _i2c->read(_i2caddr, _data, 1);
+
+ if (_data[0] != 0x3A)
+ return;
+ _foundDevice = true;
+
+ readSerialNumber();
+ _readRevision();
+}
+
+
+HELIOS_Si7021::~HELIOS_Si7021(void)
+{
+ if (_i2c)
+ delete _i2c;
+}
+
+
+void HELIOS_Si7021::reset(void)
+{
+
+ _data[0] = SI7021_RESET_CMD;
+ _i2c->write(_i2caddr, _data, 1);
+ wait_ms(50);
+}
+
+
+void HELIOS_Si7021::readSerialNumber(void)
+{
+
+ if (!_foundDevice)
+ return;
+
+ _data[0] = SI7021_ID1_CMD >> 8;
+ _data[1] = SI7021_ID1_CMD & 0xFF;
+ _i2c->write(_i2caddr, _data, 2);
+
+ _i2c->read(_i2caddr, _data, 8);
+ sernum_a = _data[0];
+ sernum_a <<= 8;
+ sernum_a |= _data[2];
+ sernum_a <<= 8;
+ sernum_a |= _data[4];
+ sernum_a <<= 8;
+ sernum_a |= _data[6];
+
+
+
+ _data[0] = SI7021_ID2_CMD >> 8;
+ _data[1] = SI7021_ID2_CMD & 0xFF;
+ _i2c->write(_i2caddr, _data, 2);
+
+ _i2c->read(_i2caddr, _data, 8);
+ sernum_b = _data[0];
+ sernum_b <<= 8;
+ sernum_b |= _data[2];
+ sernum_b <<= 8;
+ sernum_b |= _data[4];
+ sernum_b <<= 8;
+ sernum_b |= _data[6];
+
+
+ switch(sernum_b >> 24) {
+ case 0:
+ case 0xff:
+ _model = SI_Engineering_Samples;
+ break;
+ case 0x0D:
+ _model = SI_7013;
+ break;
+ case 0x14:
+ _model = SI_7020;
+ break;
+ case 0x15:
+ _model = SI_7021;
+ break;
+ default:
+ _model = SI_unkown;
+ }
+}
+
+
+void HELIOS_Si7021::_readRevision(void)
+{
+ if (!_foundDevice)
+ return;
+
+ _revision = 0;
+
+ _data[0] = SI7021_FIRMVERS_CMD >> 8;
+ _data[1] = SI7021_FIRMVERS_CMD & 0xFF;
+ _i2c->write(_i2caddr, _data, 2);
+
+ _i2c->read(_i2caddr, _data, 2);
+ if (_data[0] == SI7021_REV_1) {
+ _revision = 1;
+ } else if (_data[0] == SI7021_REV_2) {
+ _revision = 2;
+ }
+}
+
+
+float HELIOS_Si7021::readTemperature(void) {
+ if (!_foundDevice)
+ return NAN;
+
+ _data[0] = SI7021_MEASTEMP_NOHOLD_CMD;
+ _i2c->write(_i2caddr, _data, 1);
+
+ Timer t;
+ t.start();
+ while(_i2c->read(_i2caddr, _data, 3) != 0) {
+ if (t.read_ms() > _TRANSACTION_TIMEOUT)
+ return NAN;
+ wait_ms(6); // 1/2 typical sample processing time
+ }
+
+ float temperature = _data[0] << 8 | _data[1];
+ temperature *= 175.72;
+ temperature /= 65536;
+ temperature -= 46.85;
+
+ return temperature;
+}
+
+
+float HELIOS_Si7021::readHumidity(void)
+{
+ if (!_foundDevice)
+ return NAN;
+
+ _data[0] = SI7021_MEASRH_NOHOLD_CMD;
+ _i2c->write(_i2caddr, _data, 1);
+
+ Timer t;
+ t.start();
+ while(_i2c->read(_i2caddr, _data, 3) != 0) {
+ if (t.read_ms() > _TRANSACTION_TIMEOUT)
+ return NAN;
+ wait_ms(6); // 1/2 typical sample processing time
+ }
+
+ float humidity = (_data[0] << 8 | _data[1]) * 125;
+ humidity /= 65536;
+ humidity -= 6;
+
+ return humidity;
+}
+
+
+const char *HELIOS_Si7021::getModelName(void)
+{
+ switch(_model) {
+ case SI_Engineering_Samples:
+ return "SI engineering samples";
+ case SI_7013:
+ return "Si7013";
+ case SI_7020:
+ return "Si7020";
+ case SI_7021:
+ return "Si7021";
+ case SI_unkown:
+ default:
+ return "unknown";
+ }
+}
+
+
+HELIOS_Si7021::sensorType HELIOS_Si7021::getModel(void)
+{
+ return _model;
+}
+
+#endif // FEATURE_SI7021
+
Helmut Tschemernjak