hadif azli
/
TEST123
BLYNK TEST
AM2321.cpp@4:e5018e5ba340, 2016-06-16 (annotated)
- Committer:
- lixianyu
- Date:
- Thu Jun 16 08:12:33 2016 +0000
- Revision:
- 4:e5018e5ba340
- Parent:
- 3:4cd9171ba989
ok
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
lixianyu | 2:6cd3b0947188 | 1 | // |
lixianyu | 0:d8f4c441e032 | 2 | // AM2321 Temperature & Humidity Sensor library for Arduino |
lixianyu | 0:d8f4c441e032 | 3 | // |
lixianyu | 0:d8f4c441e032 | 4 | // The MIT License (MIT) |
lixianyu | 0:d8f4c441e032 | 5 | // |
lixianyu | 0:d8f4c441e032 | 6 | // Copyright (c) 2013 Wang Dong |
lixianyu | 0:d8f4c441e032 | 7 | // |
lixianyu | 0:d8f4c441e032 | 8 | // Permission is hereby granted, free of charge, to any person obtaining a copy |
lixianyu | 0:d8f4c441e032 | 9 | // of this software and associated documentation files (the "Software"), to deal |
lixianyu | 0:d8f4c441e032 | 10 | // in the Software without restriction, including without limitation the rights |
lixianyu | 0:d8f4c441e032 | 11 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
lixianyu | 0:d8f4c441e032 | 12 | // copies of the Software, and to permit persons to whom the Software is |
lixianyu | 0:d8f4c441e032 | 13 | // furnished to do so, subject to the following conditions: |
lixianyu | 0:d8f4c441e032 | 14 | // |
lixianyu | 0:d8f4c441e032 | 15 | // The above copyright notice and this permission notice shall be included in |
lixianyu | 0:d8f4c441e032 | 16 | // all copies or substantial portions of the Software. |
lixianyu | 0:d8f4c441e032 | 17 | // |
lixianyu | 0:d8f4c441e032 | 18 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
lixianyu | 0:d8f4c441e032 | 19 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
lixianyu | 0:d8f4c441e032 | 20 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
lixianyu | 0:d8f4c441e032 | 21 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
lixianyu | 0:d8f4c441e032 | 22 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
lixianyu | 0:d8f4c441e032 | 23 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN |
lixianyu | 0:d8f4c441e032 | 24 | // THE SOFTWARE. |
lixianyu | 0:d8f4c441e032 | 25 | // |
lixianyu | 0:d8f4c441e032 | 26 | |
lixianyu | 0:d8f4c441e032 | 27 | #include "AM2321.h" |
lixianyu | 2:6cd3b0947188 | 28 | #include "mbed.h" |
lixianyu | 2:6cd3b0947188 | 29 | extern I2C g_i2c; |
lixianyu | 2:6cd3b0947188 | 30 | extern Serial pc; |
lixianyu | 2:6cd3b0947188 | 31 | |
lixianyu | 0:d8f4c441e032 | 32 | #define I2C_ADDR_AM2321 (0xB8 >> 1) //AM2321温湿度计I2C地址 |
lixianyu | 0:d8f4c441e032 | 33 | #define PARAM_AM2321_READ 0x03 //读寄存器命令 |
lixianyu | 0:d8f4c441e032 | 34 | #define REG_AM2321_HUMIDITY_MSB 0x00 //湿度寄存器高位 |
lixianyu | 0:d8f4c441e032 | 35 | #define REG_AM2321_HUMIDITY_LSB 0x01 //湿度寄存器低位 |
lixianyu | 0:d8f4c441e032 | 36 | #define REG_AM2321_TEMPERATURE_MSB 0x02 //温度寄存器高位 |
lixianyu | 0:d8f4c441e032 | 37 | #define REG_AM2321_TEMPERATURE_LSB 0x03 //温度寄存器低位 |
lixianyu | 0:d8f4c441e032 | 38 | #define REG_AM2321_DEVICE_ID_BIT_24_31 0x0B //32位设备ID高8位 |
lixianyu | 0:d8f4c441e032 | 39 | |
lixianyu | 0:d8f4c441e032 | 40 | template<int I2CADDR, int COMMAND, int REGADDR, int REGCOUNT> |
lixianyu | 2:6cd3b0947188 | 41 | class DataReader |
lixianyu | 2:6cd3b0947188 | 42 | { |
lixianyu | 0:d8f4c441e032 | 43 | protected: |
lixianyu | 0:d8f4c441e032 | 44 | enum { len = 32 }; |
lixianyu | 0:d8f4c441e032 | 45 | uint8_t buf[len]; |
lixianyu | 0:d8f4c441e032 | 46 | |
lixianyu | 0:d8f4c441e032 | 47 | protected: |
lixianyu | 0:d8f4c441e032 | 48 | DataReader() { |
lixianyu | 0:d8f4c441e032 | 49 | memset(buf, 0, len); |
lixianyu | 2:6cd3b0947188 | 50 | } |
lixianyu | 0:d8f4c441e032 | 51 | bool readRaw() { |
lixianyu | 0:d8f4c441e032 | 52 | // |
lixianyu | 0:d8f4c441e032 | 53 | // Wakeup |
lixianyu | 0:d8f4c441e032 | 54 | // |
lixianyu | 2:6cd3b0947188 | 55 | //Wire.beginTransmission(I2CADDR); |
lixianyu | 2:6cd3b0947188 | 56 | //Wire.endTransmission(); |
lixianyu | 2:6cd3b0947188 | 57 | g_i2c.write(I2CADDR<<1, (char*)&buf[0], 1); |
lixianyu | 0:d8f4c441e032 | 58 | |
lixianyu | 0:d8f4c441e032 | 59 | // |
lixianyu | 0:d8f4c441e032 | 60 | // Read Command |
lixianyu | 0:d8f4c441e032 | 61 | // |
lixianyu | 2:6cd3b0947188 | 62 | #if 0 |
lixianyu | 0:d8f4c441e032 | 63 | Wire.beginTransmission(I2CADDR); |
lixianyu | 0:d8f4c441e032 | 64 | Wire.write(COMMAND); |
lixianyu | 0:d8f4c441e032 | 65 | Wire.write(REGADDR); |
lixianyu | 0:d8f4c441e032 | 66 | Wire.write(REGCOUNT); |
lixianyu | 0:d8f4c441e032 | 67 | Wire.endTransmission(); |
lixianyu | 2:6cd3b0947188 | 68 | #else |
lixianyu | 2:6cd3b0947188 | 69 | char bu[3] = {COMMAND, REGADDR, REGCOUNT}; |
lixianyu | 2:6cd3b0947188 | 70 | g_i2c.write(I2CADDR<<1, bu, 3); |
lixianyu | 2:6cd3b0947188 | 71 | #endif |
lixianyu | 0:d8f4c441e032 | 72 | |
lixianyu | 0:d8f4c441e032 | 73 | // |
lixianyu | 0:d8f4c441e032 | 74 | // Waiting |
lixianyu | 0:d8f4c441e032 | 75 | // |
lixianyu | 2:6cd3b0947188 | 76 | //delayMicroseconds(1600); //>1.5ms |
lixianyu | 2:6cd3b0947188 | 77 | wait_ms(1.6); |
lixianyu | 0:d8f4c441e032 | 78 | |
lixianyu | 0:d8f4c441e032 | 79 | // |
lixianyu | 0:d8f4c441e032 | 80 | // Read |
lixianyu | 0:d8f4c441e032 | 81 | // |
lixianyu | 2:6cd3b0947188 | 82 | #if 0 |
lixianyu | 0:d8f4c441e032 | 83 | Wire.requestFrom(I2CADDR, 2 + REGCOUNT + 2); // COMMAND + REGCOUNT + DATA + CRCLSB + CRCMSB |
lixianyu | 0:d8f4c441e032 | 84 | int i = 0; |
lixianyu | 0:d8f4c441e032 | 85 | for (; i < 2 + REGCOUNT; ++i) |
lixianyu | 0:d8f4c441e032 | 86 | buf[i] = Wire.read(); |
lixianyu | 0:d8f4c441e032 | 87 | |
lixianyu | 0:d8f4c441e032 | 88 | unsigned short crc = 0; |
lixianyu | 0:d8f4c441e032 | 89 | crc = Wire.read(); //CRC LSB |
lixianyu | 0:d8f4c441e032 | 90 | crc |= Wire.read() << 8;//CRC MSB |
lixianyu | 0:d8f4c441e032 | 91 | |
lixianyu | 0:d8f4c441e032 | 92 | if (crc == crc16(buf, i)) |
lixianyu | 0:d8f4c441e032 | 93 | return true; |
lixianyu | 0:d8f4c441e032 | 94 | return false; |
lixianyu | 2:6cd3b0947188 | 95 | #else |
lixianyu | 2:6cd3b0947188 | 96 | uint8_t realAddr = (I2CADDR << 1) | 0x01; |
lixianyu | 2:6cd3b0947188 | 97 | //pc.printf("realAddr = 0x%x\r\n", realAddr); |
lixianyu | 2:6cd3b0947188 | 98 | g_i2c.read(realAddr, (char*)buf, 2 + REGCOUNT + 2); |
lixianyu | 2:6cd3b0947188 | 99 | unsigned short crc = 0; |
lixianyu | 2:6cd3b0947188 | 100 | crc = buf[2+REGCOUNT]; //CRC LSB |
lixianyu | 2:6cd3b0947188 | 101 | crc |= buf[2+REGCOUNT+1] << 8;//CRC MSB |
lixianyu | 2:6cd3b0947188 | 102 | #if 0 |
lixianyu | 2:6cd3b0947188 | 103 | for (int i = 0; i < 2 + REGCOUNT + 2; i++) { |
lixianyu | 2:6cd3b0947188 | 104 | pc.printf("0x%X ", buf[i]); |
lixianyu | 2:6cd3b0947188 | 105 | } |
lixianyu | 2:6cd3b0947188 | 106 | pc.printf("\r\n"); |
lixianyu | 2:6cd3b0947188 | 107 | #endif |
lixianyu | 2:6cd3b0947188 | 108 | if (crc == crc16(buf, 2 + REGCOUNT)) |
lixianyu | 2:6cd3b0947188 | 109 | return true; |
lixianyu | 2:6cd3b0947188 | 110 | return false; |
lixianyu | 2:6cd3b0947188 | 111 | #endif |
lixianyu | 0:d8f4c441e032 | 112 | } |
lixianyu | 0:d8f4c441e032 | 113 | |
lixianyu | 0:d8f4c441e032 | 114 | private: |
lixianyu | 0:d8f4c441e032 | 115 | unsigned short crc16(unsigned char *ptr, unsigned char len) { |
lixianyu | 2:6cd3b0947188 | 116 | unsigned short crc = 0xFFFF; |
lixianyu | 0:d8f4c441e032 | 117 | unsigned char i = 0; |
lixianyu | 0:d8f4c441e032 | 118 | while(len--) { |
lixianyu | 2:6cd3b0947188 | 119 | crc ^= *ptr++; |
lixianyu | 0:d8f4c441e032 | 120 | for(i = 0 ; i < 8 ; i++) { |
lixianyu | 0:d8f4c441e032 | 121 | if(crc & 0x01) { |
lixianyu | 0:d8f4c441e032 | 122 | crc >>= 1; |
lixianyu | 2:6cd3b0947188 | 123 | crc ^= 0xA001; |
lixianyu | 2:6cd3b0947188 | 124 | } else { |
lixianyu | 2:6cd3b0947188 | 125 | crc >>= 1; |
lixianyu | 0:d8f4c441e032 | 126 | } |
lixianyu | 0:d8f4c441e032 | 127 | } |
lixianyu | 0:d8f4c441e032 | 128 | } |
lixianyu | 2:6cd3b0947188 | 129 | return crc; |
lixianyu | 0:d8f4c441e032 | 130 | } |
lixianyu | 0:d8f4c441e032 | 131 | }; |
lixianyu | 0:d8f4c441e032 | 132 | |
lixianyu | 0:d8f4c441e032 | 133 | class UidReader : public DataReader<I2C_ADDR_AM2321, PARAM_AM2321_READ, REG_AM2321_DEVICE_ID_BIT_24_31, 4> |
lixianyu | 0:d8f4c441e032 | 134 | { |
lixianyu | 0:d8f4c441e032 | 135 | public: |
lixianyu | 0:d8f4c441e032 | 136 | unsigned int uid; |
lixianyu | 0:d8f4c441e032 | 137 | public: |
lixianyu | 0:d8f4c441e032 | 138 | bool read() { |
lixianyu | 2:6cd3b0947188 | 139 | if(!readRaw()) |
lixianyu | 0:d8f4c441e032 | 140 | return false; |
lixianyu | 0:d8f4c441e032 | 141 | uid = buf[2] << 24; |
lixianyu | 0:d8f4c441e032 | 142 | uid += buf[3] << 16; |
lixianyu | 0:d8f4c441e032 | 143 | uid += buf[4] << 8; |
lixianyu | 0:d8f4c441e032 | 144 | uid += buf[5]; |
lixianyu | 0:d8f4c441e032 | 145 | return true; |
lixianyu | 0:d8f4c441e032 | 146 | } |
lixianyu | 0:d8f4c441e032 | 147 | }; |
lixianyu | 0:d8f4c441e032 | 148 | |
lixianyu | 0:d8f4c441e032 | 149 | class AirConditionReader : public DataReader<I2C_ADDR_AM2321, PARAM_AM2321_READ, REG_AM2321_HUMIDITY_MSB, 4> |
lixianyu | 0:d8f4c441e032 | 150 | { |
lixianyu | 0:d8f4c441e032 | 151 | public: |
lixianyu | 0:d8f4c441e032 | 152 | unsigned int humidity; |
lixianyu | 0:d8f4c441e032 | 153 | int temperature; |
lixianyu | 0:d8f4c441e032 | 154 | public: |
lixianyu | 0:d8f4c441e032 | 155 | bool read() { |
lixianyu | 2:6cd3b0947188 | 156 | if(!readRaw()) |
lixianyu | 0:d8f4c441e032 | 157 | return false; |
lixianyu | 0:d8f4c441e032 | 158 | humidity = buf[2] << 8; |
lixianyu | 0:d8f4c441e032 | 159 | humidity += buf[3]; |
lixianyu | 0:d8f4c441e032 | 160 | temperature = (buf[4]&0x7F) << 8; |
lixianyu | 0:d8f4c441e032 | 161 | temperature += buf[5]; |
lixianyu | 2:6cd3b0947188 | 162 | if((buf[4]&0x80) == 0x80) |
lixianyu | 2:6cd3b0947188 | 163 | temperature = -temperature; |
lixianyu | 0:d8f4c441e032 | 164 | return true; |
lixianyu | 0:d8f4c441e032 | 165 | } |
lixianyu | 0:d8f4c441e032 | 166 | }; |
lixianyu | 0:d8f4c441e032 | 167 | |
lixianyu | 0:d8f4c441e032 | 168 | |
lixianyu | 2:6cd3b0947188 | 169 | AM2321::AM2321() |
lixianyu | 2:6cd3b0947188 | 170 | { |
lixianyu | 2:6cd3b0947188 | 171 | //Wire.begin(); |
lixianyu | 0:d8f4c441e032 | 172 | temperature = 0; |
lixianyu | 0:d8f4c441e032 | 173 | humidity = 0; |
lixianyu | 0:d8f4c441e032 | 174 | } |
lixianyu | 0:d8f4c441e032 | 175 | |
lixianyu | 2:6cd3b0947188 | 176 | unsigned long AM2321::uid() |
lixianyu | 2:6cd3b0947188 | 177 | { |
lixianyu | 0:d8f4c441e032 | 178 | UidReader reader; |
lixianyu | 0:d8f4c441e032 | 179 | if (reader.read()) |
lixianyu | 0:d8f4c441e032 | 180 | return reader.uid; |
lixianyu | 0:d8f4c441e032 | 181 | return -1; |
lixianyu | 0:d8f4c441e032 | 182 | } |
lixianyu | 0:d8f4c441e032 | 183 | |
lixianyu | 0:d8f4c441e032 | 184 | |
lixianyu | 2:6cd3b0947188 | 185 | bool AM2321::available() |
lixianyu | 2:6cd3b0947188 | 186 | { |
lixianyu | 0:d8f4c441e032 | 187 | return !(temperature == 0 && humidity == 0); |
lixianyu | 0:d8f4c441e032 | 188 | } |
lixianyu | 0:d8f4c441e032 | 189 | |
lixianyu | 2:6cd3b0947188 | 190 | bool AM2321::read() |
lixianyu | 2:6cd3b0947188 | 191 | { |
lixianyu | 0:d8f4c441e032 | 192 | AirConditionReader reader; |
lixianyu | 0:d8f4c441e032 | 193 | if (reader.read()) { |
lixianyu | 0:d8f4c441e032 | 194 | temperature = reader.temperature; |
lixianyu | 0:d8f4c441e032 | 195 | humidity = reader.humidity; |
lixianyu | 0:d8f4c441e032 | 196 | return true; |
lixianyu | 0:d8f4c441e032 | 197 | } |
lixianyu | 0:d8f4c441e032 | 198 | return false; |
lixianyu | 0:d8f4c441e032 | 199 | } |
lixianyu | 0:d8f4c441e032 | 200 | // |
lixianyu | 0:d8f4c441e032 | 201 | // END OF FILE |
lixianyu | 0:d8f4c441e032 | 202 | // |