Sensirion SHT11 library

Committer:
timm
Date:
Sun Apr 19 01:09:46 2015 +0000
Revision:
0:56bbfad2d592
initial version

Who changed what in which revision?

UserRevisionLine numberNew contents of line
timm 0:56bbfad2d592 1 /**
timm 0:56bbfad2d592 2 @file sht11.cpp
timm 0:56bbfad2d592 3
timm 0:56bbfad2d592 4 @brief Member functions implementations
timm 0:56bbfad2d592 5
timm 0:56bbfad2d592 6 */
timm 0:56bbfad2d592 7 #include "mbed.h"
timm 0:56bbfad2d592 8 #include "sht11.h"
timm 0:56bbfad2d592 9
timm 0:56bbfad2d592 10 //adr command r/w
timm 0:56bbfad2d592 11 #define STATUS_REG_W 0x06 //000 0011 0
timm 0:56bbfad2d592 12 #define STATUS_REG_R 0x07 //000 0011 1
timm 0:56bbfad2d592 13 #define MEASURE_TEMP 0x03 //000 0001 1
timm 0:56bbfad2d592 14 #define MEASURE_HUMI 0x05 //000 0010 1
timm 0:56bbfad2d592 15 #define RESET 0x1e //000 1111 0
timm 0:56bbfad2d592 16
timm 0:56bbfad2d592 17 SHT11::SHT11(PinName clkPin, PinName dataPin)
timm 0:56bbfad2d592 18 {
timm 0:56bbfad2d592 19 clk = new DigitalOut(clkPin);
timm 0:56bbfad2d592 20 data = new DigitalInOut(dataPin);
timm 0:56bbfad2d592 21 }
timm 0:56bbfad2d592 22
timm 0:56bbfad2d592 23 /*
timm 0:56bbfad2d592 24 * To initiate a transmission, a .Transmission Start. sequence
timm 0:56bbfad2d592 25 * has to be issued. It consists of a lowering of the DATA line
timm 0:56bbfad2d592 26 * while SCK is high, followed by a low pulse on SCK and
timm 0:56bbfad2d592 27 * raising DATA again while SCK is still high.
timm 0:56bbfad2d592 28 *
timm 0:56bbfad2d592 29 * ______ _________
timm 0:56bbfad2d592 30 * DATA: \___________/
timm 0:56bbfad2d592 31 * _____ _____
timm 0:56bbfad2d592 32 * SCK: ___/ \____/ \_____
timm 0:56bbfad2d592 33 */
timm 0:56bbfad2d592 34
timm 0:56bbfad2d592 35 void SHT11::sendTransmissionStart()
timm 0:56bbfad2d592 36 {
timm 0:56bbfad2d592 37 data->output();
timm 0:56bbfad2d592 38
timm 0:56bbfad2d592 39 clk->write(0);
timm 0:56bbfad2d592 40 data->write(1);
timm 0:56bbfad2d592 41 wait_ms(10);
timm 0:56bbfad2d592 42
timm 0:56bbfad2d592 43 clk->write(1);
timm 0:56bbfad2d592 44 wait_ms(10);
timm 0:56bbfad2d592 45
timm 0:56bbfad2d592 46 data->write(0);
timm 0:56bbfad2d592 47 wait_ms(10);
timm 0:56bbfad2d592 48
timm 0:56bbfad2d592 49 clk->write(0);
timm 0:56bbfad2d592 50 wait_ms(10);
timm 0:56bbfad2d592 51
timm 0:56bbfad2d592 52 clk->write(1);
timm 0:56bbfad2d592 53 wait_ms(10);
timm 0:56bbfad2d592 54
timm 0:56bbfad2d592 55 data->write(1);
timm 0:56bbfad2d592 56 wait_ms(10);
timm 0:56bbfad2d592 57
timm 0:56bbfad2d592 58 clk->write(0);
timm 0:56bbfad2d592 59 wait_ms(10);
timm 0:56bbfad2d592 60 }
timm 0:56bbfad2d592 61
timm 0:56bbfad2d592 62 /*
timm 0:56bbfad2d592 63 * connection reset: release the data line high and clock out >= 9 SCK cycles
timm 0:56bbfad2d592 64 * followed by transaction start cycle
timm 0:56bbfad2d592 65 */
timm 0:56bbfad2d592 66 void SHT11::connectionReset()
timm 0:56bbfad2d592 67 {
timm 0:56bbfad2d592 68 int i;
timm 0:56bbfad2d592 69
timm 0:56bbfad2d592 70 data->output();
timm 0:56bbfad2d592 71 data->write(1);
timm 0:56bbfad2d592 72 clk->write(0);
timm 0:56bbfad2d592 73 wait_ms(10);
timm 0:56bbfad2d592 74
timm 0:56bbfad2d592 75 for(i=0; i<10; i++)
timm 0:56bbfad2d592 76 {
timm 0:56bbfad2d592 77 clk->write(1);
timm 0:56bbfad2d592 78 wait_ms(10);
timm 0:56bbfad2d592 79 clk->write(0);
timm 0:56bbfad2d592 80 wait_ms(10);
timm 0:56bbfad2d592 81 }
timm 0:56bbfad2d592 82 }
timm 0:56bbfad2d592 83
timm 0:56bbfad2d592 84 void SHT11::init()
timm 0:56bbfad2d592 85 {
timm 0:56bbfad2d592 86 connectionReset();
timm 0:56bbfad2d592 87 }
timm 0:56bbfad2d592 88
timm 0:56bbfad2d592 89 int SHT11::writeByte(unsigned char writeData)
timm 0:56bbfad2d592 90 {
timm 0:56bbfad2d592 91 unsigned char writeMask = 0x80;
timm 0:56bbfad2d592 92 int ack = 0;
timm 0:56bbfad2d592 93
timm 0:56bbfad2d592 94 // Ensure initial condition: clock low, data is an output
timm 0:56bbfad2d592 95 clk->write(0);
timm 0:56bbfad2d592 96 data->output();
timm 0:56bbfad2d592 97 wait_ms(10);
timm 0:56bbfad2d592 98
timm 0:56bbfad2d592 99 while(writeMask != 0)
timm 0:56bbfad2d592 100 {
timm 0:56bbfad2d592 101 if ((writeData & writeMask) != 0) {
timm 0:56bbfad2d592 102 data->write(1);
timm 0:56bbfad2d592 103 }
timm 0:56bbfad2d592 104 else {
timm 0:56bbfad2d592 105 data->write(0);
timm 0:56bbfad2d592 106 }
timm 0:56bbfad2d592 107
timm 0:56bbfad2d592 108 // delay for data to stabilize
timm 0:56bbfad2d592 109 wait_ms(10);
timm 0:56bbfad2d592 110
timm 0:56bbfad2d592 111 clk->write(1);
timm 0:56bbfad2d592 112 wait_ms(10);
timm 0:56bbfad2d592 113 clk->write(0);
timm 0:56bbfad2d592 114 wait_ms(10);
timm 0:56bbfad2d592 115
timm 0:56bbfad2d592 116 writeMask >>= 1;
timm 0:56bbfad2d592 117 }
timm 0:56bbfad2d592 118
timm 0:56bbfad2d592 119 // release the data line
timm 0:56bbfad2d592 120 data->write(1);
timm 0:56bbfad2d592 121 data->input();
timm 0:56bbfad2d592 122 wait_ms(10);
timm 0:56bbfad2d592 123
timm 0:56bbfad2d592 124 // 9th clock for ack, read the ack, return clk to low
timm 0:56bbfad2d592 125 clk->write(1);
timm 0:56bbfad2d592 126 wait_ms(10);
timm 0:56bbfad2d592 127 ack = data->read();
timm 0:56bbfad2d592 128 clk->write(0);
timm 0:56bbfad2d592 129 wait_ms(10);
timm 0:56bbfad2d592 130
timm 0:56bbfad2d592 131 return((int)ack);
timm 0:56bbfad2d592 132 }
timm 0:56bbfad2d592 133
timm 0:56bbfad2d592 134 void SHT11::softReset()
timm 0:56bbfad2d592 135 {
timm 0:56bbfad2d592 136 connectionReset();
timm 0:56bbfad2d592 137 writeByte(RESET);
timm 0:56bbfad2d592 138 }
timm 0:56bbfad2d592 139
timm 0:56bbfad2d592 140 int SHT11::readByte(unsigned char *pReadData, bool doAck)
timm 0:56bbfad2d592 141 {
timm 0:56bbfad2d592 142 unsigned char retData = 0x00;
timm 0:56bbfad2d592 143 unsigned char readMask = 0x80;
timm 0:56bbfad2d592 144 int bitVal;
timm 0:56bbfad2d592 145
timm 0:56bbfad2d592 146 // Ensure start conditions: clock low; data is input
timm 0:56bbfad2d592 147 clk->write(0);
timm 0:56bbfad2d592 148 data->write(1);
timm 0:56bbfad2d592 149 data->input();
timm 0:56bbfad2d592 150 wait_ms(10);
timm 0:56bbfad2d592 151
timm 0:56bbfad2d592 152 while(readMask != 0)
timm 0:56bbfad2d592 153 {
timm 0:56bbfad2d592 154 clk->write(1);
timm 0:56bbfad2d592 155 wait_ms(10);
timm 0:56bbfad2d592 156 bitVal = data->read();
timm 0:56bbfad2d592 157 if (bitVal != 0)
timm 0:56bbfad2d592 158 retData |= readMask;
timm 0:56bbfad2d592 159 clk->write(0);
timm 0:56bbfad2d592 160 wait_ms(10);
timm 0:56bbfad2d592 161 readMask >>= 1;
timm 0:56bbfad2d592 162 }
timm 0:56bbfad2d592 163
timm 0:56bbfad2d592 164 // If clocking out an ack;
timm 0:56bbfad2d592 165 if (doAck == true)
timm 0:56bbfad2d592 166 {
timm 0:56bbfad2d592 167 data->output();
timm 0:56bbfad2d592 168 data->write(0);
timm 0:56bbfad2d592 169 }
timm 0:56bbfad2d592 170
timm 0:56bbfad2d592 171 wait_ms(10);
timm 0:56bbfad2d592 172 clk->write(1);
timm 0:56bbfad2d592 173 wait_ms(10);
timm 0:56bbfad2d592 174 clk->write(0);
timm 0:56bbfad2d592 175 data->input();
timm 0:56bbfad2d592 176
timm 0:56bbfad2d592 177 *pReadData = retData;
timm 0:56bbfad2d592 178 return 1;
timm 0:56bbfad2d592 179 }
timm 0:56bbfad2d592 180
timm 0:56bbfad2d592 181 int SHT11::readStatus(unsigned char *pRetStatus)
timm 0:56bbfad2d592 182 {
timm 0:56bbfad2d592 183 unsigned char retStatus, checksum;
timm 0:56bbfad2d592 184 int retVal = -1;
timm 0:56bbfad2d592 185
timm 0:56bbfad2d592 186 sendTransmissionStart();
timm 0:56bbfad2d592 187
timm 0:56bbfad2d592 188 if (writeByte(STATUS_REG_R) == 0)
timm 0:56bbfad2d592 189 {
timm 0:56bbfad2d592 190 readByte(&retStatus, true);
timm 0:56bbfad2d592 191 readByte(&checksum, false);
timm 0:56bbfad2d592 192 *pRetStatus = retStatus;
timm 0:56bbfad2d592 193 retVal = 0;
timm 0:56bbfad2d592 194 }
timm 0:56bbfad2d592 195
timm 0:56bbfad2d592 196 return retVal;
timm 0:56bbfad2d592 197 }
timm 0:56bbfad2d592 198
timm 0:56bbfad2d592 199 int SHT11::writeStatus(unsigned char writeValue)
timm 0:56bbfad2d592 200 {
timm 0:56bbfad2d592 201 int retVal = -1;
timm 0:56bbfad2d592 202
timm 0:56bbfad2d592 203 sendTransmissionStart();
timm 0:56bbfad2d592 204
timm 0:56bbfad2d592 205 if (writeByte(STATUS_REG_W) == 0)
timm 0:56bbfad2d592 206 {
timm 0:56bbfad2d592 207 writeByte(writeValue);
timm 0:56bbfad2d592 208 retVal = 0;
timm 0:56bbfad2d592 209 }
timm 0:56bbfad2d592 210
timm 0:56bbfad2d592 211 return retVal;
timm 0:56bbfad2d592 212 }
timm 0:56bbfad2d592 213
timm 0:56bbfad2d592 214 int SHT11::measureTemp(unsigned short *pRetTempRaw)
timm 0:56bbfad2d592 215 {
timm 0:56bbfad2d592 216 int retVal = -1;
timm 0:56bbfad2d592 217 unsigned int waitCount;
timm 0:56bbfad2d592 218 union {
timm 0:56bbfad2d592 219 unsigned short u16;
timm 0:56bbfad2d592 220 unsigned char u8[2];
timm 0:56bbfad2d592 221 } u;
timm 0:56bbfad2d592 222 unsigned char checksum;
timm 0:56bbfad2d592 223
timm 0:56bbfad2d592 224 sendTransmissionStart();
timm 0:56bbfad2d592 225
timm 0:56bbfad2d592 226 retVal = writeByte(MEASURE_TEMP);
timm 0:56bbfad2d592 227
timm 0:56bbfad2d592 228 if (retVal == 0)
timm 0:56bbfad2d592 229 {
timm 0:56bbfad2d592 230 data->input();
timm 0:56bbfad2d592 231 waitCount = 65535; // UINT_MAX
timm 0:56bbfad2d592 232 while(waitCount > 0)
timm 0:56bbfad2d592 233 {
timm 0:56bbfad2d592 234 if (data->read() == 0)
timm 0:56bbfad2d592 235 {
timm 0:56bbfad2d592 236 break;
timm 0:56bbfad2d592 237 }
timm 0:56bbfad2d592 238 wait_ms(10);
timm 0:56bbfad2d592 239 waitCount -= 1;
timm 0:56bbfad2d592 240 }
timm 0:56bbfad2d592 241 }
timm 0:56bbfad2d592 242 else
timm 0:56bbfad2d592 243 {
timm 0:56bbfad2d592 244 return -1;
timm 0:56bbfad2d592 245 }
timm 0:56bbfad2d592 246
timm 0:56bbfad2d592 247 readByte(&(u.u8[1]), true);
timm 0:56bbfad2d592 248 readByte(&(u.u8[0]), true);
timm 0:56bbfad2d592 249 readByte(&checksum, false);
timm 0:56bbfad2d592 250
timm 0:56bbfad2d592 251 *pRetTempRaw = u.u16;
timm 0:56bbfad2d592 252 retVal = 0;
timm 0:56bbfad2d592 253
timm 0:56bbfad2d592 254 return retVal;
timm 0:56bbfad2d592 255 }
timm 0:56bbfad2d592 256
timm 0:56bbfad2d592 257 int SHT11::measureHumid(unsigned short *pRetHumidRaw)
timm 0:56bbfad2d592 258 {
timm 0:56bbfad2d592 259 int retVal = -1;
timm 0:56bbfad2d592 260 unsigned int waitCount;
timm 0:56bbfad2d592 261 union {
timm 0:56bbfad2d592 262 unsigned short u16;
timm 0:56bbfad2d592 263 unsigned char u8[2];
timm 0:56bbfad2d592 264 } u;
timm 0:56bbfad2d592 265 unsigned char checksum;
timm 0:56bbfad2d592 266
timm 0:56bbfad2d592 267 sendTransmissionStart();
timm 0:56bbfad2d592 268
timm 0:56bbfad2d592 269 retVal = writeByte(MEASURE_HUMI);
timm 0:56bbfad2d592 270
timm 0:56bbfad2d592 271 if (retVal == 0)
timm 0:56bbfad2d592 272 {
timm 0:56bbfad2d592 273 data->input();
timm 0:56bbfad2d592 274 waitCount = 65535; // UINT_MAX;
timm 0:56bbfad2d592 275 while(waitCount > 0)
timm 0:56bbfad2d592 276 {
timm 0:56bbfad2d592 277 if (data->read() == 0)
timm 0:56bbfad2d592 278 {
timm 0:56bbfad2d592 279 break;
timm 0:56bbfad2d592 280 }
timm 0:56bbfad2d592 281 wait_ms(10);
timm 0:56bbfad2d592 282 waitCount -= 1;
timm 0:56bbfad2d592 283 }
timm 0:56bbfad2d592 284 }
timm 0:56bbfad2d592 285 else
timm 0:56bbfad2d592 286 {
timm 0:56bbfad2d592 287 return -1;
timm 0:56bbfad2d592 288 }
timm 0:56bbfad2d592 289
timm 0:56bbfad2d592 290 readByte(&(u.u8[1]), true);
timm 0:56bbfad2d592 291 readByte(&(u.u8[0]), true);
timm 0:56bbfad2d592 292 readByte(&checksum, false);
timm 0:56bbfad2d592 293
timm 0:56bbfad2d592 294 *pRetHumidRaw = u.u16;
timm 0:56bbfad2d592 295 retVal = 0;
timm 0:56bbfad2d592 296
timm 0:56bbfad2d592 297 return retVal;
timm 0:56bbfad2d592 298 }
timm 0:56bbfad2d592 299
timm 0:56bbfad2d592 300 float SHT11::convertTempCelsius(unsigned short rawTempIn)
timm 0:56bbfad2d592 301 {
timm 0:56bbfad2d592 302 return ((((float)rawTempIn) * 0.010) - 40.0);
timm 0:56bbfad2d592 303 }
timm 0:56bbfad2d592 304
timm 0:56bbfad2d592 305
timm 0:56bbfad2d592 306 float SHT11::convertTempFahrenheit(unsigned short rawTempIn)
timm 0:56bbfad2d592 307 {
timm 0:56bbfad2d592 308 return ((((float)rawTempIn) * 0.018) - 40.0);
timm 0:56bbfad2d592 309 }
timm 0:56bbfad2d592 310
timm 0:56bbfad2d592 311 float SHT11::convertHumid(unsigned short rawHumidIn, unsigned short rawTempIn)
timm 0:56bbfad2d592 312 {
timm 0:56bbfad2d592 313 const float C1 = -4.0;
timm 0:56bbfad2d592 314 const float C2 = 0.0405;
timm 0:56bbfad2d592 315 const float C3 = -0.0000028;
timm 0:56bbfad2d592 316 const float T1 = 0.01;
timm 0:56bbfad2d592 317 const float T2 = 0.00008;
timm 0:56bbfad2d592 318
timm 0:56bbfad2d592 319 float tempOut;
timm 0:56bbfad2d592 320 float humidLinearOut;
timm 0:56bbfad2d592 321 float humidOutTrue;
timm 0:56bbfad2d592 322
timm 0:56bbfad2d592 323 tempOut = convertTempCelsius(rawTempIn);
timm 0:56bbfad2d592 324
timm 0:56bbfad2d592 325 humidLinearOut = (float)rawHumidIn;
timm 0:56bbfad2d592 326 humidLinearOut = (C3 * humidLinearOut * humidLinearOut) + (C2 * humidLinearOut) + C1;
timm 0:56bbfad2d592 327
timm 0:56bbfad2d592 328 humidOutTrue = (tempOut - 25.0) * (T1 + T2 * ((float)rawHumidIn)) + humidLinearOut;
timm 0:56bbfad2d592 329
timm 0:56bbfad2d592 330 humidOutTrue = ((humidOutTrue > 100.0) ? 100.0 : humidOutTrue);
timm 0:56bbfad2d592 331
timm 0:56bbfad2d592 332 humidOutTrue = ((humidOutTrue < 0.0) ? 0.0 : humidOutTrue);
timm 0:56bbfad2d592 333
timm 0:56bbfad2d592 334 return humidOutTrue;
timm 0:56bbfad2d592 335 }
timm 0:56bbfad2d592 336
timm 0:56bbfad2d592 337 int SHT11::getTemperature(float * pRetTemperature)
timm 0:56bbfad2d592 338 {
timm 0:56bbfad2d592 339 unsigned short rawValue;
timm 0:56bbfad2d592 340 int retVal = -1;
timm 0:56bbfad2d592 341
timm 0:56bbfad2d592 342 if (measureTemp(&rawValue) == 0) {
timm 0:56bbfad2d592 343 lastTemperature = convertTempCelsius(rawValue);
timm 0:56bbfad2d592 344 *pRetTemperature = lastTemperature;
timm 0:56bbfad2d592 345 retVal = 0;
timm 0:56bbfad2d592 346 }
timm 0:56bbfad2d592 347
timm 0:56bbfad2d592 348 return retVal;
timm 0:56bbfad2d592 349 }
timm 0:56bbfad2d592 350
timm 0:56bbfad2d592 351 int SHT11::getTempHumid(float * pRetTemperature, float * pRetHumidity)
timm 0:56bbfad2d592 352 {
timm 0:56bbfad2d592 353 unsigned short rawTempValue;
timm 0:56bbfad2d592 354 unsigned short rawHumidValue;
timm 0:56bbfad2d592 355 int retVal = -1;
timm 0:56bbfad2d592 356
timm 0:56bbfad2d592 357 if (measureTemp(&rawTempValue) == 0) {
timm 0:56bbfad2d592 358 if (measureHumid(&rawHumidValue) == 0) {
timm 0:56bbfad2d592 359 lastHumidity = convertHumid(rawHumidValue, rawTempValue);
timm 0:56bbfad2d592 360 lastTemperature = convertTempCelsius(rawTempValue);
timm 0:56bbfad2d592 361 *pRetHumidity = lastHumidity;
timm 0:56bbfad2d592 362 *pRetTemperature = lastTemperature;
timm 0:56bbfad2d592 363 retVal = 0;
timm 0:56bbfad2d592 364 }
timm 0:56bbfad2d592 365 }
timm 0:56bbfad2d592 366
timm 0:56bbfad2d592 367 return retVal;
timm 0:56bbfad2d592 368 }