Посылка с тремя датчиками BME280 приехала в один день, и все три смотрели на меня чистой площадкой SDO без единой перемычки — 0x76 у каждого. Первый датчик завёлся, второй лёг на ту же строку сканера, третий тоже, и «на шине один адрес» здесь значит совсем не «на шине одно устройство». Сканер честно доложил: на 0x76 кто-то есть. Считать, сколько именно чипов подняли за этим адресом руку, он не умеет — в этом и есть весь конфликт адресов, если коротко.
Физику наложения — двое прижимают SDA вразнобой, мастер читает средний уровень и получает мусор — я разбирал в уроке про одинаковые адреса; там же про токи: миллиамперы, ничего не выгорает, байты портятся тихо. Здесь практическая сторона: как доказать конфликт за три прогона сканера, какие перемычки и переключатели бывают у типовых модулей и что делать, когда перемычек нет вовсе. Протокол короткий, и после третьей посылки он занимает у меня меньше минуты.
Отдельно о том, почему сканер не виноват. Девятый такт каждой рамки читается мастером как один бит — подтверждение или молчание, и больше информации в ней нет. Двое ACK-ают одновременно — для мастера это неотличимо от одного. Различить их может только метод исключения: отключать модули по одному и сравнивать распечатки. Отсюда рабочая оговорка на всю жизнь: «подтверждение» в сканере — ответ анонима, и доверять ему можно ровно настолько, насколько вы уверены в составе шины.
Сканер против двоих: три прогона вместо гадания
Мой протокол такой. Прогон первый — все модули на шине: список адресов переписывается. Дальше отключаю подозреваемых по одному, после каждого — скан: список ужимается, и видно, кто именно пропал. Двое на одном адресе выдаёт себя трюком «отключил один — строка осталась»: значит, за ней стояли минимум двое. Финальный прогон — после разведения: адресов стало ровно по числу модулей, и каждый закреплён за своим. Диагност из урока про коды endTransmission добавит к списку вердикт по каждому адресу, но для развода хватает и обычного сканера.
Пара тонкостей, на которых протокол спотыкается. Конфликт нестабилен: то кадр проходит, то нет, поэтому один удачный скан — не оправдание; сравнивайте две-три распечатки подряд. И следите за партией: мне однажды привезли переходники PCF8574A вместо PCF8574 — ожидаемый 0x27 не отвечал, а 0x3F молча жил на шине. Разбор «сканер видит адрес, модуль молчит» с чек-листом сделал отдельный урок — конфликт адресов и переезд на 0x3F сидят в его первых строчках.
Границы скана тоже стоит понимать: в моём цикле адрес бегает с 8 по 119, потому что по краям живут служебные номера. Ноль отдан под общий вызов, первые семь адресов закреплены за протоколом, диапазон от 120 до 127 зарезервирован стандартом — чипа с честным адресом там я не встречал ни разу. Отклик за границей — тревожный знак: наводки, втиснувшиеся в паузу, или слейв с плавающим питанием, который отвечает хаотично.
Дерутся чаще всего три пары, и все три я проходил. Одинаковые экраны с заводскими переходниками — классика: куплены в разные годы, а адрес один. Одинаковые датчики из одной посылки — мой случай с BME280: продавец просто не разложил их по партиям. И пара «часы плюс гироскоп», у которых 0x68 зашито с завода. Отдельная категория — самодельные сборки: я однажды напаял два одинаковых модуля на одну плату и, разумеется, забыл развести их с порога. Отсюда привычка, которую я завёл после того года: сканер — до первого включения новой покупки, а не после первого глюка. Тридцать секунд до сборки против вечера с двумя молчащими модулями.
| Модуль | Адрес с завода | Чем двигается | Второй адрес |
|---|---|---|---|
| BME280 / BMP280 | 0x76 | пин SDO (земля или питание) | 0x77 |
| OLED SSD1306 | 0x3C | контактные площадки под пайку | 0x3D |
| SHT31 | 0x44 | пин ADDR | 0x45 |
| ADS1115 | 0x48 | пин ADDR | 0x49–0x4B |
| MPU6050 и DS3231 | оба 0x68 | у MPU6050 есть AD0, у DS3231 нет | 0x69 или мультиплексор |
Перемычки: паяльник, капля олова — и адрес новый
Перемычки бывают трёх пород, и к каждой нужна своя привычка. Контактные площадки под каплю олова — на платах OLED и переходников: замкнул жало — адрес сдвинулся. Штырь с джампером — на щитовых модулях и платах расширения: переставил колпачок — готово. Отдельный пин ADDR, SDO или AD0 — на сенсорных платах: его подают на землю или на питание, и у ADS1115 таких комбинаций хватает на четыре адреса 0x48–0x4B. Перепаиваю только на обесточенной плате — дешёвая страховка от случайных пяти вольт на жилу.
После каждого движения — контрольный скан и стикер с новым адресом на корпус. Две истории из личного архива: OLED после замыкания площадки остался на 0x3C, потому что капля легла на соседние контакты с обратной стороны платы; BME280 «отказался» переезжать на 0x77, пока я не вспомнил, что SDO у него подтянут изнутри, и мой внешний провод на землю спорил с этой подтяжкой. Мораль обеих историй одна: сканер после каждого действия и ровно одно изменение за прогон.
Отдельная семейная пара грабель — висящие ноги. SDO, оставленный в воздухе на самодельной плате, плавает вместе с наводками, и датчик время от времени отвечает то на 0x76, то на 0x77: сканер рисует адрес, который никто не паял. С плавающим ADDR у ADS1115 я видел то же — отклик гулял между 0x48 и 0x49. Лечение одно: каждой адресной ноге жёсткое место — земля или питание, пусть даже без джампера, просто каплей припоя на площадку.
У PCF8574 спектр шире всех: три адресных входа дают восемь дверей, а вместе с PCF8574A — шестнадцать чипов на шине. У DS3231 двери нет вовсе: 0x68 зашито в кристалл, и паре «часы плюс MPU6050» помогает только мультиплексор TCA9548A с восемью независимыми ветками или второй программный порт — bit-bang шина на любых пинах поднимается двумя резисторами и парой строк кода.
Проверка разведения помещается в один скетч, он ниже: два зондера на пару адресов и три исхода — две строки, одна или ни одной. Две строки — разведено, каждому своё; одна — перемычка не взялась или легла мимо, паяльник обратно и сравнение с прошлой распечаткой; ни одной — не конфликт, а физика, и искать надо питание с подтяжками, а не SDO. Если пара из разных диапазонов — скажем PCF8574 и PCF8574A — проба ещё и показывает, чья база где: константы для основного скетча становятся фактом, а не догадкой из двух попыток.
#include <Wire.h> // Проверка развода пары BME280: ждём ровно один отклик на каждый// из двух адресов. Прогон после каждой перемычки; одно изменение за прогон.void probe(int addr) { Wire.beginTransmission(addr); int code = Wire.endTransmission(); if (code == 0) { Serial.print("0x"); if (addr < 16) Serial.print("0"); Serial.println(addr, HEX); }} void setup() { Wire.begin(); Serial.begin(9600); Serial.println("Пара BME280: ждём отклики на 0x76 и 0x77"); probe(0x76); probe(0x77); Serial.println("Расшифровка:"); Serial.println("две строки - разведено, каждому своё"); Serial.println("одна строка - за ней двое, сканер не считает чипы"); Serial.println("ни одной - шина молчит: питание, земля, подтяжки");} void loop() { delay(3000);}Симулятор упрощает одну вещь, и честно об этом: конфликт в нём живёт в модели, а не в физике — движок ACK-ает любой адрес, и наложение двух чипов на одной линии не рисуется. На живой шине к этому добавится главное удовольствие конфликта: список может плясать между прогонами, потому что двое прижимают SDA вразнобой. Вывод от этого не меняется: одна строка сканера — не счёт устройств, и прогон после каждого отключения остаётся дешёвым способом посчитать жильцов.
Разводка не отменяет паспорта шины. Лист бумаги на крышке проекта: адрес — владелец — дата пайки перемычек. Когда через год понадобится добавить датчик, вы за минуту узнаете, что 0x76 занят, 0x68 у часов, а 0x44 достался новому. Без паспорта каждый новый модуль — повторный археологический обход всей шины со сканером в руках и ламповым чувством, что где-то это уже было.
Симулятор облегчает одну вещь, и честно об этом: конфликт в нём живёт в модели, а не в физике — движок ACK-ает любой адрес, и наложение двух чипов на одной линии не рисуется. На живой шине к этому добавится главное удовольствие конфликта: список может плясать между прогонами, потому что двое прижимают SDA вразнобой. Вывод от этого не меняется: одна строка сканера — не счёт устройств, и прогон после каждого отключения остаётся дешёвым способом посчитать жильцов.
Совет из того же гаражного ящика: одна перемычка за прогон. Развели оба адреса сразу — не факт, что оба взялись, и вы будете искать виновника вслепую. Меняйте по одной, после каждой — сканер и стикер. Три минуты против вечера с двумя изменениями одновременно: та же дисциплина, что и в любой диагностике, от реле до сериал-протоколов.
- 1. Сканер показывает 0x76, на шине заведомо два BME280. Сколько строк он напечатает и почему?
- 2. Какой пин у BME280 двигает адрес?
- 3. Часы DS3231 и гироскоп MPU6050 просят один адрес 0x68. Быстрый развод?
- 4. Отключили одного из двух конфликтующих жильцов, строка 0x76 осталась в скане. Вывод?
- 5. Перемычку SDO замкнули на питание при включённой плате. Что рекомендую?
- Одна строка сканера — не счёт устройств: двое ACK-ают на одном такте неотличимо от одного
- Протокол развода: скан — отключение по одному — скан после каждой перемычки; одно изменение за прогон
- Каталог переключателей: SDO у BME280 (0x76/0x77), ADDR у SHT31 (0x44/0x45) и ADS1115 (0x48–0x4B), A0–A2 у PCF8574, AD0 у MPU6050
- У DS3231 перемычек нет: 0x68 зашито — спасают мультиплексор TCA9548A или bit-bang порт на двух пинах
- После каждой пайки — контрольный скан и стикер: паспорт шины экономит вечер через полгода
Частые вопросы по теме урока
- Сканер показывает 0x76, на шине заведомо два BME280. Сколько строк он напечатает и почему?
- В рамке ровно один бит подтверждения. Двое прижимают SDA на том же такте, что и один, — мастер видит «кто-то есть» и не может посчитать, сколько именно. Одну: двое ACK-ают на одном такте неотличимо от одного
- Какой пин у BME280 двигает адрес?
- SDO на земле — 0x76, на питании — 0x77. У OLED адрес двигают контактные площадки, у SHT31 и ADS1115 — пин ADDR, у MPU6050 — AD0. SDO
- Часы DS3231 и гироскоп MPU6050 просят один адрес 0x68. Быстрый развод?
- Оба адреса зашиты наглухо, скорость и подтяжки ни при чём. Мультиплексор даёт независимые ветки, bit-bang — второй шинный порт на любых двух пинах. Перемычек нет ни у кого — мультиплексор TCA9548A или второй программный порт
- Отключили одного из двух конфликтующих жильцов, строка 0x76 осталась в скане. Вывод?
- Строка после отключения одного — прямое доказательство, что отклик давал не он один. Именно так конфликт доказывается без логического анализатора. За этим адресом стояли минимум двое
- Перемычку SDO замкнули на питание при включённой плате. Что рекомендую?
- Моя страховка от случайных пяти вольт на жилу: питание снято, паяем, скан. И одно изменение за прогон — иначе не поймёте, чья перемычка не взялась. Перепаивать только на обесточенной плате и проверить сканом