mbed Weather Platform post to Pachube

Dependencies:   mbed NetServices

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