hadif azli
/
TEST123
BLYNK TEST
AM2321.cpp@2:6cd3b0947188, 2016-06-15 (annotated)
- Committer:
- lixianyu
- Date:
- Wed Jun 15 03:08:40 2016 +0000
- Revision:
- 2:6cd3b0947188
- Parent:
- 0:d8f4c441e032
- Child:
- 3:4cd9171ba989
PM2.5????????5V??????????
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 "I2Cdev.h" |
lixianyu | 0:d8f4c441e032 | 29 | //#include <Wire.h> |
lixianyu | 2:6cd3b0947188 | 30 | #include "mbed.h" |
lixianyu | 2:6cd3b0947188 | 31 | extern I2C g_i2c; |
lixianyu | 2:6cd3b0947188 | 32 | //I2C gI2C(P0_11, P0_10); |
lixianyu | 2:6cd3b0947188 | 33 | extern Serial pc; |
lixianyu | 2:6cd3b0947188 | 34 | |
lixianyu | 0:d8f4c441e032 | 35 | #define I2C_ADDR_AM2321 (0xB8 >> 1) //AM2321温湿度计I2C地址 |
lixianyu | 0:d8f4c441e032 | 36 | #define PARAM_AM2321_READ 0x03 //读寄存器命令 |
lixianyu | 0:d8f4c441e032 | 37 | #define REG_AM2321_HUMIDITY_MSB 0x00 //湿度寄存器高位 |
lixianyu | 0:d8f4c441e032 | 38 | #define REG_AM2321_HUMIDITY_LSB 0x01 //湿度寄存器低位 |
lixianyu | 0:d8f4c441e032 | 39 | #define REG_AM2321_TEMPERATURE_MSB 0x02 //温度寄存器高位 |
lixianyu | 0:d8f4c441e032 | 40 | #define REG_AM2321_TEMPERATURE_LSB 0x03 //温度寄存器低位 |
lixianyu | 0:d8f4c441e032 | 41 | #define REG_AM2321_DEVICE_ID_BIT_24_31 0x0B //32位设备ID高8位 |
lixianyu | 0:d8f4c441e032 | 42 | |
lixianyu | 0:d8f4c441e032 | 43 | template<int I2CADDR, int COMMAND, int REGADDR, int REGCOUNT> |
lixianyu | 2:6cd3b0947188 | 44 | class DataReader |
lixianyu | 2:6cd3b0947188 | 45 | { |
lixianyu | 0:d8f4c441e032 | 46 | protected: |
lixianyu | 0:d8f4c441e032 | 47 | enum { len = 32 }; |
lixianyu | 0:d8f4c441e032 | 48 | uint8_t buf[len]; |
lixianyu | 0:d8f4c441e032 | 49 | |
lixianyu | 0:d8f4c441e032 | 50 | protected: |
lixianyu | 0:d8f4c441e032 | 51 | DataReader() { |
lixianyu | 0:d8f4c441e032 | 52 | memset(buf, 0, len); |
lixianyu | 2:6cd3b0947188 | 53 | } |
lixianyu | 0:d8f4c441e032 | 54 | bool readRaw() { |
lixianyu | 0:d8f4c441e032 | 55 | // |
lixianyu | 0:d8f4c441e032 | 56 | // Wakeup |
lixianyu | 0:d8f4c441e032 | 57 | // |
lixianyu | 2:6cd3b0947188 | 58 | //Wire.beginTransmission(I2CADDR); |
lixianyu | 2:6cd3b0947188 | 59 | //Wire.endTransmission(); |
lixianyu | 2:6cd3b0947188 | 60 | g_i2c.write(I2CADDR<<1, (char*)&buf[0], 1); |
lixianyu | 0:d8f4c441e032 | 61 | |
lixianyu | 0:d8f4c441e032 | 62 | // |
lixianyu | 0:d8f4c441e032 | 63 | // Read Command |
lixianyu | 0:d8f4c441e032 | 64 | // |
lixianyu | 2:6cd3b0947188 | 65 | #if 0 |
lixianyu | 0:d8f4c441e032 | 66 | Wire.beginTransmission(I2CADDR); |
lixianyu | 0:d8f4c441e032 | 67 | Wire.write(COMMAND); |
lixianyu | 0:d8f4c441e032 | 68 | Wire.write(REGADDR); |
lixianyu | 0:d8f4c441e032 | 69 | Wire.write(REGCOUNT); |
lixianyu | 0:d8f4c441e032 | 70 | Wire.endTransmission(); |
lixianyu | 2:6cd3b0947188 | 71 | #else |
lixianyu | 2:6cd3b0947188 | 72 | char bu[3] = {COMMAND, REGADDR, REGCOUNT}; |
lixianyu | 2:6cd3b0947188 | 73 | g_i2c.write(I2CADDR<<1, bu, 3); |
lixianyu | 2:6cd3b0947188 | 74 | #endif |
lixianyu | 0:d8f4c441e032 | 75 | |
lixianyu | 0:d8f4c441e032 | 76 | // |
lixianyu | 0:d8f4c441e032 | 77 | // Waiting |
lixianyu | 0:d8f4c441e032 | 78 | // |
lixianyu | 2:6cd3b0947188 | 79 | //delayMicroseconds(1600); //>1.5ms |
lixianyu | 2:6cd3b0947188 | 80 | wait_ms(1.6); |
lixianyu | 0:d8f4c441e032 | 81 | |
lixianyu | 0:d8f4c441e032 | 82 | // |
lixianyu | 0:d8f4c441e032 | 83 | // Read |
lixianyu | 0:d8f4c441e032 | 84 | // |
lixianyu | 2:6cd3b0947188 | 85 | #if 0 |
lixianyu | 0:d8f4c441e032 | 86 | Wire.requestFrom(I2CADDR, 2 + REGCOUNT + 2); // COMMAND + REGCOUNT + DATA + CRCLSB + CRCMSB |
lixianyu | 0:d8f4c441e032 | 87 | int i = 0; |
lixianyu | 0:d8f4c441e032 | 88 | for (; i < 2 + REGCOUNT; ++i) |
lixianyu | 0:d8f4c441e032 | 89 | buf[i] = Wire.read(); |
lixianyu | 0:d8f4c441e032 | 90 | |
lixianyu | 0:d8f4c441e032 | 91 | unsigned short crc = 0; |
lixianyu | 0:d8f4c441e032 | 92 | crc = Wire.read(); //CRC LSB |
lixianyu | 0:d8f4c441e032 | 93 | crc |= Wire.read() << 8;//CRC MSB |
lixianyu | 0:d8f4c441e032 | 94 | |
lixianyu | 0:d8f4c441e032 | 95 | if (crc == crc16(buf, i)) |
lixianyu | 0:d8f4c441e032 | 96 | return true; |
lixianyu | 0:d8f4c441e032 | 97 | return false; |
lixianyu | 2:6cd3b0947188 | 98 | #else |
lixianyu | 2:6cd3b0947188 | 99 | uint8_t realAddr = (I2CADDR << 1) | 0x01; |
lixianyu | 2:6cd3b0947188 | 100 | //pc.printf("realAddr = 0x%x\r\n", realAddr); |
lixianyu | 2:6cd3b0947188 | 101 | g_i2c.read(realAddr, (char*)buf, 2 + REGCOUNT + 2); |
lixianyu | 2:6cd3b0947188 | 102 | unsigned short crc = 0; |
lixianyu | 2:6cd3b0947188 | 103 | crc = buf[2+REGCOUNT]; //CRC LSB |
lixianyu | 2:6cd3b0947188 | 104 | crc |= buf[2+REGCOUNT+1] << 8;//CRC MSB |
lixianyu | 2:6cd3b0947188 | 105 | #if 0 |
lixianyu | 2:6cd3b0947188 | 106 | for (int i = 0; i < 2 + REGCOUNT + 2; i++) { |
lixianyu | 2:6cd3b0947188 | 107 | pc.printf("0x%X ", buf[i]); |
lixianyu | 2:6cd3b0947188 | 108 | } |
lixianyu | 2:6cd3b0947188 | 109 | pc.printf("\r\n"); |
lixianyu | 2:6cd3b0947188 | 110 | #endif |
lixianyu | 2:6cd3b0947188 | 111 | if (crc == crc16(buf, 2 + REGCOUNT)) |
lixianyu | 2:6cd3b0947188 | 112 | return true; |
lixianyu | 2:6cd3b0947188 | 113 | return false; |
lixianyu | 2:6cd3b0947188 | 114 | #endif |
lixianyu | 0:d8f4c441e032 | 115 | } |
lixianyu | 0:d8f4c441e032 | 116 | |
lixianyu | 0:d8f4c441e032 | 117 | private: |
lixianyu | 0:d8f4c441e032 | 118 | unsigned short crc16(unsigned char *ptr, unsigned char len) { |
lixianyu | 2:6cd3b0947188 | 119 | unsigned short crc = 0xFFFF; |
lixianyu | 0:d8f4c441e032 | 120 | unsigned char i = 0; |
lixianyu | 0:d8f4c441e032 | 121 | while(len--) { |
lixianyu | 2:6cd3b0947188 | 122 | crc ^= *ptr++; |
lixianyu | 0:d8f4c441e032 | 123 | for(i = 0 ; i < 8 ; i++) { |
lixianyu | 0:d8f4c441e032 | 124 | if(crc & 0x01) { |
lixianyu | 0:d8f4c441e032 | 125 | crc >>= 1; |
lixianyu | 2:6cd3b0947188 | 126 | crc ^= 0xA001; |
lixianyu | 2:6cd3b0947188 | 127 | } else { |
lixianyu | 2:6cd3b0947188 | 128 | crc >>= 1; |
lixianyu | 0:d8f4c441e032 | 129 | } |
lixianyu | 0:d8f4c441e032 | 130 | } |
lixianyu | 0:d8f4c441e032 | 131 | } |
lixianyu | 2:6cd3b0947188 | 132 | return crc; |
lixianyu | 0:d8f4c441e032 | 133 | } |
lixianyu | 0:d8f4c441e032 | 134 | }; |
lixianyu | 0:d8f4c441e032 | 135 | |
lixianyu | 0:d8f4c441e032 | 136 | class UidReader : public DataReader<I2C_ADDR_AM2321, PARAM_AM2321_READ, REG_AM2321_DEVICE_ID_BIT_24_31, 4> |
lixianyu | 0:d8f4c441e032 | 137 | { |
lixianyu | 0:d8f4c441e032 | 138 | public: |
lixianyu | 0:d8f4c441e032 | 139 | unsigned int uid; |
lixianyu | 0:d8f4c441e032 | 140 | public: |
lixianyu | 0:d8f4c441e032 | 141 | bool read() { |
lixianyu | 2:6cd3b0947188 | 142 | if(!readRaw()) |
lixianyu | 0:d8f4c441e032 | 143 | return false; |
lixianyu | 0:d8f4c441e032 | 144 | uid = buf[2] << 24; |
lixianyu | 0:d8f4c441e032 | 145 | uid += buf[3] << 16; |
lixianyu | 0:d8f4c441e032 | 146 | uid += buf[4] << 8; |
lixianyu | 0:d8f4c441e032 | 147 | uid += buf[5]; |
lixianyu | 0:d8f4c441e032 | 148 | return true; |
lixianyu | 0:d8f4c441e032 | 149 | } |
lixianyu | 0:d8f4c441e032 | 150 | }; |
lixianyu | 0:d8f4c441e032 | 151 | |
lixianyu | 0:d8f4c441e032 | 152 | class AirConditionReader : public DataReader<I2C_ADDR_AM2321, PARAM_AM2321_READ, REG_AM2321_HUMIDITY_MSB, 4> |
lixianyu | 0:d8f4c441e032 | 153 | { |
lixianyu | 0:d8f4c441e032 | 154 | public: |
lixianyu | 0:d8f4c441e032 | 155 | unsigned int humidity; |
lixianyu | 0:d8f4c441e032 | 156 | int temperature; |
lixianyu | 0:d8f4c441e032 | 157 | public: |
lixianyu | 0:d8f4c441e032 | 158 | bool read() { |
lixianyu | 2:6cd3b0947188 | 159 | if(!readRaw()) |
lixianyu | 0:d8f4c441e032 | 160 | return false; |
lixianyu | 0:d8f4c441e032 | 161 | humidity = buf[2] << 8; |
lixianyu | 0:d8f4c441e032 | 162 | humidity += buf[3]; |
lixianyu | 0:d8f4c441e032 | 163 | temperature = (buf[4]&0x7F) << 8; |
lixianyu | 0:d8f4c441e032 | 164 | temperature += buf[5]; |
lixianyu | 2:6cd3b0947188 | 165 | if((buf[4]&0x80) == 0x80) |
lixianyu | 2:6cd3b0947188 | 166 | temperature = -temperature; |
lixianyu | 0:d8f4c441e032 | 167 | return true; |
lixianyu | 0:d8f4c441e032 | 168 | } |
lixianyu | 0:d8f4c441e032 | 169 | }; |
lixianyu | 0:d8f4c441e032 | 170 | |
lixianyu | 0:d8f4c441e032 | 171 | |
lixianyu | 2:6cd3b0947188 | 172 | AM2321::AM2321() |
lixianyu | 2:6cd3b0947188 | 173 | { |
lixianyu | 2:6cd3b0947188 | 174 | //Wire.begin(); |
lixianyu | 0:d8f4c441e032 | 175 | temperature = 0; |
lixianyu | 0:d8f4c441e032 | 176 | humidity = 0; |
lixianyu | 0:d8f4c441e032 | 177 | } |
lixianyu | 0:d8f4c441e032 | 178 | |
lixianyu | 2:6cd3b0947188 | 179 | unsigned long AM2321::uid() |
lixianyu | 2:6cd3b0947188 | 180 | { |
lixianyu | 0:d8f4c441e032 | 181 | UidReader reader; |
lixianyu | 0:d8f4c441e032 | 182 | if (reader.read()) |
lixianyu | 0:d8f4c441e032 | 183 | return reader.uid; |
lixianyu | 0:d8f4c441e032 | 184 | return -1; |
lixianyu | 0:d8f4c441e032 | 185 | } |
lixianyu | 0:d8f4c441e032 | 186 | |
lixianyu | 0:d8f4c441e032 | 187 | |
lixianyu | 2:6cd3b0947188 | 188 | bool AM2321::available() |
lixianyu | 2:6cd3b0947188 | 189 | { |
lixianyu | 0:d8f4c441e032 | 190 | return !(temperature == 0 && humidity == 0); |
lixianyu | 0:d8f4c441e032 | 191 | } |
lixianyu | 0:d8f4c441e032 | 192 | |
lixianyu | 2:6cd3b0947188 | 193 | bool AM2321::read() |
lixianyu | 2:6cd3b0947188 | 194 | { |
lixianyu | 0:d8f4c441e032 | 195 | AirConditionReader reader; |
lixianyu | 0:d8f4c441e032 | 196 | if (reader.read()) { |
lixianyu | 0:d8f4c441e032 | 197 | temperature = reader.temperature; |
lixianyu | 0:d8f4c441e032 | 198 | humidity = reader.humidity; |
lixianyu | 0:d8f4c441e032 | 199 | return true; |
lixianyu | 0:d8f4c441e032 | 200 | } |
lixianyu | 0:d8f4c441e032 | 201 | return false; |
lixianyu | 0:d8f4c441e032 | 202 | } |
lixianyu | 0:d8f4c441e032 | 203 | // |
lixianyu | 0:d8f4c441e032 | 204 | // END OF FILE |
lixianyu | 0:d8f4c441e032 | 205 | // |