Исправленная Wire библиотека для Arduino ESP8266 core

Nov 06, 2017 21:35

Вся боль от использования библиотеки и драйвера I2C шины для Arduino ESP8266 тут, тут, тут и здесь.


Пока на шине один slave все работает, но стоит добавить устройств и ESP8266 начинает виснуть с перезагрузкой. Либа wire.h иногда не корректно завершает чтение, а slave не закончив передачу вешает SDA на землю и ждет от мастера SCL, чтоб отдать оставшийся кусок байта. Драйвер написан так, что он об этом ничего не знает и начинает передавать на этот или следующий slave новое сообщение. Устройства ничего не получают тк наш slave удерживает SDA. Либа ничего не получив начинает растягивать SCL. Когда растягивать уже некуда, главный цикл встает колом. Через ~3 секунды, после остановки loop(), срабатывает WDT и модуль перегружается. Самый треш и угар начинается если slave - это часы реального времени с резервным питанием. ESP8266 перегрузился, а часы все удерживают SDA и ждут когда же wire.h с ними закончит. Через ~3 секунды опять сработает WDT и модуль снова перезагрузится. Круг замкнулся. Не поможет даже передергивание общего питания тк часики в этот момент питаются от батарейки.

Arduino сообщество и модераторы форума esp8266.ru морозились:
- не подключайте больше одного устройства
- не используйте i2c и перейдите на spi
- добавьте еще один МК с нативной поддержкой i2c и передавайте данные в esp по uart
- у меня с одним slave все работает...

Такое чувство, что они все на заплате у Espressif. Помучившись нескольких месяцев и покурив официальный datasheet на i2c переписал драйвер и библиотеку обертку под Arduino. Теперь ничего не виснет и работает стабильно. Тестировал на скоростях шины 10KHz, 15KHz, 25KHz, 50KHz 100KHz, 200KHz, 250KHz, 300KHz, 400kHz и частоте камня 80MHz.

Забирать тут.

UDP: Официальный стандарт на i2c шину здесь.

UDP2: Народ разучился читать read.me поэтому продублирую тут.

Скопируйте и замените twi.h и core_esp8266_si2c.cpp в папке %USERPROFILE%\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.5.2\cores\esp8266.

Скопируйте и замените Wire.h и Wire.cpp в папке %USERPROFILE%\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.5.2\library\Wire.

Цифры 2.5.2 могут отличаться, зависят от версии установленного ядра. Заменить значит удалить старый и на его место записать новый. Если вы хотите сохранить исходные файлы - просто измените расширение файла например так - twi.h.OLD и т. д. Если изменить только имя файла, вы получите ошибку во время компиляции. Потому что линковщик работает с тем что внутри файлов *.h и *.cpp, а не с именами. Это вам не windows!!!

UDP3: Похоже многие свалились с луны и не знают, что для нормальной работы i2c шины линии SDA и SCL должны быть подтянуты к питанию. Почему, читаем тут и тут.

UDP4: Для сенсорных панелей и длинных проводов добавил кучу медленных скоростей: 10KHz, 15KHz, 25KHz, 50KHz. Парочку быстрых для разгона: 250KHz, 300KHz, 600KHz. Например экран на PCF8574 легко взял отметку в 600KHz. Скорость меняется так - Wire.setClock(15000), где число в герцах. По умолчанию, библиотека не получив вовремя ответ, начинает растягивать SCL до 250 микросекунд, временно уменьшая частоту до 4KHz. По совету gihub юзера добавил нулевой значение. Теперь если в setup() сразу после декларации ВСЕХ устройств на I2C вписать Wire.setClockStretchLimit(0), где число в микросекундах. Драйвер будет растягивать SCL до бесконечности, те 0Hz. Недостаток - если на шине беда, вся система подвиснет в бесконечном цикле. В общем фича для отчаянных. Лучше вписать 1250 микросекунд - скорости 0.8Hz должно хватить любому тормозу. Ширину импульсов смотрел клоном Saleae Logic.

#arduino, esp8266, arduino, #esp8266

Previous post Next post
Up