Rune L / Multichannel_Gas_Sensor
Committer:
runesla
Date:
Sat Mar 20 14:00:35 2021 +0100
Revision:
12:0d5ac08c5be3
Parent:
10:8ace727cec3f
removed unneccessary files

Who changed what in which revision?

UserRevisionLine numberNew contents of line
runesla 0:2fec9850cc9b 1 /*
runesla 0:2fec9850cc9b 2 Multichannel_Gas_GMXXX.cpp
runesla 0:2fec9850cc9b 3 Description: A drive for Seeed Grove Multichannel gas sensor V2.0.
runesla 0:2fec9850cc9b 4 2019 Copyright (c) Seeed Technology Inc. All right reserved.
runesla 0:2fec9850cc9b 5 Author: Hongtai Liu(lht856@foxmail.com)
runesla 0:2fec9850cc9b 6 2019-6-18
runesla 0:2fec9850cc9b 7
runesla 0:2fec9850cc9b 8 The MIT License (MIT)
runesla 0:2fec9850cc9b 9 Permission is hereby granted, free of charge, to any person obtaining a copy
runesla 0:2fec9850cc9b 10 of this software and associated documentation files (the "Software"), to deal
runesla 0:2fec9850cc9b 11 in the Software without restriction, including without limitation the rights
runesla 0:2fec9850cc9b 12 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
runesla 0:2fec9850cc9b 13 copies of the Software, and to permit persons to whom the Software is
runesla 0:2fec9850cc9b 14 furnished to do so, subject to the following conditions:
runesla 0:2fec9850cc9b 15 The above copyright notice and this permission notice shall be included in
runesla 0:2fec9850cc9b 16 all copies or substantial portions of the Software.
runesla 0:2fec9850cc9b 17 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
runesla 0:2fec9850cc9b 18 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
runesla 0:2fec9850cc9b 19 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
runesla 0:2fec9850cc9b 20 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
runesla 0:2fec9850cc9b 21 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
runesla 0:2fec9850cc9b 22 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
runesla 0:2fec9850cc9b 23 THE SOFTWARE.1 USA
runesla 0:2fec9850cc9b 24 */
runesla 0:2fec9850cc9b 25
runesla 0:2fec9850cc9b 26 #include "Multichannel_Gas_GMXXX.h"
runesla 0:2fec9850cc9b 27
runesla 2:c836ed5bafce 28 GAS_GMXXX::GAS_GMXXX(PinName sda, PinName scl, uint8_t addr)
runesla 2:c836ed5bafce 29 :
runesla 2:c836ed5bafce 30 _i2c_p(new I2C(sda, scl)),
runesla 2:c836ed5bafce 31 _i2c(*_i2c_p),
runesla 9:07c1751a6d00 32 GMXXX_ADDRESS((addr << 1))
runesla 8:705631dd7248 33 {
runesla 8:705631dd7248 34 init();
runesla 8:705631dd7248 35 }
runesla 8:705631dd7248 36
runesla 2:c836ed5bafce 37 void GAS_GMXXX::init()
runesla 2:c836ed5bafce 38 {
runesla 9:07c1751a6d00 39 this->_no2 = 0;
runesla 9:07c1751a6d00 40 this->_c2h5oh = 0;
runesla 9:07c1751a6d00 41 this->_voc = 0;
runesla 9:07c1751a6d00 42 this->_co = 0;
runesla 9:07c1751a6d00 43 this->gasDetected = false;
runesla 10:8ace727cec3f 44 this->_i2c_p->write(GMXXX_ADDRESS);
runesla 2:c836ed5bafce 45 this->preheated();
runesla 0:2fec9850cc9b 46 }
runesla 2:c836ed5bafce 47
runesla 2:c836ed5bafce 48 /**
runesla 2:c836ed5bafce 49 @description: set the I2C address, use after init.
runesla 0:2fec9850cc9b 50 @param {type} address(uint_8)
runesla 0:2fec9850cc9b 51 @return: None
runesla 0:2fec9850cc9b 52 */
runesla 6:52d9088d70cd 53 void GAS_GMXXX::setAddress(uint8_t address)
runesla 6:52d9088d70cd 54 {
runesla 0:2fec9850cc9b 55 GMXXX_ADDRESS = address;
runesla 0:2fec9850cc9b 56 preheated();
runesla 0:2fec9850cc9b 57 isPreheated = true;
runesla 0:2fec9850cc9b 58 }
runesla 0:2fec9850cc9b 59
runesla 0:2fec9850cc9b 60
runesla 0:2fec9850cc9b 61 /**
runesla 0:2fec9850cc9b 62 @description: transmit a byte to I2C device
runesla 0:2fec9850cc9b 63 @param {type} cmd(uint_8)
runesla 0:2fec9850cc9b 64 @return: None
runesla 0:2fec9850cc9b 65 */
runesla 6:52d9088d70cd 66 void GAS_GMXXX::GMXXXWriteByte(uint8_t cmd)
runesla 6:52d9088d70cd 67 {
runesla 4:7430c902dcc9 68 _i2c.write(cmd);
runesla 2:c836ed5bafce 69 ThisThread::sleep_for(1s);
runesla 0:2fec9850cc9b 70 }
runesla 0:2fec9850cc9b 71
runesla 0:2fec9850cc9b 72 /**
runesla 0:2fec9850cc9b 73 @description: read 4 bytes from I2C device
runesla 0:2fec9850cc9b 74 @param {type} cmd(uint_8)
runesla 0:2fec9850cc9b 75 @return: uint32_t
runesla 0:2fec9850cc9b 76 */
runesla 6:52d9088d70cd 77 uint32_t GAS_GMXXX::GMXXXRead32()
runesla 6:52d9088d70cd 78 {
runesla 0:2fec9850cc9b 79 uint8_t index = 0;
runesla 0:2fec9850cc9b 80 uint32_t value = 0;
runesla 5:1aec2da24876 81 char data[4];
runesla 2:c836ed5bafce 82
runesla 2:c836ed5bafce 83 this->_i2c_p->read(this->GMXXX_ADDRESS, data, 4);
runesla 2:c836ed5bafce 84 while(index < 4)
runesla 2:c836ed5bafce 85 {
runesla 2:c836ed5bafce 86 value += (uint8_t) atoi(data) << (8 * index);
runesla 3:447969dc4b41 87 index++;
runesla 0:2fec9850cc9b 88 }
runesla 2:c836ed5bafce 89 ThisThread::sleep_for(1s);
runesla 0:2fec9850cc9b 90 return value;
runesla 0:2fec9850cc9b 91 }
runesla 0:2fec9850cc9b 92
runesla 0:2fec9850cc9b 93 /**
runesla 0:2fec9850cc9b 94 @description: warmming up the gas sensor
runesla 0:2fec9850cc9b 95 @param {type}: None
runesla 0:2fec9850cc9b 96 @return: uint32_t
runesla 0:2fec9850cc9b 97 */
runesla 6:52d9088d70cd 98 void GAS_GMXXX::preheated()
runesla 6:52d9088d70cd 99 {
runesla 0:2fec9850cc9b 100 GMXXXWriteByte(WARMING_UP);
runesla 0:2fec9850cc9b 101 isPreheated = true;
runesla 0:2fec9850cc9b 102 }
runesla 0:2fec9850cc9b 103
runesla 0:2fec9850cc9b 104 /**
runesla 0:2fec9850cc9b 105 @description: disable warmming up the gas sensor
runesla 0:2fec9850cc9b 106 @param {type}: None
runesla 0:2fec9850cc9b 107 @return: uint32_t
runesla 0:2fec9850cc9b 108 */
runesla 6:52d9088d70cd 109 void GAS_GMXXX::unPreheated()
runesla 6:52d9088d70cd 110 {
runesla 0:2fec9850cc9b 111 GMXXXWriteByte(WARMING_DOWN);
runesla 0:2fec9850cc9b 112 isPreheated = false;
runesla 0:2fec9850cc9b 113 }
runesla 0:2fec9850cc9b 114
runesla 0:2fec9850cc9b 115 /**
runesla 0:2fec9850cc9b 116 @description: get the adc value of GM102B
runesla 0:2fec9850cc9b 117 @param {type}: None
runesla 0:2fec9850cc9b 118 @return: uint32_t
runesla 0:2fec9850cc9b 119 */
runesla 6:52d9088d70cd 120 uint32_t GAS_GMXXX::getGM102B()
runesla 6:52d9088d70cd 121 {
runesla 6:52d9088d70cd 122 if (!isPreheated)
runesla 6:52d9088d70cd 123 {
runesla 0:2fec9850cc9b 124 preheated();
runesla 0:2fec9850cc9b 125 }
runesla 0:2fec9850cc9b 126 GMXXXWriteByte(GM_102B);
runesla 0:2fec9850cc9b 127 return GMXXXRead32();
runesla 0:2fec9850cc9b 128 }
runesla 0:2fec9850cc9b 129
runesla 0:2fec9850cc9b 130 /**
runesla 0:2fec9850cc9b 131 @description: get the adc value of GM302B
runesla 0:2fec9850cc9b 132 @param {type}: None
runesla 0:2fec9850cc9b 133 @return: uint32_t
runesla 0:2fec9850cc9b 134 */
runesla 6:52d9088d70cd 135 uint32_t GAS_GMXXX::getGM302B()
runesla 6:52d9088d70cd 136 {
runesla 6:52d9088d70cd 137 if (!isPreheated)
runesla 6:52d9088d70cd 138 {
runesla 0:2fec9850cc9b 139 preheated();
runesla 0:2fec9850cc9b 140 }
runesla 0:2fec9850cc9b 141 GMXXXWriteByte(GM_302B);
runesla 0:2fec9850cc9b 142 return GMXXXRead32();
runesla 0:2fec9850cc9b 143 }
runesla 0:2fec9850cc9b 144
runesla 0:2fec9850cc9b 145 #ifdef GM_402B
runesla 0:2fec9850cc9b 146 /**
runesla 0:2fec9850cc9b 147 @description: get the adc value of GM402B
runesla 0:2fec9850cc9b 148 @param {type}: None
runesla 0:2fec9850cc9b 149 @return: uint32_t
runesla 0:2fec9850cc9b 150 */
runesla 6:52d9088d70cd 151 uint32_t GAS_GMXXX::getGM402B()
runesla 6:52d9088d70cd 152 {
runesla 6:52d9088d70cd 153 if (!isPreheated)
runesla 6:52d9088d70cd 154 {
runesla 0:2fec9850cc9b 155 preheated();
runesla 0:2fec9850cc9b 156 }
runesla 0:2fec9850cc9b 157 GMXXXWriteByte(GM_402B);
runesla 0:2fec9850cc9b 158 return GMXXXRead32();
runesla 0:2fec9850cc9b 159 }
runesla 0:2fec9850cc9b 160 #endif
runesla 0:2fec9850cc9b 161
runesla 0:2fec9850cc9b 162 /**
runesla 0:2fec9850cc9b 163 @description: get the adc value of GM502B
runesla 0:2fec9850cc9b 164 @param {type}: None
runesla 0:2fec9850cc9b 165 @return: uint32_t
runesla 0:2fec9850cc9b 166 */
runesla 6:52d9088d70cd 167 uint32_t GAS_GMXXX::getGM502B()
runesla 6:52d9088d70cd 168 {
runesla 6:52d9088d70cd 169 if (!isPreheated)
runesla 6:52d9088d70cd 170 {
runesla 0:2fec9850cc9b 171 preheated();
runesla 0:2fec9850cc9b 172 }
runesla 0:2fec9850cc9b 173 GMXXXWriteByte(GM_502B);
runesla 0:2fec9850cc9b 174 return GMXXXRead32();
runesla 0:2fec9850cc9b 175 }
runesla 0:2fec9850cc9b 176
runesla 0:2fec9850cc9b 177 /**
runesla 0:2fec9850cc9b 178 @description: get the adc value of GM702B
runesla 0:2fec9850cc9b 179 @param {type}: None
runesla 0:2fec9850cc9b 180 @return: uint32_t
runesla 0:2fec9850cc9b 181 */
runesla 6:52d9088d70cd 182 uint32_t GAS_GMXXX::getGM702B()
runesla 6:52d9088d70cd 183 {
runesla 6:52d9088d70cd 184 if (!isPreheated)
runesla 6:52d9088d70cd 185 {
runesla 0:2fec9850cc9b 186 preheated();
runesla 0:2fec9850cc9b 187 }
runesla 0:2fec9850cc9b 188 GMXXXWriteByte(GM_702B);
runesla 0:2fec9850cc9b 189 return GMXXXRead32();
runesla 0:2fec9850cc9b 190 }
runesla 0:2fec9850cc9b 191
runesla 0:2fec9850cc9b 192 #ifdef GM_802B
runesla 0:2fec9850cc9b 193 /**
runesla 0:2fec9850cc9b 194 @description: get the adc value of GM802B
runesla 0:2fec9850cc9b 195 @param {type}: None
runesla 0:2fec9850cc9b 196 @return: uint32_t
runesla 0:2fec9850cc9b 197 */
runesla 6:52d9088d70cd 198 uint32_t GAS_GMXXX::getGM802B()
runesla 6:52d9088d70cd 199 {
runesla 6:52d9088d70cd 200 if (!isPreheated)
runesla 6:52d9088d70cd 201 {
runesla 0:2fec9850cc9b 202 preheated();
runesla 0:2fec9850cc9b 203 }
runesla 0:2fec9850cc9b 204 GMXXXWriteByte(GM_802B);
runesla 0:2fec9850cc9b 205 return GMXXXRead32();
runesla 0:2fec9850cc9b 206 }
runesla 0:2fec9850cc9b 207 #endif
runesla 0:2fec9850cc9b 208
runesla 8:705631dd7248 209 void GAS_GMXXX::read()
runesla 8:705631dd7248 210 {
runesla 8:705631dd7248 211 this->_no2 = calcVol(measure_NO2());
runesla 8:705631dd7248 212 this->_c2h5oh = calcVol(measure_C2H5OH());
runesla 8:705631dd7248 213 this->_voc = calcVol(measure_VOC());
runesla 8:705631dd7248 214 this->_co = calcVol(measure_CO());
runesla 8:705631dd7248 215
runesla 8:705631dd7248 216 if(this->_no2 > 0 || this->_c2h5oh > 0 || this->_voc > 0 || this->_co > 0)
runesla 8:705631dd7248 217 {
runesla 8:705631dd7248 218 this->gasDetected = true;
runesla 8:705631dd7248 219 }
runesla 8:705631dd7248 220
runesla 8:705631dd7248 221 this->gasDetected = false;
runesla 8:705631dd7248 222 }
runesla 8:705631dd7248 223
runesla 8:705631dd7248 224 bool GAS_GMXXX::gas_detected()
runesla 8:705631dd7248 225 {
runesla 8:705631dd7248 226 return this->gasDetected;
runesla 8:705631dd7248 227 }
runesla 8:705631dd7248 228
runesla 9:07c1751a6d00 229 float GAS_GMXXX::get_no2()
runesla 8:705631dd7248 230 {
runesla 8:705631dd7248 231 return this->_no2;
runesla 8:705631dd7248 232 }
runesla 8:705631dd7248 233
runesla 9:07c1751a6d00 234 float GAS_GMXXX::get_c2h5oh()
runesla 8:705631dd7248 235 {
runesla 8:705631dd7248 236 return this->_c2h5oh;
runesla 8:705631dd7248 237 }
runesla 8:705631dd7248 238
runesla 9:07c1751a6d00 239 float GAS_GMXXX::get_voc()
runesla 8:705631dd7248 240 {
runesla 8:705631dd7248 241 return this->_voc;
runesla 8:705631dd7248 242 }
runesla 8:705631dd7248 243
runesla 9:07c1751a6d00 244 float GAS_GMXXX::get_co()
runesla 8:705631dd7248 245 {
runesla 8:705631dd7248 246 return this->_co;
runesla 8:705631dd7248 247 }
runesla 8:705631dd7248 248
runesla 0:2fec9850cc9b 249 /**
runesla 2:c836ed5bafce 250 @description: change the I2C address of gas sensor
runesla 0:2fec9850cc9b 251 @param {type}: addres(uint8_t)
runesla 0:2fec9850cc9b 252 @return: None
runesla 0:2fec9850cc9b 253 */
runesla 6:52d9088d70cd 254 void GAS_GMXXX::changeGMXXXAddr(uint8_t address)
runesla 6:52d9088d70cd 255 {
runesla 6:52d9088d70cd 256 if (address == 0 || address > 127)
runesla 6:52d9088d70cd 257 {
runesla 0:2fec9850cc9b 258 address = 0x08;
runesla 0:2fec9850cc9b 259 }
runesla 5:1aec2da24876 260 this->_i2c_p->write(CHANGE_I2C_ADDR);
runesla 5:1aec2da24876 261 this->_i2c_p->write(address);
runesla 0:2fec9850cc9b 262 GMXXX_ADDRESS = address;
runesla 2:c836ed5bafce 263 }