Dependencies:   mbed

Revision:
0:df1c8f2961a1
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/SHT.cpp	Sun Jan 24 22:00:35 2010 +0000
@@ -0,0 +1,224 @@
+/* mbed module to use a Sensirion SHT1x /SHT7x sensor
+ * Copyright (c) 2007-2009 Stephen McGarry
+ * Released under the MIT License: http://mbed.org/license/mit
+ */
+
+#include "SHT.h"
+
+#include "mbed.h"
+
+SHT::SHT(PinName p_sclk, PinName p_data, SHT_acc p_accuracy) : sclk(p_sclk), data(p_data), accuracy(p_accuracy) {
+    sclk=0;
+    data=0;               // data pin will be used as open collector pin
+    data.mode(PullUp);    // with the pull up internally active
+    data.input();        // with line released to go high
+    temperature = humidity = dewpoint=0.0f;
+   printf("constructor\n");
+}
+
+char SHT::write_byte(byte value)
+//----------------------------------------------------------------------------------
+// writes a byte on the Sensibus and checks the acknowledge
+{
+    int i;
+    char error=0;
+
+    for (i=0x80;i>0;i/=2) {           //shift bit for masking
+        if (i & value) data.input();  //masking value with i , write to SENSI-BUS
+        else data.output();
+        wait_us(1);                   //ensure sclk is low for min time
+        sclk=1;                       //clk for SENSI-BUS
+        wait_us(1);                   //pulsewith approx. 2 us
+        sclk=0;
+    }
+    data.input();                     //release DATA-line
+    wait_us(1);                       //ensure sclk is low for min time
+    sclk=1;                           //clk #9 for ack
+    error=data;                       //check ack (DATA will be pulled down by SHT11)
+    wait_us(1);
+    sclk=0;
+    return error;                     //error=1 in case of no acknowledge
+}
+
+byte SHT::read_byte(bool send_ack)
+//----------------------------------------------------------------------------------
+// reads a byte form the Sensibus and gives an acknowledge in case of "ack=1"
+{
+    byte i,val=0;
+    data.input();                     //release DATA-line
+    for (i=0x80;i>0;i/=2) {           //shift bit for masking
+        wait_us(1);
+        sclk=1;                       //clk for SENSI-BUS
+        if (data) val=(val | i);      //read bit
+        wait_us(1);
+        sclk=0;
+    }
+    wait_us(1);
+    if (send_ack) data.output();      // if ack needed then drive data low
+    sclk=1;                           //clk #9 for ack
+    wait_us(1);
+    sclk=0;
+    data.input();                     //release DATA-line
+    return val;
+}
+
+void SHT::trans_start(void)
+//----------------------------------------------------------------------------------
+// generates a transmission start
+//       _____         ________
+// DATA:      |_______|
+//           ___     ___
+// SCK : ___|   |___|   |______
+{
+    data.input();
+    sclk=0;                   //Initial state
+    wait_us(1);
+    sclk=1;
+    wait_us(1);
+    data.output();            // data low
+    wait_us(1);
+    sclk=0;
+    wait_us(1);
+    sclk=1;
+    wait_us(1);
+    data.input();            // allow data to high
+    wait_us(1);
+    sclk=0;
+    wait_us(1);
+}
+
+void SHT::connection_reset(void)
+//----------------------------------------------------------------------------------
+// communication reset: DATA-line=1 and at least 9 SCK cycles followed by transstart
+//       _____________________________________________________         ________
+// DATA:                                                      |_______|
+//          _    _    _    _    _    _    _    _    _        ___     ___
+// SCK : __| |__| |__| |__| |__| |__| |__| |__| |__| |______|   |___|   |______
+{
+    int i;
+    data.input();            // allow data high
+    sclk=0;                  // and clk low
+    for (i=0;i<9;i++) {      // 9 SCK cycles
+        wait_us(1);
+        sclk=1;
+        wait_us(1);
+        sclk=0;
+    }
+}
+char SHT::soft_reset(void)
+//----------------------------------------------------------------------------------
+// resets the sensor by a softreset
+{
+    char error=0;
+    SHT::connection_reset();                //reset communication
+    trans_start();
+    error+=write_byte(com_reset);       //send RESET-command to sensor
+    return error;                     //error=1 in case of no response form the sensor
+}
+
+char SHT::read_status(byte &value)
+//----------------------------------------------------------------------------------
+// reads the status register with checksum (8-bit)
+{
+    //byte checksum;
+
+    char error=0;
+    trans_start();                     //transmission start
+    error=write_byte(com_read_status_reg); //send command to sensor
+    value=read_byte(send_ack);             //read status register (8-bit)
+    /* checksum= */
+    (void)read_byte(no_ack);         //read checksum (8-bit)
+    // check the checksum ??
+    return error;                      //error=1 in case of no response form the sensor
+}
+
+char SHT::write_status(byte value)
+//----------------------------------------------------------------------------------
+// writes the status register (8-bit)
+{
+    char error=0;
+    trans_start();                        //transmission start
+    error+=write_byte(com_write_status_reg); //send command to sensor
+    error+=write_byte(value);            //send value of status register
+    return error;                          //error>=1 in case of no response form the sensor
+}
+
+char SHT::measure(int &value, byte command)
+//----------------------------------------------------------------------------------
+// makes a measurement (humidity/temperature) with checksum
+{
+    unsigned int i;
+    byte msb;
+    // byte checksum;
+
+    trans_start();                //transmission start
+    if (write_byte(command)) return 1; // if command fails return
+
+    for (i=10000;i;i--) {          //wait until sensor has finished the measurement
+        wait_us(100);
+        if (data==0) break;
+    }
+    if (data) return 1;            // or timeout (~1 sec.) is reached !!
+    msb = read_byte(send_ack);         //read the first byte (MSB)
+    value = msb*256 + read_byte(send_ack);    //read the second byte (LSB)
+    /* checksum= */
+    (void)read_byte(no_ack);    //read checksum
+    return 0;
+}
+
+void SHT::calculate()
+//----------------------------------------------------------------------------------------
+// calculates temperature [°C] and humidity [%RH]
+// input :  hum  [Ticks] (12 bit)
+//          temp [Ticks] (14 bit)
+// output:  humidity [%RH]
+//          temperature [°C]
+{
+    const float C1=-4.0;              // for 12 Bit
+    const float C2=+0.0405;           // for 12 Bit
+    const float C3=-0.0000028;        // for 12 Bit
+    //const float T1=+0.01;             // for 14 Bit @ 5V
+    //const float T2=+0.00008;           // for 14 Bit @ 5V
+
+    float rh;                         // rh:      Humidity [Ticks] 12 Bit
+    float t;                          // t:       Temperature [Ticks] 14 Bit
+    //float rh_lin;                     // rh_lin:  Humidity linear
+    if (accuracy==SHT_low) {
+        rh=hum*16;                    // rescale to high accuracy values - 8 to 12 bits
+        t=temp*4;                     // and 12 to 14 bits
+    } else {
+        rh=hum;
+        t=temp;
+    }
+
+    temperature=t*0.01 - 40;                  //calc. temperature from ticks to [°C]
+    humidity=C3*rh*rh + C2*rh + C1;     //calc. humidity from ticks to [%RH]
+    // =(temperature-25)*(T1+T2*rh)+rh_lin;   //calc. temperature compensated humidity [%RH] (ignore as never >0.25%)
+    if (humidity>100)humidity=100;      //cut if the value is outside of
+    if (humidity<0.1)humidity=0.1;      //the physical possible range
+}
+
+float SHT::get_temperature() {     // get the most recent temp reading
+    return temperature;
+}
+
+float SHT::get_humidity() {        // get the most recent humidity reading
+    return humidity;
+}
+
+float SHT::get_dewpoint() {        // get the most recent dewpoint value
+    return dewpoint;
+}
+
+void SHT::update(SHT_acc acc) {   // update stored values from sensor
+    int error=0;
+    connection_reset();
+    if (acc!=accuracy) {
+        accuracy=acc;
+        error+=write_status((acc==SHT_low)?0x01:0x00);    //set the status reg to high or low accuarcy
+    }
+    error+=measure(temp,com_measure_temp);
+    error+=measure(hum,com_measure_humid);
+    if (!error) calculate();
+
+}