SOLVED: problem with i2c repeated start

Hello folks,

I have a problem with the wire library. I dont know if i make a mistake or the lib doesnt work. I really dont know. I tried using google etc, but it didnt answer my questions. :frowning:

Maybe you guys can help me. Its pretty simple:

I have two arduinos. Arduino A (Duemilanove) and Arduino B (Nano)
Arduino A sends via i2c a command to Arduino B.
Arduino B answers to Arduino A.
This are only 2 Arduinos, but later i want to add more. Everyone is a master. So we have a multimaster setup.
To prevent other Arduinos to interfere the communication between Arduino A and B, A has to keep the connection alive after sending the command. So with the help of google and some other sources i made up some Arduino code i want to show you:

Arduino A:

#include <Wire.h>
#define THIS_ADDRESS 0x8
#define OTHER_ADDRESS 0x9

void setup() {
  
  Serial.begin(9600);
  Wire.begin(THIS_ADDRESS);
}

void loop() {
  Wire.beginTransmission(OTHER_ADDRESS);
  Wire.write(0x12);
  Wire.endTransmission(false);                              //dont send stop condition, keeping connection alive.
  Wire.requestFrom(OTHER_ADDRESS,1);
  byte c = Wire.read();
  Serial.println(c,HEX);
  delay(5000);
}

Arduino B:

#include <Wire.h>
#define THIS_ADDRESS 0x9
#define OTHER_ADDRESS 0x8

byte k = 0;
void setup() {
  Serial.begin(9600);
  Wire.begin(THIS_ADDRESS);
  Wire.onReceive(receiveEvent);
  Wire.onRequest(requestEvent); 
}

void loop() {
  delay(1000);
}

void receiveEvent(int howMany) {
 k = Wire.read();
 Serial.print("in: ");
 Serial.println(k,HEX); 
}

void requestEvent() {
  if (k == 0x12) {
    Wire.write(0x13);
     Serial.print("out: ");
     Serial.println(0x13,HEX); 
  } else {
    Wire.write(0x77);
  }
  k = 0;  
}

I know about the false-parameter of the Wire.endTransmission() function. But my problem is:
Arduino B does NOT trigger the requestEvent(). Whats wrong with my code? Is it on A-side oder B-side?

When i delete the "false"-parameter of the Wire.endTransmission, i can run the code without any probs, but i know between the write operation and the read operation is a short break and another master can interfere the communcation.

So, english is not my first language, so have mercy with me :slight_smile:

Hi syrix

Does it make a difference if you remove the serial print statements from receiveEvent() and requestEvent() on Arduino B?

This thread had a problem that sounds similar: Wire.onReceive() and Wire.onRequest() interference - Interfacing - Arduino Forum

Regards

Ray

Hackscribble:
Does it make a difference if you remove the serial print statements from receiveEvent() and requestEvent() on Arduino B?

I tried it without the Serial.prints, but the problem still persists. (i checked the Serial.print from Arduino A)

Arduino A sends a 0x12 and should get a 0x13 back. But instead of this, i get a 0xFF (because of the missing requestEvent).

I assume that Arduino B will still be a slave? The multiple Arduino As will be masters?

Yes, that's the plan. But later B should initiate a communication as well. So, in theory, we have masters everywhere.

I think the code from Arduino A should be OK, i saw it everywhere on the internet. But i am not sure with the code from Arduino B.... :frowning:

I've found a couple of threads dating to 2012 that highlight a bug in the Wire library (or a library called by it) that affects slave mode and repeated starts.

https://code.google.com/p/arduino/issues/detail?id=848

http://forum.arduino.cc/index.php/topic,125704.0.html

They both refer to a library patch. Might be worth trying?

You, sir, are awesome!

It seems to work now!

Thank you!!

Thank you :slight_smile:

To confirm, this was the fix?

... workaround is to comment out "twi_stop()" in Wire/utility/twi.c:411

No, i found this link in your arduino-forum link:

i commented out the line 468 in the twi.c