ESP8266 I2C не отвечает

У меня возникла огромная проблема при использовании ESP8266 от Wemos D1 mini.

Я использую STM32L073RZ для отправки запроса на ESP8266, чтобы передать мне время, полученное через соединение Wi-Fi.

Код ESP:

#include <ESP8266WiFi.h>
#include <WiFiUdp.h>
#include <NTPClient.h>
#include <Wire.h>

// Загрузка данных с помощью Twojej sieci WiFi
const char* ssid = ":>>>>>>>>>>>";
const char* password = "NOPE";
    
#define Status D4
    
WiFiUDP ntpUDP;
NTPClient timeClient(ntpUDP, "europe.pool.ntp.org", 3600, 60000);
    
void setup() {
  pinMode(D4, OUTPUT); // Пин, отвечающий за готовность устройства к общению по I2C
  digitalWrite(D4, LOW); // Вначале мы установили значение «0».
    
  Serial.begin(9600);
  WiFi.begin(ssid, password);
    
  while ( WiFi.status() != WL_CONNECTED ) {
    delay ( 500 );
    Serial.print ( "." );
  }

  timeClient.begin();

  Wire.begin(8); // Запускает D2 как SDA и D1 как SCL в качестве ведомых устройств
  Wire.onRequest(sendTime); // Регистрируем функцию обратного вызова, которая будет вызываться, когда главное устройство запрашивает данные
    
  digitalWrite(D4, HIGH); // Здесь завершена настройка сети, а также настройка контактов и настройка I2C.
                          // и сигнализируется высоким состоянием на D4
}

void loop() {
  timeClient.update();
  Serial.println(timeClient.getFormattedTime());
  delay(1000);
}
    
void sendTime() {
  String time = timeClient.getFormattedTime();
  Wire.write(time.c_str()); // Отправка времени на ведущее устройство будет иметь общий размер 8 байт, поскольку здесь есть разделительные символы.
}

Простой код STM:

xD = HAL_I2C_Master_Receive(&hi2c2, 0x08<<1, czas, 8, 1000);

Я попробовал все. Добавление подтягиваний, изменение скорости GPIO и т. д.

Вот что мне дал мой логический анализатор:

Выход логического анализатора

По-прежнему ничего. Я также проверил, какие контакты являются SDA и SCL, а именно D2 и D1. Я проверил, правильно ли установлено соединение и так оно и должно быть, но ответа по-прежнему нет.

Я больше не знаю, что не так, а что нет.

Схема:

Schematic

Он уже запитан, поэтому мне не нужно было добавлять к нему контакты 5 В и G, но я также протестировал, добавив контакт G к земле STM32, а также подключив 5 В к 5 В STM32, но это все равно не сработало.

, 👍5

Обсуждение

у вас должны быть точки соприкосновения, @jsotola

Я упоминал в редактировании, что соединил G с GND STM32, не сработало., @Jackob2001

На D4 высокий уровень – чтобы подтвердить, что инициализация прошла успешно?, @Nick Gammon

Да, D4 высокий., @Jackob2001

Каковы уровни напряжения? STM32L073RZ, похоже, является устройством с напряжением 3,3 В, как и ESP8266, однако вы упомянули 5 В. Я не эксперт ни в том, ни в другом, но это может быть проблемой., @Nick Gammon

Да, я уже упоминал, что подключил 5 В STM32 к 5 В ESP8266 только намного позже, после стольких попыток подключения по I2C. Но блин, все еще сижу 5 часов и чиню это., @Jackob2001

*Но блин, все еще сижу и чиню это 5 часов.* - Я этого не понимаю., @Nick Gammon

Ничего, просто говорю, что это утомительно. Но теперь у меня сгорел Wi-Fi, случайно подключивший GND от STM32 к 5 В ESP8266. Но все равно я не понимаю, почему у меня не работал I2C, @Jackob2001

Вы питаете оба устройства от 3,3 В или 5 В?, @Nick Gammon

Оба они питаются от простого USB-порта. Насколько я знаю, это 5 В, которое снижается до 3,3 В., @Jackob2001

Из этого: https://github.com/esp8266/Arduino/issues/5762 видно, что esp8266 не является хорошим ведомым устройством I2C., @6v6gt

Хмммм интересно. Я думал это старый пост, возможно, они его поправили. Я видел несколько руководств по использованию I2C на ESP8266, поэтому подумал, может быть, это сработает., @Jackob2001

@Jakob2001 Jakob2001 Esp8266 работает как ведущий и, если вам повезет, работает как ведомый, но только с другим esp8266 в качестве ведущего. Можно попробовать поменяться ролями. esp8266 в качестве ведущего устройства время от времени отправляет отметку времени на ваше устройство STM в качестве ведомого устройства I2C., @6v6gt


3 ответа


Лучший ответ:

5

Подчиненное устройство I2C не работает на esp8266, поскольку у него нет аппаратной поддержки I2C.

Из документации библиотеки esp8266 Wire:

Библиотека Wire в настоящее время поддерживает основной режим...

https://arduino-esp8266.readthedocs.io/en /3.1.2/libraries.html#i2c-wire-library

,

Несмотря на то, что в библиотеке проводов есть этот «onRequest», ESP8266 не может его использовать?, @Jackob2001

код для раба есть. это просто не работает., @Juraj


2

Устройства должны иметь общее заземление, а также вам могут потребоваться подтягивающие резисторы номиналом 4,7 кОм как на SDA, так и на SCL.

Подробнее см. http://gammon.com.au/i2c.

,

В сообщении я упоминал, что добавил подтягивания в STM32 с помощью программного обеспечения, а в упомянутой мной редактировании я соединил вывод G с выводом GND STM32, но все равно не работало., @Jackob2001

Я смотрел вашу схему. Вы не можете ожидать, что опубликуете неверную информацию и получите хороший ответ., @Nick Gammon

Окей, моя вина. Но решение по добавлению подтягиваний не сработало, как и подключение контакта G к контакту GND stm32., @Jackob2001


0

Оба других ответа верны, но с вашим дизайном есть еще одна проблема.

Как ясно видно из выходных данных логического анализатора, ведущее устройство работает со скоростью 100 Кбит/с (стандартная скорость i2c). Это оставляет рабу ок. 5нас отреагировать. Для чипа с тактовой частотой 80 МГц это само по себе может быть довольно трудным и требует тщательной проверки и оптимизации кода. Но UDP-запрос в большую сеть? Серьезно?!

Единственный способ, которым это может сработать, — это если обе стороны смогут договориться о продлении времени. Однако спецификация i2c никогда не определяет точные тайминги для растянутых часов, поэтому есть вероятность, что любой ведущий, вероятно, прервет сеанс, если ведомый зависнет задолго до того, как запрос UDP сможет быть обслужен.

Поэтому такие запросы необходимо разбивать на две части. Сначала ведущий просит ведомого инициировать процесс измерения/обмена/вычисления/что угодно. А во-вторых, после соответствующей задержки ведущий отправляет еще один запрос буферизованного результата от ведомого.

,

Я не так уж хорош в скорости и т. д. Так что 80 МГц и 100 кбит/с мало что говорят мне в контексте того, успеет ли это сделать и т. д. Я просто хотел выиграть время, поэтому проверил несколько руководств, как это сделать. Я проверил частоту I2C, и она составила 100 кГц. Допустим, я пока не знаю, как представить себе эти скорости и тайминги, потому что 5 нас сами по себе для меня слишком малы. Извините за мою некомпетентность. Хотя хотелось бы кое-чему научиться, как судить, достаточно часов или нет, или они должны быть всегда одинаковыми, а могут быть немного разными., @Jackob2001

@Jackob2001 Тайминги указаны на графике. 100 кГц — это наименьшая скорость i2c по спецификациям и аппаратным реализациям. 100000 циклов в секунду дают 10/1000000 секунд за весь цикл и 5/1000000 за половину его (при низкой тактовой частоте). Довольно тривиально., @Matt

Извините за пинг. ч/б? 10/100000 ? Мне просто интересно, как здесь работает время, потому что, как вы сказали, теперь их два. Один с частотой 100 кГц, другой с частотой 80 МГц. Разве время их работы не должно быть одинаковым? Если один из тактов быстрее другого, то после одного цикла один и тот же бит может изменить маминое время??? Я не знаю. Просто говорю, что после прочтения вашего комментария о сроках я хочу узнать больше., @Jackob2001

@ Jackob2001 10/1000000 = 1/100000. Разделите на два и получите 5/1000000. Если mcu работает на частоте 80 МГц, то он имеет ок. 400 внутренних тактов на 5 мкс (1/2 тактовой частоты i2c). Это максимум 400 машинных инструкций даже для RISC-архи., @Matt

@ Jackob2001 Jackob2001 Вероятно, вам нужно начать с основного режима. Не используйте библиотеки, а реализуйте это в программном обеспечении. Это довольно просто, поскольку мастер управляет тактовым сигналом scl так, как хочет. Тогда вы полностью поймете, как работает i2c., @Matt

Я до сих пор не совсем понимаю расчеты. Возможно, это не лучшая тема, но что касается времени, я не совсем понимаю, что вы пытались сказать. И реализовать это в программном обеспечении? Хммм, я совсем новичок, просто случайно узнал кое-что, поэтому не знаю, как к этому добраться. Код Wi-Fi был сделан из видео с YouTube :D, @Jackob2001