summaryrefslogtreecommitdiff
path: root/CCS811.cpp
blob: 05b71c0652a82606da9a5eb7efe5db8e4201ec09 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
#include "CCS811.h"

int CCS811::begin(void)
{
    uint8_t id=0;
    Wire.begin();
    softReset();
    delay(100);
    if(readReg(CCS811_REG_HW_ID,&id,1) != 1){DBG("");
        DBG("bus data access error");DBG("");
        return ERR_DATA_BUS;DBG("");
    }

    DBG("real sensor id=");DBG(id);
    if(id != CCS811_HW_ID){DBG("");
        delay(1);
        return ERR_IC_VERSION;
    }
    writeReg(CCS811_BOOTLOADER_APP_START, NULL, 0);
    setMeasurementMode(0,0,eMode4);
    setInTempHum(25, 50);
    return ERR_OK;
}

void CCS811::softReset(){
    uint8_t value[4] = {0x11, 0xE5, 0x72, 0x8A};
    writeReg(CCS811_REG_SW_RESET, value, 4);
}

bool CCS811::checkDataReady()
{
    int8_t status[1] = {0};
    readReg(CCS811_REG_STATUS, status, 1);
    DBG(status[0],HEX);
    if(!((status[0] >> 3) & 0x01))
        return false;
    else 
        return true;
}

uint16_t CCS811::readBaseLine(){
    uint8_t buffer[2];
    readReg(CCS811_REG_BASELINE, buffer, 2);
    return buffer[0]<<8|buffer[1];
}

void CCS811::writeBaseLine(uint16_t baseLine){
    uint8_t buffer[2];
    
    buffer[0] = baseLine>>8;
    buffer[1] = baseLine;
    writeReg(CCS811_REG_BASELINE, buffer, 2);
}

void CCS811::setMeasurementMode(uint8_t thresh, uint8_t interrupt, eDRIVE_MODE_t mode){
    uint8_t measurement[1] = {0};
    measurement[0] = (thresh << 2) | (interrupt << 3) | (mode << 4);
    writeReg(CCS811_REG_MEAS_MODE, measurement, 1);
}

void CCS811::setMeasCycle(eCycle_t cycle){
    uint8_t measurement[1] = {0};   
    measurement[0] = cycle << 4;
    writeReg(CCS811_REG_MEAS_MODE, measurement, 1);
}

uint8_t CCS811::getMeasurementMode(){
    uint8_t meas[1] = {0};
    readReg(CCS811_REG_MEAS_MODE, meas, 1);
    return meas[0];
}

void CCS811::setThresholds(uint16_t lowToMed, uint16_t medToHigh)
{
    uint8_t buffer[] = {(uint8_t)((lowToMed >> 8) & 0xF),
                        (uint8_t)(lowToMed & 0xF),
                        (uint8_t)((medToHigh >> 8) & 0xF),
                        (uint8_t)(medToHigh & 0xF)};
    
    writeReg(CCS811_REG_THRESHOLDS, buffer, 5);
    uint8_t buf[1];
    readReg(CCS811_REG_THRESHOLDS, buf, 1);
    Serial.println(buf[0],HEX);
}

uint16_t CCS811::getCO2PPM(){
    uint8_t buffer[8];
    readReg(CCS811_REG_ALG_RESULT_DATA, buffer, 8);
    eCO2 = (((uint16_t)buffer[0] << 8) | (uint16_t)buffer[1]);
    return eCO2;
}

uint16_t CCS811::getTVOCPPB(){
    uint8_t buffer[8];
    readReg(CCS811_REG_ALG_RESULT_DATA, buffer, 8);
    eTVOC = (((uint16_t)buffer[2] << 8) | (uint16_t)buffer[3]);
    return eTVOC;
}

void CCS811::setInTempHum(float temperature, float humidity)    // compensate for temperature and relative humidity
{
    int _temp, _rh;
    if(temperature>0)
        _temp = (int)temperature + 0.5;  // this will round off the floating point to the nearest integer value
    else if(temperature<0) // account for negative temperatures
        _temp = (int)temperature - 0.5;
    _temp = _temp + 25;  // temperature high byte is stored as T+25°C in the sensor's memory so the value of byte is positive
    _rh = (int)humidity + 0.5;  // this will round off the floating point to the nearest integer value
    
    uint8_t envData[4];
    
    envData[0] = _rh << 1;  // shift the binary number to left by 1. This is stored as a 7-bit value
    envData[1] = 0;  // most significant fractional bit. Using 0 here - gives us accuracy of +/-1%. Current firmware (2016) only supports fractional increments of 0.5
    envData[2] = _temp << 1;
    envData[3] = 0;
    
    writeReg(CCS811_REG_ENV_DATA, &envData, 4);
}

void CCS811::writeReg(uint8_t reg, const void* pBuf, size_t size)
{
    if(pBuf == NULL){
        DBG("pBuf ERROR!! : null pointer");
    }
    uint8_t * _pBuf = (uint8_t *)pBuf;
    _pWire->beginTransmission(_deviceAddr);
    _pWire->write(&reg, 1);
    
    for(uint16_t i = 0; i < size; i++){
        _pWire->write(_pBuf[i]);
    }
    _pWire->endTransmission();
}

uint8_t CCS811::readReg(uint8_t reg, const void* pBuf, size_t size)
{
    if(pBuf == NULL){
        DBG("pBuf ERROR!! : null pointer");
    }
    uint8_t * _pBuf = (uint8_t *)pBuf;
    _pWire->beginTransmission(_deviceAddr);
    _pWire->write(&reg, 1);
    
    if( _pWire->endTransmission() != 0){
        return 0;
    }

    _pWire->requestFrom(_deviceAddr, (uint8_t) size);
    for(uint16_t i = 0; i < size; i++){
        _pBuf[i] = _pWire->read();
    }
    _pWire->endTransmission();
    return size;
}