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

Чтение данных 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-порта:

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

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

Первый подход: отправить команду запуска измерений 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 1117÷10PM1.0 = 1,7 мкг/м³
00 1622÷10PM2.5 = 2,2 мкг/м³
00 1A26÷10PM4.0 = 2,6 мкг/м³
00 1C28÷10PM10 = 2,8 мкг/м³
0C E33299÷100Влажность = 32,99 %
13 E05088÷200Температура = 25,44 °C
01 B5437×1CO₂ = 437 ppm

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

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