CO2, humidity, and temperature sensor
SCD30.h
- Committer:
- mcm
- Date:
- 2021-05-10
- Revision:
- 3:ca833b38050f
- Parent:
- 2:0d0174b46fd3
File content as of revision 3:ca833b38050f:
/** * @brief SCD30.h * @details CO2, humidity and temperature sensor. * Header file. * * * @return N/A * * @author Manuel Caballero * @date 07/May/2021 * @version 07/May/2021 The ORIGIN * @pre N/A * @warning N/A * @pre This code belongs to Nimbus Centre ( http://www.nimbus.cit.ie ). */ #ifndef SCD30_H_ #define SCD30_H_ #include "mbed.h" /** Example: @code #include "mbed.h" #include "SCD30.h" SCD30 mySCD30 ( I2C_SDA, I2C_SCL, SCD30::SCD30_ADDRESS, 100000 ); // I2C_SDA | I2C_SCL Serial pc ( USBTX, USBRX ); // tx, rx DigitalOut myled ( LED1 ); Ticker newAction; //@brief Constants. //@brief Variables. volatile uint32_t myState; // State that indicates when to perform a new sample //@brief FUNCTION PROTOTYPES void changeDATA ( void ); //@brief FUNCTION FOR APPLICATION MAIN ENTRY. int main() { SCD30::SCD30_status_t aux; SCD30::SCD30_data_t mySCD30_Data; pc.baud ( 115200 ); myled = 1; wait(3); myled = 0; // It performs a software reset aux = mySCD30.SCD30_SoftReset (); wait_ms (2000); // It gets the firmware version aux = mySCD30.SCD30_GetFirmwareVersion ( &mySCD30_Data.firmware ); pc.printf ( "Version Major: %d, Version Minor: %d\r\n", mySCD30_Data.firmware.version_major, mySCD30_Data.firmware.version_minor ); // It sets two mesurement interval mySCD30_Data.measurement_interval = 2U; aux = mySCD30.SCD30_SetMeasurementInterval ( mySCD30_Data.measurement_interval ); // It configures the continuous automatic self-calibration mySCD30_Data.asc = SCD30::CONTINUOUS_AUTOMATIC_SELF_CALIBRATION_ASC_ACTIVATE; aux = mySCD30.SCD30_SetContinuousASC ( mySCD30_Data.asc ); wait_ms(2000); // It sets the trigger without pressure compensation mySCD30_Data.pressure_compensation = 0U; aux = mySCD30.SCD30_TriggerContinuousMeasurement ( mySCD30_Data.pressure_compensation ); myState = 0UL; // Reset the variable newAction.attach( &changeDATA, 5U ); // the address of the function to be attached ( changeDATA ) and the interval ( 5s ) // Let the callbacks take care of everything while(1) { sleep(); if ( myState == 1UL ) { myled = 1U; // Trigger to get a new data set aux = mySCD30.SCD30_TriggerContinuousMeasurement ( mySCD30_Data.pressure_compensation ); // Wait for a new data value do { aux = mySCD30.SCD30_GetDataReadyStatus ( &mySCD30_Data.status ); wait_ms (100); } while( mySCD30_Data.status == SCD30::GET_READY_STATUS_BIT_DATA_NO_READY ); // Get all the values aux = mySCD30.SCD30_ReadMeasurement ( &mySCD30_Data.data ); // Send data through the UART pc.printf ( "CO2: %d ppm, T: %d C, RH: %d %%\r\n", (uint32_t)mySCD30_Data.data.processed.co2, (uint32_t)mySCD30_Data.data.processed.temperature, (uint32_t)mySCD30_Data.data.processed.humidity ); // Reset the variables myState = 0UL; myled = 0U; } } } // @brief changeDATA ( void ) // // @details It changes myState variable // // @param[in] N/A // // @param[out] N/A. // // @return N/A. // // @author Manuel Caballero // @date 07/May/2021 // @version 07/May/2021 The ORIGIN // @pre N/A // @warning N/A. void changeDATA ( void ) { myState = 1UL; } @endcode */ /*! Library for the SCD30 CO2, humidity and temperature sensor. */ class SCD30 { public: /** * @brief DEFAULT ADDRESS */ typedef enum { SCD30_ADDRESS = ( 0x61 << 1U ) /*!< SCD30 ADDR */ } SCD30_address_t; /** * @brief COMMAND REGISTERS */ typedef enum { SCD30_TRIGGERS_CONTINUOUS_MEASUREMENT = 0x0010, /*!< Triggers continuous measurement. Ambient pressure is optional */ SCD30_STOP_CONTINUOUS_MEASUREMENT = 0x0104, /*!< Stop continuous measurement */ SCD30_SET_MEASUREMENT_INTERVAL = 0x4600, /*!< Set measurement interval for continuous measurement mode */ SCD30_GET_DATA_READY_STATUS = 0x0202, /*!< Data ready status */ SCD30_READ_MEASUREMENT = 0x0300, /*!< Reads a single measurement of C02 concentration */ SCD30_CONTINUOUS_AUTOMATIC_SELF_CALIBRATION = 0x5306, /*!< Continuous automatic self-calibration can be (de-)activated */ SCD30_SET_FORCED_RECALIBRATION = 0x5204, /*!< Forced recalibration (FRC) */ SCD30_SET_TEMPERATURE_OFFSET = 0x5403, /*!< Temperature offset */ SCD30_SET_ALTITUDE_COMPENSATION = 0x5102, /*!< Altitude compensation */ SCD30_FIRMWARE_VERSION = 0xD100, /*!< Firmware version */ SCD30_SOFTRESET = 0xD304 /*!< Software reset: Restart the sensor */ } SCD30_command_registers_t; /** * @brief GET DATA READY STATUS. * NOTE: N/A. */ /* BIT <0> * NOTE: N/A. */ typedef enum { GET_READY_STATUS_BIT_MASK = ( 1U << 0U ), /*!< BIT mask */ GET_READY_STATUS_BIT_DATA_NO_READY = ( 0U << 0U ), /*!< Measurement is not ready to be read from the sensor */ GET_READY_STATUS_BIT_DATA_READY = ( 1U << 0U ) /*!< Measurement is ready to be read from the sensor */ } SCD30_get_ready_status_bit_t; /** * @brief CONTINUOUS AUTOMATIC SELF CALIBRATION. * NOTE: N/A. */ /* ASC <0> * NOTE: N/A. */ typedef enum { CONTINUOUS_AUTOMATIC_SELF_CALIBRATION_ASC_MASK = ( 1U << 0U ), /*!< ASC mask */ CONTINUOUS_AUTOMATIC_SELF_CALIBRATION_ASC_DEACTIVATE = ( 0U << 0U ), /*!< Deactivate continuous ASC */ CONTINUOUS_AUTOMATIC_SELF_CALIBRATION_ASC_ACTIVATE = ( 1U << 0U ) /*!< Activate continuous ASC */ } SCD30_continuous_auto_selfcal_t; /** * @brief CRC-8. * NOTE: Polynomial: 0x31 (x^8 + x^5 + x^4 + 1) * Initialization: 0xFF * Final XOR: 0x00. */ #define SCD30_CRC8_POLYNOMIAL 0x31 /*!< SCD30 CRC-8: Polynomial */ #define SCD30_CRC8_INITIALIZATION 0xFF /*!< SCD30 CRC-8: Initialization */ #define SCD30_CRC8_FINAL_XOR 0x00 /*!< SCD30 CRC-8: Final XOR */ #ifndef SCD30_VECTOR_STRUCT_H #define SCD30_VECTOR_STRUCT_H /* Firmware version */ typedef struct { uint8_t version_major; uint8_t version_minor; } SCD30_fw_version_t; /* Raw measurement data */ typedef struct { uint8_t co2_mmsb; uint8_t co2_mlsb; uint8_t co2_mmsb_mlsb_crc; uint8_t co2_lmsb; uint8_t co2_llsb; uint8_t co2_lmsb_llsb_crc; uint8_t temperature_mmsb; uint8_t temperature_mlsb; uint8_t temperature_mmsb_mlsb_crc; uint8_t temperature_lmsb; uint8_t temperature_llsb; uint8_t temperature_lmsb_llsb_crc; uint8_t humidity_mmsb; uint8_t humidity_mlsb; uint8_t humidity_mmsb_mlsb_crc; uint8_t humidity_lmsb; uint8_t humidity_llsb; uint8_t humidity_lmsb_llsb_crc; } SCD30_raw_output_data_t; /* Measurement processed data */ typedef struct { float co2; float temperature; float humidity; } SCD30_processed_data_t; /* Measurement data: Raw and processed data */ typedef struct { SCD30_raw_output_data_t raw; SCD30_processed_data_t processed; } SCD30_output_data_t; /* USER: User's variables */ typedef struct { /* Output data */ SCD30_output_data_t data; /*< Data (processed and raw): CO2, Temperature and Humidity */ /* Pressure compensation */ uint16_t pressure_compensation; /*< 0 (desactivates pressure compensation) or [700 - 1400]. Pressure in mBar */ /* Set measurement interval */ uint16_t measurement_interval; /*< [2 - 1800]. Interval in seconds */ /* Status */ SCD30_get_ready_status_bit_t status; /*< Measurement is ready to be read from the sensor */ /* (De-)Activate automatic self-calibration */ SCD30_continuous_auto_selfcal_t asc; /*< Continuos automatic self-calibration */ /* Forced recalibration */ uint16_t frc; /*< Value of C02 concentration in ppm */ /* Set temperature offset */ uint16_t temperature_offset; /*< Value of Temperature offset. [°C x 100]. One tick corresponds to 0.01 C */ /* Altitude compensation */ uint16_t altitude_compensation; /*< Altitude compensation value. Height over sea level in [m] above 0 */ /* Firmware version */ SCD30_fw_version_t firmware; /*< Firmware version */ } SCD30_data_t; #endif /** * @brief INTERNAL CONSTANTS */ typedef enum { SCD30_SUCCESS = 0, SCD30_FAILURE = 1, SCD30_DATA_CORRUPTED = 2, I2C_SUCCESS = 0 } SCD30_status_t; /** * @brief FUNCTION PROTOTYPES */ /** Create an SCD30 object connected to the specified I2C pins. * * @param sda I2C data pin * @param scl I2C clock pin * @param addr I2C slave address * @param freq I2C frequency in Hz. */ SCD30 ( PinName sda, PinName scl, uint32_t addr, uint32_t freq ); /** Delete SCD30 object. */ ~SCD30(); /** It configures the I2C peripheral. */ SCD30_status_t SCD30_Init ( void ); /** It triggers continuous measurement with or without ambient pressure compensation. */ SCD30_status_t SCD30_TriggerContinuousMeasurement ( uint16_t pressure_compensation ); /** It stops the continuous measurement. */ SCD30_status_t SCD30_StopContinuousMeasurement ( void ); /** It sets the measurement interval. */ SCD30_status_t SCD30_SetMeasurementInterval ( uint16_t measurement_interval ); /** It gets the measurement interval. */ SCD30_status_t SCD30_GetMeasurementInterval ( uint16_t* measurement_interval ); /** It gets the status when the data is ready to be read. */ SCD30_status_t SCD30_GetDataReadyStatus ( SCD30_get_ready_status_bit_t* status ); /** It gets all the raw data. */ SCD30_status_t SCD30_ReadRawMeasurement ( SCD30_raw_output_data_t* raw_data ); /** It gets all the data. */ SCD30_status_t SCD30_ReadMeasurement ( SCD30_output_data_t* data ); /** It enables/disables the continuous automatic self-calibration. */ SCD30_status_t SCD30_SetContinuousASC ( SCD30_continuous_auto_selfcal_t asc ); /** It gets the continuous automatic self-calibration bit. */ SCD30_status_t SCD30_GetContinuousASC ( SCD30_continuous_auto_selfcal_t* asc ); /** It sets the forced recalibration value. */ SCD30_status_t SCD30_SetForcedRecalibrationValue ( uint16_t frc ); /** It gets the forced recalibration value. */ SCD30_status_t SCD30_GetForcedRecalibrationValue ( uint16_t* frc ); /** It sets the temperature offset value. */ SCD30_status_t SCD30_SetTemperatureOffsetValue ( uint16_t temp_offset ); /** It gets the temperature offset value. */ SCD30_status_t SCD30_GetTemperatureOffsetValue ( uint16_t* temp_offset ); /** It sets the altitude compensation value. */ SCD30_status_t SCD30_SetAltitudeCompensationValue ( uint16_t alt_comp ); /** It gets the altitude compensation value. */ SCD30_status_t SCD30_GetAltitudeCompensationValue ( uint16_t* alt_comp ); /** It gets the firmware version value. */ SCD30_status_t SCD30_GetFirmwareVersion ( SCD30_fw_version_t* fw ); /** It performs a software reset. */ SCD30_status_t SCD30_SoftReset ( void ); private: /** It calculates the I2C checksum calculation (CRC-8). */ uint8_t SCD30_CalculateI2C_CRC8 ( uint16_t seed ); I2C _i2c; uint32_t _SCD30_Addr; }; #endif /* SCD30_H */