This commit is contained in:
2022-03-28 00:42:48 +02:00
commit 3e858fa48e
56 changed files with 62251 additions and 0 deletions

180
src/sensor/dev/sgp40.cpp Normal file
View File

@@ -0,0 +1,180 @@
#include "sgp40.h"
/****************************************************************/
bool SGP40::Initialize(){
bool success(true);
success &= ReadChipID();
VocAlgorithm_init(&vocAlgorithmParameters);
if(success) success = WriteSettings();
m_initialized = success;
return m_initialized;
}
/****************************************************************/
bool SGP40::ReadChipID(){
uint8_t id = 0;
//ReadRegister(ID_ADDR, &id, 1);
switch(id){
default:
m_chip_model = ChipModel_UNKNOWN;
return false;
}
return true;
}
/****************************************************************/
bool SGP40::WriteSettings(){
uint8_t data[3];
uint8_t ord(0);
i2c->beginTransmission(SGP40_ADDRESS);
i2c->write(highByte(REG_MEASURE_TEST));
i2c->write(lowByte(REG_MEASURE_TEST));
i2c->endTransmission();
delay(320);
i2c->requestFrom(static_cast<uint8_t>(SGP40_ADDRESS), uint8_t(3));
while(i2c->available()){
data[ord++] = i2c->read();
}
if(ord != 3) return false;
uint16_t results = (data[0] << 8) | data[1];
return (results == test_pass);
}
/****************************************************************/
bool SGP40::begin(){
bool success = Initialize();
success &= m_initialized;
return success;
}
/****************************************************************/
bool SGP40::reset(){
WriteRegister(RESET_ADDR, 0x02);
delay(10); //max. startup time according to datasheet
return(begin());
}
/****************************************************************/
bool SGP40::ReadData(uint8_t data[SENSOR_DATA_LENGTH], float RH, float T){
bool success;
uint8_t ord(0);
RH = (RH>100?100: (RH<0?0:RH));
T = (T>130?130: (T<-45?-45:T));
uint16_t RH_ticks = (uint16_t)(RH * 65535 / 100); // Convert RH from %RH to ticks
uint16_t T_ticks = (uint16_t)((T + 45) * 65535 / 175); // Convert T from DegC to ticks
i2c->beginTransmission(SGP40_ADDRESS);
i2c->write(highByte(REG_MEASURE_RAW));
i2c->write(lowByte(REG_MEASURE_RAW));
i2c->write(highByte(RH_ticks));
i2c->write(lowByte(RH_ticks));
i2c->write(CRC8(RH_ticks));
i2c->write(highByte(T_ticks));
i2c->write(lowByte(T_ticks));
i2c->write(CRC8(T_ticks));
i2c->endTransmission();
delay(30);
i2c->requestFrom(SGP40_ADDRESS, SENSOR_DATA_LENGTH);
while(i2c->available()){
data[ord++] = i2c->read();
}
return success;
}
/****************************************************************/
int32_t SGP40::voc(float RH, float T){
if(!m_initialized) return 0;
uint8_t data[SENSOR_DATA_LENGTH];
ReadData(data, RH, T);
uint16_t results = (data[0]<<8) | data[1];
int32_t voci = 0;
VocAlgorithm_process(&vocAlgorithmParameters, results, &voci);
return voci;
}
void SGP40::read(int32_t& voc, float RH, float T){
if(!m_initialized) return;
uint8_t data[SENSOR_DATA_LENGTH];
ReadData(data, RH, T);
uint16_t results = (data[0]<<8) | data[1];
VocAlgorithm_process(&vocAlgorithmParameters, results, &voc);
return;
}
/****************************************************************/
SGP40::ChipModel SGP40::chipModel(){
return m_chip_model;
}
/****************************************************************/
bool SGP40::WriteRegister(uint16_t addr, uint8_t data){
i2c->beginTransmission(SGP40_ADDRESS);
i2c->write(highByte(addr));
i2c->write(lowByte(addr));
i2c->write(data);
i2c->endTransmission();
return true;
}
/****************************************************************/
bool SGP40::ReadRegister(uint8_t addr,uint8_t data[],uint8_t length){
uint8_t ord(0);
i2c->beginTransmission(SGP40_ADDRESS);
i2c->write(addr);
i2c->endTransmission();
i2c->requestFrom(static_cast<uint8_t>(SGP40_ADDRESS), length);
while(i2c->available()){
data[ord++] = i2c->read();
}
return ord == length;
}
uint8_t SGP40::CRC8(uint16_t data){
uint8_t crc = 0xFF;
crc ^= (data >> 8);
for (uint8_t i = 0 ; i < 8 ; i++){
if ((crc & 0x80) != 0) crc = (uint8_t)((crc << 1) ^ 0x31);
else crc <<= 1;
}
crc ^= (uint8_t)data;
for (uint8_t i = 0 ; i < 8 ; i++){
if ((crc & 0x80) != 0) crc = (uint8_t)((crc << 1) ^ 0x31);
else crc <<= 1;
}
return crc;
}