Wire.endTransmission() зависает, но только если wire.begin(); вызывается с адресом (MKR WiFi 1010)

i2c mkr1010

Этот код работает без проблем, в том числе и в последовательном выводе:

#include <Wire.h>

void setup() {
  // put your setup code here, to run once:
  Serial.begin(115200);
  Wire.begin();
  Wire.onReceive(receiveEvent);

  while (!Serial);
}

void loop()
{
  Serial.println("1");
  Wire.beginTransmission(8);
  Serial.println("2");
  Wire.write(0x1);
  Serial.println("3");
  delay(100);
  Wire.endTransmission();
  delay(100);
  Serial.println("4");
  delay(500);
}

void receiveEvent(int howmany)
{
  delay(100);
}

Это зависает на Wire.endtransmission():

#include <Wire.h>

void setup() {
  // put your setup code here, to run once:
  Serial.begin(115200);
  Wire.begin(10);
  Wire.onReceive(receiveEvent);

  while (!Serial);
}

void loop()
{
  Serial.println("1");
  Wire.beginTransmission(8);
  Serial.println("2");
  Wire.write(0x1);
  Serial.println("3");
  delay(100);
  Wire.endTransmission();
  delay(100);
  Serial.println("4");
  delay(500);
}

void receiveEvent(int howmany)
{
  delay(100);
}

Проблема начинается, как только я назначаю адрес в Wire.begin(). Насколько я понимаю, ведомому также разрешено отправлять данные и временно становиться ведущим при обращении к другому устройству.

, 👍0

Обсуждение

Есть ли в шине другой мастер, для которого mkr также должен быть ведомым?, @chrisl

Да и нет, у меня три устройства, мастер мкр, два брелка м0 слейв. Я хочу передавать данные от ведомых устройств к ведущему немедленно, когда они получают указанные данные. Как это настроено, коллизия данных от ведомых устройств невозможна, так как мастер попеременно включает датчики на ведомых (поэтому мне нужно, чтобы он был ведущим для координации), но я также хочу получать данные, как только они поступят и не опрашивать его, так как я боюсь, что это может испортить мои прерывания на рабах., @Horst


2 ответа


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

0

Хотя библиотека проводов поддерживает мультимастер для AVR, она не поддерживает ATSAMD.

Временное повышение до ведущего отключено, если указан адрес подчиненного устройства, поэтому программа будет зависать на wire.endTransmission().

,

0

Я хочу передавать данные от ведомых устройств к ведущему сразу после их получения.

Это означает, что каждое ведомое устройство становится ведущим сразу после получения данных от MKR. Это по-прежнему настройка с несколькими мастерами, даже если вы избегаете коллизий с помощью фиксированного протокола. Библиотека Wire не поддерживает мультимастер.

Но я тоже не понимаю, зачем вам это нужно. Ваш протокол делает следующее: MKR отправляет данные подчиненному устройству (запуская его и, возможно, также отправляя некоторые команды). Затем ведомое устройство должно отправить данные обратно ведущему. Затем передача заканчивается. Обычно это делается в I2C только с одним мастером. Мастер выполняет запись мастера (через Wire.endTransmission() и отправляет некоторые данные команды ведомому. Ведомый подготовит данные, запрошенные мастером, в своем буфере. Затем мастер начнет ведущее чтение (через Wire.requestFrom()), которое считывает данные с ведомого устройства.

Поэтому для этого вам не нужна установка с несколькими мастерами. Он делает именно то, что вы описали, но только с одним мастером.

,

Я узнал, что библиотека Wire действительно поддерживает несколько мастеров, но не на ATSAMD., @Horst

У меня нет возможности предсказать, когда подчиненное устройство получит свои данные, поэтому, кроме непрерывного опроса подчиненного устройства, я не буду знать, когда данные поступят на подчиненное устройство., @Horst

В вашем первоначальном плане вы хотели предотвратить коллизии, по сути, опрашивая ведомые устройства (записывая в них данные, чтобы они отвечали сами себе передачей ведущего). Если это больше не вариант, вам следует подумать о другом коммуникационном интерфейсе, который лучше поддерживает сценарии с несколькими мастерами., @chrisl