Как определить неисправное устройство подключённое через I2C?

o0yo1
Offline
Зарегистрирован: 10.06.2022

Добрый вечер, столкнулся с такой проблемой. Подключаю MPU6050 к ардуинке, используя при этом одноимённую библиотеку. В штатном режиме всё работает, но тк устройство должно работать продолжительное время, хотелось прописать программу, на случай если MPU просто отсоеденить. Я решил это сделать через нулевые показатели (подробнее в коде), но при тесте программы, выходит так, что программа не выполняется вовсе. И из этого следует вопрос, как вообще выяснять неисправность или полное отключение устройств от I2C? Может есть какое то решение для этого, конкретно в библиотеке MPU6050?

/////функция из программы, которая должна была отвечать за проверку////


int prov() {

  float a2;
  int prov, z = 0;
  if (z != 1) {

    shagom.getMotion6(&ax, &ay, &az, &gx, &gy, &gz); //// получение данных с датчика
    a2 = (ay / 4096.0 * 2.0); ///// перевод ускорения по одной оси в СИ

    if (a2 != 0) { ////если ускорение по этой оси не равно нулю то присваеваем определеное значение, которое используем в другом месте проги
      prov = 2;
    }
  }

  return prov;
}

 

DetSimen
DetSimen аватар
Offline
Зарегистрирован: 25.01.2017

вызывай перед чтением устройства

// ADevAddr - адрес устройства на I2C шине
// 
// отдает: 
//    true, если устройство с таким адресом на шине есть
//    false, если устройство ниажыданна спи..дили
//
bool isDevicePresent(const uint8_t ADevAddr) { 
    Wire.beginTransmission(ADevAddr);
    delay(1);
    return (Wire.endTransmission() == 0);
}

 

rkit
Offline
Зарегистрирован: 23.11.2016

Никак. Шина на это не рассчитана. Одна неудачная комбинация уровней и шина зависла.

rkit
Offline
Зарегистрирован: 23.11.2016

DetSimen пишет:

вызывай перед чтением устройства

// ADevAddr - адрес устройства на I2C шине
// 
// отдает: 
//    true, если устройство с таким адресом на шине есть
//    false, если устройство ниажыданна спи..дили
//
bool isDevicePresent(const uint8_t ADevAddr) { 
    Wire.beginTransmission(ADevAddr);
    delay(1);
    return (Wire.endTransmission() == 0);
}

 

смысла в дилее никакого нет.

DetSimen
DetSimen аватар
Offline
Зарегистрирован: 25.01.2017

rkit пишет:

смысла в дилее никакого нет.

Согласен. 

Komandir
Komandir аватар
Offline
Зарегистрирован: 18.08.2018

rkit установить таймаут отличным от 0 - религия не позволяет ? Была же уже подобная тема недавно !

rkit
Offline
Зарегистрирован: 23.11.2016

Нет в i2c шине таймаута. Для недоходчивых: шина и контроллер это разные вещи. В шине учавствуют ВСЕ устройства.

Komandir
Komandir аватар
Offline
Зарегистрирован: 18.08.2018

rkit проверка таймаута есть в библиотеке если значение таймаута не равно нулю ! Провисит ардуино в ожидании ASK время таймаута и выскочит с ошибкой !!! Харош уже тупить !

o0yo1
Offline
Зарегистрирован: 10.06.2022

Не помогло, при отсутствии устройства результат аналогичен, ардуинка тупо виснит

o0yo1
Offline
Зарегистрирован: 10.06.2022

Komandir пишет:

rkit установить таймаут отличным от 0 - религия не позволяет ? Была же уже подобная тема недавно !

немного непонятно какой и где таймаут, был бы рад если бы пояснили....

ну или хотя бы подсказали темку где это было, если помните, а то поиск не сильно помогает..

 

Komandir
Komandir аватар
Offline
Зарегистрирован: 18.08.2018

https://www.arduino.cc/reference/en/language/functions/communication/wire/setwiretimeout/

Если линия занята все время - значит кто то умер на линии.

Если не отвечает на свой адрес - тут скорее всего он физически отключен.

...

o0yo1
Offline
Зарегистрирован: 10.06.2022

Спасибо, помогло, но хочется разобраться, ибо ничего не понял, только вот вопрос, этот таймаут будет работать и в том случае если всё работает корректно? Или же он начинает работать в случае когда на запросы мастера никто не отвечает?

 

Komandir
Komandir аватар
Offline
Зарегистрирован: 18.08.2018

Если все корректно, то таймаут ни на что не влияет.