简体   繁体   中英

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

I need to send some data from my Raspberry Pi to my Arduino Uno via I2C. I want the Arduino to turn some motors with pwm and receive the data (which motor how fast) from the Raspi.

I wired it up, coded a bit and it worked. But if I increase the transmission speed, because I need the motors to change their speed every ms, the arduino kind of screws everything up.

On my Pi I got the test code running in cpp(simplyfied):

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

Code on the 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");

}

If I set the 'someTime' in my raspi code to 50000 (=50ms) everything works fine, and I got this output on my 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

which seems unneccessary for now, but its just for testing. The problem occurs, if i increase the speed, means decrease the 'someTime' on my pi to 1000(=1ms), I get this:

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

I dont know whats wrong here, cause obviously the arduino cant handle the speed. I already tried to increase the i2c-baudrate on the pi and arduino with:

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

and

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

or even changing the twi.h to:

#define TWI_FREQ 400000L

nothing worked so far. I tried every speed below 50ms, but almost everytime it failed. Is there some way to do this without the Wire lib, because I read that it is very slow.

Thanks for your help

I think I found a solution:

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

takes so much time, or keeps the arduino somehow busy, that he doesn't collect the data from the i2c fast enough. I commented all serial writings out and I was able to drop the 'someTime' down to 1, so thats pretty neat.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM