К шине метеобокса я добавил второй датчик света BH1750 — тот же модуль из той же посылки. Оба датчика умерли разом: библиотека отвалилась на init, показания нулевые, а сканер показывал один адрес 0x23 вместо двух. Полчаса я подозревал брак нового модуля, пока не сообразил: оба живы, оба здоровы и оба сидят на одном адресе — второй-то из коробки с теми же перемычками, что и первый.
Клоны с одинаковыми адресами в общем виде разобраны в уроке про одинаковые адреса, сканер как инструмент — в уроке про сканирование, диагностика конфликта по шагам — в уроке про сканер-диагност, таблица адресов модулей — в уроке про адреса, сам конфликт без привязки к железу — в уроке про конфликт адресов. Здесь мой угол — симптом «молчат оба»: почему шина не делится, как прочитать вывод сканера и план переезда соседа на свободный адрес.
Почему молчат оба, а не делят шину
Шина не спрашивает «кто тут 0x23» с поднятием рук — она называет адрес, и отвечают все, кто узнал себя. Два ответчика тянут SDA одновременно: на стадии адреса их два ACK сливаются в один, и мастер честно считает, что на 0x23 живёт одно устройство. Дальше хуже: на чтении двое толкают в линию свои биты, ноль побеждает единицу, и данные складываются в мусор. Библиотека не находит чип-ид, init возвращает ошибку — и скетч видит «датчика нет», хотя физически оба на месте и оба мешают друг другу.
Сканер при этом — главный свидетель: вы знаете, сколько модулей повесили, и если он нашёл меньше, первый подозреваемый — дубль адреса. Лечится переездом одного из соседей: у большинства чипов есть ножки конфигурации. PCF8574 — перемычки A0, A1, A2, плюс единица, двойка и четвёрка к базе; BMP280 и BME280 — ножка SDO, на земле 0x76, на питании 0x77; BH1750 — ножка ADDR, 0x23 против 0x5C. А вот AHT20 на 0x38 и DS3231 на 0x68 неперестраиваемые в принципе — второй такой модуль на ту же шину не поставить, туда нужен мультиплексор TCA9548A, про который отдельно писали в уроке про TCA9548A.
#include <Wire.h> void setup() { Wire.begin(); Serial.begin(9600); Serial.println("Skan 0x08-0x77...");} int loops = 0; void loop() { int n = 0; for (byte adr = 8; adr < 120; adr++) { Wire.beginTransmission(adr); byte kod = Wire.endTransmission(); if (kod == 0) { // ACK: кто-то узнал адрес n++; Serial.print("Otvet: 0x"); if (adr < 16) Serial.print("0"); Serial.print(adr, HEX); Serial.print(" (dec "); Serial.print(adr); Serial.println(")"); } } Serial.print("Adresov naideno: "); Serial.println(n); if (loops == 0 && n < 4) { Serial.println("Veshali 4 modulya, naideno men'she?"); Serial.println("Dva na odnom adresse skanom ne razdelyayutsya."); } loops++; delay(3000);}Разбор. Скан — это beginTransmission + endTransmission без единого байта данных: мастер называет адрес и смотрит, потянет ли кто-нибудь SDA в ACK. Код 0 — ответ есть; коды 2 и 3 (NACK на адресе, NACK на данных) и их расшифровка разобраны в уроке про коды endTransmission. Дубль сканером не разделяется: два ACK на одном адресе для мастера неотличимы от одного — отсюда правило считать руками, сколько модулей повесили, и сверять с числом адресов в скане.
План переезда простой и всегда одинаковый: замкнуть конфигурационную ножку одного из близнецов, перезалить скан, убедиться, что адресов стало на один больше, и поправить адрес в скетче этого модуля. Проверьте и вторую сторону: отключённый от питания модуль не отвечает и не мешает — конфликт виден только когда горят оба. И помните про пары адресов внутри одного семейства: PCF8574 и PCF8574A — разные диапазоны (0x20-0x27 и 0x38-0x3F), «тот же экран, но версия A» перескочит через пол-шины сам.
| Модуль | Адрес по умолчанию | Как разъехать |
|---|---|---|
| PCF8574 (LCD, реле, кнопки) | 0x20-0x27 | перемычки A0-A2: +1, +2, +4 к базе |
| PCF8574A | 0x38-0x3F | те же перемычки, своя база |
| BMP280 / BME280 | 0x76 | SDO на питание — переезд на 0x77 |
| BH1750 (свет) | 0x23 | ножка ADDR на питание — 0x5C |
| AHT20, DS3231 | 0x38, 0x68 | перемычек нет — только TCA9548A |
- 1. Сканер на шине с двумя одинаковыми датчиками показывает...
- 2. Какие модули не разъедутся перемычками?
- Два модуля с одним адресом не делят шину — они портят ACK и данные, и молчат оба
- Скан при дубле видит один адрес: считайте модули руками и сверяйте со сканом
- Перемычки: PCF8574 A0-A2, BMP280 SDO, BH1750 ADDR — переезд одного соседа
- AHT20 (0x38) и DS3231 (0x68) неперестраиваемые — выход TCA9548A
- Конфликт виден только при питании обоих: отключение одного — тоже тест
Частые вопросы по теме урока
- Сканер на шине с двумя одинаковыми датчиками показывает...
- Оба датчика тянут SDA в ACK одновременно, и мастер видит один валидный ACK. Число адресов в скане всегда сверяйте с числом модулей на шине. Один адрес: два ответчика для мастера неотличимы от одного
- Какие модули не разъедутся перемычками?
- AHT20 (0x38) и DS3231 (0x68) не имеют ножек конфигурации адреса. Второй такой модуль на существующую шину — только через мультиплексор. AHT20 и DS3231 — адреса жёсткие, нужен мультиплексор TCA9548A