• Уважаемые посетители сайта esp8266.ru!
    Мы отказались от размещения рекламы на страницах форума для большего комфорта пользователей.
    Вы можете оказать посильную поддержку администрации форума. Данные средства пойдут на оплату услуг облачных провайдеров для сайта esp8266.ru
  • Система автоматизации с открытым исходным кодом на базе 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 или что там. Не привыкать.
 
Сверху Снизу