htu21d_for_weather_shield
Dependents: SPARKFUN_WEATHER_SHIELD
Fork of htu21d by
Diff: htu21d.cpp
- Revision:
- 0:2dab43acb3a4
- Child:
- 1:d3ed713f8354
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/htu21d.cpp Wed May 14 00:31:30 2014 +0000 @@ -0,0 +1,234 @@ +/** +HTU21D 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 = new I2C(sda, scl); +} + +//--------------------------------------------------------------------------------------------------------------------------------------// +//De-contstructor + +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 + +#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 < 1000) && (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); +}