Yohei Shimmyo / CCS811

CCS811.cpp

Committer:
rollman
Date:
2020-03-05
Revision:
2:ec392b3a49f2
Parent:
1:57eb62ded32d
Child:
3:423f2830684e

File content as of revision 2:ec392b3a49f2:

#include "CCS811.h"

CCS811::CCS811(I2C& i2c, Serial& pc) : m_i2c(i2c), m_pc(pc) {
    
}

/**
 ** Initial CCS811 need write MODE register and should Write APP START register to begin measurement.
 **/
int CCS811::init() {
    char send[2];
    
    if (!checkHW()) {
        m_pc.printf("ERROR: CCS811 does not have a correct hardware id.\r\n");
        return CCS811_ERR_HWID;
    }else {
        m_pc.printf("CCS811 is confirm!\r\n");    
    }
    
    // check valid app
    send[0] = CCS811_REG_STATUS;
    m_i2c.write(CCS811_I2C_ADDR, send, 1);
    m_i2c.read(CCS811_I2C_ADDR, send, 1);
    if (!(send[0] & 0x10)){
        return CCS811_ERR_INVALID_APP;
    }
    
    // send app start
    send[0] = CCS811_REG_APP_START;
    send[1] = 0x00;
    m_i2c.write(CCS811_I2C_ADDR, send, 1);
    
    m_pc.printf("done setting app start\r\n");
    {
        char status = readStatus();
        if (status & 0x01){
            char errid = readErr();
            printerr_reg1(m_pc, errid);
        }
    }
    
    // check fw mode
    send[0] = CCS811_REG_STATUS;
    m_i2c.write(CCS811_I2C_ADDR, send, 1);
    m_i2c.read(CCS811_I2C_ADDR, send, 1);
    if (!(send[0] & 0x90)){
        return CCS811_ERR_INVALID_APPMODE;
    }
    

    
    send[0] = CCS811_REG_MEAS_MODE;
    send[1] = CCS811_MEASUREMENT_MODE1;
    
    m_i2c.write(CCS811_I2C_ADDR, send, 2);
    m_pc.printf("setting meas mode\r\n");
    {
        char status = readStatus();
        if (status & 0x01){
            char errid = readErr();
            printerr_reg1(m_pc, errid);
        }
    }
    m_pc.printf("done set meas mode\r\n");
    return 0;
}

int CCS811::setMeasureMode(char mode) {
    
    char send[2];
    
    send[0] = CCS811_MEASUREMENT_MODE1;
    send[1] = mode;
    
    m_i2c.write(CCS811_I2C_ADDR, send, 2);
    
    send[0] = CCS811_REG_APP_START;
    send[1] = 0x00;
    
    m_i2c.write(CCS811_I2C_ADDR, send, 2);
    
    return 0;
}

/**
 ** Here is that you can read CCS811 with co2 ppm and tvoc bbm is unsigned value
 **/
int CCS811::readData(uint16_t *ECO2, uint16_t *TVOC) {
    
    char recv[8];
    
    
    
    recv[0] = CCS811_REG_ALG_RESULT_DATA;
    m_i2c.write(CCS811_I2C_ADDR, recv, 1);
    m_i2c.read( CCS811_I2C_ADDR, recv, 8);

//    m_pc.printf("%X %X\r\n", recv[0], recv[1]);
//    m_pc.printf("%X %X\r\n", recv[2], recv[3]);
//    m_pc.printf("%X %X\r\n", recv[4], recv[5]);
//    m_pc.printf("%X %X\r\n", recv[6], recv[7]);
    
    *ECO2 = (uint16_t) (recv[0] <<8) + recv[1];
    *TVOC = (uint16_t) (recv[2] <<8) + recv[3];
    
    char err_id = recv[5];
    if(err_id != 0){
        printerr_reg1(m_pc, err_id);
    }
    
    return 0;
    
}

/**
 ** Here for check is CCS811 hardware from i2c bus
 **/
bool CCS811::checkHW() {

    char read[1];
    char hid[1];
    
    read[0] = CCS811_REG_HW_ID;
    
    m_i2c.write(CCS811_I2C_ADDR, read, 1, false);
    m_i2c.read(CCS811_I2C_ADDR, hid, 1, false);
    
    if (hid[0] == 0x81) {
        return true;
    } else {
        return false;
    }
    
}

/**
 **  Here is provide you soft reset CCS811 module 
 **/
bool CCS811::softRest() {
     
    char rstCMD[5] = {CCS811_REG_SW_RESET, 0x11,0xE5,0x72,0x8A};

    m_i2c.write(CCS811_I2C_ADDR, rstCMD, 5);
    
    return false;
      
}

int CCS811::readErr(){
    char i2c_buf[2];
    
    i2c_buf[0] = CCS811_REG_ERROR_ID;
    m_i2c.write(CCS811_I2C_ADDR, i2c_buf, 1);
    m_i2c.read(CCS811_I2C_ADDR, i2c_buf, 1);
    return i2c_buf[0];
}

int CCS811::readStatus(){
    char i2c_buf[2];
    
    i2c_buf[0] = CCS811_REG_STATUS;
    m_i2c.write(CCS811_I2C_ADDR, i2c_buf, 1);
    m_i2c.read(CCS811_I2C_ADDR, i2c_buf, 1);
    return i2c_buf[0];
}

void printerr(Serial& m_pc, int errid){
    if (errid == CCS811_ERR_HWID){
        m_pc.printf("CCS811_ERR_HWID\r\n");
    }else if(errid == CCS811_ERR_INVALID_APP){
        m_pc.printf("CCS811_ERR_INVALID_APP\r\n");
    }else if(errid == CCS811_ERR_INVALID_APPMODE){
        m_pc.printf("CCS811_ERR_INVALID_APPMODE\r\n");
    }else if(errid == 0){
        m_pc.printf("printerr called but no error\r\n");
        return;
    }else{
        m_pc.printf("Unknown error: %d\r\n", errid);
    }
    exit(errid);
}

void printerr_reg1(Serial& m_pc, int errid){
    m_pc.printf("err reg: %X\r\n", errid);
    exit(errid);
}