Термодатчик в теплице я вынес на пять метров плоским шлейфом. Первый день всё было отлично, на второй половина опросов вернула мусор, на третий шина умолкла совсем. Я рассудил по-новичковски: сигнал слабый — добавлю подтяжек. Стало хуже: экран показывал кракозябры ещё чаще. Так я познакомился с главным врагом длинного I2C — не сопротивлением проводов, а их ёмкостью.
В этом уроке посчитаем бюджет ёмкости шины в пФ и метрах, выберем подтяжку под длину, разберём, что делает Wire.setClock(), и познакомимся с буферами-повторителями P82B715 и P82B96 — микросхемами, которые переносят шину на десятки метров. А в конце обсудим честную альтернативу: иногда вместо удлинителя проще перенести мастера к датчику.
Почему шина устаёт с расстоянием
Шина I2C — открытый сток: устройства умеют только прижимать линии к земле, вверх их поднимают подтяжки, заряжая ёмкость провода, как ведром наполняют бассейн. Чем длиннее провод, тем больше ёмкость и тем более пологим становится фронт. Стандарт отводит на 100 кГц бюджет 400 пФ и требует, чтобы фронт уложился примерно в микросекунду. Ориентировочная ёмкость плоского шлейфа — около 50 пФ на метр: восемь метров — и бюджет исчерпан, а dupont-скрутки через макетку добавляют сверху ещё и сами контакты. Формула фронта простая: примерно 0,85 × R × C. При подтяжке 4,7 кОм и линии на 200 пФ фронт выходит 0,8 мкс — впритык к лимиту; добавьте метр-другой — и мастер начнёт читать на границе нуля и единицы.
Лечится это тремя ходами по нарастающей. Первый: ужать подтяжку с 4,7 кОм до 2,2 кОм — фронт станет вдвое круче. Второй: снизить скорость через Wire.setClock(50000) — на 50 кГц лимит фронта удваивается, и тот же кабель проходит со запасом. Третий — про буферы, он отдельный. А вот подтягивать линию вниз бесконечно нельзя, и об этом ниже. Подробно про подтяжки 4,7 кОм и открытый сток мы говорили в уроке про устройство шины — здесь считаем их применительно к метрам.
| Длина | Типовая проводка | Что ставить |
|---|---|---|
| До 0,5 м | Dupont-провода через макетку | Подтяжки модулей 4,7 кОм, 100 кГц — без вопросов |
| 0,5–2 м | Цельные провода, один шлейф | 2,2–3,3 кОм, 100 кГц |
| 2–10 м | Витая пара, земля рядом с каждым сигналом | 1,5–2,2 кОм и 50 кГц через Wire.setClock() |
| Дальше 10 м | Кабель | Буфер P82B715/P82B96 или мастер у датчика |
Моя история-тупик с теплицей развивалась по всем законам жанра. Половина опросов возвращала мусор — и я решил «ускорить» шину до 400 кГц, чтобы данные проходили быстрее. На 400 кГц лимит фронта — 300 наносекунд, а мой фронт на шлейфе был около 800: мастер стал читать состояния линий до того, как они устоялись. Шина превратилась в генератор случайных чисел, и я потерял на это полвечера. Правильное лечение оказалось противоположным по смыслу: Wire.setClock(50000) — и через минуту показания встали ровными. Длина лечится не скоростью, а её отсутствием.
К слову о том, что рядом. Шину я вёл в одном жгуте с проводами реле полива — и половина помех приходила оттуда: щёлкнуло реле — в линии всплеск, слейв пропустил бит. Правило, которое я вынес: каждый сигнальный провод — между землями, силовые — в отдельном жгуте, а лучше и в другой стороне.
Активные удлинители: буферы-повторители
Когда метры нужны, а скорость терять не хочется, в дело вступают буферы. Микросхема P82B715 — усилитель шины: втекающий ток она поднимает примерно в десять раз, а значит, во столько же раз можно увеличить и ёмкость — бюджет 400 пФ превращается в 4000 пФ, это десятки метров шлейфа. Со стороны мастера она выглядит как обычное устройство, а в сторону кабеля выдаёт пожёстче: по даташиту там ставят подтяжку порядка 680 Ом. P82B96 — следующий уровень: буфер, рассчитанный на кабельные линии, — в апноутах производителя он тянет и сотни метров по витой паре на 100 кГц. Обе микросхемы двунаправленные и не требуют управляющих пинов: воткнул между мастером и кабелем — и поехал.
Моё мнение с границей применимости: для теплицы на пять метров я взял пару P82B96 — и не прогадал, линия стоит третий год. Но чаще честнее другой путь: Pro Mini у датчика стоит дешевле одного буфера, а данные уезжают по UART или радиоканалу без капризов. Если датчиков много и они далеко — переносите мастер к датчикам, а не датчики к мастеру. Про то, что делать, когда дальняя линия всё же заедает, у меня есть отдельный урок про зависания шины — таймауты и счётчик потерь там как раз пригодятся.
#include <Wire.h> const byte SENSOR = 0x68; // часы DS3231 в роли дальнего слейваint vsego = 0;int poteri = 0; void setup() { Wire.begin(); Wire.setClock(50000); // 50 кГц: лимит фронта вдвое больше Serial.begin(9600); Serial.println("Monitor dalnej linii, 50 kHz");} void loop() { unsigned long t0 = millis(); Wire.beginTransmission(SENSOR); byte code = Wire.endTransmission(); vsego++; if (code == 0) { Wire.requestFrom(SENSOR, 2); unsigned long deadline = millis() + 200; while (Wire.available() < 2 && millis() < deadline) { delay(1); // ждём с дедлайном, не вечно } if (Wire.available() >= 2) { int a = Wire.read(); int b = Wire.read(); Serial.print("ping=ok bayt="); Serial.print(a); Serial.print("."); Serial.println(b); } else { poteri++; Serial.println("ping=net (tajmaut)"); } } else { poteri++; Serial.print("ping=net code="); Serial.println(code); } Serial.print("vremya_ms="); Serial.println(millis() - t0); Serial.print("vsego="); Serial.print(vsego); Serial.print(" poteri="); Serial.println(poteri); delay(2000);}Приёмка линии в эксплуатацию
Скетч выше — это половина протокола приёмки. Полный у меня такой. Сначала сканер адресов на новой линии: если он видит устройства — физика в порядке, адреса на месте. Потом счётчик потерь на час работы: мой критерий — ноль потерь за час на 50 кГц. Одна потеря — пересматриваем подтяжку и разводку; потери пачками — снижаем скорость дальше или ставим буфер. И время ответа следим: на короткой линии ping укладывается в единицы миллисекунд, если vremya_ms поползло вверх — кабель стареет, контакт уходит.
Ещё две привычки, которые сберегли мне нервы. Первая: на длинных линиях я всегда оставляю запас — рассчитал на 10 метров, ставлю подтяжку и скорость как на 20. Вторая: любые изменения в жгуте (перенесли реле, добавили ленту) — заново час приёмки. Ёмкость не прощает самоуверенности: она копится незаметно, а предъявляется разом.
- Бюджет шины на 100 кГц — 400 пФ ёмкости; шлейф добавляет около 50 пФ на метр, dupont и макетка — сверху
- Фронт считается как 0,85 × R × C: при 4,7 кОм и 200 пФ это 0,8 мкс против лимита в 1 мкс
- Подтяжка ниже ~1,5 кОм при 5 В запрещена: слейв обязан втягивать 3 мА
- Длину лечат по нарастающей: короче, подтяжка 2,2 кОм, Wire.setClock(50000), буфер P82B715/P82B96
- Критерий приёмки линии — ноль потерь за час; счётчик poteri из урока показывает это вживую
- 1. Какой бюджет ёмкости отводит стандарт шине на 100 кГц?
- 2. Плоский монтажный шлейф добавляет ёмкости примерно:
- 3. Ниже какого номинала нельзя ставить подтяжку при питании 5 В?
- 4. Что делает P82B715?
- 5. Дальняя линия начала давать мусор. Что я сделал зря, подняв скорость до 400 кГц?
Итого: шина не имеет счётчика метров — у неё счётчик пикафарад, и он честнее. Посчитайте ёмкость, ужмите подтяжку, снизьте скорость — и пять метров перестанут быть проблемой; а когда метры измеряются десятками, берите P82B96 или переносите мастера. В следующем уроке речь пойдёт о другом соседстве на шине: 3,3-вольтовые и 5-вольтовые устройства в одной схеме — чем опасно прямое подключение и как устроен двунаправленный конвертер уровней.
Частые вопросы по теме урока
- Какой бюджет ёмкости отводит стандарт шине на 100 кГц?
- 400 пФ суммарно на всю шину. Плоский шлейф съедает этот бюджет примерно за восемь метров. 400 пФ
- Плоский монтажный шлейф добавляет ёмкости примерно:
- Около 50 пФ на метр. Dupont-скрутки и макетные контакты добавляют ещё сверху. 50 пФ на метр
- Ниже какого номинала нельзя ставить подтяжку при питании 5 В?
- Стандарт требует втягивания 3 мА: (5 − 0,4) В / 3 мА ≈ 1,5 кОм. Слабее — линия не опустится до честного нуля. Ниже 1,5 кОм
- Что делает P82B715?
- Десятикратный запас по току означает десятикратный запас по ёмкости: 400 пФ превращаются в 4000 пФ. Усиливает втекающий ток примерно в десять раз
- Дальняя линия начала давать мусор. Что я сделал зря, подняв скорость до 400 кГц?
- На 400 кГц лимит фронта 300 нс. Длинная линия даёт фронт вдвое-втрое больше — мастер читает неустоявшиеся уровни. Ужесточил требования к фронту втрое — на длинной линии это гарантированный сбой