First working version of CDM7160 library

CDM7160.h

Committer:
MichalKozlowski
Date:
2020-05-04
Revision:
2:207717b5eaee
Parent:
1:4a0a9c03afba

File content as of revision 2:207717b5eaee:

/**
 * Project:      CDM7160
 * Company:      yosensi.io
 * CodeWriter:   Michal Kozlowski
 * File:         CDM7160.h
 * Date:         09-09-2019
 * Description:  CDM7160 Driver Header File
 */

/**
 *   #include "mbed.h"
 *   #include "CDM7160.h"
 *
 *   DigitalIn busy(PC_8);
 *   CDM7160 CO2(PB_9, PB_8);
 *   InterruptIn sw(USER_BUTTON);
 *   InterruptIn irq(PC_9);
 *
 *   volatile bool button, isIrq;
 *
 *   void buttonCallback(){
 *       button = true;    
 *   }
 *
 *   void irqCallback(){
 *       isIrq = true;    
 *   }
 *
 *   int main()
 *   {
 *       int i=0;    // Number of measurement
 *       irq.rise(&irqCallback);
 *       //irq.fall(&irqCallback);
 *       sw.rise(&buttonCallback);
 *
 *
 *       if(CO2.initIntegrated() == CDM7160_I2C_ADDR){
 *           printf("Initialization Success\r\n\n");
 *       }
 *       if(CO2.setAlarmLimits(1500,1450) == CDM7160_SUCCESS){
 *           printf("Alarm Limits has been set!\r\n");
 *       }
 *
 *       while (true) {
 *           if(button){
 *               if(CO2.getAlarmLimits() == CDM7160_SUCCESS){
 *                   printf("High Alert Limit = %d Low Alert Limit = %d\r\n", CO2.cdm7160.highAlertLimit, CO2.cdm7160.lowAlertLimit);
 *               }
 *               if(CO2.getAirPressureAndAltitude() == CDM7160_SUCCESS){
 *                   printf("Atmosferic Pressure = %d [hPa] Altitude = %d [m]\r\n", CO2.cdm7160.atmosferic_pressure, CO2.cdm7160.altitude);
 *               }
 *               button = false;
 *           }
 *
 *           if(busy == 0){           
 *               if(i==0){
 *                   wait(2);
 *                   isIrq = false;
 *               }else{
 *                   printf("CO2 = %d [ppm]\r\n", CO2.getCO2());
 *                   wait(2);
 *                   if(isIrq){
 *                       printf("Interrupt !!!\r\n");
 *                       isIrq = false;
 *                   }
 *               }
 *               i++;
 *           }
 *       }
 *   }
 *
 */

#include "mbed.h"

#ifndef CDM7160_H
#define CDM7160_H

#include "mbed.h"

/**
 * Sensor I2C address
 */
//#define CDM7160_I2C_ADDR             0x68       // CAD0 pin to low logic
#define CDM7160_I2C_ADDR              0x69       // CAD0 pin to high logic (left floating)

#define DIR_BIT_WRITE                 0x00
#define DIR_BIT_READ                  0x01

/**
 * Sensor name
 */
#define CDM7160_NAME                  "CDM7160"
#define CDM7160_NAME_LEN              8

/**
 * Measurements number
 */
#define CDM7160_MEASURE_NBR           1

#define CDM7160_CRC_POLYNOMIAL        0x31 
#define CDM7160_CRC8_INIT             0xFF 


/**
 * Conditions on I2C bus.
 */
#define CDM7160_SUCCESS               0
#define CDM7160_ERROR                 -1

/** Macros - Build 2-Byte data
 */
#define CDM7160_2B_BUILD(hiByte, loByte) ((uint16_t)(((loByte) & 0x00FF) | (((hiByte) & 0x00FF) << 8)))

/** Macros - Split 2-Byte data
 */
#define CDM7160_HI_BYTE(reg) (((reg) >> 8) & 0xFF)
#define CDM7160_LO_BYTE(reg) ((reg) & 0xFF)

/**
 *  @class CDM7160
 *  @brief Implementation of CDM7160 sensor CO2 library
 */   
class CDM7160{
    
public:

    /** eReg read/write commands
     */
    enum eReg {
        RST           = 0x00, // software reset
        CTL           = 0x01, // operating mode
        ST1           = 0x02, // status register
        DAL           = 0x03, // LSB CO2 data
        DAH           = 0x04, // MSB CO2 data
        HPA           = 0x09, // atmosferic pressure
        HIT           = 0x0A, // altitude
        ALHI          = 0x0C, // upper limit treshold for alarm
        ALLO          = 0x0D, // lower limit treshold for alarm
        FUNC          = 0x0F, // PWM output
        ERR           = 0x10  // Self-test 
    };

    /** Reg: CTL / Addr: 0x01 / Permission: RW / Bits:2-0
     */
    enum eControlMode {
        PWR_DOWN      = 0x00,
        CONTIN        = 0x06
    };

    /** Reg: FUNC / Addr: 0x0F / Permission: RW / Bits: 3, 2, 0
     */
    enum eFunctionSetting {
        PWME_ON          = 1 << 0,
        PWME_OFF         = 0 << 0,
        HPAE_ON          = 1 << 2,
        HPAE_OFF         = 0 << 2,
        PWMR_LOW         = 1 << 3,
        PWMR_HIGH        = 0 << 3
    };

    /** cdm7160 stuct prototype
     */
     struct cdm7160_t {
        uint8_t     addr;
        int         co2;
        uint8_t     control;
        uint8_t     status;
        uint16_t    highAlertLimit;
        uint16_t    lowAlertLimit;
        uint16_t    atmosferic_pressure;
        uint16_t    altitude;
        uint8_t     settings;
        uint8_t     selfDiag;
    };   
    cdm7160_t cdm7160;

    /** Create an CDM7160 instance
     *  which is connected to specified I2C pins with specified address
     *
     * @param sda I2C-bus SDA pin
     * @param scl I2C-bus SCL pin
     * @param addr (option) I2C-bus address (default: 0x4A)
     */
    CDM7160(PinName sda, PinName scl, uint8_t addr = CDM7160_I2C_ADDR);

    /** Create a CDM7160  instance
     *  which is connected to specified I2C pins with specified address
     *
     * @param i2c_obj I2C object (instance)
     * @param addr (option) I2C-bus address (default: 0x4A)
     */
    /** Constructor of CDM7160
     */
    CDM7160(I2C &i2c_obj, uint8_t addr = CDM7160_I2C_ADDR);

    /** Destructor of CDM7160
     */
    ~CDM7160();


    /** Initialize the CDM7160
     *  Calling function control() and set sensor in continuous mode
     * @return CDM7160 address if successful. CDM7160_ERROR if fail
     */
    int8_t init();

    /** Integrated Initialize the CDM7160 sensor 
     *  By default: set Atmospheric pressure and altitude, set sensor in countinous mode, 
     *  enable atm. pressure and altitude correction in measurement and
     *  disable PWM output PIN
     * @return CDM7160 address if successful. CDM7160_ERROR if fail
     */
    int8_t initIntegrated(  uint16_t hpa = 1005, uint16_t height = 130, 
                            eControlMode mode = CONTIN, 
                            eFunctionSetting atm_alt_correct= HPAE_ON,
                            eFunctionSetting pwm_conce = PWMR_LOW,
                            eFunctionSetting pwm_pin = PWME_OFF);

    /** Measure CO2 in ppm
     * Measurement is stored in struct variable: int co2
     * @return co2 if sucessful. CDM7160_ERROR if fail
     */
    int getCO2();


    /**  Periodic Measurement mode of the CDM7160
     * CDM7160 goes into idle state
     * @param mode - operation mode (Power down or continuous)
     * @return CDM7160_SUCCESS if successful. CDM7160_ERROR if fail
     */
    int8_t control(eControlMode mode = CONTIN);

    /** Soft reset command
     * soft reset for CDM7160 sensor
     * @return CDM7160_SUCCESS if successful. CDM7160_ERROR if fail
     */
    int8_t softReset();

    /** Read Status Register
     * status information of busy, alarm, connection on CAD0 and MSEL
     * Data stored in variable: uint8_t status
     * @return CDM7160_SUCCESS if successful. CDM7160_ERROR if fail
     */
    int8_t getStatus();

    /** Set Alert High and Low Limit 
     * @param high_limit - high limit value
     * @param low_limit - low limit value
     * @return CDM7160_SUCCESS if successful. CDM7160_ERROR if fail
     */
    int8_t setAlarmLimits(uint16_t high_limit = 1000, uint16_t low_limit = 400);

    /** Read Alert High and Low Limit 
     * Data stored in variable: uint16_t highAlertLimit, uint16_t lowAlertLimit
     * @return CDM7160_SUCCESS if successful. CDM7160_ERROR if fail
     */
    int8_t getAlarmLimits();

    /** Set Atmospheric Pressure and Altitude - to correct calculation CO2
     * @param hpa - atmospheric pressure value in [hPa]
     * @param height - altitude value in [m]
     * @return CDM7160_SUCCESS if successful. CDM7160_ERROR if fail
     */
    int8_t setAirPressureAndAltitude(uint16_t hpa = 1005, uint16_t height = 130);

    /** Read Atmospheric Pressure and Altitude - correction value calculation CO2
     * Data stored in variable: uint16_t atmosferic_pressure, uint16_t altitude
     * @return CDM7160_SUCCESS if successful. CDM7160_ERROR if fail
     */
    int8_t getAirPressureAndAltitude();

    /** Read Setting Register
     * settings information of PWM pin enable/disable, concentration range and
     * atmospheric pressure and altitude correction enable/disable
     * Data stored in variable: uint8_t settings
     * @return CDM7160_SUCCESS if successful. CDM7160_ERROR if fail
     */
    int8_t getSettings();

    /** Set Atmospheric Pressure and Altitude - to correct calculation CO2
     * @param atm_alt_correct - atm. pressure and altitude correction Enable/Disable
     * @param pwm_conce - PWM output contrntration High/Low
     * @param pwm_pin - PWM pin enable/disable
     * @return CDM7160_SUCCESS if successful. CDM7160_ERROR if fail
     */
    int8_t setSettings(eFunctionSetting atm_alt_correct= HPAE_OFF,
                       eFunctionSetting pwm_conce = PWMR_LOW,
                       eFunctionSetting pwm_pin = PWME_OFF);

    /** Self-test - diagnosis errors
     *  Data stored in variable: uint8_t selfDiag
     * @return CDM7160 address if successful. CDM7160_ERROR if fail
     */
    int8_t selfDiagnosis();

private:

    /**
     * Pointers to classes. 
     */
    I2C   *pI2C;
    
    /**
     * References to classes.
     */
    I2C   &_I2C;
    
    /*
     * ----- PRIVATE I2C FUNCTIONS -----
     */
    
    /** I2C read function.
     * @param data[] Data array to read from I2C
     * @param len Data length to read
     * @return Read status - 0 on success, non-0 on failure.
     */
    int8_t read(char data[], uint8_t len);
    
    /**
     * Write I2C register.
     * @param reg Register (1-Byte) to write
     * @returns Write status - 0 on success, non-0 on failure.
     */
    int8_t write(uint8_t reg);

    /** I2C write function.
     * @param reg Register (1-Byte) to Write
     * @param data[] Data array to write
     * @param len Data length to write
     * @return Write status - 0 on success, non-0 on failure.
     */
    int8_t write(uint8_t reg, char data[], uint8_t len);


};   
#endif // CDM7160_H