Ведомое устройство i2c записывает в ведущее устройство на базе ARM

i2c mbed

Я хочу установить связь с микропроцессором ARM по протоколу I2C (Multitech mDot, который использует платформу Mbed). Я успешно получаю от него данные (и отображаю их на последовательном мониторе Arduino), но когда я хочу отправить данные с Arduino, я ничего не получаю на другом конце. Это мой скетч:

#include <DHT.h>
#include <Wire.h>

// Датчик температуры, увлажненный DHT11 (тест).
#define DHTPIN 10
#define DHTTYPE DHT11
DHT dht(DHTPIN, DHTTYPE);

// Связь i2c с известными людьми. 7-битный адрес 010 1001 (ч/з)
#define SLAVE_ADDRESS 0x29

// Глобальные переменные датчиков
float h;
float t;

void setup() {
  Wire.begin(SLAVE_ADDRESS);
  Wire.onReceive(receiveEvent);
  dht.begin();
  Serial.begin(9600);
}

void loop() {
  delay(5000);
  h = dht.readHumidity();
  t = dht.readTemperature();

  // Comprobamos si habido algún error en la lectura
  if (isnan(h) || isnan(t)) {
    Serial.println("Error obteniendo los datos del sensor DHT11");
    return;
  }

  Serial.print("Humedad: ");
  Serial.print(h);
  Serial.print(" %\t");
  Serial.print("Temperatura: ");
  Serial.print(t);
  Serial.println(" *C ");

  Wire.onReceive(receiveEvent);
}


// Общее количество байтов для передачи данных: 28 байт.
void receiveEvent(int howMany) {
  Serial.print("Mensaje recibido por i2c desde MDOT LoRa Node: ");
  while (Wire.available() > 0) {
    Serial.print(char(Wire.read()));
  }
  Serial.println();
  char enviar = "Cacatua";
  Wire.write(enviar);
  return;
}

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

, 👍0

Обсуждение

Вы запрашиваете данные от ведомого устройства Arduino в своем мастер-коде?, @chrisl

Наверняка я, согласно документации https://os.mbed.com/docs/mbed-os/v5.12/apis/i2c.html, я выполняю i2c.read(addr, pointer, length); но я не получаю никаких извлеченных данных, поэтому я хотел знать, в порядке ли скетч, поэтому мне нужно было проверить, что происходит с тем, как я обрабатываю инструкцию чтения на устройстве ARM., @Fjallbacka

Вы можете реализовать функцию обратного вызова onRequest и активировать там светодиод, чтобы вы могли проверить, действительно ли запрос достигает Arduino., @chrisl

Я сделал это, и действительно я получаю уведомление о запросе. И, к моему удивлению, если я выполню запись, сообщение будет отправлено! Спасибо приятель! Опубликуйте это как ответ, и я проголосую за него. Еще раз спасибо!, @Fjallbacka


1 ответ


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

1

Важно понимать, что Wire.write() на самом деле не будет отправлять данные по шине I2C. В буфер отправки библиотеки будут помещены только байты данных.

Обычным способом отправки данных библиотекой Wire в качестве ведомого является реализация функции обратного вызова onRequest. Он будет вызываться из I2C ISR, когда мастер на шине I2C запрашивает данные у этого ведомого. В обратном вызове вы используете Wire.write() для заполнения буфера данными, которые затем отправляются мастеру.

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


Примечание. В коде вы вызываете Wire.onReceive(receiveEvent) на каждой итерации void loop(). Это не обязательно. Метод Wire.onReceive() устанавливает только указатель функции на функцию обратного вызова. Он НЕ выполняет эту функцию обратного вызова, которая будет вызываться соответствующим I2C ISR только при фактическом получении данных. Вы должны использовать эту строку только один раз в setup() для настройки функции обратного вызова. Хотя использование его несколько раз ничего здесь не ломает. Это просто бесполезно.

,