![](/media/cache/img/default_profile.jpg.50x50_q85.jpg)
embernet project fire detection system sensor test
Dependencies: mbed CCS811 BME280
Adafruit_SGP30.cpp
00001 /*! 00002 * @file Adafruit_SGP30.cpp 00003 * 00004 * @mainpage Adafruit SGP30 gas sensor driver 00005 * 00006 * @section intro_sec Introduction 00007 * 00008 * This is the documentation for Adafruit's SGP30 driver for the 00009 * Arduino platform. It is designed specifically to work with the 00010 * Adafruit SGP30 breakout: http://www.adafruit.com/products/3709 00011 * 00012 * These sensors use I2C to communicate, 2 pins (SCL+SDA) are required 00013 * to interface with the breakout. 00014 * 00015 * Adafruit invests time and resources providing this open source code, 00016 * please support Adafruit and open-source hardware by purchasing 00017 * products from Adafruit! 00018 * 00019 * 00020 * @section author Author 00021 * Written by Ladyada for Adafruit Industries. 00022 * 00023 * @section license License 00024 * BSD license, all text here must be included in any redistribution. 00025 * 00026 */ 00027 00028 #include "mbed.h" 00029 #include "Adafruit_SGP30.h " 00030 00031 //#define I2C_DEBUG 1 00032 00033 /**************************************************************************/ 00034 /*! 00035 @brief Instantiates a new SGP30 class 00036 */ 00037 /**************************************************************************/ 00038 Adafruit_SGP30::Adafruit_SGP30(PinName sda, PinName scl) : _i2c(sda, scl) { 00039 } 00040 00041 /**************************************************************************/ 00042 /*! 00043 @brief Setups the hardware and detects a valid SGP30. Initializes I2C 00044 then reads the serialnumber and checks that we are talking to an SGP30 00045 @param theWire Optional pointer to I2C interface, otherwise use Wire 00046 @returns True if SGP30 found on I2C, False if something went wrong! 00047 */ 00048 /**************************************************************************/ 00049 bool Adafruit_SGP30::begin() { 00050 //Mbed use 8bit addr 00051 _i2caddr = SGP30_I2CADDR_DEFAULT << 1; 00052 00053 uint8_t command[3]; 00054 command[0] = 0x36; 00055 command[1] = 0x82; 00056 command[2] = 0x0; 00057 if (! readWordFromCommand(command, 2, 5, serialnumber, 3)) 00058 return false; 00059 00060 uint16_t featureset; 00061 command[0] = 0x20; 00062 command[1] = 0x2F; 00063 if (! readWordFromCommand(command, 2, 10, &featureset, 1)) 00064 return false; 00065 //Serial.print("Featureset 0x"); Serial.println(featureset, HEX); 00066 if (featureset != SGP30_FEATURESET) 00067 return false; 00068 if (! IAQinit()) 00069 return false; 00070 00071 return true; 00072 } 00073 00074 /**************************************************************************/ 00075 /*! 00076 @brief Commands the sensor to begin the IAQ algorithm. Must be called after startup. 00077 @returns True if command completed successfully, false if something went wrong! 00078 */ 00079 /**************************************************************************/ 00080 bool Adafruit_SGP30::IAQinit(void) { 00081 uint8_t command[2]; 00082 command[0] = 0x20; 00083 command[1] = 0x03; 00084 return readWordFromCommand(command, 2, 10); 00085 } 00086 00087 /**************************************************************************/ 00088 /*! 00089 @brief Commands the sensor to take a single eCO2/VOC measurement. Places results in {@link TVOC} and {@link eCO2} 00090 @returns True if command completed successfully, false if something went wrong! 00091 */ 00092 /**************************************************************************/ 00093 bool Adafruit_SGP30::IAQmeasure(void) { 00094 uint8_t command[2]; 00095 command[0] = 0x20; 00096 command[1] = 0x08; 00097 uint16_t reply[2]; 00098 if (! readWordFromCommand(command, 2, 12, reply, 2)) 00099 return false; 00100 TVOC = reply[1]; 00101 eCO2 = reply[0]; 00102 return true; 00103 } 00104 00105 /**************************************************************************/ 00106 /*! 00107 @brief Request baseline calibration values for both CO2 and TVOC IAQ calculations. Places results in parameter memory locaitons. 00108 @param eco2_base A pointer to a uint16_t which we will save the calibration value to 00109 @param tvoc_base A pointer to a uint16_t which we will save the calibration value to 00110 @returns True if command completed successfully, false if something went wrong! 00111 */ 00112 /**************************************************************************/ 00113 bool Adafruit_SGP30::getIAQBaseline(uint16_t *eco2_base, uint16_t *tvoc_base) { 00114 uint8_t command[2]; 00115 command[0] = 0x20; 00116 command[1] = 0x15; 00117 uint16_t reply[2]; 00118 if (! readWordFromCommand(command, 2, 10, reply, 2)) 00119 return false; 00120 *eco2_base = reply[0]; 00121 *tvoc_base = reply[1]; 00122 return true; 00123 } 00124 00125 bool Adafruit_SGP30::getIAQRaw(uint16_t *H2_raw, uint16_t *Eth_raw) { 00126 uint8_t command[2]; 00127 command[0] = 0x20; 00128 command[1] = 0x50; 00129 uint16_t reply[2]; 00130 if (! readWordFromCommand(command, 2, 40, reply, 2)) 00131 return false; 00132 *H2_raw = reply[0]; 00133 *Eth_raw = reply[1]; 00134 return true; 00135 } 00136 00137 /**************************************************************************/ 00138 /*! 00139 @brief Assign baseline calibration values for both CO2 and TVOC IAQ calculations. 00140 @param eco2_base A uint16_t which we will save the calibration value from 00141 @param tvoc_base A uint16_t which we will save the calibration value from 00142 @returns True if command completed successfully, false if something went wrong! 00143 */ 00144 /**************************************************************************/ 00145 bool Adafruit_SGP30::setIAQBaseline(uint16_t eco2_base, uint16_t tvoc_base) { 00146 uint8_t command[8]; 00147 command[0] = 0x20; 00148 command[1] = 0x1e; 00149 command[2] = tvoc_base >> 8; 00150 command[3] = tvoc_base & 0xFF; 00151 command[4] = generateCRC(command+2, 2); 00152 command[5] = eco2_base >> 8; 00153 command[6] = eco2_base & 0xFF; 00154 command[7] = generateCRC(command+5, 2); 00155 00156 return readWordFromCommand(command, 8, 10); 00157 } 00158 00159 /**************************************************************************/ 00160 /*! 00161 @brief I2C low level interfacing 00162 */ 00163 /**************************************************************************/ 00164 00165 00166 bool Adafruit_SGP30::readWordFromCommand(uint8_t command[], uint8_t commandLength, uint16_t delayms, uint16_t *readdata, uint8_t readlen) 00167 { 00168 uint8_t retval; 00169 00170 00171 #ifdef I2C_DEBUG 00172 printf("\t\t-> "); 00173 #endif 00174 00175 retval = _i2c.write((int)_i2caddr, (const char*)command, (int)commandLength); 00176 //0=OK, 1=Fail https://os.mbed.com/docs/v5.9/reference/i2c.html 00177 if ( retval != 0) 00178 return false; 00179 00180 #ifdef I2C_DEBUG 00181 for (uint8_t i=0; i<commandLength; i++) { 00182 printf("0x"); 00183 printf("%x", command[i]); 00184 printf(", "); 00185 } 00186 #endif 00187 00188 #ifdef I2C_DEBUG 00189 printf("\n"); 00190 #endif 00191 00192 wait_ms(delayms); 00193 00194 00195 00196 if (readlen == 0) 00197 return true; 00198 00199 uint8_t replylen = readlen * (SGP30_WORD_LEN +1); 00200 uint8_t replybuffer[replylen]; 00201 00202 retval = _i2c.read((int)_i2caddr, (char*)replybuffer, (int)replylen); 00203 00204 //0=OK, 1=Fail https://os.mbed.com/docs/v5.9/reference/i2c.html 00205 if ( retval != 0) 00206 return false; 00207 00208 #ifdef I2C_DEBUG 00209 printf("\t\t<- "); 00210 for (uint8_t i=0; i<replylen; i++) { 00211 printf("0x"); 00212 printf("%x", replybuffer[i]); 00213 printf(", "); 00214 } 00215 #endif 00216 00217 00218 #ifdef I2C_DEBUG 00219 printf("\n"); 00220 #endif 00221 00222 for (uint8_t i=0; i<readlen; i++) { 00223 uint8_t crc = generateCRC(replybuffer+i*3, 2); 00224 #ifdef I2C_DEBUG 00225 printf("\t\tCRC calced: 0x"); 00226 printf("%x", crc); 00227 printf(" vs. 0x"); 00228 printf("%x\n" ,replybuffer[i * 3 + 2]; 00229 #endif 00230 if (crc != replybuffer[i * 3 + 2]) 00231 return false; 00232 // success! store it 00233 readdata[i] = replybuffer[i*3]; 00234 readdata[i] <<= 8; 00235 readdata[i] |= replybuffer[i*3 + 1]; 00236 #ifdef I2C_DEBUG 00237 printf("\t\tRead: 0x"); 00238 printf("%x\n", readdata[i]); 00239 #endif 00240 } 00241 return true; 00242 } 00243 00244 uint8_t Adafruit_SGP30::generateCRC(uint8_t *data, uint8_t datalen) { 00245 // calculates 8-Bit checksum with given polynomial 00246 uint8_t crc = SGP30_CRC8_INIT; 00247 00248 for (uint8_t i=0; i<datalen; i++) { 00249 crc ^= data[i]; 00250 for (uint8_t b=0; b<8; b++) { 00251 if (crc & 0x80) 00252 crc = (crc << 1) ^ SGP30_CRC8_POLYNOMIAL; 00253 else 00254 crc <<= 1; 00255 } 00256 } 00257 return crc; 00258 }
Generated on Tue Aug 2 2022 21:02:21 by
![doxygen](doxygen.png)