* AM2321的取温度间隔得大于2s,否则,i2c会不工作了 * SimpleTimer有个bug,会导致两次快速的读温度,现在读温度函数里加了保护 * Blynk有个bug,会导致无法把数据传到服务器 * 现在可以正常工作了

Dependencies:   mbed

Committer:
lixianyu
Date:
Fri Jun 24 02:06:43 2016 +0000
Revision:
1:e34100dd6532
Parent:
0:740c1eb2df13
?Arduino??????????0~255??????LPC824????????????????

Who changed what in which revision?

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