Generic Si7021 Temp/Hum sensor library

Dependents:   Turtle_RadioShuttle

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
+