Generic Si7021 Temp/Hum sensor library

Dependents:   Turtle_RadioShuttle

Committer:
Helmut64
Date:
Fri Mar 29 13:32:00 2019 +0000
Revision:
1:5ea2d9a2ef8c
Parent:
0:19633f4a946b
Updated type

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Helmut64 0:19633f4a946b 1 /*
Helmut64 0:19633f4a946b 2 * Copyright (c) 2019 Helmut Tschemernjak
Helmut64 0:19633f4a946b 3 * 30826 Garbsen (Hannover) Germany
Helmut64 0:19633f4a946b 4 * Licensed under the Apache License, Version 2.0);
Helmut64 0:19633f4a946b 5 */
Helmut64 0:19633f4a946b 6
Helmut64 0:19633f4a946b 7 #include "main.h"
Helmut64 0:19633f4a946b 8
Helmut64 0:19633f4a946b 9 #ifdef FEATURE_SI7021
Helmut64 0:19633f4a946b 10
Helmut64 0:19633f4a946b 11 #include <HELIOS_Si7021.h>
Helmut64 0:19633f4a946b 12
Helmut64 0:19633f4a946b 13
Helmut64 0:19633f4a946b 14 #define SI7021_MEASRH_HOLD_CMD 0xE5 // Measure Relative Humidity, Hold Master Mode
Helmut64 0:19633f4a946b 15 #define SI7021_MEASRH_NOHOLD_CMD 0xF5 // Measure Relative Humidity, No Hold Master Mode
Helmut64 0:19633f4a946b 16 #define SI7021_MEASTEMP_HOLD_CMD 0xE3 // Measure Temperature, Hold Master Mode
Helmut64 0:19633f4a946b 17 #define SI7021_MEASTEMP_NOHOLD_CMD 0xF3 // Measure Temperature, No Hold Master Mode
Helmut64 0:19633f4a946b 18 #define SI7021_READPREVTEMP_CMD 0xE0 // Read Temperature Value from Previous RH Measurement
Helmut64 0:19633f4a946b 19 #define SI7021_RESET_CMD 0xFE
Helmut64 0:19633f4a946b 20 #define SI7021_WRITERHT_REG_CMD 0xE6 // Write RH/T User Register 1
Helmut64 0:19633f4a946b 21 #define SI7021_READRHT_REG_CMD 0xE7 // Read RH/T User Register 1
Helmut64 0:19633f4a946b 22 #define SI7021_WRITEHEATER_REG_CMD 0x51 // Write Heater Control Register
Helmut64 0:19633f4a946b 23 #define SI7021_READHEATER_REG_CMD 0x11 // Read Heater Control Register
Helmut64 0:19633f4a946b 24 #define SI7021_ID1_CMD 0xFA0F // Read Electronic ID 1st Byte
Helmut64 0:19633f4a946b 25 #define SI7021_ID2_CMD 0xFCC9 // Read Electronic ID 2nd Byte
Helmut64 0:19633f4a946b 26 #define SI7021_FIRMVERS_CMD 0x84B8 // Read Firmware Revision
Helmut64 0:19633f4a946b 27
Helmut64 0:19633f4a946b 28 #define SI7021_REV_1 0xff
Helmut64 0:19633f4a946b 29 #define SI7021_REV_2 0x20
Helmut64 0:19633f4a946b 30
Helmut64 0:19633f4a946b 31
Helmut64 0:19633f4a946b 32
Helmut64 0:19633f4a946b 33 /**************************************************************************/
Helmut64 0:19633f4a946b 34
Helmut64 0:19633f4a946b 35 HELIOS_Si7021::HELIOS_Si7021(PinName sda, PinName scl)
Helmut64 0:19633f4a946b 36 {
Helmut64 0:19633f4a946b 37 sernum_a = sernum_b = 0;
Helmut64 0:19633f4a946b 38 _model = SI_7021;
Helmut64 0:19633f4a946b 39 _revision = 0;
Helmut64 0:19633f4a946b 40 _foundDevice = false;
Helmut64 0:19633f4a946b 41 _i2c = new I2C(sda, scl);
Helmut64 0:19633f4a946b 42
Helmut64 0:19633f4a946b 43 reset();
Helmut64 0:19633f4a946b 44
Helmut64 0:19633f4a946b 45 _data[0] = SI7021_READRHT_REG_CMD;
Helmut64 0:19633f4a946b 46 _i2c->write(_i2caddr, _data, 1);
Helmut64 0:19633f4a946b 47 _i2c->read(_i2caddr, _data, 1);
Helmut64 0:19633f4a946b 48
Helmut64 0:19633f4a946b 49 if (_data[0] != 0x3A)
Helmut64 0:19633f4a946b 50 return;
Helmut64 0:19633f4a946b 51 _foundDevice = true;
Helmut64 0:19633f4a946b 52
Helmut64 0:19633f4a946b 53 readSerialNumber();
Helmut64 0:19633f4a946b 54 _readRevision();
Helmut64 0:19633f4a946b 55 }
Helmut64 0:19633f4a946b 56
Helmut64 0:19633f4a946b 57
Helmut64 0:19633f4a946b 58 HELIOS_Si7021::~HELIOS_Si7021(void)
Helmut64 0:19633f4a946b 59 {
Helmut64 0:19633f4a946b 60 if (_i2c)
Helmut64 0:19633f4a946b 61 delete _i2c;
Helmut64 0:19633f4a946b 62 }
Helmut64 0:19633f4a946b 63
Helmut64 0:19633f4a946b 64
Helmut64 0:19633f4a946b 65 void HELIOS_Si7021::reset(void)
Helmut64 0:19633f4a946b 66 {
Helmut64 0:19633f4a946b 67
Helmut64 0:19633f4a946b 68 _data[0] = SI7021_RESET_CMD;
Helmut64 0:19633f4a946b 69 _i2c->write(_i2caddr, _data, 1);
Helmut64 0:19633f4a946b 70 wait_ms(50);
Helmut64 0:19633f4a946b 71 }
Helmut64 0:19633f4a946b 72
Helmut64 0:19633f4a946b 73
Helmut64 0:19633f4a946b 74 void HELIOS_Si7021::readSerialNumber(void)
Helmut64 0:19633f4a946b 75 {
Helmut64 0:19633f4a946b 76
Helmut64 0:19633f4a946b 77 if (!_foundDevice)
Helmut64 0:19633f4a946b 78 return;
Helmut64 0:19633f4a946b 79
Helmut64 0:19633f4a946b 80 _data[0] = SI7021_ID1_CMD >> 8;
Helmut64 0:19633f4a946b 81 _data[1] = SI7021_ID1_CMD & 0xFF;
Helmut64 0:19633f4a946b 82 _i2c->write(_i2caddr, _data, 2);
Helmut64 0:19633f4a946b 83
Helmut64 0:19633f4a946b 84 _i2c->read(_i2caddr, _data, 8);
Helmut64 0:19633f4a946b 85 sernum_a = _data[0];
Helmut64 0:19633f4a946b 86 sernum_a <<= 8;
Helmut64 0:19633f4a946b 87 sernum_a |= _data[2];
Helmut64 0:19633f4a946b 88 sernum_a <<= 8;
Helmut64 0:19633f4a946b 89 sernum_a |= _data[4];
Helmut64 0:19633f4a946b 90 sernum_a <<= 8;
Helmut64 0:19633f4a946b 91 sernum_a |= _data[6];
Helmut64 0:19633f4a946b 92
Helmut64 0:19633f4a946b 93
Helmut64 0:19633f4a946b 94
Helmut64 0:19633f4a946b 95 _data[0] = SI7021_ID2_CMD >> 8;
Helmut64 0:19633f4a946b 96 _data[1] = SI7021_ID2_CMD & 0xFF;
Helmut64 0:19633f4a946b 97 _i2c->write(_i2caddr, _data, 2);
Helmut64 0:19633f4a946b 98
Helmut64 0:19633f4a946b 99 _i2c->read(_i2caddr, _data, 8);
Helmut64 0:19633f4a946b 100 sernum_b = _data[0];
Helmut64 0:19633f4a946b 101 sernum_b <<= 8;
Helmut64 0:19633f4a946b 102 sernum_b |= _data[2];
Helmut64 0:19633f4a946b 103 sernum_b <<= 8;
Helmut64 0:19633f4a946b 104 sernum_b |= _data[4];
Helmut64 0:19633f4a946b 105 sernum_b <<= 8;
Helmut64 0:19633f4a946b 106 sernum_b |= _data[6];
Helmut64 0:19633f4a946b 107
Helmut64 0:19633f4a946b 108
Helmut64 0:19633f4a946b 109 switch(sernum_b >> 24) {
Helmut64 0:19633f4a946b 110 case 0:
Helmut64 0:19633f4a946b 111 case 0xff:
Helmut64 0:19633f4a946b 112 _model = SI_Engineering_Samples;
Helmut64 0:19633f4a946b 113 break;
Helmut64 0:19633f4a946b 114 case 0x0D:
Helmut64 0:19633f4a946b 115 _model = SI_7013;
Helmut64 0:19633f4a946b 116 break;
Helmut64 0:19633f4a946b 117 case 0x14:
Helmut64 0:19633f4a946b 118 _model = SI_7020;
Helmut64 0:19633f4a946b 119 break;
Helmut64 0:19633f4a946b 120 case 0x15:
Helmut64 0:19633f4a946b 121 _model = SI_7021;
Helmut64 0:19633f4a946b 122 break;
Helmut64 0:19633f4a946b 123 default:
Helmut64 0:19633f4a946b 124 _model = SI_unkown;
Helmut64 0:19633f4a946b 125 }
Helmut64 0:19633f4a946b 126 }
Helmut64 0:19633f4a946b 127
Helmut64 0:19633f4a946b 128
Helmut64 0:19633f4a946b 129 void HELIOS_Si7021::_readRevision(void)
Helmut64 0:19633f4a946b 130 {
Helmut64 0:19633f4a946b 131 if (!_foundDevice)
Helmut64 0:19633f4a946b 132 return;
Helmut64 0:19633f4a946b 133
Helmut64 0:19633f4a946b 134 _revision = 0;
Helmut64 0:19633f4a946b 135
Helmut64 0:19633f4a946b 136 _data[0] = SI7021_FIRMVERS_CMD >> 8;
Helmut64 0:19633f4a946b 137 _data[1] = SI7021_FIRMVERS_CMD & 0xFF;
Helmut64 0:19633f4a946b 138 _i2c->write(_i2caddr, _data, 2);
Helmut64 0:19633f4a946b 139
Helmut64 0:19633f4a946b 140 _i2c->read(_i2caddr, _data, 2);
Helmut64 0:19633f4a946b 141 if (_data[0] == SI7021_REV_1) {
Helmut64 0:19633f4a946b 142 _revision = 1;
Helmut64 0:19633f4a946b 143 } else if (_data[0] == SI7021_REV_2) {
Helmut64 0:19633f4a946b 144 _revision = 2;
Helmut64 0:19633f4a946b 145 }
Helmut64 0:19633f4a946b 146 }
Helmut64 0:19633f4a946b 147
Helmut64 0:19633f4a946b 148
Helmut64 0:19633f4a946b 149 float HELIOS_Si7021::readTemperature(void) {
Helmut64 0:19633f4a946b 150 if (!_foundDevice)
Helmut64 0:19633f4a946b 151 return NAN;
Helmut64 0:19633f4a946b 152
Helmut64 0:19633f4a946b 153 _data[0] = SI7021_MEASTEMP_NOHOLD_CMD;
Helmut64 0:19633f4a946b 154 _i2c->write(_i2caddr, _data, 1);
Helmut64 0:19633f4a946b 155
Helmut64 0:19633f4a946b 156 Timer t;
Helmut64 0:19633f4a946b 157 t.start();
Helmut64 0:19633f4a946b 158 while(_i2c->read(_i2caddr, _data, 3) != 0) {
Helmut64 0:19633f4a946b 159 if (t.read_ms() > _TRANSACTION_TIMEOUT)
Helmut64 0:19633f4a946b 160 return NAN;
Helmut64 0:19633f4a946b 161 wait_ms(6); // 1/2 typical sample processing time
Helmut64 0:19633f4a946b 162 }
Helmut64 0:19633f4a946b 163
Helmut64 0:19633f4a946b 164 float temperature = _data[0] << 8 | _data[1];
Helmut64 0:19633f4a946b 165 temperature *= 175.72;
Helmut64 0:19633f4a946b 166 temperature /= 65536;
Helmut64 0:19633f4a946b 167 temperature -= 46.85;
Helmut64 0:19633f4a946b 168
Helmut64 0:19633f4a946b 169 return temperature;
Helmut64 0:19633f4a946b 170 }
Helmut64 0:19633f4a946b 171
Helmut64 0:19633f4a946b 172
Helmut64 0:19633f4a946b 173 float HELIOS_Si7021::readHumidity(void)
Helmut64 0:19633f4a946b 174 {
Helmut64 0:19633f4a946b 175 if (!_foundDevice)
Helmut64 0:19633f4a946b 176 return NAN;
Helmut64 0:19633f4a946b 177
Helmut64 0:19633f4a946b 178 _data[0] = SI7021_MEASRH_NOHOLD_CMD;
Helmut64 0:19633f4a946b 179 _i2c->write(_i2caddr, _data, 1);
Helmut64 0:19633f4a946b 180
Helmut64 0:19633f4a946b 181 Timer t;
Helmut64 0:19633f4a946b 182 t.start();
Helmut64 0:19633f4a946b 183 while(_i2c->read(_i2caddr, _data, 3) != 0) {
Helmut64 0:19633f4a946b 184 if (t.read_ms() > _TRANSACTION_TIMEOUT)
Helmut64 0:19633f4a946b 185 return NAN;
Helmut64 0:19633f4a946b 186 wait_ms(6); // 1/2 typical sample processing time
Helmut64 0:19633f4a946b 187 }
Helmut64 0:19633f4a946b 188
Helmut64 0:19633f4a946b 189 float humidity = (_data[0] << 8 | _data[1]) * 125;
Helmut64 0:19633f4a946b 190 humidity /= 65536;
Helmut64 0:19633f4a946b 191 humidity -= 6;
Helmut64 0:19633f4a946b 192
Helmut64 0:19633f4a946b 193 return humidity;
Helmut64 0:19633f4a946b 194 }
Helmut64 0:19633f4a946b 195
Helmut64 0:19633f4a946b 196
Helmut64 0:19633f4a946b 197 const char *HELIOS_Si7021::getModelName(void)
Helmut64 0:19633f4a946b 198 {
Helmut64 0:19633f4a946b 199 switch(_model) {
Helmut64 0:19633f4a946b 200 case SI_Engineering_Samples:
Helmut64 0:19633f4a946b 201 return "SI engineering samples";
Helmut64 0:19633f4a946b 202 case SI_7013:
Helmut64 0:19633f4a946b 203 return "Si7013";
Helmut64 0:19633f4a946b 204 case SI_7020:
Helmut64 0:19633f4a946b 205 return "Si7020";
Helmut64 0:19633f4a946b 206 case SI_7021:
Helmut64 0:19633f4a946b 207 return "Si7021";
Helmut64 0:19633f4a946b 208 case SI_unkown:
Helmut64 0:19633f4a946b 209 default:
Helmut64 0:19633f4a946b 210 return "unknown";
Helmut64 0:19633f4a946b 211 }
Helmut64 0:19633f4a946b 212 }
Helmut64 0:19633f4a946b 213
Helmut64 0:19633f4a946b 214
Helmut64 0:19633f4a946b 215 HELIOS_Si7021::sensorType HELIOS_Si7021::getModel(void)
Helmut64 0:19633f4a946b 216 {
Helmut64 0:19633f4a946b 217 return _model;
Helmut64 0:19633f4a946b 218 }
Helmut64 0:19633f4a946b 219
Helmut64 0:19633f4a946b 220 #endif // FEATURE_SI7021
Helmut64 0:19633f4a946b 221