Indoor Air Quality Sensor Module
Dependents: Sensor_iAQ_core Sensor_iAQ_sgp30_bme_si7051 POCBreath_V2_smd_commercial
iAQ_Core.h@3:53c56ce59c29, 2018-06-11 (annotated)
- 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?
User | Revision | Line number | New 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 |