work.

Dependencies:   Blynk mbed

Committer:
lixianyu
Date:
Thu Jun 16 08:12:33 2016 +0000
Revision:
4:e5018e5ba340
Parent:
3:4cd9171ba989
ok

Who changed what in which revision?

UserRevisionLine numberNew 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 //