# SCD41 ESP-IDF Component A comprehensive ESP-IDF component for the Sensirion SCD41 CO2, temperature, and humidity sensor. ## Features - **CO2 Measurement**: High-precision CO2 concentration measurement (400 - 40,000 ppm) - **Temperature Measurement**: Accurate temperature measurement (-40°C to +70°C) - **Humidity Measurement**: Reliable relative humidity measurement (0% to 100% RH) - **I2C Communication**: Standard I2C interface with configurable port and timeout - **CRC Validation**: Built-in CRC8 checksum validation for data integrity - **Easy Integration**: Simple API with comprehensive error handling ## Hardware Requirements - **Sensor**: Sensirion SCD41 CO2 sensor module - **Interface**: I2C (3.3V logic level) - **Connections**: - VDD: 3.3V - GND: Ground - SDA: I2C data line - SCL: I2C clock line ## Installation ### ESP Registry (Recommended) ```bash idf.py add-dependency "chiehmin/scd41^1.0.0" ``` ### Manual Installation 1. Clone or download this component 2. Place it in your project's `components` directory 3. Include the header in your code: `#include "scd41.h"` ## Quick Start ### Basic Usage ```c #include "scd41.h" #include "esp_log.h" #include "freertos/FreeRTOS.h" #include "freertos/task.h" static const char *TAG = "SCD41_EXAMPLE"; void app_main(void) { // Configure I2C master (you need to do this before using the component) i2c_config_t conf = { .mode = I2C_MODE_MASTER, .sda_io_num = 21, // GPIO pin for SDA .scl_io_num = 22, // GPIO pin for SCL .sda_pullup_en = GPIO_PULLUP_ENABLE, .scl_pullup_en = GPIO_PULLUP_ENABLE, .master.clk_speed = 100000, // 100kHz }; ESP_ERROR_CHECK(i2c_param_config(I2C_NUM_0, &conf)); ESP_ERROR_CHECK(i2c_driver_install(I2C_NUM_0, conf.mode, 0, 0, 0)); // Initialize SCD41 scd41_config_t config = SCD41_CONFIG_DEFAULT(); config.i2c_port = I2C_NUM_0; config.timeout_ms = 1000; ESP_ERROR_CHECK(scd41_init(&config)); ESP_ERROR_CHECK(scd41_start_measurement()); // Wait for first measurement (5 seconds) vTaskDelay(pdMS_TO_TICKS(5000)); while (1) { scd41_data_t data; esp_err_t ret = scd41_read_measurement(&data); if (ret == ESP_OK && data.data_ready) { ESP_LOGI(TAG, "CO2: %d ppm, Temperature: %.1f°C, Humidity: %.1f%%", data.co2_ppm, data.temperature, data.humidity); } else { ESP_LOGW(TAG, "Failed to read sensor data"); } // SCD41 provides new data every 5 seconds vTaskDelay(pdMS_TO_TICKS(5000)); } } ``` ## API Reference ### Configuration #### `scd41_config_t` Configuration structure for the SCD41 sensor. ```c typedef struct { i2c_port_t i2c_port; ///< I2C port number (I2C_NUM_0 or I2C_NUM_1) uint32_t timeout_ms; ///< I2C timeout in milliseconds } scd41_config_t; ``` #### `SCD41_CONFIG_DEFAULT()` Macro for default configuration: - I2C port: `I2C_NUM_0` - Timeout: `1000ms` ### Data Structures #### `scd41_data_t` Structure containing sensor measurement data. ```c typedef struct { uint16_t co2_ppm; ///< CO2 concentration in parts per million float temperature; ///< Temperature in degrees Celsius float humidity; ///< Relative humidity in percent bool data_ready; ///< Flag indicating if data is valid } scd41_data_t; ``` ### Functions #### `esp_err_t scd41_init(const scd41_config_t *config)` Initialize the SCD41 sensor. **Parameters:** - `config`: Pointer to configuration structure **Returns:** - `ESP_OK`: Success - `ESP_ERR_INVALID_ARG`: Invalid configuration - Other ESP error codes for I2C communication failures #### `esp_err_t scd41_start_measurement(void)` Start periodic measurement mode. **Returns:** - `ESP_OK`: Success - Other ESP error codes for communication failures #### `esp_err_t scd41_stop_measurement(void)` Stop periodic measurement mode. **Returns:** - `ESP_OK`: Success - Other ESP error codes for communication failures #### `esp_err_t scd41_read_measurement(scd41_data_t *data)` Read the latest measurement data. **Parameters:** - `data`: Pointer to data structure to store results **Returns:** - `ESP_OK`: Success - `ESP_ERR_INVALID_ARG`: Null pointer - `ESP_ERR_INVALID_CRC`: CRC validation failed - Other ESP error codes for communication failures #### `esp_err_t scd41_get_serial_number(uint8_t serial_number[6])` Get the sensor's 6-byte serial number. **Parameters:** - `serial_number`: Buffer to store the serial number **Returns:** - `ESP_OK`: Success - Other ESP error codes for communication failures #### `esp_err_t scd41_reset(void)` Perform a soft reset of the sensor. **Returns:** - `ESP_OK`: Success - Other ESP error codes for communication failures #### `esp_err_t scd41_data_ready(bool *ready)` Check if new measurement data is available. **Parameters:** - `ready`: Pointer to boolean to store ready status **Returns:** - `ESP_OK`: Success - `ESP_ERR_INVALID_ARG`: Null pointer - Other ESP error codes for communication failures ## Technical Specifications ### Sensor Specifications - **CO2 Range**: 400 - 40,000 ppm - **CO2 Accuracy**: ±(40 ppm + 5% of reading) - **Temperature Range**: -40°C to +70°C - **Temperature Accuracy**: ±0.8°C - **Humidity Range**: 0% to 100% RH - **Humidity Accuracy**: ±6% RH - **Update Rate**: 5 seconds ### Communication - **Interface**: I2C - **I2C Address**: 0x62 (fixed) - **Clock Speed**: Up to 100 kHz - **Supply Voltage**: 2.4V to 5.5V (3.3V recommended) ## Troubleshooting ### Common Issues 1. **Sensor not responding** - Check I2C connections (SDA, SCL, VDD, GND) - Verify I2C pull-up resistors (4.7kΩ recommended) - Ensure correct I2C port configuration 2. **CRC errors** - Check for electrical noise on I2C lines - Reduce I2C clock speed - Add ferrite beads or capacitors for noise filtering 3. **Inconsistent readings** - Allow proper warm-up time (> 1 minute) - Ensure adequate ventilation around sensor - Check for electromagnetic interference ## License Apache License 2.0 ## References - [Sensirion SCD41 Datasheet](https://sensirion.com/products/catalog/SCD41/) - [ESP-IDF I2C Driver Documentation](https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/peripherals/i2c.html)
idf.py add-dependency "chiehmin/scd41^1.0.0"