Port of the SHT2x example code from Sensirion

Dependents:   sht21_test ENVLogger

Committer:
ssozonoff
Date:
Sat Apr 23 19:07:52 2011 +0000
Revision:
2:2464fed17980
Parent:
1:d0f691423bf1
Code cleanup

Who changed what in which revision?

UserRevisionLine numberNew contents of line
ssozonoff 2:2464fed17980 1 /*
ssozonoff 2:2464fed17980 2 Permission is hereby granted, free of charge, to any person obtaining a copy
ssozonoff 2:2464fed17980 3 of this software and associated documentation files (the "Software"), to deal
ssozonoff 2:2464fed17980 4 in the Software without restriction, including without limitation the rights
ssozonoff 2:2464fed17980 5 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
ssozonoff 2:2464fed17980 6 copies of the Software, and to permit persons to whom the Software is
ssozonoff 2:2464fed17980 7 furnished to do so, subject to the following conditions:
ssozonoff 2:2464fed17980 8
ssozonoff 2:2464fed17980 9 The above copyright notice and this permission notice shall be included in
ssozonoff 2:2464fed17980 10 all copies or substantial portions of the Software.
ssozonoff 2:2464fed17980 11
ssozonoff 2:2464fed17980 12 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
ssozonoff 2:2464fed17980 13 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
ssozonoff 2:2464fed17980 14 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
ssozonoff 2:2464fed17980 15 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
ssozonoff 2:2464fed17980 16 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
ssozonoff 2:2464fed17980 17 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
ssozonoff 2:2464fed17980 18 THE SOFTWARE.
ssozonoff 2:2464fed17980 19 */
ssozonoff 2:2464fed17980 20
ssozonoff 2:2464fed17980 21 //=============================================================================
ssozonoff 2:2464fed17980 22 // Port of the SHT21 example code from Sensirion
ssozonoff 2:2464fed17980 23 // port by Serge Sozonoff
ssozonoff 2:2464fed17980 24 //=============================================================================
ssozonoff 2:2464fed17980 25
ssozonoff 0:74df6ab91c79 26 #include "SHT2x.h"
ssozonoff 1:d0f691423bf1 27 #include "mbed.h"
ssozonoff 0:74df6ab91c79 28
ssozonoff 2:2464fed17980 29 SHT2x::SHT2x (PinName p_sda, PinName p_scl) : i2c(p_sda, p_scl) {
ssozonoff 0:74df6ab91c79 30 }
ssozonoff 0:74df6ab91c79 31
ssozonoff 0:74df6ab91c79 32 //==============================================================================//
ssozonoff 0:74df6ab91c79 33 int SHT2x::SHT2x_CheckCrc(int data[], int nbrOfBytes, int checksum)
ssozonoff 0:74df6ab91c79 34 //==============================================================================//
ssozonoff 0:74df6ab91c79 35 {
ssozonoff 0:74df6ab91c79 36 int crc = 0;
ssozonoff 0:74df6ab91c79 37 int byteCtr;
ssozonoff 0:74df6ab91c79 38 //calculates 8-Bit checksum with given polynomial
ssozonoff 0:74df6ab91c79 39 for (byteCtr = 0; byteCtr < nbrOfBytes; ++byteCtr) {
ssozonoff 0:74df6ab91c79 40 crc ^= (data[byteCtr]);
ssozonoff 0:74df6ab91c79 41 for (int bit = 8; bit > 0; --bit) {
ssozonoff 0:74df6ab91c79 42 if (crc & 0x80) crc = (crc << 1) ^ POLYNOMIAL;
ssozonoff 0:74df6ab91c79 43 else crc = (crc << 1);
ssozonoff 0:74df6ab91c79 44 }
ssozonoff 0:74df6ab91c79 45 }
ssozonoff 0:74df6ab91c79 46 if (crc != checksum) return CHECKSUM_ERROR;
ssozonoff 0:74df6ab91c79 47 else return 0;
ssozonoff 0:74df6ab91c79 48 }
ssozonoff 2:2464fed17980 49
ssozonoff 2:2464fed17980 50 //===========================================================================//
ssozonoff 2:2464fed17980 51 int SHT2x::i2cWrite(int data)
ssozonoff 2:2464fed17980 52 //===========================================================================//
ssozonoff 2:2464fed17980 53 {
ssozonoff 2:2464fed17980 54 if (i2c.write(data) < 1) return ACK_ERROR;
ssozonoff 2:2464fed17980 55 else return 0;
ssozonoff 2:2464fed17980 56 }
ssozonoff 2:2464fed17980 57
ssozonoff 0:74df6ab91c79 58 //===========================================================================//
ssozonoff 0:74df6ab91c79 59 int SHT2x::SHT2x_ReadUserRegister(int *pRegisterValue)
ssozonoff 0:74df6ab91c79 60 //===========================================================================//
ssozonoff 0:74df6ab91c79 61 {
ssozonoff 0:74df6ab91c79 62 int checksum; //variable for checksum byte
ssozonoff 0:74df6ab91c79 63 int error=0; //variable for error code
ssozonoff 1:d0f691423bf1 64
ssozonoff 0:74df6ab91c79 65 i2c.start();
ssozonoff 2:2464fed17980 66 error |= i2cWrite(I2C_ADR_W);
ssozonoff 2:2464fed17980 67 error |= i2cWrite(USER_REG_R);
ssozonoff 1:d0f691423bf1 68
ssozonoff 0:74df6ab91c79 69 i2c.start();
ssozonoff 2:2464fed17980 70 error |= i2cWrite(I2C_ADR_R);
ssozonoff 1:d0f691423bf1 71
ssozonoff 1:d0f691423bf1 72
ssozonoff 1:d0f691423bf1 73 *pRegisterValue = i2c.read(ACK);
ssozonoff 1:d0f691423bf1 74
ssozonoff 1:d0f691423bf1 75 checksum=i2c.read(NoACK);
ssozonoff 1:d0f691423bf1 76
ssozonoff 0:74df6ab91c79 77 error |= SHT2x_CheckCrc (pRegisterValue,1,checksum);
ssozonoff 0:74df6ab91c79 78
ssozonoff 0:74df6ab91c79 79 i2c.stop();
ssozonoff 0:74df6ab91c79 80 return error;
ssozonoff 0:74df6ab91c79 81 }
ssozonoff 0:74df6ab91c79 82 //===========================================================================//
ssozonoff 0:74df6ab91c79 83 int SHT2x::SHT2x_WriteUserRegister(int *pRegisterValue)
ssozonoff 0:74df6ab91c79 84 //===========================================================================//
ssozonoff 0:74df6ab91c79 85 {
ssozonoff 0:74df6ab91c79 86 int error=0; //variable for error code
ssozonoff 0:74df6ab91c79 87 i2c.start();
ssozonoff 1:d0f691423bf1 88
ssozonoff 2:2464fed17980 89 error |= i2cWrite(I2C_ADR_W);
ssozonoff 2:2464fed17980 90 error |= i2cWrite(USER_REG_W);
ssozonoff 2:2464fed17980 91 error |= i2cWrite(*pRegisterValue);
ssozonoff 0:74df6ab91c79 92 i2c.stop();
ssozonoff 0:74df6ab91c79 93
ssozonoff 0:74df6ab91c79 94 return error;
ssozonoff 0:74df6ab91c79 95 }
ssozonoff 0:74df6ab91c79 96 //===========================================================================//
ssozonoff 0:74df6ab91c79 97 int SHT2x::SHT2x_MeasureHM(etSHT2xMeasureType eSHT2xMeasureType, int *pMeasurand)
ssozonoff 0:74df6ab91c79 98 //===========================================================================//
ssozonoff 0:74df6ab91c79 99 {
ssozonoff 0:74df6ab91c79 100 int checksum; //checksum
ssozonoff 0:74df6ab91c79 101 int data[2]; //data array for checksum verification
ssozonoff 0:74df6ab91c79 102 int error=0; //error variable
ssozonoff 1:d0f691423bf1 103 int i;
ssozonoff 1:d0f691423bf1 104
ssozonoff 1:d0f691423bf1 105 //-- write I2C sensor address and command --
ssozonoff 0:74df6ab91c79 106 i2c.start();
ssozonoff 1:d0f691423bf1 107
ssozonoff 2:2464fed17980 108 error |= i2cWrite(I2C_ADR_W); // I2C Adr
ssozonoff 0:74df6ab91c79 109 switch (eSHT2xMeasureType) {
ssozonoff 0:74df6ab91c79 110 case HUMIDITY:
ssozonoff 2:2464fed17980 111 error |= i2cWrite(TRIG_RH_MEASUREMENT_HM);
ssozonoff 0:74df6ab91c79 112 break;
ssozonoff 1:d0f691423bf1 113 case TEMP:
ssozonoff 2:2464fed17980 114 error |= i2cWrite(TRIG_T_MEASUREMENT_HM);
ssozonoff 0:74df6ab91c79 115 break;
ssozonoff 0:74df6ab91c79 116 default:
ssozonoff 0:74df6ab91c79 117 break;
ssozonoff 0:74df6ab91c79 118 }
ssozonoff 2:2464fed17980 119
ssozonoff 0:74df6ab91c79 120 //-- wait until hold master is released --
ssozonoff 1:d0f691423bf1 121 i2c.start();
ssozonoff 2:2464fed17980 122
ssozonoff 2:2464fed17980 123 __disable_irq(); // Disable Interrupts
ssozonoff 2:2464fed17980 124
ssozonoff 2:2464fed17980 125 error |= i2cWrite(I2C_ADR_R);
ssozonoff 1:d0f691423bf1 126
ssozonoff 0:74df6ab91c79 127 //SCL=HIGH; // set SCL I/O port as input
ssozonoff 1:d0f691423bf1 128 i2c.sclAsInput();
ssozonoff 1:d0f691423bf1 129
ssozonoff 1:d0f691423bf1 130 for (i=0; i<1000; i++) { // wait until master hold is released or
ssozonoff 1:d0f691423bf1 131 wait_ms(1); // a timeout (~1s) is reached
ssozonoff 1:d0f691423bf1 132 if (i2c.sclRead() == 1) break;
ssozonoff 1:d0f691423bf1 133 }
ssozonoff 1:d0f691423bf1 134
ssozonoff 0:74df6ab91c79 135 //-- check for timeout --
ssozonoff 1:d0f691423bf1 136 if (i2c.sclRead() == 0) error |= TIME_OUT_ERROR;
ssozonoff 1:d0f691423bf1 137 //-- read two data bytes and one checksum byte --
ssozonoff 0:74df6ab91c79 138
ssozonoff 1:d0f691423bf1 139 i2c.sclNormal();
ssozonoff 1:d0f691423bf1 140
ssozonoff 1:d0f691423bf1 141 data[0] = i2c.read(ACK);
ssozonoff 1:d0f691423bf1 142 data[1] = i2c.read(ACK);
ssozonoff 1:d0f691423bf1 143
ssozonoff 0:74df6ab91c79 144 *pMeasurand = data[0] << 8;
ssozonoff 0:74df6ab91c79 145 *pMeasurand |= data[1];
ssozonoff 1:d0f691423bf1 146
ssozonoff 1:d0f691423bf1 147 checksum = i2c.read(NoACK);
ssozonoff 2:2464fed17980 148
ssozonoff 2:2464fed17980 149 __enable_irq(); // Enable Interrupts
ssozonoff 2:2464fed17980 150
ssozonoff 0:74df6ab91c79 151 //-- verify checksum --
ssozonoff 0:74df6ab91c79 152 error |= SHT2x_CheckCrc (data, 2, checksum);
ssozonoff 0:74df6ab91c79 153
ssozonoff 0:74df6ab91c79 154 i2c.stop();
ssozonoff 0:74df6ab91c79 155 return error;
ssozonoff 0:74df6ab91c79 156 }
ssozonoff 0:74df6ab91c79 157 //===========================================================================//
ssozonoff 0:74df6ab91c79 158 int SHT2x::SHT2x_MeasurePoll(etSHT2xMeasureType eSHT2xMeasureType, int *pMeasurand)
ssozonoff 0:74df6ab91c79 159 //===========================================================================//
ssozonoff 0:74df6ab91c79 160 {
ssozonoff 0:74df6ab91c79 161 int checksum; //checksum
ssozonoff 0:74df6ab91c79 162 int data[2]; //data array for checksum verification
ssozonoff 0:74df6ab91c79 163 int error = 0; //error variable
ssozonoff 0:74df6ab91c79 164 int i = 0; //counting variableSample Code SHT21
ssozonoff 0:74df6ab91c79 165
ssozonoff 0:74df6ab91c79 166 //-- write I2C sensor address and command --
ssozonoff 0:74df6ab91c79 167 i2c.start();
ssozonoff 1:d0f691423bf1 168
ssozonoff 2:2464fed17980 169 error |= i2cWrite(I2C_ADR_W);
ssozonoff 0:74df6ab91c79 170 switch (eSHT2xMeasureType) {
ssozonoff 0:74df6ab91c79 171 case HUMIDITY:
ssozonoff 2:2464fed17980 172 error |= i2cWrite(TRIG_RH_MEASUREMENT_POLL);
ssozonoff 0:74df6ab91c79 173 break;
ssozonoff 0:74df6ab91c79 174 case TEMP:
ssozonoff 2:2464fed17980 175 error |= i2cWrite(TRIG_T_MEASUREMENT_POLL);
ssozonoff 0:74df6ab91c79 176 break;
ssozonoff 0:74df6ab91c79 177 default:
ssozonoff 0:74df6ab91c79 178 break;
ssozonoff 1:d0f691423bf1 179
ssozonoff 0:74df6ab91c79 180 }
ssozonoff 0:74df6ab91c79 181 //-- poll every 10ms for measurement ready. Timeout after 20 retries (200ms)--
ssozonoff 0:74df6ab91c79 182 do {
ssozonoff 0:74df6ab91c79 183 i2c.start();
ssozonoff 1:d0f691423bf1 184 wait_ms(10);
ssozonoff 0:74df6ab91c79 185 if (i++ >= 20) break;
ssozonoff 0:74df6ab91c79 186 } while (i2c.write(I2C_ADR_R) == 0);
ssozonoff 1:d0f691423bf1 187
ssozonoff 0:74df6ab91c79 188 if (i >= 20) error |= TIME_OUT_ERROR;
ssozonoff 1:d0f691423bf1 189
ssozonoff 0:74df6ab91c79 190 //-- read two data bytes and one checksum byte --
ssozonoff 1:d0f691423bf1 191 data[0] = i2c.read(ACK);
ssozonoff 1:d0f691423bf1 192 data[1] = i2c.read(ACK);
ssozonoff 1:d0f691423bf1 193
ssozonoff 0:74df6ab91c79 194 *pMeasurand = data[0] << 8;
ssozonoff 1:d0f691423bf1 195 *pMeasurand |= data[1];
ssozonoff 1:d0f691423bf1 196
ssozonoff 1:d0f691423bf1 197 checksum = i2c.read(NoACK);
ssozonoff 0:74df6ab91c79 198 //-- verify checksum --
ssozonoff 0:74df6ab91c79 199 error |= SHT2x_CheckCrc (data,2,checksum);
ssozonoff 0:74df6ab91c79 200 i2c.stop();
ssozonoff 0:74df6ab91c79 201 return error;
ssozonoff 0:74df6ab91c79 202 }
ssozonoff 0:74df6ab91c79 203 //===========================================================================//
ssozonoff 0:74df6ab91c79 204 int SHT2x::SHT2x_SoftReset()
ssozonoff 0:74df6ab91c79 205 //===========================================================================//
ssozonoff 0:74df6ab91c79 206 {
ssozonoff 0:74df6ab91c79 207 int error=0; //error variable
ssozonoff 0:74df6ab91c79 208 i2c.start();
ssozonoff 2:2464fed17980 209 error |= i2cWrite(I2C_ADR_W); // I2C Adr
ssozonoff 2:2464fed17980 210 error |= i2cWrite(SOFT_RESET); // Command
ssozonoff 0:74df6ab91c79 211 i2c.stop();
ssozonoff 0:74df6ab91c79 212 wait_ms(15);
ssozonoff 0:74df6ab91c79 213 return error;
ssozonoff 0:74df6ab91c79 214 }
ssozonoff 0:74df6ab91c79 215 //==============================================================================//
ssozonoff 0:74df6ab91c79 216 float SHT2x::SHT2x_CalcRH(int u16sRH)
ssozonoff 0:74df6ab91c79 217 //==============================================================================//
ssozonoff 0:74df6ab91c79 218 {
ssozonoff 0:74df6ab91c79 219 float humidityRH; // variable for result
ssozonoff 0:74df6ab91c79 220 u16sRH &= ~0x0003; // clear bits [1..0] (status bits)
ssozonoff 0:74df6ab91c79 221 //-- calculate relative humidity [%RH] --
ssozonoff 0:74df6ab91c79 222 humidityRH = -6.0 + 125.0/65536 * (float)u16sRH; // RH= -6 + 125 * SRH/2^16
ssozonoff 0:74df6ab91c79 223 return humidityRH;
ssozonoff 0:74df6ab91c79 224 }
ssozonoff 0:74df6ab91c79 225 //==============================================================================//
ssozonoff 0:74df6ab91c79 226 float SHT2x::SHT2x_CalcTemperatureC(int u16sT)
ssozonoff 0:74df6ab91c79 227 //==============================================================================//
ssozonoff 0:74df6ab91c79 228 {
ssozonoff 0:74df6ab91c79 229 float temperatureC; // variable for result
ssozonoff 0:74df6ab91c79 230 u16sT &= ~0x0003; // clear bits [1..0] (status bits)
ssozonoff 2:2464fed17980 231 //-- calculate temperature [in degrees C] --
ssozonoff 0:74df6ab91c79 232 temperatureC= -46.85 + 175.72/65536 *(float)u16sT; //T= -46.85 + 175.72 * ST/2^16
ssozonoff 0:74df6ab91c79 233 return temperatureC;
ssozonoff 0:74df6ab91c79 234 }
ssozonoff 2:2464fed17980 235
ssozonoff 2:2464fed17980 236 //==============================================================================//
ssozonoff 2:2464fed17980 237 float SHT2x::SHT2x_GetDewpoint(float h, float t)
ssozonoff 2:2464fed17980 238 //==============================================================================//
ssozonoff 2:2464fed17980 239 {
ssozonoff 2:2464fed17980 240 float logEx, dew_point;
ssozonoff 2:2464fed17980 241 logEx = 0.66077 + 7.5 * t / (237.3 + t) + (log10(h) - 2);
ssozonoff 2:2464fed17980 242 dew_point = (logEx - 0.66077) * 237.3 / (0.66077 + 7.5 - logEx);
ssozonoff 2:2464fed17980 243 return dew_point;
ssozonoff 2:2464fed17980 244 }
ssozonoff 2:2464fed17980 245
ssozonoff 0:74df6ab91c79 246 //==============================================================================//
ssozonoff 0:74df6ab91c79 247 int SHT2x::SHT2x_GetSerialNumber(int u8SerialNumber[])
ssozonoff 0:74df6ab91c79 248 //==============================================================================//
ssozonoff 0:74df6ab91c79 249 {
ssozonoff 0:74df6ab91c79 250 int error=0; //error variable
ssozonoff 1:d0f691423bf1 251 //Read from memory location 1
ssozonoff 0:74df6ab91c79 252 i2c.start();
ssozonoff 2:2464fed17980 253 error |= i2cWrite(I2C_ADR_W);
ssozonoff 2:2464fed17980 254 error |= i2cWrite(0xFA); //Command for readout on-chip memory
ssozonoff 2:2464fed17980 255 error |= i2cWrite(0x0F); //on-chip memory address
ssozonoff 0:74df6ab91c79 256 i2c.start();
ssozonoff 2:2464fed17980 257 error |= i2cWrite(I2C_ADR_R); //I2C address
ssozonoff 1:d0f691423bf1 258 u8SerialNumber[5] = i2c.read(ACK); //Read SNB_3
ssozonoff 1:d0f691423bf1 259 i2c.read(ACK); //Read CRC SNB_3 (CRC is not analyzed)
ssozonoff 1:d0f691423bf1 260 u8SerialNumber[4] = i2c.read(ACK); //Read SNB_2
ssozonoff 1:d0f691423bf1 261 i2c.read(ACK); //Read CRC SNB_2 (CRC is not analyzed)
ssozonoff 1:d0f691423bf1 262 u8SerialNumber[3] = i2c.read(ACK); //Read SNB_1Sample Code SHT21
ssozonoff 1:d0f691423bf1 263 i2c.read(ACK); //Read CRC SNB_1 (CRC is not analyzed)
ssozonoff 1:d0f691423bf1 264 u8SerialNumber[2] = i2c.read(ACK); //Read SNB_0
ssozonoff 1:d0f691423bf1 265 i2c.read(NoACK); //Read CRC SNB_0 (CRC is not analyzed)
ssozonoff 0:74df6ab91c79 266 i2c.stop();
ssozonoff 0:74df6ab91c79 267 //Read from memory location 2
ssozonoff 0:74df6ab91c79 268 i2c.start();
ssozonoff 2:2464fed17980 269 error |= i2cWrite(I2C_ADR_W); //I2C address
ssozonoff 2:2464fed17980 270 error |= i2cWrite(0xFC); //Command for readout on-chip memory
ssozonoff 2:2464fed17980 271 error |= i2cWrite(0xC9); //on-chip memory address
ssozonoff 0:74df6ab91c79 272 i2c.start();
ssozonoff 2:2464fed17980 273 error |= i2cWrite(I2C_ADR_R); //I2C address
ssozonoff 1:d0f691423bf1 274 u8SerialNumber[1] = i2c.read(ACK); //Read SNC_1
ssozonoff 1:d0f691423bf1 275 u8SerialNumber[0] = i2c.read(ACK); //Read SNC_0
ssozonoff 1:d0f691423bf1 276 i2c.read(ACK);
ssozonoff 1:d0f691423bf1 277 u8SerialNumber[7] = i2c.read(ACK); //Read SNA_1
ssozonoff 1:d0f691423bf1 278 u8SerialNumber[6] = i2c.read(ACK); //Read SNA_0
ssozonoff 1:d0f691423bf1 279 i2c.read(NoACK); //Read CRC SNA0/1 (CRC is not analyzed)
ssozonoff 0:74df6ab91c79 280 i2c.stop();
ssozonoff 0:74df6ab91c79 281 return error;
ssozonoff 0:74df6ab91c79 282 }