htu21d_for_weather_shield
Dependents: SPARKFUN_WEATHER_SHIELD
Fork of htu21d by
htu21d.cpp
- Committer:
- loopsva
- Date:
- 2014-05-15
- Revision:
- 1:d3ed713f8354
- Parent:
- 0:2dab43acb3a4
- Child:
- 2:8fbe84ed61e6
File content as of revision 1:d3ed713f8354:
/** HTU21D / HPP828E031 driver for mbed. - Includes RTOS hooks if RTOS is detected during compile. Author: Kevin Braun **/ #include "htu21d.h" #ifdef RTOS_H extern Mutex MutexI2cWait; #endif //--------------------------------------------------------------------------------------------------------------------------------------// //Contstructor htu21d::htu21d(PinName sda, PinName scl) : _i2c(sda, scl) { _i2c.frequency(400000); } htu21d::htu21d(PinName sda, PinName scl, int i2cFrequency) : _i2c(sda, scl) { _i2c.frequency(i2cFrequency); } //--------------------------------------------------------------------------------------------------------------------------------------// //Destructor htu21d::~htu21d() { } //--------------------------------------------------------------------------------------------------------------------------------------// //Perform a soft reset on the HTU21D. REturn of 1 = ok, 0 = timeout. int htu21d::softReset() { #ifdef RTOS_H MutexI2cWait.lock(); #endif int htu21 = 0; _i2c.start(); htu21 = _i2c.write(HTU21Di2cWRITE); //i2c, 1 = ack if(htu21 == 1) { _i2c.write(HTU21DRESET); //soft reset, must wait 15mS _i2c.stop(); wait_ms(16); //must wait a least 15mS for reset to finish htu21d::getSNReg(); //go load up the s/n registers } #ifdef RTOS_H MutexI2cWait.unlock(); #endif return(htu21); } //--------------------------------------------------------------------------------------------------------------------------------------// //Get the HTU21D user register. Returns 8 bit register. uint8_t htu21d::getUserReg() { #ifdef RTOS_H MutexI2cWait.lock(); #endif int htu21 = 0; uint8_t htu21data = 0; _i2c.start(); htu21 = _i2c.write(HTU21Di2cWRITE); //i2c, 1 = ack if(htu21 == 1) { _i2c.write(HTU21DREADUSER); _i2c.start(); htu21 = _i2c.write(HTU21Di2cREAD); htu21data = _i2c.read(0); _i2c.stop(); } #ifdef RTOS_H MutexI2cWait.unlock(); #endif return(htu21data); } //--------------------------------------------------------------------------------------------------------------------------------------// //Turn ON the heater the HTU21D user register. int htu21d::heaterOn() { uint8_t htu21data = htu21d::getUserReg(); htu21data |= HTU21DHEATER; #ifdef RTOS_H MutexI2cWait.lock(); #endif int htu21 = 0; _i2c.start(); htu21 = _i2c.write(HTU21Di2cWRITE); //i2c, 1 = ack if(htu21 == 1) { _i2c.write(HTU21DWRITEUSER); htu21 = _i2c.write(htu21data); _i2c.stop(); } #ifdef RTOS_H MutexI2cWait.unlock(); #endif return(htu21); } //--------------------------------------------------------------------------------------------------------------------------------------// //Turn OFF the heater the HTU21D user register. int htu21d::heaterOff() { uint8_t htu21data = htu21d::getUserReg(); htu21data &= ~HTU21DHEATER; #ifdef RTOS_H MutexI2cWait.lock(); #endif int htu21 = 0; _i2c.start(); htu21 = _i2c.write(HTU21Di2cWRITE); //i2c, 1 = ack if(htu21 == 1) { _i2c.write(HTU21DWRITEUSER); htu21 = _i2c.write(htu21data); _i2c.stop(); } #ifdef RTOS_H MutexI2cWait.unlock(); #endif return(htu21); } //--------------------------------------------------------------------------------------------------------------------------------------// //Get the status of the heater the HTU21D user register. 0 = off, 4 = on. uint8_t htu21d::getHeater() { uint8_t htu21data = htu21d::getUserReg(); htu21data &= HTU21DHEATER; return(htu21data); } //--------------------------------------------------------------------------------------------------------------------------------------// //generic routine to get temp or humidity from HTU21D. //Returns 14 bits of data (anded 0xFFFC) or 0000 if i2c timeout occurs. //After a read temp or humidity command, HTU21D responds with NACKs until data is ready. //NOTE: Use non-hold commands uint16_t htu21d::getData(uint8_t reg) { int htu21 = 0; //ACK flag int htu21cnt = 0; //number of NACKs before ACK or timeout uint16_t htu21data = 0; //returned data #ifdef RTOS_H MutexI2cWait.lock(); #endif _i2c.start(); htu21 = _i2c.write(HTU21Di2cWRITE); _i2c.write(reg); //read temp, no hold if(htu21 == 0) return 0; //HTU21T not responding do { htu21cnt++; _i2c.start(); htu21 = _i2c.write(HTU21Di2cREAD); if(htu21 == 1) { htu21data = _i2c.read(1) << 8; htu21data |= _i2c.read(0) & 0xFC; _i2c.stop(); } wait_us(50); } while((htu21cnt < 10000) && (htu21 == 0)); //htu21cnt takes 510 to get temp, 160 for humidity #ifdef RTOS_H MutexI2cWait.unlock(); #endif if(htu21 == 0) return 0; //HTU21D ACK response timed out return(htu21data); //return 14 bit value } double theTempIs = 0.0; double theHumIs = 0.0; //--------------------------------------------------------------------------------------------------------------------------------------// //get temperature from HTU21D in degrees C. Returns with 255.0 if HTU21D had timed out. float htu21d::getTemp() { uint16_t getData = htu21d::getData(HTU21DtempNOHOLD); if (getData == 0) return(255.0); //return with error double tempData = (double)getData / 65536.0; theTempIs = -46.85 + (175.72 * tempData); return(theTempIs); } //--------------------------------------------------------------------------------------------------------------------------------------// //get humidity from HTU21D in percentage. Returns with 255.0 if HTU21D had timed out. float htu21d::getHum() { uint16_t getData = htu21d::getData(HTU21DhumNOHOLD); if (getData == 0) return(255.0); //return with error double tempData = (double)getData / 65536.0; theHumIs = -6.0 + (125.0 * tempData); return(theHumIs); } //--------------------------------------------------------------------------------------------------------------------------------------// //Calculate the Dew Point from getTemp and getHum. User must first execute both getTemp and getHum for an accurate result. //Calculations come from DHT library /* Copyright (C) Wim De Roeve * based on DHT22 sensor library by HO WING KIT * Arduino DHT11 library */ float htu21d::getDewPt() { // dewPoint function NOAA // reference: http://wahiduddin.net/calc/density_algorithms.htm double A0= 373.15/(273.15 + (double)theTempIs); double SUM = -7.90298 * (A0-1); SUM += 5.02808 * log10(A0); SUM += -1.3816e-7 * (pow(10, (11.344*(1-1/A0)))-1) ; SUM += 8.1328e-3 * (pow(10,(-3.49149*(A0-1)))-1) ; SUM += log10(1013.246); double VP = pow(10, SUM-3) * theHumIs; double T = log(VP/0.61078); // temp var return (241.88 * T) / (17.558-T); } float htu21d::getDewPtFast() { // delta max = 0.6544 wrt dewPoint() // 5x faster than dewPoint() // reference: http://en.wikipedia.org/wiki/Dew_point double h21DtzA = 17.271; double h21DtzB = 237.7; double h21DtzC = (h21DtzA * theTempIs) / (h21DtzB + theTempIs) + log(theHumIs/100); double h21DtzD = (h21DtzB * h21DtzC) / (h21DtzA - h21DtzC); return (h21DtzD); } //--------------------------------------------------------------------------------------------------------------------------------------// //Get the HTU21D serial number registers. Returns 64 bit register. //should return 0x4854 00xx xxxx 32xx void htu21d::getSNReg() { #ifdef RTOS_H MutexI2cWait.lock(); #endif //get 16 bit SNC register, 8 bit SNC-CRC, 16 bit SNA register, 8 bit SNA-CRC int htu21 = 0; _i2c.start(); htu21 = _i2c.write(HTU21Di2cWRITE); //i2c, 1 = ack if(htu21 == 1) { _i2c.write(HTU21SNAC1); _i2c.write(HTU21SNAC2); _i2c.start(); htu21 = _i2c.write(HTU21Di2cREAD); HTU21sn.HTU21D_snc = _i2c.read(1) << 8; HTU21sn.HTU21D_snc |= _i2c.read(1); HTU21sn.HTU21D_crcc = _i2c.read(1); HTU21sn.HTU21D_sna = _i2c.read(1) << 8; HTU21sn.HTU21D_sna |= _i2c.read(1); HTU21sn.HTU21D_crca = _i2c.read(0); _i2c.stop(); } //get 32 bit SNB register, 32 bit SNB-CRC - regs are intermixed htu21 = 0; _i2c.start(); htu21 = _i2c.write(HTU21Di2cWRITE); //i2c, 1 = ack if(htu21 == 1) { _i2c.write(HTU21SNB1); _i2c.write(HTU21SNB2); _i2c.start(); htu21 = _i2c.write(HTU21Di2cREAD); HTU21sn.HTU21D_snb = _i2c.read(1) << 24; HTU21sn.HTU21D_crcb = _i2c.read(1) << 24; HTU21sn.HTU21D_snb |= _i2c.read(1) << 16; HTU21sn.HTU21D_crcb |= _i2c.read(1) << 16; HTU21sn.HTU21D_snb |= _i2c.read(1) << 8; HTU21sn.HTU21D_crcb |= _i2c.read(1) << 8; HTU21sn.HTU21D_snb |= _i2c.read(1); HTU21sn.HTU21D_crcb |= _i2c.read(0); _i2c.stop(); } #ifdef RTOS_H MutexI2cWait.unlock(); #endif }