Arduino-Uno通过I2C从树莓派接收1或2个字节

Arduino-Uno receive 1 or 2 bytes from Raspberry Pi over I2C

本文关键字:2个 字节 I2C 通过 Arduino-Uno      更新时间:2023-10-16

我需要通过I2C从我的树莓派发送一些数据到我的Arduino Uno。我希望Arduino用pwm转动一些电机,并从Raspi接收数据(哪个电机有多快)。

我把它连接起来,编码了一点,它就工作了。但是如果我提高传输速度,因为我需要马达每毫秒改变一次速度,arduino就会把一切都搞砸。

在我的Pi上,我得到了运行在cpp(简化)中的测试代码:

file = open(deviceName, O_RDWR);
uint8_t command[2] = {motorNum, pwm};
while(1) {
  write(file, command, 2);
  usleep(someTime);
}

Arduino上的代码:

#include <Wire.h>
#define SLAVE_ADDRESS 0x04
byte pwm[] = {3, 9, 10, 11};
void setup() {
  Serial.begin(9600); // start serial for output
  Wire.begin(SLAVE_ADDRESS);
  Wire.onReceive(receiveData);
  Serial.println("Ready!");
}
void loop() {
  delay(10);
}
void receiveData(int byteCount) {
  byte motor = Wire.read(); //should be between 0 and 4
  byte freq = Wire.read(); //should be between 150 and 220
  if(motor == 4) { //all motors same speed
    Serial.print("All Motors with pwm: ");
    Serial.println(freq);
    for(byte i=0; i<4; i++) analogWrite(pwm[i], freq);
  } else {
    Serial.print("Motor: ");
    Serial.print(motor);
    Serial.print(" with pwm: ");
    Serial.println(freq);
    analogWrite(pwm[motor], freq);
  }
  if(Wire.available())
    Serial.println("...more than 2 bytes received");
}

如果我将' sometimes '在我的raspi代码中设置为50000 (=50ms),一切工作正常,我在arduino上得到了这个输出:

Ready!
Motor: 0 with pwm: 100
Motor: 0 with pwm: 100
Motor: 0 with pwm: 100
Motor: 0 with pwm: 100
Motor: 0 with pwm: 100
Motor: 0 with pwm: 100
Motor: 0 with pwm: 100
Motor: 0 with pwm: 100
Motor: 0 with pwm: 100
Motor: 0 with pwm: 100
Motor: 0 with pwm: 100
Motor: 0 with pwm: 100

现在似乎没有必要,但它只是用于测试。问题发生了,如果我增加速度,意味着减少我的pi上的'someTime'到1000(=1ms),我得到这个:

Ready!
Motor: 0 with pwm: 100
Motor: 0 with pwm: 100
Motor: 0 with pwm: 100
Motor: 8 with pwm: 0
...more than 2 bytes received

我不知道这里有什么问题,因为很明显arduino无法处理这个速度。我已经尝试在pi和arduino上增加i2c波特率:

 sudo nano /etc/modprobe.d/i2c.conf
 ->  options i2c_bcm2708 baudrate=400000

Wire.begin(SLAVE_ADDRESS);
TWBR = 12; //should be 400khz

,甚至把twi.h改成:

#define TWI_FREQ 400000L

到目前为止没有任何效果。我尝试了每一个低于50毫秒的速度,但几乎每次都失败了。有没有办法在没有Wire lib的情况下做到这一点,因为我读到它非常慢。

谢谢你的帮助

我想我找到解决办法了:

Serial.begin();
Serial.print(...);

花费太多时间,或者使arduino不知何故忙碌,以至于他不能足够快地从i2c收集数据。我注释了所有的连写,我可以把'someTime'降为1,所以这很简洁。