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?
1 Answer 1
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.
delay
inside an interrupt routine isn't adviced. Try usingdelayMicroseconds(60000000)
. Also from reading the documentation, you only need to callWire.onRequest(returnData);
once, so you should move that to thesetup
routine.