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

Dependencies:   mbed

Revision:
0:740c1eb2df13
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/AM2321.cpp	Thu Jun 23 11:16:14 2016 +0000
@@ -0,0 +1,202 @@
+//
+// AM2321 Temperature & Humidity Sensor library for Arduino
+//
+// The MIT License (MIT)
+//
+// Copyright (c) 2013 Wang Dong
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+//
+
+#include "AM2321.h"
+#include "mbed.h"
+extern I2C g_i2c;
+extern Serial pc;
+
+#define I2C_ADDR_AM2321                 (0xB8 >> 1)          //AM2321温湿度计I2C地址
+#define PARAM_AM2321_READ                0x03                //读寄存器命令
+#define REG_AM2321_HUMIDITY_MSB          0x00                //湿度寄存器高位
+#define REG_AM2321_HUMIDITY_LSB          0x01                //湿度寄存器低位
+#define REG_AM2321_TEMPERATURE_MSB       0x02                //温度寄存器高位
+#define REG_AM2321_TEMPERATURE_LSB       0x03                //温度寄存器低位
+#define REG_AM2321_DEVICE_ID_BIT_24_31   0x0B                //32位设备ID高8位
+
+template<int I2CADDR, int COMMAND, int REGADDR, int REGCOUNT>
+class DataReader
+{
+protected:
+    enum { len = 32 };
+    uint8_t buf[len];
+
+protected:
+    DataReader() {
+        memset(buf, 0, len);
+    }
+    bool readRaw() {
+        //
+        // Wakeup
+        //
+        //Wire.beginTransmission(I2CADDR);
+        //Wire.endTransmission();
+        g_i2c.write(I2CADDR<<1, (char*)&buf[0], 1);
+        wait_ms(2.9);
+        //
+        // Read Command
+        //
+#if 0
+        Wire.beginTransmission(I2CADDR);
+        Wire.write(COMMAND);
+        Wire.write(REGADDR);
+        Wire.write(REGCOUNT);
+        Wire.endTransmission();
+#else
+        char bu[3] = {COMMAND, REGADDR, REGCOUNT};
+        g_i2c.write(I2CADDR<<1, bu, 3);
+#endif
+
+        //
+        // Waiting
+        //
+        //delayMicroseconds(1600); //>1.5ms
+        wait_ms(1.6);
+
+        //
+        // Read
+        //
+#if 0
+        Wire.requestFrom(I2CADDR, 2 + REGCOUNT + 2); // COMMAND + REGCOUNT + DATA + CRCLSB + CRCMSB
+        int i = 0;
+        for (; i < 2 + REGCOUNT; ++i)
+            buf[i] = Wire.read();
+
+        unsigned short crc = 0;
+        crc  = Wire.read();     //CRC LSB
+        crc |= Wire.read() << 8;//CRC MSB
+
+        if (crc == crc16(buf, i))
+            return true;
+        return false;
+#else
+        uint8_t realAddr = (I2CADDR << 1) | 0x01;
+        //pc.printf("realAddr = 0x%x\r\n", realAddr);
+        g_i2c.read(realAddr, (char*)buf, 2 + REGCOUNT + 2);
+        unsigned short crc = 0;
+        crc  = buf[2+REGCOUNT];       //CRC LSB
+        crc |= buf[2+REGCOUNT+1] << 8;//CRC MSB
+#if 1
+        for (int i = 0; i < 2 + REGCOUNT + 2; i++) {
+            pc.printf("0x%X ", buf[i]);
+        }
+        pc.printf("\r\n");
+#endif
+        if (crc == crc16(buf, 2 + REGCOUNT))
+            return true;
+        return false;
+#endif
+    }
+
+private:
+    unsigned short crc16(unsigned char *ptr, unsigned char len) {
+        unsigned short crc = 0xFFFF;
+        unsigned char  i   = 0;
+        while(len--) {
+            crc ^= *ptr++;
+            for(i = 0 ; i < 8 ; i++) {
+                if(crc & 0x01) {
+                    crc >>= 1;
+                    crc  ^= 0xA001;
+                } else {
+                    crc >>= 1;
+                }
+            }
+        }
+        return crc;
+    }
+};
+
+class UidReader : public DataReader<I2C_ADDR_AM2321, PARAM_AM2321_READ, REG_AM2321_DEVICE_ID_BIT_24_31, 4>
+{
+public:
+    unsigned int uid;
+public:
+    bool read() {
+        if(!readRaw())
+            return false;
+        uid  = buf[2] << 24;
+        uid += buf[3] << 16;
+        uid += buf[4] << 8;
+        uid += buf[5];
+        return true;
+    }
+};
+
+class AirConditionReader : public DataReader<I2C_ADDR_AM2321, PARAM_AM2321_READ, REG_AM2321_HUMIDITY_MSB, 4>
+{
+public:
+    unsigned int humidity;
+    int temperature;
+public:
+    bool read() {
+        if(!readRaw())
+            return false;
+        humidity     = buf[2] << 8;
+        humidity    += buf[3];
+        temperature  = (buf[4]&0x7F) << 8;
+        temperature += buf[5];
+        if((buf[4]&0x80) == 0x80)
+            temperature = -temperature;
+        return true;
+    }
+};
+
+
+AM2321::AM2321()
+{
+    //Wire.begin();
+    temperature = 0;
+    humidity    = 0;
+}
+
+unsigned long AM2321::uid()
+{
+    UidReader reader;
+    if (reader.read())
+        return reader.uid;
+    return -1;
+}
+
+
+bool AM2321::available()
+{
+    return !(temperature == 0 && humidity == 0);
+}
+
+bool AM2321::read()
+{
+    AirConditionReader reader;
+    if (reader.read()) {
+        temperature = reader.temperature;
+        humidity = reader.humidity;
+        return true;
+    }
+    return false;
+}
+//
+// END OF FILE
+//