• Система автоматизации с открытым исходным кодом на базе esp8266/esp32 микроконтроллеров и приложения IoT Manager. Наша группа в Telegram

Зависание I2C

bstsoft

Member
Первый вариант работы по таймеру реализовал через

Код:
#include <Ticker.h>

Ticker Ticker1;
...
  Ticker1.attach(1, timerIsr);
Все было замечательно. Время с часов ds3231 отрабатывало без проблем. Когда пришел датчик SI7021. Я побаловался и решил его прописать в обработчике. И началось зависание ESP12F с постоянной перезагрузкой.

Начал разбираться и заметил, что при запросе данных с SI7021 происходит зависание ESP12F с дампом и перезагрузка. Самое страшное в этом всем, что пока не отключишь питание порт I2C будет висеть. Предположив, что таймер возможно работает как какое то прерывание, я сделал эмуляцию таймера в loop().
Код:
void loop() {
  HTTP.handleClient();

  if (millis() - job_ms > 1000) {
    timerIsr();
    job_ms = millis();
  }
}
И теперь все работает.

Кто знает почему при использовании Ticker шина I2C виснет? Может надо какую команду прописать в timerIsr() типа начало и конец критической секции(в смысле захват устройств на монопольное использование и запрет прерываний). Походу Ticker и I2C используют какое то прерывание и виснут при одновременном обращении.
 

bstsoft

Member
@enjoynering
возможно, но судя по тому, что я вынес чтение с шины i2c в другое место и все работает это связано с прерываниями.
Надо понять как сделать так что бы блокировать другие прерывания на момент получения данных с i2c. Если вообще такое возможно.
 

Сергей_Ф

Moderator
Команда форума
@bstsoft вообще-то, внутри колбэка Ticker не рекомендуется выполнять какую либо длительную обработку. Работа с шиной i2c явно не на 5 мкс, а значит ее надо выносить из колбэка в основной цикл и будет счастье. Т.е. в колбеке поднимаем флаг для обработки шины и всё. А в основном цикле проверяем флаг и обрабатываем шину, если надо.
 

bstsoft

Member
@Сергей_Ф На данный момент там все операции очень быстрые. А если есть ограничения, то значит должны быть и условия, при которых допускается долгая работа. Например при потоках делается критическая секция. И обруливание ее. Тут же получается не дается таких возможностей либо мы не знаем, что должны сделать при работе внутри прерывания, что бы одно не на ехало на другое.

Я пробовал делать один тик и остановка тиккера. Это не помогло. По идее делается просто, поток остался, а тиккер умер. Поток работает пока не закончится. Но засада в том, что тиккер как будто не умер пока не выполнится поток, вот и получаем конфликт. В винде и люнихе это разруливается, но тут знаний нижнего уровня маловато.

Если основной цикл будет отрабатывать к примеру за 1.5 сек. А показание датчика надо получать каждые 0.5 сек. То ваш метод не подойдет.

Например температурные датчики 1820 первый цикл они все разом получают команду перерасчет, а потом через секунду долбишь их все на получение от них данных. Проблем нету. Но с датчиками SI7021 такое не прокатило, первый цикл тупо заставляешь его пересчитать и все равно на чтении он падает. И падает только на одно команде. На лицо конфликт железа.

Если тиккер будет долгим и будет делать работу по WD не срабатывает. Делал задержки на секунды чтобы лог было хоть успеть читать. Он срабатывает в местах где циклы короткие или пустые и походу когда железо тупо молчит и не отдает данные. Вообще хотелось бы просто его отключить и проверить без WD будет работать и какие задержки где происходят. Но я так понял WD не отключить ни как. Или все же есть решение?

Хочется понять это датчик тупит или I2C. Но раз датчик нормально работает с I2C, то проблема в работе прерываний в тиккере.

Также вынесем все во внешний цикл и получим тормоза ответа Web интерфейса. Тиккер хоть какую, то аналогию параллельности работы давал.
 

Сергей_Ф

Moderator
Команда форума
@bstsoft посмотрите тему https://esp8266.ru/forum/threads/esp12-problema-s-odnovremennoj-rabotoj-dvux-modulej-i2c.2393/

Если там ничего полезного не найдете, то можно говорить о неправильном выборе инструмента. Ардуино+есп не самый лучший выбор для сложных задач ;)

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

Представить себе основной цикл на 1.5 секунды, честно говоря не могу. Если конечно, delay не вставлять на каждом углу.
 

bstsoft

Member
@Сергей_Ф
Там ситуация другая. Я пробовал и задержки добавлять и танцы с бубном не помогало. Поэтому и писал что долгая работа тиккера не приводила к WD. Я пробовал тиккер с работой только SI7021 намертво виснет после первого опроса. У меня налицо конфликт оборудования. Походу тиккер и I2C по прерываниям пересекаются.
 

enjoynering

Well-known member
вам как бы намекнули о глючности - "Ардуино+есп не самый лучший выбор для сложных задач..."
 

bstsoft

Member
@enjoynering
и я это понял. На данный момент все работает. Сложных задач не планировалось пока. Просто на будущее надо знать в чем проблема. А при необходимости сложных задач, тупо сделаю обмен по своему или перейду на другой SDK или что там. Не привыкать.
 
Сверху Снизу