Library for Sensirion Environmental Sensor Shield for SGP30 & SHTC1
Dependents: example-sensirion-ublox-c030
sensirion_ess.cpp@0:3e97001a43f8, 2018-12-21 (annotated)
- Committer:
- Haseeb Khalid
- Date:
- Fri Dec 21 17:24:52 2018 +0500
- Revision:
- 0:3e97001a43f8
Sensirion-ess library
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
Haseeb Khalid |
0:3e97001a43f8 | 1 | /* |
Haseeb Khalid |
0:3e97001a43f8 | 2 | * Copyright (c) 2017-2018, Sensirion AG |
Haseeb Khalid |
0:3e97001a43f8 | 3 | * All rights reserved. |
Haseeb Khalid |
0:3e97001a43f8 | 4 | * |
Haseeb Khalid |
0:3e97001a43f8 | 5 | * Redistribution and use in source and binary forms, with or without |
Haseeb Khalid |
0:3e97001a43f8 | 6 | * modification, are permitted provided that the following conditions are met: |
Haseeb Khalid |
0:3e97001a43f8 | 7 | * |
Haseeb Khalid |
0:3e97001a43f8 | 8 | * * Redistributions of source code must retain the above copyright notice, this |
Haseeb Khalid |
0:3e97001a43f8 | 9 | * list of conditions and the following disclaimer. |
Haseeb Khalid |
0:3e97001a43f8 | 10 | * |
Haseeb Khalid |
0:3e97001a43f8 | 11 | * * Redistributions in binary form must reproduce the above copyright notice, |
Haseeb Khalid |
0:3e97001a43f8 | 12 | * this list of conditions and the following disclaimer in the documentation |
Haseeb Khalid |
0:3e97001a43f8 | 13 | * and/or other materials provided with the distribution. |
Haseeb Khalid |
0:3e97001a43f8 | 14 | * |
Haseeb Khalid |
0:3e97001a43f8 | 15 | * * Neither the name of Sensirion AG nor the names of its |
Haseeb Khalid |
0:3e97001a43f8 | 16 | * contributors may be used to endorse or promote products derived from |
Haseeb Khalid |
0:3e97001a43f8 | 17 | * this software without specific prior written permission. |
Haseeb Khalid |
0:3e97001a43f8 | 18 | * |
Haseeb Khalid |
0:3e97001a43f8 | 19 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" |
Haseeb Khalid |
0:3e97001a43f8 | 20 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
Haseeb Khalid |
0:3e97001a43f8 | 21 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE |
Haseeb Khalid |
0:3e97001a43f8 | 22 | * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE |
Haseeb Khalid |
0:3e97001a43f8 | 23 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
Haseeb Khalid |
0:3e97001a43f8 | 24 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR |
Haseeb Khalid |
0:3e97001a43f8 | 25 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER |
Haseeb Khalid |
0:3e97001a43f8 | 26 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, |
Haseeb Khalid |
0:3e97001a43f8 | 27 | * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
Haseeb Khalid |
0:3e97001a43f8 | 28 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
Haseeb Khalid |
0:3e97001a43f8 | 29 | */ |
Haseeb Khalid |
0:3e97001a43f8 | 30 | |
Haseeb Khalid |
0:3e97001a43f8 | 31 | /* |
Haseeb Khalid |
0:3e97001a43f8 | 32 | * TODO: |
Haseeb Khalid |
0:3e97001a43f8 | 33 | * - Baseline store/restore |
Haseeb Khalid |
0:3e97001a43f8 | 34 | * - proper init |
Haseeb Khalid |
0:3e97001a43f8 | 35 | * - IAQ levels, getIAQLevel() |
Haseeb Khalid |
0:3e97001a43f8 | 36 | */ |
Haseeb Khalid |
0:3e97001a43f8 | 37 | |
Haseeb Khalid |
0:3e97001a43f8 | 38 | |
Haseeb Khalid |
0:3e97001a43f8 | 39 | |
Haseeb Khalid |
0:3e97001a43f8 | 40 | #include <string.h> |
Haseeb Khalid |
0:3e97001a43f8 | 41 | |
Haseeb Khalid |
0:3e97001a43f8 | 42 | #include "sensirion_ess.h" |
Haseeb Khalid |
0:3e97001a43f8 | 43 | DigitalOut led_red(LED_RED); |
Haseeb Khalid |
0:3e97001a43f8 | 44 | DigitalOut led_yellow(LED_YEL); |
Haseeb Khalid |
0:3e97001a43f8 | 45 | DigitalOut led_green(LED_GRN); |
Haseeb Khalid |
0:3e97001a43f8 | 46 | |
Haseeb Khalid |
0:3e97001a43f8 | 47 | SensirionESS::SensirionESS(void *interface) |
Haseeb Khalid |
0:3e97001a43f8 | 48 | { |
Haseeb Khalid |
0:3e97001a43f8 | 49 | i2c_connection = (I2C*)(interface); |
Haseeb Khalid |
0:3e97001a43f8 | 50 | t = new Timer(); |
Haseeb Khalid |
0:3e97001a43f8 | 51 | } |
Haseeb Khalid |
0:3e97001a43f8 | 52 | |
Haseeb Khalid |
0:3e97001a43f8 | 53 | int SensirionESS::initSensors() |
Haseeb Khalid |
0:3e97001a43f8 | 54 | { |
Haseeb Khalid |
0:3e97001a43f8 | 55 | |
Haseeb Khalid |
0:3e97001a43f8 | 56 | if (measureRHTInt() != 0) { |
Haseeb Khalid |
0:3e97001a43f8 | 57 | setError("Error communicating with SHTC1"); |
Haseeb Khalid |
0:3e97001a43f8 | 58 | return -1; |
Haseeb Khalid |
0:3e97001a43f8 | 59 | } |
Haseeb Khalid |
0:3e97001a43f8 | 60 | |
Haseeb Khalid |
0:3e97001a43f8 | 61 | if (initSGP() != 0) { |
Haseeb Khalid |
0:3e97001a43f8 | 62 | setError("Error communicating with SGPC3"); |
Haseeb Khalid |
0:3e97001a43f8 | 63 | return -2; |
Haseeb Khalid |
0:3e97001a43f8 | 64 | } |
Haseeb Khalid |
0:3e97001a43f8 | 65 | |
Haseeb Khalid |
0:3e97001a43f8 | 66 | t->start(); |
Haseeb Khalid |
0:3e97001a43f8 | 67 | |
Haseeb Khalid |
0:3e97001a43f8 | 68 | mInitialized = true; |
Haseeb Khalid |
0:3e97001a43f8 | 69 | return 0; |
Haseeb Khalid |
0:3e97001a43f8 | 70 | } |
Haseeb Khalid |
0:3e97001a43f8 | 71 | |
Haseeb Khalid |
0:3e97001a43f8 | 72 | ////////////////////////////////////////////////////////////////////////////// |
Haseeb Khalid |
0:3e97001a43f8 | 73 | // SHT |
Haseeb Khalid |
0:3e97001a43f8 | 74 | |
Haseeb Khalid |
0:3e97001a43f8 | 75 | int SensirionESS::measureRHT() |
Haseeb Khalid |
0:3e97001a43f8 | 76 | { |
Haseeb Khalid |
0:3e97001a43f8 | 77 | if (!mInitialized) { |
Haseeb Khalid |
0:3e97001a43f8 | 78 | setError("ESS not initialized"); |
Haseeb Khalid |
0:3e97001a43f8 | 79 | return -1; |
Haseeb Khalid |
0:3e97001a43f8 | 80 | } |
Haseeb Khalid |
0:3e97001a43f8 | 81 | |
Haseeb Khalid |
0:3e97001a43f8 | 82 | measureRHTInt(); |
Haseeb Khalid |
0:3e97001a43f8 | 83 | return 0; |
Haseeb Khalid |
0:3e97001a43f8 | 84 | } |
Haseeb Khalid |
0:3e97001a43f8 | 85 | |
Haseeb Khalid |
0:3e97001a43f8 | 86 | int SensirionESS::measureRHTInt() |
Haseeb Khalid |
0:3e97001a43f8 | 87 | { |
Haseeb Khalid |
0:3e97001a43f8 | 88 | uint8_t cmd[CMD_LENGTH] = { 0x7C, 0xA2 }; |
Haseeb Khalid |
0:3e97001a43f8 | 89 | |
Haseeb Khalid |
0:3e97001a43f8 | 90 | if (i2c_write(SHT_I2C_ADDR, cmd, CMD_LENGTH)) { |
Haseeb Khalid |
0:3e97001a43f8 | 91 | setError("I2C write error"); |
Haseeb Khalid |
0:3e97001a43f8 | 92 | return -1; |
Haseeb Khalid |
0:3e97001a43f8 | 93 | } |
Haseeb Khalid |
0:3e97001a43f8 | 94 | |
Haseeb Khalid |
0:3e97001a43f8 | 95 | wait_ms(SHT_MEASURE_DELAY); |
Haseeb Khalid |
0:3e97001a43f8 | 96 | |
Haseeb Khalid |
0:3e97001a43f8 | 97 | int ret = i2c_read(SHT_I2C_ADDR, mDataBuf, SHT_DATA_LENGTH); |
Haseeb Khalid |
0:3e97001a43f8 | 98 | if (ret == -1) { |
Haseeb Khalid |
0:3e97001a43f8 | 99 | setError("I2C read error"); |
Haseeb Khalid |
0:3e97001a43f8 | 100 | return -2; |
Haseeb Khalid |
0:3e97001a43f8 | 101 | } |
Haseeb Khalid |
0:3e97001a43f8 | 102 | |
Haseeb Khalid |
0:3e97001a43f8 | 103 | // check CRC for both RH and T |
Haseeb Khalid |
0:3e97001a43f8 | 104 | if (crc8(mDataBuf+0, 2) != mDataBuf[2] || |
Haseeb Khalid |
0:3e97001a43f8 | 105 | crc8(mDataBuf+3, 2) != mDataBuf[5]) { |
Haseeb Khalid |
0:3e97001a43f8 | 106 | setError("CRC mismatch"); |
Haseeb Khalid |
0:3e97001a43f8 | 107 | return -3; |
Haseeb Khalid |
0:3e97001a43f8 | 108 | } |
Haseeb Khalid |
0:3e97001a43f8 | 109 | |
Haseeb Khalid |
0:3e97001a43f8 | 110 | uint16_t val; |
Haseeb Khalid |
0:3e97001a43f8 | 111 | val = (mDataBuf[0] << 8) + mDataBuf[1]; |
Haseeb Khalid |
0:3e97001a43f8 | 112 | mTemperature = -45 + 175 * (val / 65535.0); |
Haseeb Khalid |
0:3e97001a43f8 | 113 | val = (mDataBuf[3] << 8) + mDataBuf[4]; |
Haseeb Khalid |
0:3e97001a43f8 | 114 | mHumidity = 100 * (val / 65535.0); |
Haseeb Khalid |
0:3e97001a43f8 | 115 | |
Haseeb Khalid |
0:3e97001a43f8 | 116 | return 0; |
Haseeb Khalid |
0:3e97001a43f8 | 117 | } |
Haseeb Khalid |
0:3e97001a43f8 | 118 | |
Haseeb Khalid |
0:3e97001a43f8 | 119 | ////////////////////////////////////////////////////////////////////////////// |
Haseeb Khalid |
0:3e97001a43f8 | 120 | // SGP |
Haseeb Khalid |
0:3e97001a43f8 | 121 | |
Haseeb Khalid |
0:3e97001a43f8 | 122 | int SensirionESS::getProductType() const |
Haseeb Khalid |
0:3e97001a43f8 | 123 | { |
Haseeb Khalid |
0:3e97001a43f8 | 124 | return mProductType; |
Haseeb Khalid |
0:3e97001a43f8 | 125 | } |
Haseeb Khalid |
0:3e97001a43f8 | 126 | |
Haseeb Khalid |
0:3e97001a43f8 | 127 | int SensirionESS::getFeatureSetVersion() const |
Haseeb Khalid |
0:3e97001a43f8 | 128 | { |
Haseeb Khalid |
0:3e97001a43f8 | 129 | return mFeatureSetVersion; |
Haseeb Khalid |
0:3e97001a43f8 | 130 | } |
Haseeb Khalid |
0:3e97001a43f8 | 131 | |
Haseeb Khalid |
0:3e97001a43f8 | 132 | int SensirionESS::measureIAQ() |
Haseeb Khalid |
0:3e97001a43f8 | 133 | { |
Haseeb Khalid |
0:3e97001a43f8 | 134 | if (!mInitialized) { |
Haseeb Khalid |
0:3e97001a43f8 | 135 | setError("ESS not initialized"); |
Haseeb Khalid |
0:3e97001a43f8 | 136 | return -1; |
Haseeb Khalid |
0:3e97001a43f8 | 137 | } |
Haseeb Khalid |
0:3e97001a43f8 | 138 | |
Haseeb Khalid |
0:3e97001a43f8 | 139 | // keep track of timing |
Haseeb Khalid |
0:3e97001a43f8 | 140 | mSGPMeasurementTimestamp = t->read_ms(); |
Haseeb Khalid |
0:3e97001a43f8 | 141 | |
Haseeb Khalid |
0:3e97001a43f8 | 142 | uint8_t cmd[CMD_LENGTH] = { 0x20, 0x08 }; |
Haseeb Khalid |
0:3e97001a43f8 | 143 | |
Haseeb Khalid |
0:3e97001a43f8 | 144 | if (i2c_write(SGP_I2C_ADDR, cmd, CMD_LENGTH)) { |
Haseeb Khalid |
0:3e97001a43f8 | 145 | setError("error in i2c_write"); |
Haseeb Khalid |
0:3e97001a43f8 | 146 | return -1; |
Haseeb Khalid |
0:3e97001a43f8 | 147 | } |
Haseeb Khalid |
0:3e97001a43f8 | 148 | |
Haseeb Khalid |
0:3e97001a43f8 | 149 | wait_ms(SGP_MEASURE_DELAY); |
Haseeb Khalid |
0:3e97001a43f8 | 150 | |
Haseeb Khalid |
0:3e97001a43f8 | 151 | int ret = i2c_read(SGP_I2C_ADDR, mDataBuf, SGP_DATA_LENGTH); |
Haseeb Khalid |
0:3e97001a43f8 | 152 | if (ret == -1) { |
Haseeb Khalid |
0:3e97001a43f8 | 153 | setError("error in i2c_read"); |
Haseeb Khalid |
0:3e97001a43f8 | 154 | return -2; |
Haseeb Khalid |
0:3e97001a43f8 | 155 | } |
Haseeb Khalid |
0:3e97001a43f8 | 156 | |
Haseeb Khalid |
0:3e97001a43f8 | 157 | if (crc8(mDataBuf, 2) != mDataBuf[2]) { |
Haseeb Khalid |
0:3e97001a43f8 | 158 | setError("CRC mismatch"); |
Haseeb Khalid |
0:3e97001a43f8 | 159 | return -3; |
Haseeb Khalid |
0:3e97001a43f8 | 160 | } |
Haseeb Khalid |
0:3e97001a43f8 | 161 | |
Haseeb Khalid |
0:3e97001a43f8 | 162 | // SGPC3 only has TVOC; SGP30 sends [eco2, tvoc] |
Haseeb Khalid |
0:3e97001a43f8 | 163 | if (mProductType == PRODUCT_TYPE_SGP30) { |
Haseeb Khalid |
0:3e97001a43f8 | 164 | mECO2 = (mDataBuf[0] << 8) | mDataBuf[1]; |
Haseeb Khalid |
0:3e97001a43f8 | 165 | if (crc8(mDataBuf+3, 2) != mDataBuf[5]) { |
Haseeb Khalid |
0:3e97001a43f8 | 166 | setError("CRC mismatch"); |
Haseeb Khalid |
0:3e97001a43f8 | 167 | return -4; |
Haseeb Khalid |
0:3e97001a43f8 | 168 | } |
Haseeb Khalid |
0:3e97001a43f8 | 169 | mTVOC = (mDataBuf[3] << 8) | mDataBuf[4]; |
Haseeb Khalid |
0:3e97001a43f8 | 170 | } else { |
Haseeb Khalid |
0:3e97001a43f8 | 171 | mTVOC = (mDataBuf[0] << 8) | mDataBuf[1];; |
Haseeb Khalid |
0:3e97001a43f8 | 172 | } |
Haseeb Khalid |
0:3e97001a43f8 | 173 | |
Haseeb Khalid |
0:3e97001a43f8 | 174 | return 0; |
Haseeb Khalid |
0:3e97001a43f8 | 175 | } |
Haseeb Khalid |
0:3e97001a43f8 | 176 | |
Haseeb Khalid |
0:3e97001a43f8 | 177 | int SensirionESS::readFeatureSetInt() |
Haseeb Khalid |
0:3e97001a43f8 | 178 | { |
Haseeb Khalid |
0:3e97001a43f8 | 179 | uint8_t cmd[CMD_LENGTH] = { 0x20, 0x2f }; |
Haseeb Khalid |
0:3e97001a43f8 | 180 | |
Haseeb Khalid |
0:3e97001a43f8 | 181 | if (i2c_write(SGP_I2C_ADDR, cmd, CMD_LENGTH)) { |
Haseeb Khalid |
0:3e97001a43f8 | 182 | setError("error in i2c_write"); |
Haseeb Khalid |
0:3e97001a43f8 | 183 | return -1; |
Haseeb Khalid |
0:3e97001a43f8 | 184 | } |
Haseeb Khalid |
0:3e97001a43f8 | 185 | |
Haseeb Khalid |
0:3e97001a43f8 | 186 | wait_ms(2); |
Haseeb Khalid |
0:3e97001a43f8 | 187 | |
Haseeb Khalid |
0:3e97001a43f8 | 188 | const uint8_t DATA_LEN = 3; |
Haseeb Khalid |
0:3e97001a43f8 | 189 | uint8_t data[DATA_LEN] = { 0 }; |
Haseeb Khalid |
0:3e97001a43f8 | 190 | int ret = i2c_read(SGP_I2C_ADDR, data, DATA_LEN); |
Haseeb Khalid |
0:3e97001a43f8 | 191 | if (ret == -1) { |
Haseeb Khalid |
0:3e97001a43f8 | 192 | setError("I2C read error"); |
Haseeb Khalid |
0:3e97001a43f8 | 193 | return -3; |
Haseeb Khalid |
0:3e97001a43f8 | 194 | } |
Haseeb Khalid |
0:3e97001a43f8 | 195 | |
Haseeb Khalid |
0:3e97001a43f8 | 196 | // check CRC |
Haseeb Khalid |
0:3e97001a43f8 | 197 | if (crc8(data, 2) != data[2]) { |
Haseeb Khalid |
0:3e97001a43f8 | 198 | setError("CRC mismatch"); |
Haseeb Khalid |
0:3e97001a43f8 | 199 | return -4; |
Haseeb Khalid |
0:3e97001a43f8 | 200 | } |
Haseeb Khalid |
0:3e97001a43f8 | 201 | |
Haseeb Khalid |
0:3e97001a43f8 | 202 | // 0 = SGP30, 1 = SGPC3 |
Haseeb Khalid |
0:3e97001a43f8 | 203 | mProductType = (data[0] & 0xF0) >> 4; |
Haseeb Khalid |
0:3e97001a43f8 | 204 | mFeatureSetVersion = data[1] & 0xFF; |
Haseeb Khalid |
0:3e97001a43f8 | 205 | |
Haseeb Khalid |
0:3e97001a43f8 | 206 | return 0; |
Haseeb Khalid |
0:3e97001a43f8 | 207 | } |
Haseeb Khalid |
0:3e97001a43f8 | 208 | |
Haseeb Khalid |
0:3e97001a43f8 | 209 | int SensirionESS::initSGP() |
Haseeb Khalid |
0:3e97001a43f8 | 210 | { |
Haseeb Khalid |
0:3e97001a43f8 | 211 | int ret = readFeatureSetInt(); |
Haseeb Khalid |
0:3e97001a43f8 | 212 | // default: SGP30 |
Haseeb Khalid |
0:3e97001a43f8 | 213 | SGP_INTERMEASURE_DELAY = SGP30_INTERMEASURE_DELAY; |
Haseeb Khalid |
0:3e97001a43f8 | 214 | SGP_DATA_LENGTH = SGP30_DATA_LENGTH; |
Haseeb Khalid |
0:3e97001a43f8 | 215 | uint8_t cmd[CMD_LENGTH] = { 0x20, 0x03 }; |
Haseeb Khalid |
0:3e97001a43f8 | 216 | |
Haseeb Khalid |
0:3e97001a43f8 | 217 | if (mProductType == PRODUCT_TYPE_SGPC3) { |
Haseeb Khalid |
0:3e97001a43f8 | 218 | SGP_INTERMEASURE_DELAY = SGPC3_INTERMEASURE_DELAY; |
Haseeb Khalid |
0:3e97001a43f8 | 219 | cmd[1] = 0xae; |
Haseeb Khalid |
0:3e97001a43f8 | 220 | } |
Haseeb Khalid |
0:3e97001a43f8 | 221 | |
Haseeb Khalid |
0:3e97001a43f8 | 222 | // run init air quality |
Haseeb Khalid |
0:3e97001a43f8 | 223 | if (i2c_write(SGP_I2C_ADDR, cmd, CMD_LENGTH)) { |
Haseeb Khalid |
0:3e97001a43f8 | 224 | setError("error in i2c_write"); |
Haseeb Khalid |
0:3e97001a43f8 | 225 | return -1; |
Haseeb Khalid |
0:3e97001a43f8 | 226 | } |
Haseeb Khalid |
0:3e97001a43f8 | 227 | wait_ms(10); |
Haseeb Khalid |
0:3e97001a43f8 | 228 | |
Haseeb Khalid |
0:3e97001a43f8 | 229 | return ret; |
Haseeb Khalid |
0:3e97001a43f8 | 230 | } |
Haseeb Khalid |
0:3e97001a43f8 | 231 | |
Haseeb Khalid |
0:3e97001a43f8 | 232 | ////////////////////////////////////////////////////////////////////////////// |
Haseeb Khalid |
0:3e97001a43f8 | 233 | // getter for values read earlier |
Haseeb Khalid |
0:3e97001a43f8 | 234 | bool SensirionESS::isInitialized() |
Haseeb Khalid |
0:3e97001a43f8 | 235 | { |
Haseeb Khalid |
0:3e97001a43f8 | 236 | return mInitialized; |
Haseeb Khalid |
0:3e97001a43f8 | 237 | } |
Haseeb Khalid |
0:3e97001a43f8 | 238 | |
Haseeb Khalid |
0:3e97001a43f8 | 239 | float SensirionESS::getTemperature() const |
Haseeb Khalid |
0:3e97001a43f8 | 240 | { |
Haseeb Khalid |
0:3e97001a43f8 | 241 | return mTemperature; |
Haseeb Khalid |
0:3e97001a43f8 | 242 | } |
Haseeb Khalid |
0:3e97001a43f8 | 243 | |
Haseeb Khalid |
0:3e97001a43f8 | 244 | float SensirionESS::getHumidity() const |
Haseeb Khalid |
0:3e97001a43f8 | 245 | { |
Haseeb Khalid |
0:3e97001a43f8 | 246 | return mHumidity; |
Haseeb Khalid |
0:3e97001a43f8 | 247 | } |
Haseeb Khalid |
0:3e97001a43f8 | 248 | |
Haseeb Khalid |
0:3e97001a43f8 | 249 | float SensirionESS::getTVOC() const |
Haseeb Khalid |
0:3e97001a43f8 | 250 | { |
Haseeb Khalid |
0:3e97001a43f8 | 251 | return mTVOC; |
Haseeb Khalid |
0:3e97001a43f8 | 252 | } |
Haseeb Khalid |
0:3e97001a43f8 | 253 | |
Haseeb Khalid |
0:3e97001a43f8 | 254 | float SensirionESS::getECO2() const |
Haseeb Khalid |
0:3e97001a43f8 | 255 | { |
Haseeb Khalid |
0:3e97001a43f8 | 256 | return mECO2; |
Haseeb Khalid |
0:3e97001a43f8 | 257 | } |
Haseeb Khalid |
0:3e97001a43f8 | 258 | |
Haseeb Khalid |
0:3e97001a43f8 | 259 | void SensirionESS::setLedRYG(int r, int y, int g) |
Haseeb Khalid |
0:3e97001a43f8 | 260 | { |
Haseeb Khalid |
0:3e97001a43f8 | 261 | led_red = r; |
Haseeb Khalid |
0:3e97001a43f8 | 262 | led_yellow = y; |
Haseeb Khalid |
0:3e97001a43f8 | 263 | led_green = g; |
Haseeb Khalid |
0:3e97001a43f8 | 264 | } |
Haseeb Khalid |
0:3e97001a43f8 | 265 | |
Haseeb Khalid |
0:3e97001a43f8 | 266 | ////////////////////////////////////////////////////////////////////////////// |
Haseeb Khalid |
0:3e97001a43f8 | 267 | // error handling |
Haseeb Khalid |
0:3e97001a43f8 | 268 | |
Haseeb Khalid |
0:3e97001a43f8 | 269 | inline void SensirionESS::setError(const char* error) |
Haseeb Khalid |
0:3e97001a43f8 | 270 | { |
Haseeb Khalid |
0:3e97001a43f8 | 271 | strlcpy(mErrorBuf, error, ERROR_BUF_LENGTH); |
Haseeb Khalid |
0:3e97001a43f8 | 272 | } |
Haseeb Khalid |
0:3e97001a43f8 | 273 | |
Haseeb Khalid |
0:3e97001a43f8 | 274 | const char* SensirionESS::getError() const |
Haseeb Khalid |
0:3e97001a43f8 | 275 | { |
Haseeb Khalid |
0:3e97001a43f8 | 276 | return mErrorBuf; |
Haseeb Khalid |
0:3e97001a43f8 | 277 | } |
Haseeb Khalid |
0:3e97001a43f8 | 278 | |
Haseeb Khalid |
0:3e97001a43f8 | 279 | ////////////////////////////////////////////////////////////////////////////// |
Haseeb Khalid |
0:3e97001a43f8 | 280 | // helper |
Haseeb Khalid |
0:3e97001a43f8 | 281 | |
Haseeb Khalid |
0:3e97001a43f8 | 282 | int SensirionESS::remainingWaitTimeMS() |
Haseeb Khalid |
0:3e97001a43f8 | 283 | { |
Haseeb Khalid |
0:3e97001a43f8 | 284 | unsigned long deltaT = t->read_ms() - mSGPMeasurementTimestamp; |
Haseeb Khalid |
0:3e97001a43f8 | 285 | if (deltaT > SGP_INTERMEASURE_DELAY) { |
Haseeb Khalid |
0:3e97001a43f8 | 286 | // we're already late, don't wait any longer |
Haseeb Khalid |
0:3e97001a43f8 | 287 | return 0; |
Haseeb Khalid |
0:3e97001a43f8 | 288 | } |
Haseeb Khalid |
0:3e97001a43f8 | 289 | return (SGP_INTERMEASURE_DELAY - deltaT); |
Haseeb Khalid |
0:3e97001a43f8 | 290 | } |
Haseeb Khalid |
0:3e97001a43f8 | 291 | |
Haseeb Khalid |
0:3e97001a43f8 | 292 | int8_t SensirionESS::i2c_read(uint8_t address, uint8_t* data, uint16_t count) |
Haseeb Khalid |
0:3e97001a43f8 | 293 | { |
Haseeb Khalid |
0:3e97001a43f8 | 294 | if (i2c_connection->read(address << 1, (char *) data, count) != 0) |
Haseeb Khalid |
0:3e97001a43f8 | 295 | return -1; |
Haseeb Khalid |
0:3e97001a43f8 | 296 | return 0; |
Haseeb Khalid |
0:3e97001a43f8 | 297 | } |
Haseeb Khalid |
0:3e97001a43f8 | 298 | |
Haseeb Khalid |
0:3e97001a43f8 | 299 | int8_t SensirionESS::i2c_write(uint8_t address, const uint8_t* data, uint16_t count) |
Haseeb Khalid |
0:3e97001a43f8 | 300 | { |
Haseeb Khalid |
0:3e97001a43f8 | 301 | if (i2c_connection->write(address << 1, (char *) data, count) != 0) |
Haseeb Khalid |
0:3e97001a43f8 | 302 | return -1; |
Haseeb Khalid |
0:3e97001a43f8 | 303 | return 0; |
Haseeb Khalid |
0:3e97001a43f8 | 304 | } |
Haseeb Khalid |
0:3e97001a43f8 | 305 | |
Haseeb Khalid |
0:3e97001a43f8 | 306 | uint8_t SensirionESS::crc8(const uint8_t* data, uint8_t len) |
Haseeb Khalid |
0:3e97001a43f8 | 307 | { |
Haseeb Khalid |
0:3e97001a43f8 | 308 | // adapted from SHT21 sample code from http://www.sensirion.com/en/products/humidity-temperature/download-center/ |
Haseeb Khalid |
0:3e97001a43f8 | 309 | |
Haseeb Khalid |
0:3e97001a43f8 | 310 | uint8_t crc = 0xff; |
Haseeb Khalid |
0:3e97001a43f8 | 311 | uint8_t byteCtr; |
Haseeb Khalid |
0:3e97001a43f8 | 312 | for (byteCtr = 0; byteCtr < len; ++byteCtr) { |
Haseeb Khalid |
0:3e97001a43f8 | 313 | crc ^= (data[byteCtr]); |
Haseeb Khalid |
0:3e97001a43f8 | 314 | for (uint8_t bit = 8; bit > 0; --bit) { |
Haseeb Khalid |
0:3e97001a43f8 | 315 | if (crc & 0x80) { |
Haseeb Khalid |
0:3e97001a43f8 | 316 | crc = (crc << 1) ^ 0x31; |
Haseeb Khalid |
0:3e97001a43f8 | 317 | } else { |
Haseeb Khalid |
0:3e97001a43f8 | 318 | crc = (crc << 1); |
Haseeb Khalid |
0:3e97001a43f8 | 319 | } |
Haseeb Khalid |
0:3e97001a43f8 | 320 | } |
Haseeb Khalid |
0:3e97001a43f8 | 321 | } |
Haseeb Khalid |
0:3e97001a43f8 | 322 | return crc; |
Haseeb Khalid |
0:3e97001a43f8 | 323 | } |