3

I am currently trying to communicate between 3 Arduinos using I2C. One of them acts as a master, while the rest act as slaves.

I can request data correctly from the master. But if I were to do 2 consecutive requests, I will only get data for the last request. Please assist.

Master:

#include <Wire.h>
#define BLUNO_SLAVE 0x09
#define BLUNO_SLAVE_2 0X0A
void setup() {
 Serial.begin(115200);
 Wire.begin();
 Serial.println("Initialized as Master");
 Serial.println("Reading from slave 1 now..");
 //Wire.beginTransmission(BLUNO_SLAVE);
 Wire.requestFrom(BLUNO_SLAVE, 25); //char occupy 1 byte
 //Wire.endTransmission();
 Serial.println("Reading from slave 2 now..");
 Wire.requestFrom(BLUNO_SLAVE_2, 30);
}
void loop () {
 while(Wire.available()) {
 char c = Wire.read();
 Serial.print(c);
 }
}

Slave 1:

#include <Wire.h>
void setup() {
 Serial.begin(115200);
 Wire.begin(0x09); //slave address
 Serial.println("Serials initialized");
}
void loop() {
 Wire.onRequest(returnData);
}
void returnData() {
 Wire.write("received master's request");
}

Slave 2:

#include <Wire.h>
void setup() {
 Serial.begin(115200);
 Wire.begin(0x0A); //slave address
 Serial.println("initialized!");
}
void loop() {
 Wire.onRequest(returnData);
}
void returnData() {
 delay(60000); //60 * 1000 = 60 seconds
 Wire.write("Lat: 103.123456, Lon: 1.098765");
}

Output on the master:

Initialized as Master
Reading from slave 1 now..
Reading from slave 2 now..
Lat: 103.123456, Lon: 1.098765

On top of that, I do not understand why the 1 minute delay was not executed before the slaves write the GPS coordinates.

I figured out from http://playground.arduino.cc/Main/WireLibraryDetailedReference that each call to the requestFrom() method, RESETS the read buffer. I looked at my code back and I saw a silly mistake on the master code. So, I corrected the master code:

#include <Wire.h>
#define BLUNO_SLAVE 0x09
#define BLUNO_SLAVE_2 0X0A
void setup() {
 Serial.begin(115200);
 Wire.begin();
 Serial.println("Initialized as Master");
 Serial.print("Slave 1: ");
 Wire.requestFrom(BLUNO_SLAVE, 25); //char occupy 1 byte
 readData();
 //each call to requestFrom, RESETs the read buffer index
 Serial.println();
 Serial.print("Slave 2: ");
 Wire.requestFrom(BLUNO_SLAVE_2, 30);
 readData();
}
void loop () {
}
void readData () {
 while(Wire.available()) {
 char c = Wire.read();
 Serial.print(c);
 }
}

But still, I don't understand why slave2 writes the data immediately instead of waiting for 1 minute?

dda
1,5951 gold badge12 silver badges17 bronze badges
asked Jul 29, 2014 at 3:56
4
  • Using delay inside an interrupt routine isn't adviced. Try using delayMicroseconds(60000000). Also from reading the documentation, you only need to call Wire.onRequest(returnData); once, so you should move that to the setup routine. Commented Jul 29, 2014 at 10:13
  • @Gerben When I implement delayMicroseconds(60000000), it just hangs there. It does not write to the master at all. Even if I changed it to just delayMicroseconds(10), it does not write to the master. Commented Jul 30, 2014 at 1:26
  • Slave also cannot execute any codes inside a for loop. Commented Jul 30, 2014 at 2:01
  • I'm not sure I2C even allows extended pauses during communication. Maybe it just times-out. Commented Jul 30, 2014 at 11:49

1 Answer 1

2

I recommend you to just set a semaphore inside your handler. When your handler is called, set it, nothing more. In your main loop, poll for this semaphore and do your communication when true. When you receive this semaphore you can easily wait as long as you like without breaking interrupt handling. As interrupt service routines should always be as short as possible, both in terms of time and code, it is generally a bad idea to do complex communication from within or wait for something.

And don't forget the "volatile" keyword for your semaphore.

answered Oct 27, 2014 at 23:12

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

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.