SHT V4 5V UART

Dependencies:   mbed

Fork of SHT_v1 by Stephen McGarry

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers SHT.cpp Source File

SHT.cpp

00001 /* mbed module to use a Sensirion SHT1x /SHT7x sensor
00002  * Copyright (c) 2007-2009 Stephen McGarry
00003  * Released under the MIT License: http://mbed.org/license/mit
00004  */
00005 
00006 #include "SHT.h"
00007 
00008 #include "mbed.h"
00009 #define MICROSECONDE 10//1
00010 
00011 SHT::SHT(PinName p_sclk, PinName p_data, SHT_acc p_accuracy) : sclk(p_sclk), data(p_data), accuracy(p_accuracy) {
00012     sclk=0;
00013     data=0;               // data pin will be used as open collector pin
00014     data.mode(PullUp);    // with the pull up internally active
00015     data.input();        // with line released to go high
00016     temperature = humidity = dewpoint=0.0f;
00017   
00018 }
00019 
00020 char SHT::write_byte(byte value)
00021 //----------------------------------------------------------------------------------
00022 // writes a byte on the Sensibus and checks the acknowledge
00023 {
00024     int i;
00025     char error=0;
00026 
00027     for (i=0x80;i>0;i/=2) {           //shift bit for masking
00028         if (i & value) data.input();  //masking value with i , write to SENSI-BUS
00029         else data.output();
00030         wait_us(MICROSECONDE);                   //ensure sclk is low for min time
00031         
00032         sclk=1;                       //clk for SENSI-BUS
00033         wait_us(MICROSECONDE);                   //pulsewith approx. 2 us
00034         sclk=0;
00035     }
00036     data.input();                     //release DATA-line
00037     wait_us(MICROSECONDE);                       //ensure sclk is low for min time
00038     sclk=1;                           //clk #9 for ack
00039     error=data;                       //check ack (DATA will be pulled down by SHT11)
00040     wait_us(MICROSECONDE);
00041     sclk=0;
00042     return error;                     //error=1 in case of no acknowledge
00043 }
00044 
00045 byte SHT::read_byte(bool send_ack)
00046 //----------------------------------------------------------------------------------
00047 // reads a byte form the Sensibus and gives an acknowledge in case of "ack=1"
00048 {
00049     byte i,val=0;
00050     data.input();                     //release DATA-line
00051     for (i=0x80;i>0;i/=2) {           //shift bit for masking
00052         wait_us(MICROSECONDE);
00053         sclk=1;                       //clk for SENSI-BUS
00054         if (data) val=(val | i);      //read bit
00055         wait_us(MICROSECONDE);
00056         sclk=0;
00057     }
00058     wait_us(MICROSECONDE);
00059     if (send_ack) data.output();      // if ack needed then drive data low
00060     sclk=1;                           //clk #9 for ack
00061     wait_us(MICROSECONDE);
00062     sclk=0;
00063     data.input();                     //release DATA-line
00064     return val;
00065 }
00066 
00067 void SHT::trans_start(void)
00068 //----------------------------------------------------------------------------------
00069 // generates a transmission start
00070 //       _____         ________
00071 // DATA:      |_______|
00072 //           ___     ___
00073 // SCK : ___|   |___|   |______
00074 {
00075     data.input();
00076     sclk=0;                   //Initial state
00077     wait_us(MICROSECONDE);
00078     sclk=1;
00079     wait_us(MICROSECONDE);
00080     data.output();            // data low
00081     wait_us(MICROSECONDE);
00082     sclk=0;
00083     wait_us(MICROSECONDE);
00084     sclk=1;
00085     wait_us(MICROSECONDE);
00086     data.input();            // allow data to high
00087     wait_us(MICROSECONDE);
00088     sclk=0;
00089     wait_us(MICROSECONDE);
00090 }
00091 
00092 void SHT::connection_reset(void)
00093 //----------------------------------------------------------------------------------
00094 // communication reset: DATA-line=1 and at least 9 SCK cycles followed by transstart
00095 //       _____________________________________________________         ________
00096 // DATA:                                                      |_______|
00097 //          _    _    _    _    _    _    _    _    _        ___     ___
00098 // SCK : __| |__| |__| |__| |__| |__| |__| |__| |__| |______|   |___|   |______
00099 {
00100     int i;
00101     data.input();            // allow data high
00102     sclk=0;                  // and clk low
00103     for (i=0;i<9;i++) {      // 9 SCK cycles
00104         wait_us(MICROSECONDE);
00105         sclk=1;
00106         wait_us(MICROSECONDE);
00107         sclk=0;
00108     }
00109 }
00110 
00111 char SHT::soft_reset(void)
00112 //----------------------------------------------------------------------------------
00113 // resets the sensor by a softreset
00114 {
00115     char error=0;
00116     SHT::connection_reset();                //reset communication
00117     trans_start();
00118     error+=write_byte(com_reset);       //send RESET-command to sensor
00119     return error;                     //error=1 in case of no response form the sensor
00120 }
00121 
00122 char SHT::read_status(byte &value)
00123 //----------------------------------------------------------------------------------
00124 // reads the status register with checksum (8-bit)
00125 {
00126     //byte checksum;
00127 
00128     char error=0;
00129     trans_start();                     //transmission start
00130     error=write_byte(com_read_status_reg); //send command to sensor
00131     value=read_byte(send_ack);             //read status register (8-bit)
00132     /* checksum= */
00133     (void)read_byte(no_ack);         //read checksum (8-bit)
00134     // check the checksum ??
00135     return error;                      //error=1 in case of no response form the sensor
00136 }
00137 
00138 char SHT::write_status(byte value)
00139 //----------------------------------------------------------------------------------
00140 // writes the status register (8-bit)
00141 {
00142     char error=0;
00143     trans_start();                        //transmission start
00144     error+=write_byte(com_write_status_reg); //send command to sensor
00145     error+=write_byte(value);            //send value of status register
00146     return error;                          //error>=1 in case of no response form the sensor
00147 }
00148 
00149 char SHT::measure(int &value, byte command)
00150 //----------------------------------------------------------------------------------
00151 // makes a measurement (humidity/temperature) with checksum
00152 {
00153     unsigned int i;
00154     byte msb;
00155     // byte checksum;
00156 
00157     trans_start();                //transmission start
00158     if (write_byte(command)) return 1; // if command fails return
00159 
00160     for (i=10000;i;i--) {          //wait until sensor has finished the measurement
00161         wait_us(100);
00162         if (data==0) break;
00163     }
00164     if (data) return 1;            // or timeout (~1 sec.) is reached !!
00165     msb = read_byte(send_ack);         //read the first byte (MSB)
00166     value = msb*256 + read_byte(send_ack);    //read the second byte (LSB)
00167     /* checksum= */
00168     (void)read_byte(no_ack);    //read checksum
00169     return 0;
00170 }
00171 
00172 void SHT::calculate()
00173 //----------------------------------------------------------------------------------------
00174 // calculates temperature [�C] and humidity [%RH]
00175 // input :  hum  [Ticks] (12 bit)
00176 //          temp [Ticks] (14 bit)
00177 // output:  humidity [%RH]
00178 //          temperature [�C]
00179 {
00180     //Optimized V4 humidity conversion coefficients
00181     const float C1=-2.0468;              // for 12 Bit
00182     const float C2=0.0367;           // for 12 Bit
00183     const float C3=-1.5955E-6;        // for 12 Bit
00184     const float T1=0.01;             // for 12 
00185     const float T2=0.00008;           // for 12 Bit 
00186     const float D1= -40.1;             //for °C 5V
00187     const float D2= 0.01 ;            //for °C for 14
00188     float rh;                         // rh:      Humidity [Ticks] 12 Bit
00189     float t;                          // t:       Temperature [Ticks] 14 Bit
00190     float rh_lin;                     // rh_lin:  Humidity linear
00191     if (accuracy==SHT_low) {
00192         rh=hum*16;                    // rescale to high accuracy values - 8 to 12 bits
00193         t=temp*4;                     // and 12 to 14 bits
00194     } else {
00195         rh=hum;
00196         t=temp;
00197     }
00198 
00199     temperature=D1 + D2*t ;                  //calc. temperature from ticks to [�C]
00200      rh_lin=C3*rh*rh + C2*rh + C1;     //calc. humidity from ticks to [%RH]
00201      humidity =(temperature-25)*(T1+T2*rh)+rh_lin;   //calc. temperature compensated humidity [%RH] (ignore as never >0.25%)
00202     if (humidity>100)humidity=100;      //cut if the value is outside of
00203     if (humidity<0.1)humidity=0.1;      //the physical possible range
00204 }
00205 
00206 float SHT::get_temperature() {     // get the most recent temp reading
00207     return temperature;
00208 }
00209 
00210 float SHT::get_humidity() {        // get the most recent humidity reading
00211     return humidity;
00212 }
00213 
00214 float SHT::get_dewpoint() {        // get the most recent dewpoint value
00215     return dewpoint;
00216 }
00217 
00218 int SHT::update(SHT_acc acc) {   // update stored values from sensor
00219     int error=0;
00220     soft_reset();
00221     //connection_reset();
00222     if (acc!=accuracy) {
00223         accuracy=acc;
00224         error+=write_status((acc==SHT_low)?0x01:0x00);    //set the status reg to high or low accuarcy
00225     }
00226     error+=measure(temp,com_measure_temp);
00227     error+=measure(hum,com_measure_humid);
00228     if (!error) calculate();
00229 return error;
00230 }