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

Dependencies:   mbed

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers AM2321.cpp Source File

AM2321.cpp

00001 //
00002 // AM2321 Temperature & Humidity Sensor library for Arduino
00003 //
00004 // The MIT License (MIT)
00005 //
00006 // Copyright (c) 2013 Wang Dong
00007 //
00008 // Permission is hereby granted, free of charge, to any person obtaining a copy
00009 // of this software and associated documentation files (the "Software"), to deal
00010 // in the Software without restriction, including without limitation the rights
00011 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
00012 // copies of the Software, and to permit persons to whom the Software is
00013 // furnished to do so, subject to the following conditions:
00014 //
00015 // The above copyright notice and this permission notice shall be included in
00016 // all copies or substantial portions of the Software.
00017 //
00018 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
00019 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
00020 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
00021 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
00022 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
00023 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
00024 // THE SOFTWARE.
00025 //
00026 
00027 #include "AM2321.h"
00028 #include "mbed.h"
00029 extern I2C g_i2c;
00030 extern Serial pc;
00031 
00032 #define I2C_ADDR_AM2321                 (0xB8 >> 1)          //AM2321温湿度计I2C地址
00033 #define PARAM_AM2321_READ                0x03                //读寄存器命令
00034 #define REG_AM2321_HUMIDITY_MSB          0x00                //湿度寄存器高位
00035 #define REG_AM2321_HUMIDITY_LSB          0x01                //湿度寄存器低位
00036 #define REG_AM2321_TEMPERATURE_MSB       0x02                //温度寄存器高位
00037 #define REG_AM2321_TEMPERATURE_LSB       0x03                //温度寄存器低位
00038 #define REG_AM2321_DEVICE_ID_BIT_24_31   0x0B                //32位设备ID高8位
00039 
00040 template<int I2CADDR, int COMMAND, int REGADDR, int REGCOUNT>
00041 class DataReader
00042 {
00043 protected:
00044     enum { len = 32 };
00045     uint8_t buf[len];
00046 
00047 protected:
00048     DataReader() {
00049         memset(buf, 0, len);
00050     }
00051     bool readRaw() {
00052         //
00053         // Wakeup
00054         //
00055         //Wire.beginTransmission(I2CADDR);
00056         //Wire.endTransmission();
00057         g_i2c.write(I2CADDR<<1, (char*)&buf[0], 1);
00058         wait_ms(2.9);
00059         //
00060         // Read Command
00061         //
00062 #if 0
00063         Wire.beginTransmission(I2CADDR);
00064         Wire.write(COMMAND);
00065         Wire.write(REGADDR);
00066         Wire.write(REGCOUNT);
00067         Wire.endTransmission();
00068 #else
00069         char bu[3] = {COMMAND, REGADDR, REGCOUNT};
00070         g_i2c.write(I2CADDR<<1, bu, 3);
00071 #endif
00072 
00073         //
00074         // Waiting
00075         //
00076         //delayMicroseconds(1600); //>1.5ms
00077         wait_ms(1.6);
00078 
00079         //
00080         // Read
00081         //
00082 #if 0
00083         Wire.requestFrom(I2CADDR, 2 + REGCOUNT + 2); // COMMAND + REGCOUNT + DATA + CRCLSB + CRCMSB
00084         int i = 0;
00085         for (; i < 2 + REGCOUNT; ++i)
00086             buf[i] = Wire.read();
00087 
00088         unsigned short crc = 0;
00089         crc  = Wire.read();     //CRC LSB
00090         crc |= Wire.read() << 8;//CRC MSB
00091 
00092         if (crc == crc16(buf, i))
00093             return true;
00094         return false;
00095 #else
00096         uint8_t realAddr = (I2CADDR << 1) | 0x01;
00097         //pc.printf("realAddr = 0x%x\r\n", realAddr);
00098         g_i2c.read(realAddr, (char*)buf, 2 + REGCOUNT + 2);
00099         unsigned short crc = 0;
00100         crc  = buf[2+REGCOUNT];       //CRC LSB
00101         crc |= buf[2+REGCOUNT+1] << 8;//CRC MSB
00102 #if 1
00103         for (int i = 0; i < 2 + REGCOUNT + 2; i++) {
00104             pc.printf("0x%X ", buf[i]);
00105         }
00106         pc.printf("\r\n");
00107 #endif
00108         if (crc == crc16(buf, 2 + REGCOUNT))
00109             return true;
00110         return false;
00111 #endif
00112     }
00113 
00114 private:
00115     unsigned short crc16(unsigned char *ptr, unsigned char len) {
00116         unsigned short crc = 0xFFFF;
00117         unsigned char  i   = 0;
00118         while(len--) {
00119             crc ^= *ptr++;
00120             for(i = 0 ; i < 8 ; i++) {
00121                 if(crc & 0x01) {
00122                     crc >>= 1;
00123                     crc  ^= 0xA001;
00124                 } else {
00125                     crc >>= 1;
00126                 }
00127             }
00128         }
00129         return crc;
00130     }
00131 };
00132 
00133 class UidReader : public DataReader<I2C_ADDR_AM2321, PARAM_AM2321_READ, REG_AM2321_DEVICE_ID_BIT_24_31, 4>
00134 {
00135 public:
00136     unsigned int uid;
00137 public:
00138     bool read() {
00139         if(!readRaw())
00140             return false;
00141         uid  = buf[2] << 24;
00142         uid += buf[3] << 16;
00143         uid += buf[4] << 8;
00144         uid += buf[5];
00145         return true;
00146     }
00147 };
00148 
00149 class AirConditionReader : public DataReader<I2C_ADDR_AM2321, PARAM_AM2321_READ, REG_AM2321_HUMIDITY_MSB, 4>
00150 {
00151 public:
00152     unsigned int humidity;
00153     int temperature;
00154 public:
00155     bool read() {
00156         if(!readRaw())
00157             return false;
00158         humidity     = buf[2] << 8;
00159         humidity    += buf[3];
00160         temperature  = (buf[4]&0x7F) << 8;
00161         temperature += buf[5];
00162         if((buf[4]&0x80) == 0x80)
00163             temperature = -temperature;
00164         return true;
00165     }
00166 };
00167 
00168 
00169 AM2321::AM2321()
00170 {
00171     //Wire.begin();
00172     temperature = 0;
00173     humidity    = 0;
00174 }
00175 
00176 unsigned long AM2321::uid()
00177 {
00178     UidReader reader;
00179     if (reader.read())
00180         return reader.uid;
00181     return -1;
00182 }
00183 
00184 
00185 bool AM2321::available()
00186 {
00187     return !(temperature == 0 && humidity == 0);
00188 }
00189 
00190 bool AM2321::read()
00191 {
00192     AirConditionReader reader;
00193     if (reader.read()) {
00194         temperature = reader.temperature;
00195         humidity = reader.humidity;
00196         return true;
00197     }
00198     return false;
00199 }
00200 //
00201 // END OF FILE
00202 //