I will be attempting to communicate between two arduinos via I2C. One will be the slave and the other the master.
My question is, when the one arduino sends to the slave, for example:
Wire.send(something);
and the slave reads it:
boolean ex = Wire.receive();
does the arduino that is Listening for data get delayed? If one arduino is sending data but it has ALOT of computations and once done, it sends the data, then what does the other Arduino do during the time it hasnt received any data? Will it sit idle waiting for data or can it run more code in the loop?
I will be using the: Wire.onReceive(callFunction); which seems like when DATA is sent, it will trigger callFunction which is a function that will run once data is received. Seems like this acts like an interrupt.
I want to do this so I do not incur any delays in the master arduino that is reading the data sent from the other arduino.
Sorry if this is very confusion but your help is appreciated.
so I do not incur any delays in the master arduino that is reading the data sent from the other arduino
It is transferring data, this takes time, therefore there will be delays.
The slave only sends data to the master when the master requests it. Therefore the master will be waiting for data after the request. The salve has a function that is evoked by interrupts when ever a request is received so it will service that request at the expense of any processing it is currently doing.
#include <Wire.h>
int LED = 2;
void setup()
{
Wire.begin(4); // set the address for slave as 0x04
Wire.onReceive(receiveEvent); //
pinMode(LED,OUTPUT);
}
void loop()
{
delay(100);
}
// that executes whenever data is received from master
// this is registered as an event, see setup()
void receiveEvent(int howMany)
{
int c = Wire.read(); // receive byte as a character
if(c==1)
{
digitalWrite(LED,HIGH);
}
else if(c==0)
{
digitalWrite(LED,LOW);
}
}
Using the serial monitor, input 1 and 2 to master so as to control the led of slave on and off.
I use receiveEvent(), whichexecutes whenever data is RECEIVED from master. So you can view it like an interrupt.
Keep in mind that IIC bus can NOT read and send as the same time, which is a big different from SPI bus.
I paste a code for slave and master. I've already test it on Arduino 1.0
Why? This code is already loaded into the arduino software on the computer in the examples menu item.
IIC bus can NOT read and send as the same time
A slave should only be transmitting when the master asked it to, there is no way you could or should try to get it to transmit and recieve at the same time.
So you guys are saying, when the Master asks for data form the slave, that is when the slave will being computation and therefore, the master will wait until it receives data.
So the issue here is, the master is as strong as the weakest link in the I2C line. For example, if my I2C takes 10ms to compute and ouput a few numbers, the master will wait 10ms on its side to retrieve the data and NOT run any code.
Basically the master has to wait until it gets all the data it is expecting in. There is a time out in case it does not reply to stop the system from hanging but basically yes. The whole protocol was not designed for aysynchronous data transfer.
I see. Is SPI better in this case? Issue with SPI is that baud rate cannot be as high as I2C and I also do not know if arduino's can communicate via SPI together.
Let me explain what I want to do. I have a computational expensive algorithm that runs at 125 hertz. So to remove the bottleneck on my main controller I wanted to have the algorithm residing on a separate controller that will spit out data when the main controller requests it.
The main controller will act as the brain and handle other actions and request the data when it needs to. If I have to wait 8ms (1/125 hz) to get the data each time, then it is the same as having the main controller running the algorithm.
I hope I was able to be clear. Thanks for your time and any help is appreciated.
Issue with SPI is that baud rate cannot be as high as I2C
No this is wrong. I2C runs at 100KHz where as SPI can run up to 2MHz.
I also do not know if arduino's can communicate via SPI together.
They would have to be synchronised, that is they would both have to do it at the same time, giving you more problems than the I2C.
Why not use just serial, the serial input is buffered until you need it.
That was my initial requirement to use Serial. But with more testing via TX and RX, i cannot put more devices on the same serial line such as Bluetooth and my board.
Do you recommend that I use SoftwareSerial and use two different pins for Serial line pins 6,7 or something? Would that work?
Then I can use, newSerial.Available() to wait for data on the line and it can run code in the meantime when data is not available?
Yes. Program your slave device to change the state of one of the digital pins after the computation and when the new data is available. The master will see the digital pin go low/high and knows new data is available. Then you can retrieve the data using I2C/SPI/Serial or whatever.