Indoor Air Quality Sensor Module

Dependents:   Sensor_iAQ_core Sensor_iAQ_sgp30_bme_si7051 POCBreath_V2_smd_commercial

Committer:
mcm
Date:
Mon Jun 11 12:31:22 2018 +0000
Revision:
3:53c56ce59c29
Parent:
2:cddf1d41f9b0
The driver was completed and tested ( using a NUCLEO-L152RE board ), it works as expected.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
mcm 1:9245bbbcbc40 1 /**
mcm 1:9245bbbcbc40 2 * @brief iAQ_Core.h
mcm 1:9245bbbcbc40 3 * @details Indoor air quality module, I2C interface.
mcm 1:9245bbbcbc40 4 * Header file.
mcm 1:9245bbbcbc40 5 *
mcm 1:9245bbbcbc40 6 *
mcm 1:9245bbbcbc40 7 * @return N/A
mcm 1:9245bbbcbc40 8 *
mcm 1:9245bbbcbc40 9 * @author Manuel Caballero
mcm 1:9245bbbcbc40 10 * @date 8/June/2018
mcm 1:9245bbbcbc40 11 * @version 8/June/2018 The ORIGIN
mcm 1:9245bbbcbc40 12 * @pre N/A
mcm 1:9245bbbcbc40 13 * @warning N/A
mcm 1:9245bbbcbc40 14 * @pre This code belongs to Nimbus Centre ( http://www.nimbus.cit.ie ).
mcm 1:9245bbbcbc40 15 */
mcm 1:9245bbbcbc40 16 #ifndef iAQ_Core_H
mcm 1:9245bbbcbc40 17 #define iAQ_Core_H
mcm 1:9245bbbcbc40 18
mcm 1:9245bbbcbc40 19 #include "mbed.h"
mcm 1:9245bbbcbc40 20
mcm 1:9245bbbcbc40 21
mcm 1:9245bbbcbc40 22 /**
mcm 1:9245bbbcbc40 23 Example:
mcm 1:9245bbbcbc40 24 @code
mcm 3:53c56ce59c29 25 #include "mbed.h"
mcm 3:53c56ce59c29 26 #include "iAQ_Core.h"
mcm 3:53c56ce59c29 27
mcm 3:53c56ce59c29 28 iAQ_Core myiAQ_Core ( I2C_SDA, I2C_SCL, iAQ_Core::iAQ_Core_ADDRESS );
mcm 3:53c56ce59c29 29 Serial pc ( USBTX, USBRX );
mcm 3:53c56ce59c29 30
mcm 3:53c56ce59c29 31 DigitalOut myled ( LED1 );
mcm 3:53c56ce59c29 32 Ticker newReading;
mcm 3:53c56ce59c29 33
mcm 3:53c56ce59c29 34 iAQ_Core::iAQ_Core_status_t aux;
mcm 3:53c56ce59c29 35 iAQ_Core::iAQ_Core_data_t myiAQ_Core_data;
mcm 3:53c56ce59c29 36 uint32_t myState = 0;
mcm 3:53c56ce59c29 37
mcm 3:53c56ce59c29 38
mcm 3:53c56ce59c29 39 void changeDATA ( void )
mcm 3:53c56ce59c29 40 {
mcm 3:53c56ce59c29 41 myState = 1;
mcm 3:53c56ce59c29 42 }
mcm 3:53c56ce59c29 43
mcm 3:53c56ce59c29 44
mcm 3:53c56ce59c29 45 int main()
mcm 3:53c56ce59c29 46 {
mcm 3:53c56ce59c29 47 uint32_t myWarmUpCounter = 0;
mcm 3:53c56ce59c29 48
mcm 3:53c56ce59c29 49
mcm 3:53c56ce59c29 50 pc.baud ( 115200 );
mcm 3:53c56ce59c29 51
mcm 3:53c56ce59c29 52 myled = 1;
mcm 3:53c56ce59c29 53 wait(3);
mcm 3:53c56ce59c29 54 myled = 0;
mcm 3:53c56ce59c29 55
mcm 3:53c56ce59c29 56
mcm 3:53c56ce59c29 57 // iAQ-Core warm up is at least 5 minutes ( 300 * 1s ) or when the sensor is ready
mcm 3:53c56ce59c29 58 do
mcm 3:53c56ce59c29 59 {
mcm 3:53c56ce59c29 60 aux = myiAQ_Core.iAQ_Core_GetNewReading ( &myiAQ_Core_data );
mcm 3:53c56ce59c29 61 wait(1);
mcm 3:53c56ce59c29 62 myWarmUpCounter++;
mcm 3:53c56ce59c29 63 } while( ( myWarmUpCounter < 300 ) && ( myiAQ_Core_data.status == iAQ_Core::iAQ_Core_STATUS_RUNIN ) );
mcm 3:53c56ce59c29 64
mcm 3:53c56ce59c29 65
mcm 3:53c56ce59c29 66 newReading.attach( &changeDATA, 1 ); // the address of the function to be attached ( changeDATA ) and the interval ( 1s )
mcm 3:53c56ce59c29 67
mcm 3:53c56ce59c29 68 // Let the callbacks take care of everything
mcm 3:53c56ce59c29 69 while(1)
mcm 3:53c56ce59c29 70 {
mcm 3:53c56ce59c29 71 sleep();
mcm 3:53c56ce59c29 72
mcm 3:53c56ce59c29 73 myled = 1;
mcm 3:53c56ce59c29 74
mcm 3:53c56ce59c29 75 if ( myState == 1 ) {
mcm 3:53c56ce59c29 76 // New reading
mcm 3:53c56ce59c29 77 do {
mcm 3:53c56ce59c29 78 aux = myiAQ_Core.iAQ_Core_GetNewReading ( &myiAQ_Core_data );
mcm 3:53c56ce59c29 79 wait_ms(1);
mcm 3:53c56ce59c29 80 } while( myiAQ_Core_data.status != iAQ_Core::iAQ_Core_STATUS_OK ); // [TODO] Dangerous!!! The uC may get stuck here if something goes wrong!
mcm 3:53c56ce59c29 81 // [WORKAROUND] Insert a counter.
mcm 3:53c56ce59c29 82
mcm 3:53c56ce59c29 83 // Send data through the UART
mcm 3:53c56ce59c29 84 pc.printf( "Pred: %d | Tvoc: %d | Resistance: %d\r\n", myiAQ_Core_data.pred, myiAQ_Core_data.Tvoc, myiAQ_Core_data.resistance );
mcm 3:53c56ce59c29 85 myState = 0; // Reset the variable
mcm 3:53c56ce59c29 86 }
mcm 3:53c56ce59c29 87
mcm 3:53c56ce59c29 88 myled = 0;
mcm 3:53c56ce59c29 89 }
mcm 3:53c56ce59c29 90 }
mcm 1:9245bbbcbc40 91 @endcode
mcm 1:9245bbbcbc40 92 */
mcm 1:9245bbbcbc40 93
mcm 1:9245bbbcbc40 94
mcm 1:9245bbbcbc40 95 /*!
mcm 1:9245bbbcbc40 96 Library for the iAQ_Core Indoor air quality module, I2C interface.
mcm 1:9245bbbcbc40 97 */
mcm 1:9245bbbcbc40 98 class iAQ_Core
mcm 1:9245bbbcbc40 99 {
mcm 1:9245bbbcbc40 100 public:
mcm 1:9245bbbcbc40 101 /**
mcm 1:9245bbbcbc40 102 * @brief DEFAULT ADDRESS
mcm 1:9245bbbcbc40 103 */
mcm 1:9245bbbcbc40 104 typedef enum {
mcm 1:9245bbbcbc40 105 iAQ_Core_ADDRESS = ( 0x5A << 1 ) /*!< Address for iAQ_Core */
mcm 1:9245bbbcbc40 106 } iAQ_Core_address_t;
mcm 1:9245bbbcbc40 107
mcm 1:9245bbbcbc40 108
mcm 1:9245bbbcbc40 109 // iAQ_Core DATA. NOTE: The I2C master can request up to 9 bytes.
mcm 1:9245bbbcbc40 110 /**
mcm 1:9245bbbcbc40 111 * @brief STATUS FLAG. NOTE: If status is OK the data is valid. If the status is BUSY, the data integrity is not guaranteed for
mcm 1:9245bbbcbc40 112 * variables of size > 8 bits, because the module may be updating a part of the variable. If the status
mcm 1:9245bbbcbc40 113 * is ERROR constantly (or very frequently) this indicates that the module is reading non-realistic values,
mcm 1:9245bbbcbc40 114 * and the sensor element is probably defective.
mcm 1:9245bbbcbc40 115 */
mcm 1:9245bbbcbc40 116 typedef enum {
mcm 1:9245bbbcbc40 117 iAQ_Core_STATUS_OK = 0x00, /*!< Status Flag: OK ( data valid ) */
mcm 1:9245bbbcbc40 118 iAQ_Core_STATUS_BUSY = 0x01, /*!< Status Flag: BUSY ( re-read multi byte data! ) */
mcm 1:9245bbbcbc40 119 iAQ_Core_STATUS_RUNIN = 0x10, /*!< Status Flag: RUNIN ( module in warm up phase ) */
mcm 1:9245bbbcbc40 120 iAQ_Core_STATUS_ERROR = 0x80 /*!< Status Flag: ERROR ( if constant: replace sensor ) */
mcm 1:9245bbbcbc40 121 } iAQ_Core_status_flag_t;
mcm 1:9245bbbcbc40 122
mcm 1:9245bbbcbc40 123
mcm 1:9245bbbcbc40 124
mcm 1:9245bbbcbc40 125
mcm 3:53c56ce59c29 126 #ifndef iAQ_Core_STRUCT_H
mcm 3:53c56ce59c29 127 #define iAQ_Core_STRUCT_H
mcm 1:9245bbbcbc40 128 typedef struct {
mcm 1:9245bbbcbc40 129 uint16_t pred; /*!< Prediction (CO2 eq. ppm), Typical Value: 450 */
mcm 1:9245bbbcbc40 130 iAQ_Core_status_flag_t status; /*!< Status, Typical Value: 0 */
mcm 1:9245bbbcbc40 131 int32_t resistance; /*!< Sensor resistance [Ohm], Typical Value: 256431 */
mcm 1:9245bbbcbc40 132 uint16_t Tvoc; /*!< Prediction (TVOC eq. ppb), Typical Value: 125 */
mcm 3:53c56ce59c29 133 } iAQ_Core_data_t;
mcm 1:9245bbbcbc40 134 #endif
mcm 1:9245bbbcbc40 135
mcm 1:9245bbbcbc40 136
mcm 1:9245bbbcbc40 137
mcm 1:9245bbbcbc40 138 /**
mcm 1:9245bbbcbc40 139 * @brief INTERNAL CONSTANTS
mcm 1:9245bbbcbc40 140 */
mcm 1:9245bbbcbc40 141 typedef enum {
mcm 1:9245bbbcbc40 142 iAQ_Core_SUCCESS = 0,
mcm 1:9245bbbcbc40 143 iAQ_Core_FAILURE = 1,
mcm 1:9245bbbcbc40 144 I2C_SUCCESS = 0 /*!< I2C communication was fine */
mcm 1:9245bbbcbc40 145 } iAQ_Core_status_t;
mcm 1:9245bbbcbc40 146
mcm 1:9245bbbcbc40 147
mcm 1:9245bbbcbc40 148
mcm 1:9245bbbcbc40 149
mcm 1:9245bbbcbc40 150 /** Create an iAQ_Core object connected to the specified I2C pins.
mcm 1:9245bbbcbc40 151 *
mcm 1:9245bbbcbc40 152 * @param sda I2C data pin
mcm 1:9245bbbcbc40 153 * @param scl I2C clock pin
mcm 1:9245bbbcbc40 154 * @param addr I2C slave address
mcm 1:9245bbbcbc40 155 */
mcm 2:cddf1d41f9b0 156 iAQ_Core ( PinName sda, PinName scl, uint32_t addr );
mcm 1:9245bbbcbc40 157
mcm 1:9245bbbcbc40 158 /** Delete iAQ_Core object.
mcm 1:9245bbbcbc40 159 */
mcm 1:9245bbbcbc40 160 ~iAQ_Core();
mcm 1:9245bbbcbc40 161
mcm 1:9245bbbcbc40 162 /** It performs a new parameters reading from the sensor.
mcm 1:9245bbbcbc40 163 */
mcm 3:53c56ce59c29 164 iAQ_Core_status_t iAQ_Core_GetNewReading ( iAQ_Core_data_t* myData );
mcm 1:9245bbbcbc40 165
mcm 1:9245bbbcbc40 166
mcm 1:9245bbbcbc40 167
mcm 1:9245bbbcbc40 168 private:
mcm 1:9245bbbcbc40 169 I2C _i2c;
mcm 1:9245bbbcbc40 170 uint32_t _iAQ_Core_Addr;
mcm 1:9245bbbcbc40 171 };
mcm 1:9245bbbcbc40 172
mcm 1:9245bbbcbc40 173 #endif