Делюсь опытом ESP12 Проблема с одновременной работой двух модулей I2C

MihaNN52

Member
Проблема. При подключении датчика BME280 и часов DS3131 к шине I2C.
Беру примеры из библиотек.
Отдельно и BME и часы работают нормально.
Объединяю скетчи - все работает до перезагрузки ESP12E.
После перезагрузки, на первый , а может на пятый раз шина i2c падает.
И не восстанавливает свою работу до тех пор пока не выдерну провод SDA из часов.
После чего снова все работает без проблем до перезагрузки .
Подтяжка стоит и в BME и в модуле часов.
Из модуля часов выпаял все лишнее -епром подтяжку зарядку.
Менял ESP на wemos d1. nodemcuv3. и просто голую ESP12E. Результат один и тот же.
Менял библиотеки BME и часов на другие - все бестолково.
Думаю есть какая то особенность которую я не учел, возможно что то не так в библиотеке wire.
Не могу понять в чем дело. Скетчи пишу в ардуино IDE 1.8.1 Пробовал менять источник питания и напряжение питание. - так же без результата.
При всем все отлично работает на UNO и STM32.

Код:
#include <Wire.h>
#include "RTClib.h"
#include <Adafruit_Sensor.h>
#include <Adafruit_BME280.h>
#define SEALEVELPRESSURE_HPA (1013.25)
Adafruit_BME280 bme; // I2C



RTC_DS3231 rtc;
unsigned long long time1 = millis();

char daysOfTheWeek[7][12] = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"};
unsigned long time1 = 0;
float BME_T;
float BME_H;
float BME_P;

void read_sensor() {
    Serial.print("Temperature = ");
    Serial.print(bme.readTemperature());
    Serial.println(" *C");
    BME_T = bme.readTemperature();

    Serial.print("Pressure = ");

    Serial.print(bme.readPressure() / 133.322);/// 100.0F
    Serial.println(" hPa");
    BME_P = bme.readPressure() / 133.322;

    Serial.print("Approx. Altitude = ");
    Serial.print(bme.readAltitude(SEALEVELPRESSURE_HPA));
    Serial.println(" m");

    Serial.print("Humidity = ");
    Serial.print(bme.readHumidity());
    Serial.println(" %");
    BME_H = bme.readHumidity();

    Serial.println();
}

void data_time(){
    DateTime now = rtc.now();
    Serial.print(now.year(), DEC);
    Serial.print('/');
    Serial.print(now.month(), DEC);
    Serial.print('/');
    Serial.print(now.day(), DEC);
    Serial.print(" (");
    Serial.print(daysOfTheWeek[now.dayOfTheWeek()]);
    Serial.print(") ");
    Serial.print(now.hour(), DEC);
    Serial.print(':');
    Serial.print(now.minute(), DEC);
    Serial.print(':');
    Serial.print(now.second(), DEC);
    Serial.println();
}



void setup () {

#ifndef ESP8266
  while (!Serial); // for Leonardo/Micro/Zero
#endif

  Serial.begin(9600);

  delay(3000); // wait for console opening

  if (! rtc.begin()) {
    Serial.println("Couldn't find RTC");
    while (1);
  }

  if (rtc.lostPower()) {
    Serial.println("RTC lost power, lets set the time!");
    // following line sets the RTC to the date & time this sketch was compiled
    rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
    // This line sets the RTC with an explicit date & time, for example to set
    // January 21, 2014 at 3am you would call:
    // rtc.adjust(DateTime(2014, 1, 21, 3, 0, 0));
  }

  ////
  Serial.println(F("BME280 test"));

    bool status;
  
    // default settings
    status = bme.begin();
    if (!status) {
        Serial.println("Could not find a valid BME280 sensor, check wiring!");
        while (1);
    }
  
    Serial.println("-- Default Test --");
    //delayTime = 1000;

    Serial.println();

    delay(100); // let sensor boot up
    ////

}

void loop () {

    DateTime now = rtc.now();


    if (millis() - time1 >= 5000) {
    time1 = millis();
    data_time();
    read_sensor();
  }
 
 
}
 
Последнее редактирование:

rst

Member
Проблема. При подключении датчика BME280 и часов DS3131 к шине I2C.
Сталкивался с подобной проблемой на ESP8266.
Есть устройство (на EVB). В нём одна шина I2C и на ней 3 слэйва. При отключенном ESP устройство работает без сбоев часами (запускал на сутки). Написал даже тест, который грузит I2C на 100% непрерывным обменом поочерёдно со всеми слэйвами на макс. частоте - ни одного сбоя за весь день.
Как только начинаешь обмен с ESP (просто начинаешь периодически подавать команду AT+GMR даже без выхода ESP в эфир) - уже через несколько секунд происходит сбой обмена на одном из слэйвов. Обычно это сбой или Arbitration lost или Bus error или просто NACK на очередной байт.
Понятно, что помеха прёт от ESP. И понятно, что по питанию или сигнальным линиям (UART + GPIO).
Но что только ни делал - ничего не помогло. Навесил блокировочных кондёров везде где можно у всех потребителей питания причём от 100nF до 10мкФ керамики, развязал ESP8266 по линии питания и по GND дросселями, навесил на все сигнальные линии ESP последовательные резисторы, запитал даже от отдельной цепочки DC-DC + LDO питающейся даже от отдельной розетки 220V, уменьшил сопротивление подтяжек I2C до малых номиналов (до ~1кОм), раскидал эти подтяжки по плате к слэйвам. Ничего не помогает. Единственное, что после этих мер число сбоев уменьшилось кратно, но один фиг - работает максимум минуту потом обязательно сбой, а чаще - уже через неск. секунд сбой.
Потом всё-таки нашёл решение. Оно плохое, но пока другого решения не вижу. Сделал сигнал SCLK активным. После этого все сбои как рукой сняло. Работает по много часов с интенсивным обменом по эфиру и через UART с ESP8266 и по I2C - ни одного сбоя.
Это конечно неправильно так делать (активный SCLK), но по-другому никак. :(:(:(:(
 
Последнее редактирование:

rst

Member
"Ветви" длинные?
Физическое подключение реально "шина" или "звезда"?
Шина I2C у меня длиной максимум до 10см. А один из слэйвов вообще - меньше 1см от проца. В то время как провода до ESP - около 10см. Снижение частоты SCLK тоже не помогает.
 

MihaNN52

Member
"Ветви" длинные?
Физическое подключение реально "шина" или "звезда"?
шина.
от esp к BME280 c него на часы
подтяжку перебирал от 1-10КОм
длина проводов 10см(не думаю сто больше)
сейчас поставил транзистор который дергает SDA если часы несут пургу)) но хотелось бы решение нормальное.
 

MihaNN52

Member
уменьшил длину проводов до 5см. ситуацию не изменило
наверное придется ставить второй контроллер для датчиков, а есп как вифи...
может есть у кого предположения что может это быть? кроме моих кривых рук)))
 

MihaNN52

Member
>Сделал сигнал SCLK активным
Давайте попробуем)) ккак это сделать?
 

rst

Member
>Сделал сигнал SCLK активным
Давайте попробуем)) ккак это сделать?
Нормально по стандарту он должен быть oped drain, я его сделал push-pull (включил транзистор верхнего плеча).
Так можно делать только если у Вас один мастер на шине. Да и то это неправильно конечно, но по-другому мне не удалось победить :(
 

nikolz

Well-known member
Проблема. При подключении датчика BME280 и часов DS3131 к шине I2C.
Беру примеры из библиотек.
Отдельно и BME и часы работают нормально.
Объединяю скетчи - все работает до перезагрузки ESP12E.
После перезагрузки, на первый , а может на пятый раз шина i2c падает.
И не восстанавливает свою работу до тех пор пока не выдерну провод SDA из часов.
После чего снова все работает без проблем до перезагрузки .
Подтяжка стоит и в BME и в модуле часов.
Из модуля часов выпаял все лишнее -епром подтяжку зарядку.
Менял ESP на wemos d1. nodemcuv3. и просто голую ESP12E. Результат один и тот же.
Менял библиотеки BME и часов на другие - все бестолково.
Думаю есть какая то особенность которую я не учел, возможно что то не так в библиотеке wire.
Не могу понять в чем дело. Скетчи пишу в ардуино IDE 1.8.1 Пробовал менять источник питания и напряжение питание. - так же без результата.
При всем все отлично работает на UNO и STM32.
Могу предположить следующее.
Провода не виноваты , поэтому не надо над ними издеваться.
Я бы посмотрел на состояние SDA в момент залипания.
предположу что часы виснут в режиме вывода на SDA нуля. в результате на SDA всегда ноль т е кз.
Возможно надо создать третье состояние (вкл диод) или еще что-то.
но сначала посмотрите что там.
 

MihaNN52

Member
да так и есть SCL подымается в высокий а SDA остается в нуле и не работает. Если SDA подымается вместе SCL то все работает.
Чито делать то?))
 

MihaNN52

Member
схему покажите.
BME 280 и часы имеют свою подтяжку. Но на осциллографе фронты становятся ровными при доп подтяжке 1КОм . Расположение пинов датчиков отличаются от реального но это ни чего не меняет.
 
Последнее редактирование:

nikolz

Well-known member
BME 280 и часы имеют свою подтяжку. Но на осциллографе фронты становятся ровными при доп подтяжке 1КОм . Расположение пинов датчиков отличаются от реального но это ни чего не меняет.
для начала давайте выкинем ваши подтяжки и посмотрим результат.
 

nikolz

Well-known member
еще я бы предположил что проблема в софте
Например, возникает одновременная готовность, либо чтение второго датчика начинается до завершения работы с первым. Возможно где-то надо добавить задержку или сделать флаг готовности.
Но это лишь рабочие гипотезы.
 

MihaNN52

Member
я выкидывал
все тоже самое только передний фронт заваливается
вот без внешних подтяжек в 1КОм
1.JPG

момент зависания выглядит так же
2.JPG

так с подтяжкой в 1 КОм
1k2.JPG
 

nikolz

Well-known member
Если резисторы не влияют то нафига их ставить.
Момент зависания пока не ясен.
---------------------
Правильно я понял, что подключены оба. Но обращаетесь к одному - проблем нет.
Тогда надо смотреть софт.
 

MihaNN52

Member
по проблеме в софте - этот же скетч работает без нареканий в UNO и STM32
у меня есть проект на stm32 где и часы и бме живут вместе и все норм
 
Сверху Снизу