Port of the SHT2x example code from Sensirion

Dependents:   sht21_test ENVLogger

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers SHT2x.cpp Source File

SHT2x.cpp

00001 /*
00002     Permission is hereby granted, free of charge, to any person obtaining a copy
00003     of this software and associated documentation files (the "Software"), to deal
00004     in the Software without restriction, including without limitation the rights
00005     to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
00006     copies of the Software, and to permit persons to whom the Software is
00007     furnished to do so, subject to the following conditions:
00008  
00009     The above copyright notice and this permission notice shall be included in
00010     all copies or substantial portions of the Software.
00011  
00012     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
00013     IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
00014     FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
00015     AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
00016     LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
00017     OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
00018     THE SOFTWARE.
00019 */
00020 
00021 //=============================================================================
00022 // Port of the SHT21 example code from Sensirion
00023 // port by Serge Sozonoff
00024 //=============================================================================
00025 
00026 #include "SHT2x.h"
00027 #include "mbed.h"
00028 
00029 SHT2x::SHT2x (PinName p_sda, PinName p_scl) : i2c(p_sda, p_scl)  {
00030 }
00031 
00032 //==============================================================================//
00033 int SHT2x::SHT2x_CheckCrc(int data[], int nbrOfBytes, int checksum)
00034 //==============================================================================//
00035 {
00036     int crc = 0;
00037     int byteCtr;
00038     //calculates 8-Bit checksum with given polynomial
00039     for (byteCtr = 0; byteCtr < nbrOfBytes; ++byteCtr) {
00040         crc ^= (data[byteCtr]);
00041         for (int bit = 8; bit > 0; --bit) {
00042             if (crc & 0x80) crc = (crc << 1) ^ POLYNOMIAL;
00043             else crc = (crc << 1);
00044         }
00045     }
00046     if (crc != checksum) return CHECKSUM_ERROR;
00047     else return 0;
00048 }
00049 
00050 //===========================================================================//
00051 int SHT2x::i2cWrite(int data)
00052 //===========================================================================//
00053 {
00054     if (i2c.write(data) < 1) return ACK_ERROR;
00055     else return 0;
00056 }
00057 
00058 //===========================================================================//
00059 int SHT2x::SHT2x_ReadUserRegister(int *pRegisterValue)
00060 //===========================================================================//
00061 {
00062     int checksum;   //variable for checksum byte
00063     int error=0;    //variable for error code
00064 
00065     i2c.start();
00066     error |= i2cWrite(I2C_ADR_W);
00067     error |= i2cWrite(USER_REG_R);
00068 
00069     i2c.start();
00070     error |= i2cWrite(I2C_ADR_R);
00071 
00072 
00073     *pRegisterValue = i2c.read(ACK);
00074 
00075     checksum=i2c.read(NoACK);
00076 
00077     error |= SHT2x_CheckCrc (pRegisterValue,1,checksum);
00078 
00079     i2c.stop();
00080     return error;
00081 }
00082 //===========================================================================//
00083 int SHT2x::SHT2x_WriteUserRegister(int *pRegisterValue)
00084 //===========================================================================//
00085 {
00086     int error=0;   //variable for error code
00087     i2c.start();
00088 
00089     error |= i2cWrite(I2C_ADR_W);
00090     error |= i2cWrite(USER_REG_W);
00091     error |= i2cWrite(*pRegisterValue);
00092     i2c.stop();
00093 
00094     return error;
00095 }
00096 //===========================================================================//
00097 int SHT2x::SHT2x_MeasureHM(etSHT2xMeasureType eSHT2xMeasureType, int *pMeasurand)
00098 //===========================================================================//
00099 {
00100     int  checksum;   //checksum
00101     int  data[2];    //data array for checksum verification
00102     int  error=0;    //error variable
00103     int i;
00104 
00105     //-- write I2C sensor address and command --
00106     i2c.start();
00107 
00108     error |= i2cWrite(I2C_ADR_W); // I2C Adr
00109     switch (eSHT2xMeasureType) {
00110         case HUMIDITY:
00111             error |= i2cWrite(TRIG_RH_MEASUREMENT_HM);
00112             break;
00113         case TEMP:
00114             error |= i2cWrite(TRIG_T_MEASUREMENT_HM);
00115             break;
00116         default:
00117             break;
00118     }
00119 
00120     //-- wait until hold master is released --
00121     i2c.start();
00122 
00123     __disable_irq();     // Disable Interrupts
00124 
00125     error |= i2cWrite(I2C_ADR_R);
00126 
00127     //SCL=HIGH;                     // set SCL I/O port as input
00128     i2c.sclAsInput();
00129 
00130     for (i=0; i<1000; i++) {      // wait until master hold is released or
00131         wait_ms(1);    // a timeout (~1s) is reached
00132         if (i2c.sclRead() == 1) break;
00133     }
00134 
00135     //-- check for timeout --
00136     if (i2c.sclRead() == 0) error |= TIME_OUT_ERROR;
00137     //-- read two data bytes and one checksum byte --
00138 
00139     i2c.sclNormal();
00140 
00141     data[0] = i2c.read(ACK);
00142     data[1] = i2c.read(ACK);
00143 
00144     *pMeasurand = data[0] << 8;
00145     *pMeasurand |= data[1];
00146 
00147     checksum = i2c.read(NoACK);
00148 
00149     __enable_irq();     // Enable Interrupts
00150 
00151     //-- verify checksum --
00152     error |= SHT2x_CheckCrc (data, 2, checksum);
00153 
00154     i2c.stop();
00155     return error;
00156 }
00157 //===========================================================================//
00158 int SHT2x::SHT2x_MeasurePoll(etSHT2xMeasureType eSHT2xMeasureType, int *pMeasurand)
00159 //===========================================================================//
00160 {
00161     int  checksum;   //checksum
00162     int  data[2];    //data array for checksum verification
00163     int  error = 0;    //error variable
00164     int i = 0;        //counting variableSample Code SHT21
00165 
00166     //-- write I2C sensor address and command --
00167     i2c.start();
00168 
00169     error |= i2cWrite(I2C_ADR_W);
00170     switch (eSHT2xMeasureType) {
00171         case HUMIDITY:
00172             error |= i2cWrite(TRIG_RH_MEASUREMENT_POLL);
00173             break;
00174         case TEMP:
00175             error |= i2cWrite(TRIG_T_MEASUREMENT_POLL);
00176             break;
00177         default:
00178             break;
00179 
00180     }
00181     //-- poll every 10ms for measurement ready. Timeout after 20 retries (200ms)--
00182     do {
00183         i2c.start();
00184         wait_ms(10);
00185         if (i++ >= 20) break;
00186     } while (i2c.write(I2C_ADR_R) == 0);
00187 
00188     if (i >= 20) error |= TIME_OUT_ERROR;
00189 
00190     //-- read two data bytes and one checksum byte --
00191     data[0] = i2c.read(ACK);
00192     data[1] = i2c.read(ACK);
00193 
00194     *pMeasurand = data[0] << 8;
00195     *pMeasurand |= data[1];
00196 
00197     checksum = i2c.read(NoACK);
00198     //-- verify checksum --
00199     error |= SHT2x_CheckCrc (data,2,checksum);
00200     i2c.stop();
00201     return error;
00202 }
00203 //===========================================================================//
00204 int SHT2x::SHT2x_SoftReset()
00205 //===========================================================================//
00206 {
00207     int  error=0;           //error variable
00208     i2c.start();
00209     error |= i2cWrite(I2C_ADR_W); // I2C Adr
00210     error |= i2cWrite(SOFT_RESET);                            // Command
00211     i2c.stop();
00212     wait_ms(15);
00213     return error;
00214 }
00215 //==============================================================================//
00216 float SHT2x::SHT2x_CalcRH(int u16sRH)
00217 //==============================================================================//
00218 {
00219     float humidityRH;              // variable for result
00220     u16sRH &= ~0x0003;          // clear bits [1..0] (status bits)
00221     //-- calculate relative humidity [%RH] --
00222     humidityRH = -6.0 + 125.0/65536 * (float)u16sRH; // RH= -6 + 125 * SRH/2^16
00223     return humidityRH;
00224 }
00225 //==============================================================================//
00226 float SHT2x::SHT2x_CalcTemperatureC(int u16sT)
00227 //==============================================================================//
00228 {
00229     float temperatureC;            // variable for result
00230     u16sT &= ~0x0003;           // clear bits [1..0] (status bits)
00231     //-- calculate temperature [in degrees C] --
00232     temperatureC= -46.85 + 175.72/65536 *(float)u16sT; //T= -46.85 + 175.72 * ST/2^16
00233     return temperatureC;
00234 }
00235 
00236 //==============================================================================//
00237 float SHT2x::SHT2x_GetDewpoint(float h, float t)
00238 //==============================================================================//
00239 {
00240     float logEx, dew_point;
00241     logEx = 0.66077 + 7.5 * t / (237.3 + t) + (log10(h) - 2);
00242     dew_point = (logEx - 0.66077) * 237.3 / (0.66077 + 7.5 - logEx);
00243     return dew_point;
00244 }
00245 
00246 //==============================================================================//
00247 int SHT2x::SHT2x_GetSerialNumber(int u8SerialNumber[])
00248 //==============================================================================//
00249 {
00250     int  error=0;                          //error variable
00251     //Read from memory location 1
00252     i2c.start();
00253     error |= i2cWrite(I2C_ADR_W);
00254     error |= i2cWrite(0xFA);         //Command for readout on-chip memory
00255     error |= i2cWrite(0x0F);         //on-chip memory address
00256     i2c.start();
00257     error |= i2cWrite(I2C_ADR_R);    //I2C address
00258     u8SerialNumber[5] = i2c.read(ACK); //Read SNB_3
00259     i2c.read(ACK);                     //Read CRC SNB_3 (CRC is not analyzed)
00260     u8SerialNumber[4] = i2c.read(ACK); //Read SNB_2
00261     i2c.read(ACK);                     //Read CRC SNB_2 (CRC is not analyzed)
00262     u8SerialNumber[3] = i2c.read(ACK); //Read SNB_1Sample Code SHT21
00263     i2c.read(ACK);                     //Read CRC SNB_1 (CRC is not analyzed)
00264     u8SerialNumber[2] = i2c.read(ACK); //Read SNB_0
00265     i2c.read(NoACK);                  //Read CRC SNB_0 (CRC is not analyzed)
00266     i2c.stop();
00267     //Read from memory location 2
00268     i2c.start();
00269     error |= i2cWrite(I2C_ADR_W);    //I2C address
00270     error |= i2cWrite(0xFC);         //Command for readout on-chip memory
00271     error |= i2cWrite(0xC9);         //on-chip memory address
00272     i2c.start();
00273     error |= i2cWrite(I2C_ADR_R);    //I2C address
00274     u8SerialNumber[1] = i2c.read(ACK); //Read SNC_1
00275     u8SerialNumber[0] = i2c.read(ACK); //Read SNC_0
00276     i2c.read(ACK);
00277     u8SerialNumber[7] = i2c.read(ACK); //Read SNA_1
00278     u8SerialNumber[6] = i2c.read(ACK); //Read SNA_0
00279     i2c.read(NoACK);                  //Read CRC SNA0/1 (CRC is not analyzed)
00280     i2c.stop();
00281     return error;
00282 }