0

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

1 Answer 1

0

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.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.