Canberk Sönmez
/
SHT21
A simple example adopting SHT21 Arduino library to mbed.
main.cpp@0:062188c0bb61, 2017-08-10 (annotated)
- Committer:
- odtulumbedder
- Date:
- Thu Aug 10 13:25:37 2017 +0000
- Revision:
- 0:062188c0bb61
- Child:
- 1:f4a1942b4486
Initial Commit
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
odtulumbedder | 0:062188c0bb61 | 1 | #include "mbed.h" |
odtulumbedder | 0:062188c0bb61 | 2 | |
odtulumbedder | 0:062188c0bb61 | 3 | /** |
odtulumbedder | 0:062188c0bb61 | 4 | * A simple library for SHT21 humidity and temperature sensor. |
odtulumbedder | 0:062188c0bb61 | 5 | * Based on the Arduino library. |
odtulumbedder | 0:062188c0bb61 | 6 | */ |
odtulumbedder | 0:062188c0bb61 | 7 | |
odtulumbedder | 0:062188c0bb61 | 8 | class SHT21 { |
odtulumbedder | 0:062188c0bb61 | 9 | public: |
odtulumbedder | 0:062188c0bb61 | 10 | SHT21(PinName sda, PinName scl, char addr = (0x40 << 1)); |
odtulumbedder | 0:062188c0bb61 | 11 | SHT21(I2C &i2c, char addr = (0x40 << 1)); |
odtulumbedder | 0:062188c0bb61 | 12 | |
odtulumbedder | 0:062188c0bb61 | 13 | float temperature(); |
odtulumbedder | 0:062188c0bb61 | 14 | float humidity(); |
odtulumbedder | 0:062188c0bb61 | 15 | |
odtulumbedder | 0:062188c0bb61 | 16 | void reset(); |
odtulumbedder | 0:062188c0bb61 | 17 | void serialNumber(uint8_t *serialNumber); |
odtulumbedder | 0:062188c0bb61 | 18 | |
odtulumbedder | 0:062188c0bb61 | 19 | ~SHT21(); |
odtulumbedder | 0:062188c0bb61 | 20 | private: |
odtulumbedder | 0:062188c0bb61 | 21 | enum commands { |
odtulumbedder | 0:062188c0bb61 | 22 | TRIGGER_T_MEASUREMENT_HM = 0xE3, |
odtulumbedder | 0:062188c0bb61 | 23 | TRIGGER_RH_MEASUREMENT_HM = 0xE5, |
odtulumbedder | 0:062188c0bb61 | 24 | TRIGGER_T_MEASUREMENT_NHM = 0xF3, |
odtulumbedder | 0:062188c0bb61 | 25 | TRIGGER_RH_MEASUREMENT_NHM = 0xF5, |
odtulumbedder | 0:062188c0bb61 | 26 | USER_REGISTER_W = 0xE6, |
odtulumbedder | 0:062188c0bb61 | 27 | USER_REGISTER_R = 0xE7, |
odtulumbedder | 0:062188c0bb61 | 28 | SOFT_RESET = 0xFE |
odtulumbedder | 0:062188c0bb61 | 29 | }; |
odtulumbedder | 0:062188c0bb61 | 30 | |
odtulumbedder | 0:062188c0bb61 | 31 | static const uint16_t POLYNOMIAL; |
odtulumbedder | 0:062188c0bb61 | 32 | |
odtulumbedder | 0:062188c0bb61 | 33 | char addr_; |
odtulumbedder | 0:062188c0bb61 | 34 | I2C *pi2c_; |
odtulumbedder | 0:062188c0bb61 | 35 | I2C &i2c_; |
odtulumbedder | 0:062188c0bb61 | 36 | |
odtulumbedder | 0:062188c0bb61 | 37 | uint16_t readRaw(uint8_t cmd); |
odtulumbedder | 0:062188c0bb61 | 38 | static bool crcChecksum(const uint8_t *data, uint8_t sz, uint8_t checksum); |
odtulumbedder | 0:062188c0bb61 | 39 | }; |
odtulumbedder | 0:062188c0bb61 | 40 | |
odtulumbedder | 0:062188c0bb61 | 41 | const uint16_t SHT21::POLYNOMIAL = 0x131; |
odtulumbedder | 0:062188c0bb61 | 42 | |
odtulumbedder | 0:062188c0bb61 | 43 | SHT21::SHT21(PinName sda, PinName scl, char addr) : |
odtulumbedder | 0:062188c0bb61 | 44 | addr_(addr), |
odtulumbedder | 0:062188c0bb61 | 45 | pi2c_(new I2C(sda, scl)), |
odtulumbedder | 0:062188c0bb61 | 46 | i2c_(*pi2c_) { |
odtulumbedder | 0:062188c0bb61 | 47 | } |
odtulumbedder | 0:062188c0bb61 | 48 | |
odtulumbedder | 0:062188c0bb61 | 49 | SHT21::SHT21(I2C &i2c, char addr) : |
odtulumbedder | 0:062188c0bb61 | 50 | addr_(addr), |
odtulumbedder | 0:062188c0bb61 | 51 | pi2c_(NULL), |
odtulumbedder | 0:062188c0bb61 | 52 | i2c_(i2c) { |
odtulumbedder | 0:062188c0bb61 | 53 | } |
odtulumbedder | 0:062188c0bb61 | 54 | |
odtulumbedder | 0:062188c0bb61 | 55 | float SHT21::temperature() { |
odtulumbedder | 0:062188c0bb61 | 56 | uint16_t r = readRaw(TRIGGER_T_MEASUREMENT_HM); |
odtulumbedder | 0:062188c0bb61 | 57 | r &= ~0x0003; |
odtulumbedder | 0:062188c0bb61 | 58 | return (-46.85 + 175.72/65536 * (float) r); |
odtulumbedder | 0:062188c0bb61 | 59 | } |
odtulumbedder | 0:062188c0bb61 | 60 | |
odtulumbedder | 0:062188c0bb61 | 61 | float SHT21::humidity() { |
odtulumbedder | 0:062188c0bb61 | 62 | uint16_t r = readRaw(TRIGGER_RH_MEASUREMENT_HM); |
odtulumbedder | 0:062188c0bb61 | 63 | r &= ~0x0003; |
odtulumbedder | 0:062188c0bb61 | 64 | return (-6.0 + 125.0/65536 * (float) r); |
odtulumbedder | 0:062188c0bb61 | 65 | } |
odtulumbedder | 0:062188c0bb61 | 66 | |
odtulumbedder | 0:062188c0bb61 | 67 | void SHT21::reset() { |
odtulumbedder | 0:062188c0bb61 | 68 | uint8_t pcmd [] = { SOFT_RESET }; |
odtulumbedder | 0:062188c0bb61 | 69 | i2c_.write(addr_, (const char *) pcmd, 1); |
odtulumbedder | 0:062188c0bb61 | 70 | wait_ms(15); |
odtulumbedder | 0:062188c0bb61 | 71 | } |
odtulumbedder | 0:062188c0bb61 | 72 | |
odtulumbedder | 0:062188c0bb61 | 73 | void SHT21::serialNumber(uint8_t *serialNumber) { |
odtulumbedder | 0:062188c0bb61 | 74 | uint8_t data[8]; |
odtulumbedder | 0:062188c0bb61 | 75 | uint8_t pcmd0[2] = { 0xFA, 0x0F }; |
odtulumbedder | 0:062188c0bb61 | 76 | uint8_t pcmd1[2] = { 0xFC, 0xC9 }; |
odtulumbedder | 0:062188c0bb61 | 77 | uint8_t i = 0; |
odtulumbedder | 0:062188c0bb61 | 78 | i2c_.write(addr_, (const char *) pcmd0, 2); |
odtulumbedder | 0:062188c0bb61 | 79 | i2c_.read(addr_, (char *) data, 8); |
odtulumbedder | 0:062188c0bb61 | 80 | |
odtulumbedder | 0:062188c0bb61 | 81 | serialNumber[5] = data[i++]; |
odtulumbedder | 0:062188c0bb61 | 82 | i++; |
odtulumbedder | 0:062188c0bb61 | 83 | serialNumber[4] = data[i++]; |
odtulumbedder | 0:062188c0bb61 | 84 | i++; |
odtulumbedder | 0:062188c0bb61 | 85 | serialNumber[3] = data[i++]; |
odtulumbedder | 0:062188c0bb61 | 86 | i++; |
odtulumbedder | 0:062188c0bb61 | 87 | serialNumber[2] = data[i++]; |
odtulumbedder | 0:062188c0bb61 | 88 | i = 0; |
odtulumbedder | 0:062188c0bb61 | 89 | |
odtulumbedder | 0:062188c0bb61 | 90 | i2c_.write(addr_, (const char *) pcmd1, 2); |
odtulumbedder | 0:062188c0bb61 | 91 | i2c_.read(addr_, (char *) data, 6); |
odtulumbedder | 0:062188c0bb61 | 92 | |
odtulumbedder | 0:062188c0bb61 | 93 | serialNumber[1] = data[i++]; |
odtulumbedder | 0:062188c0bb61 | 94 | serialNumber[0] = data[i++]; |
odtulumbedder | 0:062188c0bb61 | 95 | i++; |
odtulumbedder | 0:062188c0bb61 | 96 | serialNumber[7] = data[i++]; |
odtulumbedder | 0:062188c0bb61 | 97 | serialNumber[8] = data[i++]; |
odtulumbedder | 0:062188c0bb61 | 98 | i = 0; |
odtulumbedder | 0:062188c0bb61 | 99 | } |
odtulumbedder | 0:062188c0bb61 | 100 | |
odtulumbedder | 0:062188c0bb61 | 101 | SHT21::~SHT21() { |
odtulumbedder | 0:062188c0bb61 | 102 | if (pi2c_) delete pi2c_; |
odtulumbedder | 0:062188c0bb61 | 103 | } |
odtulumbedder | 0:062188c0bb61 | 104 | |
odtulumbedder | 0:062188c0bb61 | 105 | uint16_t SHT21::readRaw(uint8_t cmd) { |
odtulumbedder | 0:062188c0bb61 | 106 | uint8_t checksum; |
odtulumbedder | 0:062188c0bb61 | 107 | uint8_t data[2]; |
odtulumbedder | 0:062188c0bb61 | 108 | uint16_t result; |
odtulumbedder | 0:062188c0bb61 | 109 | |
odtulumbedder | 0:062188c0bb61 | 110 | uint8_t pcmd [] = { cmd }; |
odtulumbedder | 0:062188c0bb61 | 111 | |
odtulumbedder | 0:062188c0bb61 | 112 | i2c_.write(addr_, (const char *) pcmd, 1); |
odtulumbedder | 0:062188c0bb61 | 113 | i2c_.read(addr_, (char *) data, 2); |
odtulumbedder | 0:062188c0bb61 | 114 | i2c_.read(addr_, (char *) &checksum, 1); |
odtulumbedder | 0:062188c0bb61 | 115 | |
odtulumbedder | 0:062188c0bb61 | 116 | result = data[0] << 8; |
odtulumbedder | 0:062188c0bb61 | 117 | result += data[1]; |
odtulumbedder | 0:062188c0bb61 | 118 | |
odtulumbedder | 0:062188c0bb61 | 119 | if (crcChecksum(data, 2, checksum)) { |
odtulumbedder | 0:062188c0bb61 | 120 | reset(); |
odtulumbedder | 0:062188c0bb61 | 121 | return 1; |
odtulumbedder | 0:062188c0bb61 | 122 | } |
odtulumbedder | 0:062188c0bb61 | 123 | return result; |
odtulumbedder | 0:062188c0bb61 | 124 | } |
odtulumbedder | 0:062188c0bb61 | 125 | |
odtulumbedder | 0:062188c0bb61 | 126 | bool SHT21::crcChecksum(const uint8_t *data, uint8_t sz, uint8_t checksum) { |
odtulumbedder | 0:062188c0bb61 | 127 | uint8_t crc = 0; |
odtulumbedder | 0:062188c0bb61 | 128 | |
odtulumbedder | 0:062188c0bb61 | 129 | for (uint8_t i = 0; i < sz; ++i) { |
odtulumbedder | 0:062188c0bb61 | 130 | crc ^= data[i]; |
odtulumbedder | 0:062188c0bb61 | 131 | for (uint8_t j /* bit index */ = 8; j > 0; --j) { |
odtulumbedder | 0:062188c0bb61 | 132 | if (crc & 0x80) |
odtulumbedder | 0:062188c0bb61 | 133 | crc = (crc << 1) ^ POLYNOMIAL; |
odtulumbedder | 0:062188c0bb61 | 134 | else |
odtulumbedder | 0:062188c0bb61 | 135 | crc = (crc << 1); |
odtulumbedder | 0:062188c0bb61 | 136 | } |
odtulumbedder | 0:062188c0bb61 | 137 | } |
odtulumbedder | 0:062188c0bb61 | 138 | |
odtulumbedder | 0:062188c0bb61 | 139 | return crc == checksum; |
odtulumbedder | 0:062188c0bb61 | 140 | } |
odtulumbedder | 0:062188c0bb61 | 141 | |
odtulumbedder | 0:062188c0bb61 | 142 | SHT21 sht21(PB_9 /* I2C_SDA */, PB_8 /* I2C_SCL */); |
odtulumbedder | 0:062188c0bb61 | 143 | Serial pc(USBTX, USBRX); |
odtulumbedder | 0:062188c0bb61 | 144 | |
odtulumbedder | 0:062188c0bb61 | 145 | int main() { |
odtulumbedder | 0:062188c0bb61 | 146 | while(1) { |
odtulumbedder | 0:062188c0bb61 | 147 | pc.printf( |
odtulumbedder | 0:062188c0bb61 | 148 | "%2.2f degC, %2.2f %%\n", |
odtulumbedder | 0:062188c0bb61 | 149 | sht21.temperature(), |
odtulumbedder | 0:062188c0bb61 | 150 | sht21.humidity()); |
odtulumbedder | 0:062188c0bb61 | 151 | wait(1); |
odtulumbedder | 0:062188c0bb61 | 152 | } |
odtulumbedder | 0:062188c0bb61 | 153 | } |