AM2321 Temperature and Humidity Sensor mbed library

Dependents:   AM2321_Example mbed_vfd_thermometer

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers AM2321.cpp Source File

AM2321.cpp

00001 /*
00002  *  AM2321 (Aosong Guangzhou Electronics)
00003  *  Temperature and Humidity Sensor mbed library
00004  * 
00005  *  Copyright (c) 2014 tomozh <tomozh@gmail.com>
00006  *  
00007  *  This software is released under the MIT License.
00008  *  http://opensource.org/licenses/mit-license.php
00009  *
00010  *  Last update : 2014/05/06
00011  */
00012 
00013 #include "mbed.h"
00014 #include "AM2321.h"
00015 
00016 const int AM2321_I2C_ADDR = 0xB8;
00017 
00018 AM2321::AM2321(PinName sda, PinName scl)
00019 : _i2c(sda, scl)
00020 {
00021     _result.temperature = 0.0f;
00022     _result.humidity    = 0.0f;        
00023 }
00024 
00025 float AM2321::getLogicalValue(uint16_t regVal) const
00026 {
00027     if(regVal & 0x8000)
00028     {
00029         regVal &= ~0x8000;
00030         return (float)regVal / -10.0;
00031     }
00032     else
00033     {
00034         return (float)regVal / 10.0;    
00035     }
00036 }
00037 
00038 uint16_t AM2321::calcCRC16(const uint8_t* src, int len) const
00039 {
00040     uint16_t crc = 0xFFFF;
00041 
00042     while(len--)
00043     {
00044         crc ^= *(src++);
00045         
00046         for(uint8_t i = 0; i < 8; i++)
00047         {
00048             if(crc & 0x01)
00049             {
00050                 crc >>= 1;
00051                 crc ^= 0xA001;
00052             }
00053             else
00054             {
00055                 crc >>= 1;
00056             }
00057         }
00058     }
00059     
00060     return crc; 
00061 }
00062 
00063 bool AM2321::poll(void)
00064 {
00065     bool    success = false;
00066     uint8_t data[8];
00067     
00068     const static uint8_t READ_REGISTER_CMD[] = {
00069            0x03     // Read register command
00070          , 0x00     // start addrress
00071          , 0x04     // read length
00072           };
00073 
00074     // wakeup
00075     _i2c.write(AM2321_I2C_ADDR, NULL, 0);
00076 
00077     // read data
00078     _i2c.write(AM2321_I2C_ADDR, (char*)READ_REGISTER_CMD, 3);
00079     wait_us(1600);
00080 
00081     if(_i2c.read(AM2321_I2C_ADDR, (char*)data, 8) == 0)
00082     {
00083         uint8_t  cmd     = data[0];
00084         uint8_t  dataLen = data[1];
00085         uint16_t humiVal = (data[2] * 256) + data[3];
00086         uint16_t tempVal = (data[4] * 256) + data[5];
00087         uint16_t recvCRC = data[6] + (data[7] * 256);
00088         uint16_t chkCRC  = calcCRC16(&data[0], 6);
00089 
00090         if(dataLen == 4)
00091         {
00092             if(recvCRC == chkCRC)
00093             {
00094                 if(cmd == 0x03)
00095                 {
00096                     _result.temperature = getLogicalValue(tempVal);
00097                     _result.humidity    = getLogicalValue(humiVal);
00098 
00099                     success = true;
00100                 }
00101             }
00102         }
00103     }
00104     
00105     return success;
00106 }
00107 
00108 float AM2321::getTemperature(void) const
00109 {
00110     return _result.temperature;
00111 }
00112 
00113 float AM2321::getHumidity(void) const
00114 {
00115     return _result.humidity;
00116 }