Sensirion SHT11 library

Revision:
0:56bbfad2d592
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sht11.cpp	Sun Apr 19 01:09:46 2015 +0000
@@ -0,0 +1,368 @@
+/**
+@file sht11.cpp
+
+@brief Member functions implementations
+
+*/
+#include "mbed.h"
+#include "sht11.h"
+
+                            //adr  command  r/w
+#define STATUS_REG_W 0x06   //000   0011    0
+#define STATUS_REG_R 0x07   //000   0011    1
+#define MEASURE_TEMP 0x03   //000   0001    1
+#define MEASURE_HUMI 0x05   //000   0010    1
+#define RESET        0x1e   //000   1111    0
+
+SHT11::SHT11(PinName clkPin, PinName dataPin)
+{
+    clk = new DigitalOut(clkPin);
+    data = new DigitalInOut(dataPin);
+}
+
+/*
+ * To initiate a transmission, a .Transmission Start. sequence
+ * has to be issued. It consists of a lowering of the DATA line
+ * while SCK is high, followed by a low pulse on SCK and
+ * raising DATA again while SCK is still high.
+ *
+ *         ______             _________
+ *  DATA:        \___________/
+ *              _____       _____
+ *   SCK:  ___/      \____/      \_____
+ */
+ 
+void SHT11::sendTransmissionStart()
+{
+    data->output();
+    
+    clk->write(0);
+    data->write(1);
+    wait_ms(10);
+    
+    clk->write(1);
+    wait_ms(10);
+    
+    data->write(0);
+    wait_ms(10);
+    
+    clk->write(0);
+    wait_ms(10);
+    
+    clk->write(1);
+    wait_ms(10);
+    
+    data->write(1);
+    wait_ms(10);
+    
+    clk->write(0);
+    wait_ms(10);
+}
+
+/* 
+ * connection reset: release the data line high and clock out >= 9 SCK cycles 
+ * followed by transaction start cycle
+ */
+void SHT11::connectionReset()
+{
+    int i;
+    
+    data->output();
+    data->write(1);
+    clk->write(0);
+    wait_ms(10);
+    
+    for(i=0; i<10; i++)
+    {
+        clk->write(1);
+        wait_ms(10);
+        clk->write(0);
+        wait_ms(10);
+    }
+}
+
+void SHT11::init() 
+{
+    connectionReset();
+}
+
+int SHT11::writeByte(unsigned char writeData)
+{
+    unsigned char writeMask = 0x80;
+    int ack = 0;
+    
+    // Ensure initial condition: clock low, data is an output
+    clk->write(0);
+    data->output();
+    wait_ms(10);
+    
+    while(writeMask != 0)
+    {
+        if ((writeData & writeMask) != 0) {
+            data->write(1);
+            }
+        else {
+            data->write(0);
+            }
+        
+        // delay for data to stabilize
+        wait_ms(10);
+        
+        clk->write(1);
+        wait_ms(10);
+        clk->write(0);
+        wait_ms(10);
+        
+        writeMask >>= 1;
+    }
+    
+    // release the data line
+    data->write(1);
+    data->input();
+    wait_ms(10);
+    
+    // 9th clock for ack, read the ack, return clk to low
+    clk->write(1);
+    wait_ms(10);   
+    ack = data->read();
+    clk->write(0);
+    wait_ms(10);
+    
+    return((int)ack);   
+}
+
+void SHT11::softReset()
+{
+    connectionReset();
+    writeByte(RESET);
+}
+
+int SHT11::readByte(unsigned char *pReadData, bool doAck)
+{
+    unsigned char retData = 0x00;
+    unsigned char readMask = 0x80;
+    int bitVal;
+    
+    // Ensure start conditions: clock low; data is input
+    clk->write(0);
+    data->write(1);
+    data->input();
+    wait_ms(10);
+    
+    while(readMask != 0)
+    {
+        clk->write(1);
+        wait_ms(10);
+        bitVal = data->read();
+        if (bitVal != 0)
+            retData |= readMask;
+        clk->write(0);
+        wait_ms(10);
+        readMask >>= 1;
+    }
+    
+    // If clocking out an ack; 
+    if (doAck == true)
+    {
+        data->output();
+        data->write(0);
+    }
+
+    wait_ms(10);
+    clk->write(1);
+    wait_ms(10);
+    clk->write(0);
+    data->input();
+    
+    *pReadData = retData;
+    return 1;
+}
+
+int SHT11::readStatus(unsigned char *pRetStatus)
+{
+    unsigned char retStatus, checksum;
+    int retVal = -1;
+    
+    sendTransmissionStart();
+    
+    if (writeByte(STATUS_REG_R) == 0)
+    {
+        readByte(&retStatus, true);
+        readByte(&checksum, false);
+        *pRetStatus = retStatus;
+        retVal = 0;
+    }
+    
+    return retVal;
+}
+    
+int SHT11::writeStatus(unsigned char writeValue)
+{
+    int retVal = -1;
+    
+    sendTransmissionStart();
+    
+    if (writeByte(STATUS_REG_W) == 0)
+    {
+        writeByte(writeValue);
+        retVal = 0;
+    }
+    
+    return retVal;
+}
+
+int SHT11::measureTemp(unsigned short *pRetTempRaw)
+{
+    int retVal = -1;
+    unsigned int waitCount;
+    union {
+        unsigned short u16;
+        unsigned char u8[2];
+        } u;
+    unsigned char checksum;
+    
+    sendTransmissionStart();
+    
+    retVal = writeByte(MEASURE_TEMP);
+    
+    if (retVal == 0)
+    {
+        data->input();
+        waitCount = 65535; // UINT_MAX
+        while(waitCount > 0)
+        {
+            if (data->read() == 0)
+            {
+                break;
+            }
+            wait_ms(10);
+            waitCount -= 1;
+        }
+    }
+    else
+    {
+        return -1;
+    }
+    
+    readByte(&(u.u8[1]), true);
+    readByte(&(u.u8[0]), true);
+    readByte(&checksum, false);
+
+    *pRetTempRaw = u.u16;
+    retVal = 0;
+    
+    return retVal;
+}
+
+int SHT11::measureHumid(unsigned short *pRetHumidRaw)
+{
+    int retVal = -1;
+    unsigned int waitCount;
+    union {
+        unsigned short u16;
+        unsigned char u8[2];
+        } u;
+    unsigned char checksum;
+    
+    sendTransmissionStart();
+    
+    retVal = writeByte(MEASURE_HUMI);
+    
+    if (retVal == 0)
+    {
+        data->input();
+        waitCount = 65535; // UINT_MAX;
+        while(waitCount > 0)
+        {
+            if (data->read() == 0)
+            {
+                break;
+            }
+            wait_ms(10);
+            waitCount -= 1;
+        }
+    }
+    else
+    {
+        return -1;
+    }
+    
+    readByte(&(u.u8[1]), true);
+    readByte(&(u.u8[0]), true);
+    readByte(&checksum, false);
+
+    *pRetHumidRaw = u.u16;
+    retVal = 0;
+    
+    return retVal;
+}
+
+float SHT11::convertTempCelsius(unsigned short rawTempIn)
+{
+    return ((((float)rawTempIn) * 0.010) - 40.0);
+}
+
+
+float SHT11::convertTempFahrenheit(unsigned short rawTempIn)
+{
+    return ((((float)rawTempIn) * 0.018) - 40.0);
+}
+
+float SHT11::convertHumid(unsigned short rawHumidIn, unsigned short rawTempIn)
+{
+    const float C1 = -4.0;
+    const float C2 = 0.0405;
+    const float C3 = -0.0000028;
+    const float T1 = 0.01;
+    const float T2 = 0.00008;
+    
+    float tempOut;
+    float humidLinearOut;
+    float humidOutTrue;
+    
+    tempOut = convertTempCelsius(rawTempIn);
+    
+    humidLinearOut = (float)rawHumidIn;
+    humidLinearOut = (C3 * humidLinearOut * humidLinearOut) + (C2 * humidLinearOut) + C1;
+    
+    humidOutTrue = (tempOut - 25.0) * (T1 + T2 * ((float)rawHumidIn)) + humidLinearOut;
+    
+    humidOutTrue = ((humidOutTrue > 100.0) ? 100.0 : humidOutTrue);
+    
+    humidOutTrue = ((humidOutTrue < 0.0) ? 0.0 : humidOutTrue);
+    
+    return humidOutTrue;
+}
+
+int SHT11::getTemperature(float * pRetTemperature)
+{
+  unsigned short rawValue;
+  int retVal = -1;
+    
+  if (measureTemp(&rawValue) == 0) {
+    lastTemperature = convertTempCelsius(rawValue);
+    *pRetTemperature = lastTemperature;
+    retVal = 0;
+    }
+
+  return retVal;
+}
+
+int SHT11::getTempHumid(float * pRetTemperature, float * pRetHumidity)
+{
+  unsigned short rawTempValue;
+  unsigned short rawHumidValue;
+  int retVal = -1;
+    
+  if (measureTemp(&rawTempValue) == 0) {
+    if (measureHumid(&rawHumidValue) == 0) {
+      lastHumidity = convertHumid(rawHumidValue, rawTempValue);
+      lastTemperature = convertTempCelsius(rawTempValue);
+      *pRetHumidity = lastHumidity;
+      *pRetTemperature = lastTemperature;
+      retVal = 0;
+      }
+    }
+
+  return retVal;
+}