Wire.setWireTimeout()

Описание

setWireTimeout() устанавливает тайм-аут для передач Wire в режиме контроллера.

При вызове без параметров устанавливается тайм-аут по умолчанию, которого должно быть достаточно для предотвращения зависаний в типичной конфигурации с одним контроллером.

Эта функция является частью библиотеки Wire. Подробнее см. на главной странице Wire.

Синтаксис

Wire.setWireTimeout(timeout, reset_on_timeout)
Wire.setWireTimeout()

Параметры

  • timeout: значение тайм-аута в микросекундах. Если установлено в 0, проверка тайм-аута отключается. Допустимые типы данных: uint32_t.

  • reset_on_timeout: если true, аппаратный модуль Wire будет автоматически сброшен по тайм-ауту. Допустимые типы данных: bool.

Возвращаемое значение

Функция ничего не возвращает.

Пример кода

#include <Wire.h>

void setup() {
  Wire.begin();  // Подключаемся к шине I2C (адрес необязателен для контроллера)
  #if defined(WIRE_HAS_TIMEOUT)
    Wire.setWireTimeout(3000 /* us */, true /* reset_on_timeout */);
  #endif
}

void loop() {
  // Отправляем команду периферийному устройству
  Wire.beginTransmission(8);
  Wire.write(123);
  byte error = Wire.endTransmission();
  if (error) {
    Serial.println("Error occurred when writing");
    if (error == 5)
      Serial.println("It was a timeout");
  }

  delay(100);

  // Читаем результат
  #if defined(WIRE_HAS_TIMEOUT)
    Wire.clearWireTimeoutFlag();
  #endif
  byte len = Wire.requestFrom(8, 1);
  if (len == 0) {
    Serial.println("Error occurred when reading");
    #if defined(WIRE_HAS_TIMEOUT)
      if (Wire.getWireTimeoutFlag())
        Serial.println("It was a timeout");
    #endif
  }

  delay(100);
}

Примечания и предупреждения

Важно

Понимание тайм-аутов: тайм-ауты почти всегда указывают на нижележащую проблему — например, неправильно работающие устройства, помехи, недостаточную экранировку или другие электрические проблемы. Тайм-ауты не дадут скетчу зависнуть, но не решают эти проблемы. При возникновении тайм-аута часть ранее прочитанных или записанных данных также может быть повреждена. Могут потребоваться дополнительные меры (например, контрольные суммы или повторное чтение записанных значений) и стратегии восстановления (например, полный сброс системы). Когда это возможно, нужно устранять первопричину.

Примечание

Как работают тайм-ауты: условие тайм-аута обычно срабатывает при ожидании какой-либо части транзакции (например, ожидания доступности шины, ожидания бита ACK или ожидания завершения всей транзакции). При возникновении тайм-аута транзакция прерывается, и endTransmission() или requestFrom() возвращают код ошибки или ноль байтов соответственно.

Примечание

Аппаратный сброс: если reset_on_timeout был установлен в true и платформа поддерживает это, аппаратный модуль Wire также сбрасывается, что может помочь очистить любое некорректное состояние внутри Wire-модуля.

Примечание

Флаг тайм-аута: при срабатывании тайм-аута устанавливается флаг, который можно прочитать с помощью getWireTimeoutFlag() и который должен быть очищен вручную с помощью clearWireTimeoutFlag() (он также сбрасывается при вызове setWireTimeout()).

Совет

Рекомендуемые значения: типичный тайм-аут — 25 мс (это максимальное растяжение тактового сигнала, разрешённое протоколом SMBus), но обычно работают и меньшие значения. При необходимости адаптируйте тайм-аут с учётом растяжения тактового сигнала или конфигураций с несколькими контроллерами.

Предупреждение

Переносимость: эта функция отсутствовала в исходной версии библиотеки Wire и до сих пор может быть недоступна на всех платформах. Код, который должен быть переносимым между платформами и версиями, может использовать макрос WIRE_HAS_TIMEOUT, который определён только тогда, когда Wire.setWireTimeout(), Wire.getWireTimeoutFlag() и Wire.clearWireTimeoutFlag() все доступны.

Примечание

Значения по умолчанию: настройки тайм-аута по умолчанию доступны через макросы WIRE_DEFAULT_TIMEOUT и WIRE_DEFAULT_RESET_WITH_TIMEOUT. Если требуется отключить тайм-аут, рекомендуется отключать его явно с помощью setWireTimeout(0), даже если это уже текущее значение по умолчанию.