Indoor Air Quality Sensor Module

Dependents:   Sensor_iAQ_core Sensor_iAQ_sgp30_bme_si7051 POCBreath_V2_smd_commercial

iAQ_Core.h

Committer:
mcm
Date:
2018-06-11
Revision:
3:53c56ce59c29
Parent:
2:cddf1d41f9b0

File content as of revision 3:53c56ce59c29:

/**
 * @brief       iAQ_Core.h
 * @details     Indoor air quality module, I2C interface.
 *              Header file.
 *
 *
 * @return      N/A
 *
 * @author      Manuel Caballero
 * @date        8/June/2018
 * @version     8/June/2018    The ORIGIN
 * @pre         N/A
 * @warning     N/A
 * @pre         This code belongs to Nimbus Centre ( http://www.nimbus.cit.ie ).
 */
#ifndef iAQ_Core_H
#define iAQ_Core_H

#include "mbed.h"


/**
    Example:
@code
#include "mbed.h"
#include "iAQ_Core.h"

iAQ_Core myiAQ_Core ( I2C_SDA, I2C_SCL, iAQ_Core::iAQ_Core_ADDRESS );
Serial pc           ( USBTX, USBRX );

DigitalOut  myled       ( LED1 );
Ticker      newReading;

iAQ_Core::iAQ_Core_status_t  aux;
iAQ_Core::iAQ_Core_data_t    myiAQ_Core_data;
uint32_t                     myState = 0;


void changeDATA ( void )
{
    myState = 1;
}


int main()
{
    uint32_t myWarmUpCounter  =   0;


    pc.baud ( 115200 );

    myled   =   1;
    wait(3);
    myled   =   0;


    // iAQ-Core warm up is at least 5 minutes ( 300 * 1s ) or when the sensor is ready
    do
    {
      aux      =   myiAQ_Core.iAQ_Core_GetNewReading ( &myiAQ_Core_data );
      wait(1);
      myWarmUpCounter++;
    } while( ( myWarmUpCounter < 300 ) && ( myiAQ_Core_data.status == iAQ_Core::iAQ_Core_STATUS_RUNIN ) );


    newReading.attach( &changeDATA, 1 );                                        // the address of the function to be attached ( changeDATA ) and the interval ( 1s )

    // Let the callbacks take care of everything
    while(1)
    {
      sleep();

      myled = 1;

      if ( myState == 1 ) {
        // New reading
        do {
            aux      =   myiAQ_Core.iAQ_Core_GetNewReading (  &myiAQ_Core_data );
            wait_ms(1);
        } while( myiAQ_Core_data.status != iAQ_Core::iAQ_Core_STATUS_OK );          // [TODO] Dangerous!!! The uC may get stuck here if something goes wrong!
                                                                                    // [WORKAROUND] Insert a counter.

        // Send data through the UART
        pc.printf( "Pred: %d | Tvoc: %d | Resistance: %d\r\n", myiAQ_Core_data.pred, myiAQ_Core_data.Tvoc, myiAQ_Core_data.resistance );
        myState  =   0;                                                             // Reset the variable
      }

      myled = 0;
    }
}
@endcode
*/


/*!
 Library for the iAQ_Core Indoor air quality module, I2C interface.
*/
class iAQ_Core
{
public:
    /**
    * @brief   DEFAULT ADDRESS
    */
    typedef enum {
        iAQ_Core_ADDRESS     =   ( 0x5A << 1 )      /*!<   Address for iAQ_Core                                             */
    } iAQ_Core_address_t;


    // iAQ_Core DATA. NOTE: The I2C master can request up to 9 bytes.
    /**
      * @brief   STATUS FLAG. NOTE: If status is OK the data is valid. If the status is BUSY, the data integrity is not guaranteed for
      *                             variables of size > 8 bits, because the module may be updating a part of the variable. If the status
      *                             is ERROR constantly (or very frequently) this indicates that the module is reading non-realistic values,
      *                             and the sensor element is probably defective.
      */
    typedef enum {
        iAQ_Core_STATUS_OK        =   0x00,         /*!<  Status Flag: OK      ( data valid )                               */
        iAQ_Core_STATUS_BUSY      =   0x01,         /*!<  Status Flag: BUSY    ( re-read multi byte data! )                 */
        iAQ_Core_STATUS_RUNIN     =   0x10,         /*!<  Status Flag: RUNIN   ( module in warm up phase )                  */
        iAQ_Core_STATUS_ERROR     =   0x80          /*!<  Status Flag: ERROR   ( if constant: replace sensor )              */
    } iAQ_Core_status_flag_t;




#ifndef iAQ_Core_STRUCT_H
#define iAQ_Core_STRUCT_H
    typedef struct {
        uint16_t                pred;               /*!<  Prediction (CO2 eq. ppm),  Typical Value: 450                     */
        iAQ_Core_status_flag_t  status;             /*!<  Status,                    Typical Value: 0                       */
        int32_t                 resistance;         /*!<  Sensor resistance [Ohm],   Typical Value: 256431                  */
        uint16_t                Tvoc;               /*!<  Prediction (TVOC eq. ppb), Typical Value: 125                     */
    } iAQ_Core_data_t;
#endif



    /**
      * @brief   INTERNAL CONSTANTS
      */
    typedef enum {
        iAQ_Core_SUCCESS    =       0,
        iAQ_Core_FAILURE    =       1,
        I2C_SUCCESS         =       0                           /*!<   I2C communication was fine                                                          */
    } iAQ_Core_status_t;




    /** Create an iAQ_Core object connected to the specified I2C pins.
      *
      * @param sda     I2C data pin
      * @param scl     I2C clock pin
      * @param addr    I2C slave address
      */
    iAQ_Core ( PinName sda, PinName scl, uint32_t addr );

    /** Delete iAQ_Core object.
     */
    ~iAQ_Core();

    /** It performs a new parameters reading from the sensor.
      */
    iAQ_Core_status_t iAQ_Core_GetNewReading     ( iAQ_Core_data_t* myData );



private:
    I2C      _i2c;
    uint32_t _iAQ_Core_Addr;
};

#endif