Hey guys,
I used to have a master Arduino control 5 to 10 other Arduinos and communicate through I2C without much issue. The master constantly wrote 2 bytes, waited 2 milliseconds, and then read the results.
Recently I decided to switch the master to Raspberry pi. I ported the code over and tested I2C with i2cdetect and by testing it through a simple code. It worked and I was able to send and receive data.
The issue I'm having is that if I read a bunch of times the Arduino will lock up. I even lowered my main loop frequency to 50 Hz and it still often fails to write to the I2C and locks up. I'm attaching a simplified snippet of my code on raspberry pi just as a reference. I know that with Arduino I had to put a 2 milliseconds delay or the data would not be reliable, but I don't have such timer on raspberry pi anymore. Would that be the culprit? Has anybody else experienced something similar?
Thanks in advance,
int main(void)
{
//-------------- OPEN THE I2C BUS--------------------------
char *filename = (char*)"/dev/i2c-1";
if((file_i2c = open(filename, O_RDWR))< 0 ){
//ERROR HANDLING: you can check errno to see what went wrong;
cout << "Failed to open the i2c bus" << endl;
return 0;
}
while(1){
if (loopTime.check()) { // A timer class to make sure that it only runs every so often
loopTime.reset();
cout << sendCmd_d(0x03, 40, 42);
}
}
return 0;
}
float sendCmd_d(uint8_t SlaveDeviceID, uint8_t cmd1, uint8_t cmd2) {
// Check to see if you can gain access to the I2C port
if (ioctl(file_i2c, I2C_SLAVE, SlaveDeviceID) < 0){
cout << "Failed to acquire bus access and/or talk to slave" << endl;
//ERROR HANDLING: you can check errno to see what went wrong;
}
uint8_t buffer[2] = {0};
buffer[0] = cmd1;
buffer[1] = cmd2;
uint8_t length = 2; //<<<<< Number of bytes to write
if (write(file_i2c, buffer, length) != length){ // write() returns the number of bytes actually written, if it doesn't match then an error occurred (e.g. no response from the device)
// ERROR HANDLING: i2c transaction failed
cout << "Failed to write to the i2c bus " << SlaveDeviceID << endl;
}
// GET RESPONSE
if (cmd1 == get_info_cmd || cmd1 == get_pos_cmd) {
length = sizeof(float);
float2byte_t data;
if (read(file_i2c, data.b , length) != length){ // read() returns the number of bytes actually read, if it doesn't match then an error occurred (e.g. no response from the device)
//ERROR HANDLING: i2c transaction failed
cout << " Failed to read from the i2c bus" <<SlaveDeviceID << endl;
} else {
return data.f;
}
}
return 0;
}