TI HDC1000 Temperature and Humidity Sensor
Revision 0:1db0d0071723, committed 2017-04-17
- Comitter:
- Rhyme
- Date:
- Mon Apr 17 02:49:07 2017 +0000
- Child:
- 1:f2c04c5b28ab
- Commit message:
- First working version
Changed in this revision
| HDC1000.cpp | Show annotated file Show diff for this revision Revisions of this file |
| HDC1000.h | Show annotated file Show diff for this revision Revisions of this file |
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/HDC1000.cpp Mon Apr 17 02:49:07 2017 +0000
@@ -0,0 +1,349 @@
+#include "mbed.h"
+#include "HDC1000.h"
+
+#define REG_TEMPERATURE 0x00
+#define REG_HUMIDITY 0x01
+#define REG_CONFIGURATION 0x02
+#define REG_ID_FIRST_WORD 0xFB
+#define REG_ID_SECOND_WORD 0xFC
+#define REG_ID_LAST_BYTE 0xFD
+#define REG_MANUFACTURE_ID 0xFE
+#define REG_DEVICE_ID 0xFF
+
+/* Bit field of Configuration register */
+/* bit[15] RST Sowtware Rest Bit 0: Normal 1: Reset
+ * bit[14:13] (Reserved) must be 00
+ * bit[12] MODE 0:Aquire Temp/Hum separately(16bit each) 1:Aquire both Temp/Hum same time (32bit)
+ * bit[11] BTST Battery Test(?) 0:VDD > 2.8V 1:VDD < 2.8V
+ * bit[10] TRES Temperature Resolution 0:14bit 1:11bit
+ * bit[9:8] HRES Humidity Resolution 00:14bit 01:11bit 10:8bit
+ * bit[7:0] (Reserved) must be 00000000
+ */
+#define BIT_RESET 0x8000
+#define BIT_MODE 0x1000
+#define BIT_BTST 0x0800
+#define BIT_TRES 0x0400
+#define BIT_HRES14 0x0000
+#define BIT_HRES11 0x0100
+#define BIT_HRES08 0x0200
+
+HDC1000::HDC1000(PinName sda, PinName scl, PinName rdy, int addr) : m_i2c(sda, scl), m_rdy(rdy), m_addr(addr<<1) {
+// HDC1000::HDC1000(PinName sda, PinName scl, int addr) : m_i2c(sda, scl), m_addr(addr<<1) {
+ // activate the peripheral
+
+}
+
+HDC1000::~HDC1000(void)
+{
+}
+
+void HDC1000::reset(void)
+{
+ uint16_t conf = 0x8000 ;
+ setConfig(conf) ;
+}
+
+float HDC1000::readTemperature(void)
+{
+ uint16_t utemp, uhum ;
+ int32_t ltemp ;
+ int mode ;
+ float ftemp ;
+
+ mode = getMode() ;
+ switch(mode) {
+ case 0: /* temp or hum can be acquired */
+ utemp = getTemperature() ;
+ break ;
+ case 1: /* temp and hum can be acquired */
+ getData(&utemp, &uhum) ;
+ break ;
+ default:
+ printf("Error: unexpected mode %d\n",mode) ;
+ break ;
+ }
+ // note: the data sheet suggests to use 0x10000 for denominator
+ // but to allow 100% I chose 0xFFFF instead, I may be wrong
+ printf("utemp = 0x%04X ", utemp) ;
+ ltemp = (utemp >> 2) & 0x3FFF ;
+
+ ftemp = ((float)(ltemp)/ (float)0x3FFF)*165.0 - 40.0 ;
+ return( ftemp ) ;
+}
+
+float HDC1000::readHumidity(void)
+{
+ uint16_t utemp, uhume ;
+ int mode ;
+ int32_t lhume ;
+ float fhum ;
+
+ mode = getMode() ;
+ switch(mode) {
+ case 0: /* temp or hum can be acquired */
+ uhume = getHumidity() ;
+ break ;
+ case 1: /* temp and hum can be acquired */
+ getData(&utemp, &uhume) ;
+ break ;
+ default:
+ printf("Error: unexpected mode %d\n",mode) ;
+ break ;
+ }
+ // note: the data sheet suggests to use 0x10000 for denominator
+ // but to allow 100% I chose 0xFFFF instead, I may be wrong
+ printf("uhume = 0x%04X\n", uhume) ;
+ lhume = (uhume>>2) & 0x3FFF ;
+
+ fhum = ((float)(lhume) / (float)0x3FFF) * 100.0 ;
+ return( fhum ) ;
+}
+
+void HDC1000::readData(float *ftemp, float *fhume)
+{
+ uint16_t utemp, uhume ;
+ getData(&utemp, &uhume) ;
+ printf("utemp: 0x%04X, uhume: 0x%04X\n", utemp, uhume) ;
+ utemp = (utemp >> 2) & 0x3FFF ;
+ uhume = (uhume >> 2) & 0x3FFF ;
+ *ftemp = ((float)(utemp)/ (float)0x3FFF)*165.0 - 40.0 ;
+ *fhume = ((float)(uhume) / (float)0x3FFF) * 100.0 ;
+}
+/* for mode 0 */
+uint16_t HDC1000::getTemperature(void)
+{
+ uint16_t temp ;
+ uint8_t data[2] ;
+ float delay ;
+ data[0] = REG_TEMPERATURE ;
+ data[1] = (m_addr << 1) | 0x01 ;
+ m_i2c.write(m_addr, (const char*)data, 2, true);
+ while(m_rdy == 1) { } /* wait for rdy */
+
+// delay = getTDelay() ;
+// wait_us(1000 * delay) ;
+
+ m_i2c.read(m_addr, (char *)data, 2);
+ temp = (data[0] << 8) | data[1] ;
+ return( temp ) ;
+}
+
+uint16_t HDC1000::getHumidity(void)
+{
+ uint16_t hume ;
+ uint8_t data[2] ;
+ float delay ;
+// readRegs(REG_HUMIDITY, data, 2) ;
+ data[0] = REG_HUMIDITY ;
+ data[1] = (m_addr << 1) | 0x01 ;
+ m_i2c.write(m_addr, (const char*)data, 2, true);
+
+ while(m_rdy == 1) { } /* wait for rdy */
+// delay = getHDelay() ;
+// wait_us(1000 * delay) ;
+// wait(0.1) ;
+
+ m_i2c.read(m_addr, (char *)data, 2);
+ hume = (data[0] << 8) | data[1] ;
+ return( hume ) ;
+}
+
+/* for mode 1 */
+void HDC1000::getData(uint16_t *temp, uint16_t *hume)
+{
+ float delay ;
+ uint8_t data[4] = { 0, 0, 0, 0 } ;
+ int mode ;
+
+ mode = getMode() ;
+ if (mode == 0) {
+ *temp = getTemperature() ;
+ *hume = getHumidity() ;
+ } else { /* mode == 1 */
+ data[0] = REG_TEMPERATURE ;
+ data[1] = (m_addr << 1) | 0x01 ;
+ m_i2c.write(m_addr,(const char *)data, 2, false);
+
+ while(m_rdy == 1) { } /* wait for rdy */
+// delay = getTDelay() + getHDelay() ;
+// wait_us(1000 * delay) ;
+
+// m_i2c.write(m_addr,(const char *)data, 1, true);
+// while(m_rdy == 1) { } /* wait for rdy */
+ m_i2c.read(m_addr, (char *)data, 4);
+ *temp = (data[0] << 8) | data[1] ;
+ *hume = (data[2] << 8) | data[3] ;
+ }
+}
+
+void HDC1000::setConfig(uint16_t conf)
+{
+ uint8_t data[3] ;
+ data[0] = REG_CONFIGURATION ;
+ data[1] = (conf >> 8) & 0xFF ;
+ data[2] = conf & 0xFF ;
+ writeRegs(data, 3) ;
+}
+
+uint16_t HDC1000::getConfig(void)
+{
+ uint8_t data[2] ;
+ uint16_t conf ;
+ readRegs(REG_CONFIGURATION, data, 2) ;
+ conf = (data[0] << 8) | data[1] ;
+ return( conf ) ;
+}
+
+void HDC1000::setMode(int mode)
+{
+ uint16_t conf ;
+ conf = getConfig() ;
+ if (mode) {
+ conf |= BIT_MODE ;
+ } else {
+ conf ^= BIT_MODE ;
+ }
+ setConfig( conf ) ;
+}
+
+int HDC1000::getMode(void)
+{
+ uint16_t conf ;
+ int mode ;
+ conf = getConfig() ;
+ if (conf & BIT_MODE) {
+ mode = 1 ;
+ } else {
+ mode = 0 ;
+ }
+ return( mode ) ;
+}
+
+void HDC1000::setTres(int tres)
+{
+ uint16_t conf ;
+ conf = getConfig() ;
+ if (tres) {
+ conf |= BIT_TRES ;
+ } else {
+ conf ^= BIT_TRES ;
+ }
+}
+
+int HDC1000::getTres(void)
+{
+ uint16_t conf ;
+ int tres ;
+ conf = getConfig() ;
+ if (conf & BIT_TRES) {
+ tres = 1 ;
+ } else {
+ tres = 0 ;
+ }
+ return( tres ) ;
+}
+
+void HDC1000::setHres(int hres)
+{
+ uint16_t conf ;
+ conf = getConfig() ;
+ conf ^= (BIT_HRES11 | BIT_HRES08) ;
+ conf |= ((hres & 0x03) << 8) ;
+}
+
+int HDC1000::getHres(void)
+{
+ uint16_t conf ;
+ int hres ;
+ conf = getConfig() ;
+ hres = (conf >> 8)&0x03 ;
+ return( hres ) ;
+}
+
+void HDC1000::getSerialID(uint8_t data[])
+{
+ uint8_t udata[2] ;
+ readRegs(REG_ID_FIRST_WORD, &data[0], 2) ;
+ readRegs(REG_ID_SECOND_WORD, &data[2], 2) ;
+ readRegs(REG_ID_LAST_BYTE, udata, 2) ;
+ data[4] = udata[0] ;
+}
+
+uint16_t HDC1000::getManufactureID(void) /* 0x5449 : Texas Instruments */
+{
+ uint8_t data[2] ;
+ uint16_t id ;
+ readRegs(REG_MANUFACTURE_ID, data, 2) ;
+ id = (data[0] << 8) | data[1] ;
+ return( id ) ;
+}
+
+uint16_t HDC1000::getDeviceID(void) /* 0x1000 */
+{
+ uint8_t data[2] ;
+ uint16_t id ;
+ readRegs(REG_DEVICE_ID, data, 2) ;
+ id = (data[0] << 8) | data[1] ;
+ return( id ) ;
+}
+
+float HDC1000::getTDelay(void)
+{
+ int tres ;
+ float tdelay ;
+
+ tres = getTres() ;
+ switch(tres) {
+ case 0: /* 14bit */
+ tdelay = 6.35 ;
+ break ;
+ case 1: /* 11bit */
+ tdelay = 3.65 ;
+ break ;
+ default:
+ tdelay = 6.35 ;
+ break ;
+ }
+ return(tdelay) ;
+}
+
+float HDC1000::getHDelay(void)
+{
+ int hres ;
+ float hdelay ;
+
+ hres = getHres() ;
+ switch(hres) {
+ case 0: /* 14bit */
+ hdelay = 6.5 ;
+ break ;
+ case 1: /* 11bit */
+ hdelay = 3.85 ;
+ break ;
+ case 2: /* 8bit */
+ hdelay = 2.5 ;
+ break ;
+ default:
+ hdelay = 6.5 ; /* let's use the longest value */
+ break ;
+ }
+ return(hdelay) ;
+}
+
+float HDC1000::getDelay(void)
+{
+ float tdelay, hdelay ;
+ tdelay = getTDelay() ;
+ hdelay = getHDelay() ;
+ return( tdelay + hdelay ) ;
+}
+
+void HDC1000::readRegs(int addr, uint8_t * data, int len) {
+ char t[1] = {addr};
+ m_i2c.write(m_addr, t, 1, true);
+ m_i2c.read(m_addr, (char *)data, len) ;
+}
+
+void HDC1000::writeRegs(uint8_t * data, int len) {
+ m_i2c.write(m_addr, (char *)data, len);
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/HDC1000.h Mon Apr 17 02:49:07 2017 +0000
@@ -0,0 +1,60 @@
+#ifndef _HDC1000_H_
+#define _HDC1000_H_
+#include "mbed.h"
+/**
+ * HDC1000 Integrated Low Power Humidity and Temperature Digital Sensor
+ * I2C address: 0x40
+ */
+
+class HDC1000 {
+public:
+ /**
+ * constructor
+ *
+ * @param sda SDA pin
+ * @param scl SCL pin
+ * @param addr address of the I2C peripheral
+ */
+// HDC1000(PinName sda, PinName scl, int addr=0x40) ;
+HDC1000(PinName sda, PinName scl, PinName rdy, int addr=0x40) ;
+
+~HDC1000() ;
+
+float readTemperature(void) ;
+float readHumidity(void) ;
+
+void reset(void) ;
+
+/* for mode 0 */
+uint16_t getTemperature(void) ;
+uint16_t getHumidity(void) ;
+void readData(float *temp, float *hume) ;
+
+/* for mode 1 */
+void getData(uint16_t *temp, uint16_t *hume) ;
+
+void setConfig(uint16_t conf) ;
+uint16_t getConfig(void) ;
+void setMode(int mode) ;
+int getMode(void) ;
+void setTres(int tres) ;
+int getTres(void) ;
+void setHres(int hres) ;
+int getHres(void) ;
+void getSerialID(uint8_t data[]) ; /* returns 5 bytes ID */
+uint16_t getManufactureID(void) ; /* 0x5449 : Texas Instruments */
+uint16_t getDeviceID(void) ; /* 0x1000 */
+
+float getTDelay(void) ;
+float getHDelay(void) ;
+float getDelay(void) ;
+
+private:
+ I2C m_i2c;
+ DigitalIn m_rdy ;
+ int m_addr;
+ void readRegs(int addr, uint8_t * data, int len);
+ void writeRegs(uint8_t * data, int len);
+} ;
+
+#endif /* _HDC1000_H_ */
\ No newline at end of file