【问题标题】:Arduino I²C slave onReceive failsArduino I²C slave onReceive 失败
【发布时间】:2015-07-01 19:58:24
【问题描述】:

我的 Arduino 和 Raspberry Pi 2 目前有一些问题。

我在 Arduino 和 Pi 之间建立了一个有效的 I²C 连接。我将 Arduino 配置为从机。

一些简单的测试奏效了。但是,当我在 I²C 上继续使用 Arduino 约 5 分钟(实际时间是随机的)时,我使用 Wire.onReceive 注册的函数停止被调用。 Arduino 不断根据请求发送值,但似乎完全忽略了发送给它的任何数据。

到目前为止我测试过的内容:

  • 删除 Arduino 上的所有引脚写入和读取
  • 增加来自 Pi 的两个请求之间的延迟。这似乎只是增加了它的工作时间。最终还是失败了
  • 经常重新注册函数

这是 Arduino 上的代码:

#include <Wire.h>

const byte ADDRESS = 0x4E;
const byte FLAG_PWM = 0x80;

byte states[22] = {OUTPUT, OUTPUT, OUTPUT, OUTPUT, OUTPUT, OUTPUT, OUTPUT, OUTPUT, OUTPUT, OUTPUT, OUTPUT, OUTPUT, OUTPUT, OUTPUT, OUTPUT, OUTPUT, OUTPUT, OUTPUT, OUTPUT, OUTPUT, OUTPUT, OUTPUT};
byte request;

void setup() {
  Wire.begin(ADDRESS);
  Wire.onReceive(receiveEvent);
  Wire.onRequest(requestEvent);
}

void loop() {
  delay(100);
}

// At some point this function isn't called anymore. (request doesn't change)
void receiveEvent(int howMany) {
  byte byteIN = Wire.read();
  boolean pwm = byteIN & FLAG_PWM;

  byteIN &= ~FLAG_PWM;

  if (byteIN > 21)
    return;

  if (howMany == 1) {
    request = byteIN;

    if (states[byteIN] != INPUT)
      pinMode(byteIN, INPUT);
  } else if (howMany == 2) {
    if (states[byteIN] != OUTPUT)
        pinMode(byteIN, OUTPUT);

    byte value = Wire.read();

    // Disabling this does not help
    if (pwm)
      analogWrite(byteIN, value);
    else
      digitalWrite(byteIN, value);
  }
}

// This function keeps working after the other failed.
void requestEvent() {
  if (request < A0) {
    // Disabling this does not help
    byte value = digitalRead(request);

    Wire.write(&value, 1);
  } else {
    // Disabling this does not help
    int value = analogRead(request);

    Wire.write((char*)&value, 2);
  }
}

现在我无法访问 Pi 上的代码。但如果需要,我可以在这里发布。

树莓派大约每 20 毫秒请求一次读取。

我想不出什么可能是错的......

【问题讨论】:

  • 你能发布你处理 i2c 的部分代码吗?如果您重新启动两个设备,它会再次开始工作吗?我假设您使用了电平转换器和所有东西,因为 Rpi 是 3v3 设备而 arduino 是 5v 设备。
  • @dastaan​​ 当我重置 Arduino 时它已经工作了。
  • @dastaan​​ 是的。我正在使用电平转换器。
  • @BrainStone 你有没有到任何地方?我还使用 pi 通过 I2C 与 Arduino 对话,并且 onReceive() 在 30 秒左右后停止被调用。
  • @Bort 是的,我最终解决了它。但我不记得我做了什么。我现在可以访问代码。如果我没记错的话,睡眠时间太短或太少了。

标签: arduino raspberry-pi i2c raspberry-pi2


【解决方案1】:

我不是专家,但 Wire 中有一个函数可以检查是否有可用的内容可供阅读:

String DecodeUri()
{
  String ret = "";
  while (1 < Wire.available())
  {
     ret += (char)Wire.read();
  }
    ret += (char)Wire.read();
 return ret;
}

你可以检查howMany来检查你是否可以阅读。

另外一件奇怪的事情是,如果我使用电量不足的电池,I2C 就会变得奇怪。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-03-15
    • 1970-01-01
    • 2021-10-07
    • 1970-01-01
    • 2021-10-17
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多