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