* AM2321的取温度间隔得大于2s,否则,i2c会不工作了 * SimpleTimer有个bug,会导致两次快速的读温度,现在读温度函数里加了保护 * Blynk有个bug,会导致无法把数据传到服务器 * 现在可以正常工作了
Diff: AM2321.cpp
- 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 +//