CCS811 цифровой газовый датчик

Узнайте все о CCS811: технические характеристики, распиновка, схемы подключения, datasheet и примеры кода для ESP32, Arduino, Raspberry

Качество воздуха I2C

Обзор

CCS811 — это цифровой газовый датчик для мониторинга качества воздуха в помещении. Он измеряет уровни летучих органических соединений (TVOC) и эквивалентного CO₂ (eCO₂), предоставляя ценные данные для систем вентиляции, умного дома и очистителей воздуха. Датчик работает через интерфейс I²C, что упрощает интеграцию в различные проекты.

Быстрая навигация

Характеристики Распиновка Подключение Отладка

Примеры кода

Где купить

Приобретите CCS811 цифровой газовый датчик

Технические характеристики

ПараметрЗначение
Напряжение питания3.3V - 5V DC
Ток потребления0.7µA (спящий режим), 1.2mA (активный режим)
Диапазон измерений400-8192 ppm (eCO₂), 0-1187 ppb (TVOC)
ИнтерфейсI²C
Рабочая температура-5°C - 50°C
Рабочая влажность10% - 95% RH
Размеры2.7mm x 4.0mm x 1.1mm

Скачать datasheet

Распиновка CCS811

Датчик CCS811 имеет 8 пинов для I²C коммуникации, питания и сигнальных линий.

Схема распиновки

CCS811 распиновка

Типы пинов

ТипКоличество
Питание2
Управление2

Описание пинов

ПинТипОписание
VDDПитаниеНапряжение питания (3.3V - 5V). Подключить к стабильному источнику питания.
GNDПитаниеЗемля. Подключить к системной земле.
SDAI²CЛиния данных I²C. Подключить к GPIO 21 (ESP32). Требуется подтягивающий резистор 4.7kΩ.
SCLI²CЛиния тактирования I²C. Подключить к GPIO 22 (ESP32). Требуется подтягивающий резистор 4.7kΩ.
nWAKEУправлениеПин пробуждения (активный LOW). Подключить к GND для непрерывной работы.
nINTПрерываниеПин прерывания (опционально). Активный LOW.
nRESETУправлениеПин сброса (активный LOW). Опционально.
ADDRАдресВыбор I²C адреса. GND = 0x5A, VDD = 0x5B. По умолчанию: 0x5A.

Подключение CCS811 к ESP32

Для подключения CCS811 к ESP32 используется интерфейс I²C.

Схема подключения

Подключение CCS811 к ESP32

Таблица подключения

CCS811 ПинПодключениеESP32 ПинОписание
VDDОбязательно3.3VПитание 3.3V
GNDОбязательноGNDЗемля
SDAОбязательноGPIO 21Линия данных I²C
SCLОбязательноGPIO 22Линия тактирования I²C
nWAKEОбязательноGNDПробуждение (активный LOW)
ADDRОбязательноGNDВыбор адреса (0x5A)
nINTОпциональноGPIO (любой)Прерывание
nRESETОпциональноVDD или GPIOСброс

Важно: требуются подтягивающие резисторы 4.7kΩ на линиях SDA и SCL.

Отладка

🔄 Периодические зависания датчика на ESP8266

Проблема: Датчик CCS811 периодически зависает на ESP8266, возвращая ошибку: False (255)

Причина: ESP8266 не может обработать требования CCS811 к растяжению тактового сигнала (clock stretching).

Решение: Добавьте задержки в I²C операции. Обновите прошивку датчика. Рассмотрите использование микроконтроллера с лучшей поддержкой I²C clock stretching.

❌ Ошибка инициализации на ESP8266

Проблема: Датчик не инициализируется: setup: CCS811 begin FAILED

Причина: Неправильное подключение, отсутствие подтягивающих резисторов или проблемы с clock stretching.

Решение: Проверьте подключение SDA/SCL. Добавьте резисторы 4.7kΩ. Убедитесь, что пин WAKE подключен к GND.

⚠️ Ошибка Remote I/O на ESP32

Проблема: Ошибка: OSError: [Errno 121] Remote I/O error

Причина: Неправильный I²C адрес или проблемы с clock stretching.

Решение: Проверьте адрес (0x5A или 0x5B). Уменьшите скорость шины I²C: добавьте dtparam=i2c_arm_baudrate=10000 в /boot/config.txt.

❓ Код ошибки 2

Проблема: Датчик возвращает код ошибки: ERROR! 2

Причина: Недостаточное время прогрева датчика.

Решение: Дайте датчику время для стабилизации после включения (минимум 20 минут для первого использования).

Примеры кода

Arduino

#include <Wire.h>
#include "Adafruit_CCS811.h"

Adafruit_CCS811 ccs;

void setup() {
    Serial.begin(9600);
    Wire.begin();
    
    if (!ccs.begin()) {
        Serial.println("Failed to start sensor! Please check your wiring.");
        while (1);
    }
    
    // Ожидание готовности датчика
    while (!ccs.available());
}

void loop() {
    if (ccs.available()) {
        if (!ccs.readData()) {
            Serial.print("eCO2: ");
            Serial.print(ccs.geteCO2());
            Serial.print(" ppm, TVOC: ");
            Serial.print(ccs.getTVOC());
            Serial.println(" ppb");
        } else {
            Serial.println("Error reading sensor data");
        }
    }
    delay(1000);
}

ESP-IDF

#include <stdio.h>
#include "driver/i2c.h"
#include "ccs811.h"

#define I2C_MASTER_SCL_IO 22
#define I2C_MASTER_SDA_IO 21
#define I2C_MASTER_NUM I2C_NUM_0
#define I2C_MASTER_FREQ_HZ 100000

void app_main(void) {
    i2c_config_t i2c_config = {
        .mode = I2C_MODE_MASTER,
        .sda_io_num = I2C_MASTER_SDA_IO,
        .scl_io_num = I2C_MASTER_SCL_IO,
        .sda_pullup_en = GPIO_PULLUP_ENABLE,
        .scl_pullup_en = GPIO_PULLUP_ENABLE,
        .master.clk_speed = I2C_MASTER_FREQ_HZ
    };
    
    i2c_param_config(I2C_MASTER_NUM, &i2c_config);
    i2c_driver_install(I2C_MASTER_NUM, I2C_MODE_MASTER, 0, 0, 0);
    
    ccs811_t sensor;
    ccs811_init(&sensor, I2C_MASTER_NUM, CCS811_ADDR_LOW);
    
    printf("Initializing CCS811\n");
    if (ccs811_start(&sensor) != CCS811_OK) {
        printf("Failed to start CCS811 sensor\n");
        return;
    }
    
    while (1) {
        uint16_t eco2, tvoc;
        if (ccs811_read_data(&sensor, &eco2, &tvoc) == CCS811_OK) {
            printf("eCO2: %d ppm, TVOC: %d ppb\n", eco2, tvoc);
        } else {
            printf("Error reading data from CCS811\n");
        }
        vTaskDelay(pdMS_TO_TICKS(1000));
    }
}

ESPHome

i2c:
  sda: GPIO21
  scl: GPIO22

sensor:
  - platform: ccs811
    eco2:
      name: "eCO2"
    tvoc:
      name: "TVOC"
    address: 0x5A
    update_interval: 1s

PlatformIO

platformio.ini:

[env:esp32dev]
platform = espressif32
board = esp32dev
framework = arduino
monitor_speed = 115200

main.cpp:

#include <Wire.h>
#include "Adafruit_CCS811.h"

Adafruit_CCS811 ccs;

void setup() {
    Serial.begin(115200);
    Wire.begin(21, 22); // SDA: GPIO21, SCL: GPIO22
    
    if (!ccs.begin()) {
        Serial.println("Failed to start sensor! Please check your wiring.");
        while (1);
    }
    
    while (!ccs.available()); // Ожидание готовности датчика
}

void loop() {
    if (ccs.available()) {
        if (!ccs.readData()) {
            Serial.print("eCO2: ");
            Serial.print(ccs.geteCO2());
            Serial.print(" ppm, TVOC: ");
            Serial.print(ccs.getTVOC());
            Serial.println(" ppb");
        } else {
            Serial.println("Error reading sensor data");
        }
    }
    delay(1000);
}

MicroPython

from machine import I2C, Pin
import time

# I2C адрес CCS811
CCS811_ADDR = 0x5A

# Регистры
MEAS_MODE = 0x01
ALG_RESULT_DATA = 0x02
APP_START = 0xF4
HW_ID = 0x20

# Инициализация I2C
i2c = I2C(0, scl=Pin(22), sda=Pin(21))

# Проверка датчика
hw_id = i2c.readfrom_mem(CCS811_ADDR, HW_ID, 1)
if hw_id[0] != 0x81:
    print("CCS811 not found!")
    while True:
        pass

# Запуск датчика
i2c.writeto(CCS811_ADDR, bytes([APP_START]))
time.sleep(0.1)

# Установка режима измерения
i2c.writeto_mem(CCS811_ADDR, MEAS_MODE, bytes([0x10]))

def read_data():
    data = i2c.readfrom_mem(CCS811_ADDR, ALG_RESULT_DATA, 8)
    eCO2 = (data[0] << 8) | data[1]
    TVOC = (data[2] << 8) | data[3]
    return eCO2, TVOC

while True:
    eCO2, TVOC = read_data()
    print(f"eCO2: {eCO2} ppm, TVOC: {TVOC} ppb")
    time.sleep(1)

Итоги

CCS811 — это мощный датчик качества воздуха с поддержкой множества платформ разработки: Arduino, ESP-IDF, ESPHome, PlatformIO и MicroPython.

Рекомендации

  • Для точных измерений дайте датчику прогреться минимум 20 минут при первом использовании
  • Используйте стабильный источник питания 3.3V
  • Добавьте подтягивающие резисторы 4.7kΩ на линиях SDA и SCL

Похожие датчики

  • AGS10 — датчик газов (VOC)
  • ENS160 — мультигазовый датчик (MOX)
  • MiCS-4514 — двухканальный газовый датчик