Звезда не активнаЗвезда не активнаЗвезда не активнаЗвезда не активнаЗвезда не активна
 

Чтение данных Sensirion SEN63C через адаптер KEL USB–I²C

Пошаговый разбор общения с датчиком качества воздуха на уровне сырых байт — включая всё, что шло не так по дороге.

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

Задача была простой: считать значения PM, температуры, влажности и CO₂ с датчика Sensirion SEN63C через адаптер KEL USB–I²C — небольшой модуль, который представляется компьютеру как виртуальный COM-порт и позволяет общаться с I²C-устройствами путём отправки ASCII/hex-последовательностей.

SEN63C находится на шине I²C по адресу 0x6B (7-бит). От адаптера KEL к датчику подключены все четыре линии: SDA, SCL, 3.3V и GND. Питание датчика берётся непосредственно с адаптера. На линиях SDA и SCL установлены подтягивающие резисторы 5,6 кОм к шине 3.3V.

Протокол KEL

Адаптер использует простой байтовый протокол поверх виртуального COM-порта:

Байт(ы) Команда Значение
1B RESET Сброс состояния адаптера
41 xx ADDRESS Установить адрес I²C-устройства
57 nn WLENGTH Количество байт для записи (макс. 64)
77 [данные] WDATA Байты для передачи
52 nn RLENGTH Количество байт для чтения (макс. 64)
53 START Выполнить I²C-транзакцию
73 STATUS Опрос: FF=занят, 00=готов
45 ERROR Последняя ошибка: 4E=нет, 61=NACK
72 RDATA Получить принятые байты

Первые попытки — и почему они провалились

Первый подход: отправить команду запуска измерений 00 21, затем сразу команду чтения значений 03 C4 с RLENGTH = 24 — всё в одной транзакции START, в расчёте на то, что адаптер сам обработает повторный старт I²C (repeated start).

Адаптер всегда сообщал об отсутствии ошибок (4E) и моментально переходил в состояние простоя (00), однако 72 неизменно возвращал FF FF FF FF... — буфер, заполненный нулями.

Ложный след: статус 00 появлялся мгновенно — это подозрительно, потому что реальное чтение 24 байт по I²C на скорости 100 кГц занимает минимум 2 мс. Это означало, что транзакция на шине вообще не выполнялась.

Было опробовано множество вариантов: разный порядок байт, разбиение сообщений, добавление задержек, опрос статуса. Всё возвращало FF. Байт ошибки всегда показывал 4E (нет ошибки) — что сбивало с толку, потому что что-то явно шло не так.

Прорыв — раздельные транзакции

Ключевое открытие пришло при тестировании совершенно другой команды: D0 14 (чтение названия продукта) — регистр, который работает в любом состоянии датчика, а не только во время измерений. Была опробована двухшаговая схема:

  1. Записать байты команды в датчик с RLENGTH = 0 (транзакция только на запись, полный STOP)
  2. Выполнить отдельную транзакцию чистого чтения с WLENGTH = 0 (только чтение, без команды)
TX: 41 6B 57 02 77 D0 14 52 00 53 ← отправить команду, затем STOP
TX: 41 6B 57 00 52 0C 53 ← чистое чтение 12 байт
TX: 72
RX: 53 45 83 4E 36 06 33 43 70 00 00 81

Декодирование: 53 45 = SE, 4E 36 = N6, 33 43 = 3C«SEN63C». Датчик работал и отвечал корректно. Адаптер попросту не поддерживает repeated-start — между фазой записи и фазой чтения необходим полный STOP.

Рабочая последовательность

Полная последовательность байт для запуска измерений и считывания одного набора данных:

# 1. Сброс адаптера и запуск измерений
1B 41 6B 57 02 77 00 21 52 00 53

# 2. Ждать 3 секунды до первого измерения

# 3. Проверка готовности данных (отправка команды)
41 6B 57 02 77 02 02 52 00 53

# 4. Чтение ответа о готовности (3 байта)
41 6B 57 00 52 03 53
72
# → 00 01 B0  (01 = данные готовы)

# 5. Отправка команды чтения результатов
41 6B 57 02 77 04 71 52 00 53

# 6. Чтение 21 байта данных измерений
41 6B 57 00 52 15 53
72
# → 00 11 F3 00 16 64 00 1A 19 00 1C BF 0C E3 A7 13 E0 03 01 B5 3F

Разбор результата

21 байт — это 7 значений по 3 байта каждое (2 байта данных + 1 байт CRC). Из первого успешного чтения:

00 11 F3  00 16 64  00 1A 19  00 1C BF  0C E3 A7  13 E0 03  01 B5 3F
Байты Сырое значение Масштаб Результат
00 11 17 ÷10 PM1.0 = 1,7 мкг/м³
00 16 22 ÷10 PM2.5 = 2,2 мкг/м³
00 1A 26 ÷10 PM4.0 = 2,6 мкг/м³
00 1C 28 ÷10 PM10 = 2,8 мкг/м³
0C E3 3299 ÷100 Влажность = 32,99 %
13 E0 5088 ÷200 Температура = 25,44 °C
01 B5 437 ×1 CO₂ = 437 ppm
Чистый воздух. Все значения PM значительно ниже норм ВОЗ. CO₂ на уровне 437 ppm близок к уличному фону. Температура и влажность выглядят правдоподобно.

Главные выводы

  • Адаптер KEL USB–I²C не поддерживает repeated-start (Sr). Запись и чтение должны быть двумя отдельными транзакциями с STOP между ними.
  • Всегда проверяйте байт ошибки (45) — 4E означает отсутствие ошибки, даже если данные приходят как FF.
  • Семейство SEN6x имеет одинаковый форм-фактор, но у каждого варианта свои коды команд. Всегда сверяйтесь с даташитом на конкретный артикул.
  • Статичный регистр вроде названия продукта (D0 14) — лучший первый тест: он работает в любом состоянии датчика и подтверждает работоспособность шины от начала до конца.
  • Запуск вентилятора SEN63C — отличное физическое подтверждение того, что транзакция записи была принята и выполнена датчиком корректно.