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.