Guest User

ESP-IDF Code

a guest
Apr 23rd, 2026
57
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 2.59 KB | Source Code | 0 0
  1. #include <stdio.h>
  2. #include "freertos/FreeRTOS.h"
  3. #include "driver/gpio.h"
  4. #include "esp_log.h"
  5. #include "driver/i2c_master.h"
  6.  
  7. // Settings
  8. static const char* TAG = "AirQuality";
  9.  
  10. // I2C Variables
  11. i2c_master_bus_handle_t bus_handle; // this will hold the bus
  12. i2c_master_dev_handle_t scd40_handle;
  13.  
  14. void setup_i2c_bus() {
  15.     i2c_master_bus_config_t i2c_mst_config = {
  16.     .clk_source = I2C_CLK_SRC_DEFAULT,
  17.     .i2c_port = I2C_NUM_1, // tried 0,-1 to no avail
  18.     .scl_io_num = 4,
  19.     .sda_io_num = 3,
  20.     .glitch_ignore_cnt = 7,
  21.     .flags.enable_internal_pullup = true,
  22.     };
  23.  
  24.     ESP_ERROR_CHECK(i2c_new_master_bus(&i2c_mst_config, &bus_handle));
  25. }
  26.  
  27. void setup_scd40_device() {
  28.     i2c_device_config_t scd40_dev_cfg = {
  29.         .dev_addr_length = I2C_ADDR_BIT_LEN_7,
  30.         .device_address = 0x62,
  31.         .scl_speed_hz = 100000,
  32.     };
  33.  
  34.     ESP_ERROR_CHECK(i2c_master_bus_add_device(bus_handle, &scd40_dev_cfg, &scd40_handle));
  35. }
  36.  
  37. void start_scd40() {
  38.     uint8_t periodic_measurement_cmd[2] = {0x21, 0xb1};
  39.     ESP_ERROR_CHECK(i2c_master_transmit(scd40_handle, periodic_measurement_cmd, sizeof(periodic_measurement_cmd), -1));
  40.     vTaskDelay(pdMS_TO_TICKS(5000));
  41. }
  42.  
  43. void read_scd40() {
  44.     uint8_t read_measurement_cmd[2] = {0xec, 0x05};
  45.     i2c_master_transmit(scd40_handle, read_measurement_cmd, sizeof(read_measurement_cmd), -1);
  46.     vTaskDelay(pdMS_TO_TICKS(1));
  47.  
  48.     uint8_t buf[9];
  49.     i2c_master_receive(scd40_handle, buf, sizeof(buf), -1);
  50.  
  51.     // TODO: buf[2] is the crc of CO2, which should be checked
  52.     uint16_t co2 = (buf[0] << 8) | buf[1];
  53.     // TODO: buf[5] is the crc of TEMP, which should be checked
  54.     uint16_t temp_hex = (buf[3] << 8) | buf[4];
  55.     float temperature = -45.0 + 175.0 * ((float)temp_hex / 65535.0);
  56.     // TODO: buf[5] is the crc of HUM, which should be checked
  57.     uint16_t hum_hex = (buf[6] << 8) | buf[7];
  58.     float humidity = 100.0 * ((float)hum_hex / 65535.0);
  59.  
  60.     ESP_LOGI("SCD40", "CO2: %u ppm | Temp: %.2f C | Hum: %.2f %%", co2, temperature, humidity);
  61. }
  62.  
  63. void stop_scd40() {
  64.     uint8_t stop_measurement_cmd[2] = {0x3f, 0x86};
  65.     i2c_master_transmit(scd40_handle, stop_measurement_cmd, sizeof(stop_measurement_cmd), -1);
  66.     vTaskDelay(pdMS_TO_TICKS(500));
  67.     ESP_LOGI(TAG, "Stopped SCD40 periodic measurement");
  68. }
  69.  
  70. void app_main(void)
  71. {
  72.     vTaskDelay(pdMS_TO_TICKS(5000));
  73.     ESP_LOGI(TAG, "Starting...");
  74.  
  75.     setup_i2c_bus();
  76.     setup_scd40_device();
  77.  
  78.     start_scd40();
  79.  
  80.     for (uint8_t i = 0; i < 30; i++) {
  81.         read_scd40();
  82.         vTaskDelay(pdMS_TO_TICKS(5000));
  83.     }
  84.  
  85.     stop_scd40();
  86. }
  87.  
Tags: esp-idf
Advertisement
Add Comment
Please, Sign In to add comment