Tim M / SHT11
Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers sht11.cpp Source File

sht11.cpp

Go to the documentation of this file.
00001 /**
00002 @file sht11.cpp
00003 
00004 @brief Member functions implementations
00005 
00006 */
00007 #include "mbed.h"
00008 #include "sht11.h"
00009 
00010                             //adr  command  r/w
00011 #define STATUS_REG_W 0x06   //000   0011    0
00012 #define STATUS_REG_R 0x07   //000   0011    1
00013 #define MEASURE_TEMP 0x03   //000   0001    1
00014 #define MEASURE_HUMI 0x05   //000   0010    1
00015 #define RESET        0x1e   //000   1111    0
00016 
00017 SHT11::SHT11(PinName clkPin, PinName dataPin)
00018 {
00019     clk = new DigitalOut(clkPin);
00020     data = new DigitalInOut(dataPin);
00021 }
00022 
00023 /*
00024  * To initiate a transmission, a .Transmission Start. sequence
00025  * has to be issued. It consists of a lowering of the DATA line
00026  * while SCK is high, followed by a low pulse on SCK and
00027  * raising DATA again while SCK is still high.
00028  *
00029  *         ______             _________
00030  *  DATA:        \___________/
00031  *              _____       _____
00032  *   SCK:  ___/      \____/      \_____
00033  */
00034  
00035 void SHT11::sendTransmissionStart()
00036 {
00037     data->output();
00038     
00039     clk->write(0);
00040     data->write(1);
00041     wait_ms(10);
00042     
00043     clk->write(1);
00044     wait_ms(10);
00045     
00046     data->write(0);
00047     wait_ms(10);
00048     
00049     clk->write(0);
00050     wait_ms(10);
00051     
00052     clk->write(1);
00053     wait_ms(10);
00054     
00055     data->write(1);
00056     wait_ms(10);
00057     
00058     clk->write(0);
00059     wait_ms(10);
00060 }
00061 
00062 /* 
00063  * connection reset: release the data line high and clock out >= 9 SCK cycles 
00064  * followed by transaction start cycle
00065  */
00066 void SHT11::connectionReset()
00067 {
00068     int i;
00069     
00070     data->output();
00071     data->write(1);
00072     clk->write(0);
00073     wait_ms(10);
00074     
00075     for(i=0; i<10; i++)
00076     {
00077         clk->write(1);
00078         wait_ms(10);
00079         clk->write(0);
00080         wait_ms(10);
00081     }
00082 }
00083 
00084 void SHT11::init() 
00085 {
00086     connectionReset();
00087 }
00088 
00089 int SHT11::writeByte(unsigned char writeData)
00090 {
00091     unsigned char writeMask = 0x80;
00092     int ack = 0;
00093     
00094     // Ensure initial condition: clock low, data is an output
00095     clk->write(0);
00096     data->output();
00097     wait_ms(10);
00098     
00099     while(writeMask != 0)
00100     {
00101         if ((writeData & writeMask) != 0) {
00102             data->write(1);
00103             }
00104         else {
00105             data->write(0);
00106             }
00107         
00108         // delay for data to stabilize
00109         wait_ms(10);
00110         
00111         clk->write(1);
00112         wait_ms(10);
00113         clk->write(0);
00114         wait_ms(10);
00115         
00116         writeMask >>= 1;
00117     }
00118     
00119     // release the data line
00120     data->write(1);
00121     data->input();
00122     wait_ms(10);
00123     
00124     // 9th clock for ack, read the ack, return clk to low
00125     clk->write(1);
00126     wait_ms(10);   
00127     ack = data->read();
00128     clk->write(0);
00129     wait_ms(10);
00130     
00131     return((int)ack);   
00132 }
00133 
00134 void SHT11::softReset()
00135 {
00136     connectionReset();
00137     writeByte(RESET);
00138 }
00139 
00140 int SHT11::readByte(unsigned char *pReadData, bool doAck)
00141 {
00142     unsigned char retData = 0x00;
00143     unsigned char readMask = 0x80;
00144     int bitVal;
00145     
00146     // Ensure start conditions: clock low; data is input
00147     clk->write(0);
00148     data->write(1);
00149     data->input();
00150     wait_ms(10);
00151     
00152     while(readMask != 0)
00153     {
00154         clk->write(1);
00155         wait_ms(10);
00156         bitVal = data->read();
00157         if (bitVal != 0)
00158             retData |= readMask;
00159         clk->write(0);
00160         wait_ms(10);
00161         readMask >>= 1;
00162     }
00163     
00164     // If clocking out an ack; 
00165     if (doAck == true)
00166     {
00167         data->output();
00168         data->write(0);
00169     }
00170 
00171     wait_ms(10);
00172     clk->write(1);
00173     wait_ms(10);
00174     clk->write(0);
00175     data->input();
00176     
00177     *pReadData = retData;
00178     return 1;
00179 }
00180 
00181 int SHT11::readStatus(unsigned char *pRetStatus)
00182 {
00183     unsigned char retStatus, checksum;
00184     int retVal = -1;
00185     
00186     sendTransmissionStart();
00187     
00188     if (writeByte(STATUS_REG_R) == 0)
00189     {
00190         readByte(&retStatus, true);
00191         readByte(&checksum, false);
00192         *pRetStatus = retStatus;
00193         retVal = 0;
00194     }
00195     
00196     return retVal;
00197 }
00198     
00199 int SHT11::writeStatus(unsigned char writeValue)
00200 {
00201     int retVal = -1;
00202     
00203     sendTransmissionStart();
00204     
00205     if (writeByte(STATUS_REG_W) == 0)
00206     {
00207         writeByte(writeValue);
00208         retVal = 0;
00209     }
00210     
00211     return retVal;
00212 }
00213 
00214 int SHT11::measureTemp(unsigned short *pRetTempRaw)
00215 {
00216     int retVal = -1;
00217     unsigned int waitCount;
00218     union {
00219         unsigned short u16;
00220         unsigned char u8[2];
00221         } u;
00222     unsigned char checksum;
00223     
00224     sendTransmissionStart();
00225     
00226     retVal = writeByte(MEASURE_TEMP);
00227     
00228     if (retVal == 0)
00229     {
00230         data->input();
00231         waitCount = 65535; // UINT_MAX
00232         while(waitCount > 0)
00233         {
00234             if (data->read() == 0)
00235             {
00236                 break;
00237             }
00238             wait_ms(10);
00239             waitCount -= 1;
00240         }
00241     }
00242     else
00243     {
00244         return -1;
00245     }
00246     
00247     readByte(&(u.u8[1]), true);
00248     readByte(&(u.u8[0]), true);
00249     readByte(&checksum, false);
00250 
00251     *pRetTempRaw = u.u16;
00252     retVal = 0;
00253     
00254     return retVal;
00255 }
00256 
00257 int SHT11::measureHumid(unsigned short *pRetHumidRaw)
00258 {
00259     int retVal = -1;
00260     unsigned int waitCount;
00261     union {
00262         unsigned short u16;
00263         unsigned char u8[2];
00264         } u;
00265     unsigned char checksum;
00266     
00267     sendTransmissionStart();
00268     
00269     retVal = writeByte(MEASURE_HUMI);
00270     
00271     if (retVal == 0)
00272     {
00273         data->input();
00274         waitCount = 65535; // UINT_MAX;
00275         while(waitCount > 0)
00276         {
00277             if (data->read() == 0)
00278             {
00279                 break;
00280             }
00281             wait_ms(10);
00282             waitCount -= 1;
00283         }
00284     }
00285     else
00286     {
00287         return -1;
00288     }
00289     
00290     readByte(&(u.u8[1]), true);
00291     readByte(&(u.u8[0]), true);
00292     readByte(&checksum, false);
00293 
00294     *pRetHumidRaw = u.u16;
00295     retVal = 0;
00296     
00297     return retVal;
00298 }
00299 
00300 float SHT11::convertTempCelsius(unsigned short rawTempIn)
00301 {
00302     return ((((float)rawTempIn) * 0.010) - 40.0);
00303 }
00304 
00305 
00306 float SHT11::convertTempFahrenheit(unsigned short rawTempIn)
00307 {
00308     return ((((float)rawTempIn) * 0.018) - 40.0);
00309 }
00310 
00311 float SHT11::convertHumid(unsigned short rawHumidIn, unsigned short rawTempIn)
00312 {
00313     const float C1 = -4.0;
00314     const float C2 = 0.0405;
00315     const float C3 = -0.0000028;
00316     const float T1 = 0.01;
00317     const float T2 = 0.00008;
00318     
00319     float tempOut;
00320     float humidLinearOut;
00321     float humidOutTrue;
00322     
00323     tempOut = convertTempCelsius(rawTempIn);
00324     
00325     humidLinearOut = (float)rawHumidIn;
00326     humidLinearOut = (C3 * humidLinearOut * humidLinearOut) + (C2 * humidLinearOut) + C1;
00327     
00328     humidOutTrue = (tempOut - 25.0) * (T1 + T2 * ((float)rawHumidIn)) + humidLinearOut;
00329     
00330     humidOutTrue = ((humidOutTrue > 100.0) ? 100.0 : humidOutTrue);
00331     
00332     humidOutTrue = ((humidOutTrue < 0.0) ? 0.0 : humidOutTrue);
00333     
00334     return humidOutTrue;
00335 }
00336 
00337 int SHT11::getTemperature(float * pRetTemperature)
00338 {
00339   unsigned short rawValue;
00340   int retVal = -1;
00341     
00342   if (measureTemp(&rawValue) == 0) {
00343     lastTemperature = convertTempCelsius(rawValue);
00344     *pRetTemperature = lastTemperature;
00345     retVal = 0;
00346     }
00347 
00348   return retVal;
00349 }
00350 
00351 int SHT11::getTempHumid(float * pRetTemperature, float * pRetHumidity)
00352 {
00353   unsigned short rawTempValue;
00354   unsigned short rawHumidValue;
00355   int retVal = -1;
00356     
00357   if (measureTemp(&rawTempValue) == 0) {
00358     if (measureHumid(&rawHumidValue) == 0) {
00359       lastHumidity = convertHumid(rawHumidValue, rawTempValue);
00360       lastTemperature = convertTempCelsius(rawTempValue);
00361       *pRetHumidity = lastHumidity;
00362       *pRetTemperature = lastTemperature;
00363       retVal = 0;
00364       }
00365     }
00366 
00367   return retVal;
00368 }